/** * Shared design tokens + KPI data for the AI Logistics Optimization section. * Centralizing here keeps the 3D scene, overlay and metrics panel in sync. */ export const COLORS = { bg: "#020617", cyan: "#00E5FF", green: "#22C55E", red: "#EF4444", amber: "#F59E0B", ink: "#0B1220", slate: "#64748B", textDim: "rgba(226,232,240,0.66)", } as const; /** rgba helper used by inline styles + scoped CSS. */ export function rgba(hex: string, alpha: number): string { const h = hex.replace("#", ""); const r = parseInt(h.substring(0, 2), 16); const g = parseInt(h.substring(2, 4), 16); const b = parseInt(h.substring(4, 6), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; } export type Kpi = { key: string; /** numeric value the counter animates between */ before: number; after: number; prefixBefore?: string; prefixAfter?: string; suffix?: string; labelBefore: string; labelAfter: string; /** lower number is the better outcome (drives the up/down arrow) */ goodWhenLower: boolean; }; export const KPIS: Kpi[] = [ { key: "distance", before: 312, after: 182, suffix: " km", labelBefore: "Route Distance", labelAfter: "Route Distance", goodWhenLower: true, }, { key: "vehicles", before: 8, after: 5, labelBefore: "Vehicles", labelAfter: "Vehicles", goodWhenLower: true, }, { key: "orders", before: 59, after: 59, labelBefore: "Orders", labelAfter: "Orders Fulfilled", goodWhenLower: false, }, { key: "delayed", before: 23, after: 0, labelBefore: "Delayed", labelAfter: "Delayed", goodWhenLower: true, }, { key: "cost", before: 18, after: 18, prefixBefore: "+", prefixAfter: "−", suffix: "%", labelBefore: "Cost Overrun", labelAfter: "Cost Saved", goodWhenLower: false, }, ]; /** * Scroll-phase thresholds (normalized 0 → 1). The whole narrative is driven by * a single scroll progress value shared between GSAP, R3F and Framer Motion. */ export const PHASES = { chaos: 0.0, // Stage 1 & 2: Network appears & vehicles active scan: 0.28, // Stage 3: AI scans routes dissolve: 0.42, // Stage 4 & 5: Optimize begins & bad routes dissolve optimize: 0.56, // Stage 6: Optimized routes appear reorganize: 0.70, // Reassigning vehicles metrics: 0.84, // Stage 7: KPIs update & complete } as const; export type PhaseKey = keyof typeof PHASES; export function phaseFromProgress(p: number): PhaseKey { if (p >= PHASES.metrics) return "metrics"; if (p >= PHASES.reorganize) return "reorganize"; if (p >= PHASES.optimize) return "optimize"; if (p >= PHASES.dissolve) return "dissolve"; if (p >= PHASES.scan) return "scan"; return "chaos"; } export const PHASE_LABELS: Record = { chaos: "Monitoring network", scan: "AI SCANNING NETWORK", dissolve: "AI OPTIMIZING ROUTES", optimize: "AI OPTIMIZING ROUTES", reorganize: "AI REASSIGNING VEHICLES", metrics: "AI COMPLETE", };