update solution page

This commit is contained in:
2026-07-20 13:33:30 +05:30
parent c29dc64c38
commit ca83f34b11
46 changed files with 4058 additions and 146 deletions

View File

@@ -259,7 +259,7 @@ export default function ConnectedLogistics() {
</div>
<div className="elementor-element elementor-element-165dfa5 elementor-widget__width-initial elementor-widget elementor-widget-text-editor" data-id="165dfa5" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
<div className="elementor-widget-container">
<p>Learn from every delivery. Get smarter with every mile traveled.</p>
<p>Learn from every shipment. Get smarter with every mile traveled.</p>
</div>
</div>
</ScrollReveal>

View File

@@ -13,7 +13,7 @@ const CARDS_DATA = [
{
index: 1,
title: "Operational Visibility",
desc: "Real-time tracking and centralized control provide complete visibility across every shipment, vehicle, and delivery milestone.",
desc: "Real-time tracking and centralized control provide complete visibility across every shipment, vehicle, and logistics milestone.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<rect x="2" y="7" width="16" height="10" rx="2" ry="2" />
@@ -26,7 +26,7 @@ const CARDS_DATA = [
{
index: 2,
title: "Intelligent Routing",
desc: "AI-powered route optimization reduces travel time, improves delivery accuracy, and maximizes fleet utilization.",
desc: "AI-powered route optimization reduces travel time, improves routing accuracy, and maximizes fleet utilization.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
@@ -49,7 +49,7 @@ const CARDS_DATA = [
{
index: 4,
title: "Scalable Network",
desc: "Flexible logistics infrastructure supports growth across cities, regions, and high-volume delivery operations without disruption.",
desc: "Flexible logistics infrastructure supports growth across cities, regions, and high-volume logistics operations without disruption.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 3.5 2 5.5a7 7 0 0 1-7 7h-3" />

View File

@@ -135,7 +135,7 @@ const DEFAULT_FEATURES: EVFeature[] = [
</svg>
),
title: "Charging Integration",
desc: "Seamlessly integrate charging stops without compromising delivery windows or SLA commitments.",
desc: "Seamlessly integrate charging stops without compromising arrival windows or SLA commitments.",
},
{
icon: (
@@ -352,7 +352,7 @@ export default function EVSection({
titleAccent = "NOT ADAPTED.",
features = DEFAULT_FEATURES,
image = "/images/premium-ev-van.webp",
imageAlt = "DoorMile electric delivery van",
imageAlt = "DoorMile electric fleet van",
badges = DEFAULT_BADGES,
stats = DEFAULT_STATS,
gapTop = false,

View File

@@ -301,8 +301,8 @@ export default function HowItWorksHero() {
<div className="text-content">
<p>
See how Doormile connects first, mid, and
last mile into a seamless delivery
experience powered by MileTruth AI.
last mile into a seamless end-to-end
logistics experience powered by MileTruth AI.
</p>
</div>
</div>
@@ -341,8 +341,8 @@ export default function HowItWorksHero() {
<div className="text-content">
<p>
See how Doormile connects first, mid, and
last mile into a seamless delivery
experience powered by MileTruth AI.
last mile into a seamless end-to-end
logistics experience powered by MileTruth AI.
</p>
</div>
</div>

View File

@@ -197,7 +197,7 @@ export default function IndexHero() {
</h1>
<div className="content-slider-item-text logico-content-wrapper-2" style={{ display: "flex", justifyContent: "center", width: "100%", marginTop: "23px" }}>
<div className="text-content" style={{ textAlign: "center", maxWidth: "680px", margin: "0 auto" }}>
<p>Stop managing three separate logistics services. Doormile unifies first, mid and last mile into a single intelligent delivery system powered by MileTruth AI.</p>
<p>Stop managing three separate logistics services. Doormile unifies first, mid and last mile into a single intelligent logistics system powered by MileTruth AI.</p>
</div>
</div>
</div>

View File

@@ -189,7 +189,7 @@ export default function IndustrySolutions() {
<h5 className="industry-card-section-title">Doormile Solutions</h5>
<ul className="industry-card-list">
<li className="industry-card-list-item bullet-4">AI-driven demand-responsive routing</li>
<li className="industry-card-list-item bullet-5">Freshness-aware delivery prioritization</li>
<li className="industry-card-list-item bullet-5">Freshness-aware shipment prioritization</li>
<li className="industry-card-list-item bullet-6">Dynamic batch optimization</li>
</ul>
</div>
@@ -246,7 +246,7 @@ export default function IndustrySolutions() {
<ul className="industry-card-list">
<li className="industry-card-list-item bullet-1">Cold chain integrity requirements</li>
<li className="industry-card-list-item bullet-2">Regulatory compliance tracking</li>
<li className="industry-card-list-item bullet-3">Critical delivery time windows</li>
<li className="industry-card-list-item bullet-3">Critical shipment time windows</li>
</ul>
</div>
<div>
@@ -303,13 +303,13 @@ export default function IndustrySolutions() {
<div className="industry-card-hover-content">
<div className="industry-card-hover-top">
<p className="industry-card-description">
High-value shipments with complex delivery requirements.
High-value shipments with complex logistics requirements.
</p>
<div>
<h5 className="industry-card-section-title">Challenges</h5>
<ul className="industry-card-list">
<li className="industry-card-list-item bullet-1">Appointment scheduling coordination</li>
<li className="industry-card-list-item bullet-2">White-glove delivery standards</li>
<li className="industry-card-list-item bullet-2">White-glove logistics standards</li>
<li className="industry-card-list-item bullet-3">Multi-location routing complexity</li>
</ul>
</div>

View File

@@ -22,15 +22,15 @@ const SECTIONS: Section[] = [
image: "/images/tab-pic-1-solution.webp",
alt: "FMCG logistics",
desc:
"FMCG logistics demands speed, precision, and continuous fulfillment across high-volume delivery networks. Businesses must balance tight delivery timelines, inventory movement, and operational efficiency without compromising product availability.",
"FMCG logistics demands speed, precision, and continuous fulfillment across high-volume logistics networks. Businesses must balance tight shipment timelines, inventory movement, and operational efficiency without compromising product availability.",
ch: [
"Unpredictable demand spikes create delivery pressure and reduce operational efficiency during peak periods.",
"Fresh product expiry constraints require faster, precisely timed deliveries to maintain product quality.",
"Multi-stop route complexity increases travel time, operational costs, and delivery coordination challenges.",
"Inventory stockout risks increase when delivery delays disrupt fast-moving product distribution.",
"Unpredictable demand spikes create logistics pressure and reduce operational efficiency during peak periods.",
"Fresh product expiry constraints require faster, precisely timed shipments to maintain product quality.",
"Multi-stop route complexity increases travel time, operational costs, and logistics coordination challenges.",
"Inventory stockout risks increase when shipment delays disrupt fast-moving product distribution.",
],
so: [
"AI demand forecasting adapts delivery plans instantly to real-time order demand.",
"AI demand forecasting adapts logistics plans instantly to real-time order demand.",
"Expiry-aware routing prioritises perishable goods for on-time freshness.",
"Smart multi-stop optimisation groups orders to cut cost and travel time.",
"Real-time inventory sync prevents stockouts and improves fulfilment accuracy.",
@@ -42,17 +42,17 @@ const SECTIONS: Section[] = [
image: "/images/tab-pic-2-solution.webp",
alt: "Pharma logistics",
desc:
"Pharma logistics requires precision, compliance, and real-time monitoring so every shipment arrives safely and on time — from temperature-sensitive medicines to urgent emergency deliveries.",
"Pharma logistics requires precision, compliance, and real-time monitoring so every shipment arrives safely and on time — from temperature-sensitive medicines to urgent emergency shipments.",
ch: [
"Cold chain integrity demands precise temperature control throughout transit.",
"Regulatory compliance must be tracked and documented on every delivery.",
"Critical delivery time windows require highly accurate scheduling.",
"Regulatory compliance must be tracked and documented on every shipment.",
"Critical arrival windows require highly accurate scheduling.",
"Emergency shipments need instant dispatch and zero-delay execution.",
],
so: [
"Cold chain monitoring with automatic re-routing keeps shipments in-spec.",
"Compliance engine with audit trails ensures full chain-of-custody visibility.",
"Precision scheduling locks in critical delivery windows reliably.",
"Precision scheduling locks in critical arrival windows reliably.",
"Priority dispatch queue fast-tracks urgent, life-critical shipments.",
],
},
@@ -65,14 +65,14 @@ const SECTIONS: Section[] = [
"Enterprise and B2B logistics require coordination and reliability to manage high-value shipments at scale — with appointment scheduling, white-glove standards, and strict SLA commitments.",
ch: [
"Appointment scheduling requires precise timing across many locations.",
"White-glove delivery standards demand premium handling and accuracy.",
"White-glove logistics standards demand premium handling and accuracy.",
"Multi-location routing complexity grows with large-scale operations.",
"Strict SLA commitments pressure teams to stay timely and error-free.",
],
so: [
"Intelligent appointment engine streamlines and automates delivery slots.",
"Intelligent appointment engine streamlines and automates arrival slots.",
"White-glove workflow module enforces premium handling end to end.",
"Enterprise route planner coordinates efficient multi-location delivery.",
"Enterprise route planner coordinates efficient multi-location logistics.",
"SLA monitoring dashboard tracks commitments and flags risk in real time.",
],
},

View File

@@ -0,0 +1,164 @@
"use client";
import React, { useMemo, useRef } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { Sparkles } from "@react-three/drei";
import { EffectComposer, Bloom } from "@react-three/postprocessing";
import { KernelSize } from "postprocessing";
import * as THREE from "three";
/* ============================================================
MileTruthCanvas — small, self-contained R3F scene for the
"MileTruth AI" section: a 4-node data → AI → recommendations →
improvement network with glowing cores and travelling light
packets along each connector. Deliberately lightweight (a
handful of meshes + a low-count sparkle field) — this and the
Quantum section are the ONLY two places on the Solutions page
that touch Three.js.
============================================================ */
const RED = "#C01227";
const RED_BRIGHT = "#E2354A";
const STEEL = "#8b8b96";
const WHITE = "#f4f4f6";
type Node = { pos: [number, number, number]; color: string; label: string; scale: number };
const NODES: Node[] = [
{ pos: [-4.6, 0.3, 0], color: STEEL, label: "data", scale: 0.34 },
{ pos: [-1.6, 0.75, 0.4], color: RED, label: "ai", scale: 0.46 },
{ pos: [1.5, 0.25, -0.35], color: RED_BRIGHT, label: "recs", scale: 0.38 },
{ pos: [4.5, -0.15, 0.15], color: WHITE, label: "improve", scale: 0.34 },
];
const LINKS: [number, number][] = [
[0, 1],
[1, 2],
[2, 3],
];
function NodeMesh({ node, reduced, seed }: { node: Node; reduced: boolean; seed: number }) {
const meshRef = useRef<THREE.Mesh>(null);
const haloRef = useRef<THREE.Mesh>(null);
useFrame((state) => {
const t = state.clock.elapsedTime;
const pulse = reduced ? 1 : 1 + Math.sin(t * 1.6 + seed) * 0.08;
if (meshRef.current) meshRef.current.scale.setScalar(node.scale * pulse);
if (haloRef.current) {
const haloPulse = reduced ? 1.4 : 1.4 + Math.sin(t * 1.6 + seed) * 0.18;
haloRef.current.scale.setScalar(node.scale * haloPulse);
const mat = haloRef.current.material as THREE.MeshBasicMaterial;
mat.opacity = reduced ? 0.16 : 0.14 + Math.sin(t * 1.6 + seed) * 0.06;
}
});
return (
<group position={node.pos}>
<mesh ref={haloRef}>
<sphereGeometry args={[1, 20, 20]} />
<meshBasicMaterial color={node.color} transparent opacity={0.16} depthWrite={false} />
</mesh>
<mesh ref={meshRef}>
<sphereGeometry args={[1, 28, 28]} />
<meshStandardMaterial
color={node.color}
emissive={node.color}
emissiveIntensity={1.4}
roughness={0.35}
metalness={0.1}
/>
</mesh>
</group>
);
}
function Connector({ a, b, reduced, index }: { a: Node; b: Node; reduced: boolean; index: number }) {
const packetRef = useRef<THREE.Mesh>(null);
const lineMatRef = useRef<THREE.LineBasicMaterial>(null);
const start = useMemo(() => new THREE.Vector3(...a.pos), [a]);
const end = useMemo(() => new THREE.Vector3(...b.pos), [b]);
const geo = useMemo(() => {
const g = new THREE.BufferGeometry();
g.setAttribute("position", new THREE.BufferAttribute(new Float32Array([...a.pos, ...b.pos]), 3));
return g;
}, [a, b]);
useFrame((state) => {
const t = state.clock.elapsedTime;
if (lineMatRef.current) {
lineMatRef.current.opacity = reduced ? 0.3 : 0.2 + Math.sin(t * 1.2 + index) * 0.12;
}
if (packetRef.current) {
if (reduced) {
packetRef.current.visible = false;
return;
}
packetRef.current.visible = true;
const speed = 0.28;
const u = (t * speed + index * 0.33) % 1;
packetRef.current.position.lerpVectors(start, end, u);
const mat = packetRef.current.material as THREE.MeshBasicMaterial;
mat.opacity = Math.sin(u * Math.PI);
}
});
return (
<group>
<lineSegments geometry={geo}>
<lineBasicMaterial ref={lineMatRef} color={RED_BRIGHT} transparent opacity={0.25} depthWrite={false} />
</lineSegments>
<mesh ref={packetRef}>
<sphereGeometry args={[0.09, 12, 12]} />
<meshBasicMaterial color="#ffffff" transparent opacity={0.9} depthWrite={false} />
</mesh>
</group>
);
}
function SlowSpin({ reduced, children }: { reduced: boolean; children: React.ReactNode }) {
const group = useRef<THREE.Group>(null);
useFrame((_state, dt) => {
if (reduced || !group.current) return;
group.current.rotation.y += dt * 0.035;
});
return <group ref={group}>{children}</group>;
}
export default function MileTruthCanvas({
reduced = false,
isMobile = false,
active = true,
}: {
reduced?: boolean;
isMobile?: boolean;
active?: boolean;
}) {
return (
<Canvas
flat
frameloop={active ? "always" : "never"}
dpr={[1, isMobile || reduced ? 1.2 : 1.6]}
camera={{ position: [0, 1.4, 9.2], fov: 42, near: 0.1, far: 60 }}
gl={{ antialias: !isMobile, powerPreference: "high-performance", alpha: false }}
>
<color attach="background" args={["#0c0c10"]} />
<ambientLight intensity={0.35} />
<SlowSpin reduced={reduced}>
{LINKS.map(([a, b], i) => (
<Connector key={i} a={NODES[a]} b={NODES[b]} reduced={reduced} index={i} />
))}
{NODES.map((n, i) => (
<NodeMesh key={n.label} node={n} reduced={reduced} seed={i * 1.75} />
))}
</SlowSpin>
{!isMobile && (
<Sparkles count={70} scale={[11, 4.5, 6]} size={1.6} speed={reduced ? 0 : 0.15} color={RED_BRIGHT} opacity={0.3} />
)}
<EffectComposer enabled={!isMobile} multisampling={isMobile ? 0 : 2}>
<Bloom kernelSize={KernelSize.SMALL} luminanceThreshold={0.2} intensity={0.55} mipmapBlur />
</EffectComposer>
</Canvas>
);
}

View File

@@ -260,9 +260,6 @@ export default function MileTruthHero() {
}
}
@media (max-width: 1024px) {
.miletruth-hero .elementor-element-86f3204 {
padding: 0 10px !important;
}
.miletruth-hero-container {
min-height: 600px;
padding: 80px 0 !important;
@@ -290,6 +287,15 @@ export default function MileTruthHero() {
font-size: 16px !important;
}
}
/* Horizontal inset switches to 10px here (not at 1024px) to match the
breakpoint every other MileTruth section (Intro, Workflow1/2/4) uses
for the same 20px -> 10px step, so the Hero's left/right edges stay
aligned with the rest of the page through the whole 768-1024px range. */
@media (max-width: 767px) {
.miletruth-hero .elementor-element-86f3204 {
padding: 0 10px !important;
}
}
@media (max-width: 580px) {
.miletruth-hero-container {
min-height: 500px;
@@ -358,7 +364,7 @@ export default function MileTruthHero() {
</h1>
<div className="content-slider-item-text logico-content-wrapper-2">
<div className="text-content">
<p>Optimizes every stage of the delivery journey for maximum efficiency.</p>
<p>Optimizes every stage of the logistics journey for maximum efficiency.</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,413 @@
"use client";
import { useEffect, useRef } from "react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
/* A small route graph: three loose columns of candidate nodes converging on
* one destination. Coordinates are hand-placed (not a strict grid) so the
* mesh reads as organic route options rather than a wiring diagram. */
const NODES = [
{ x: 40, y: 50 },
{ x: 40, y: 130 },
{ x: 40, y: 210 },
{ x: 150, y: 30 },
{ x: 150, y: 95 },
{ x: 150, y: 160 },
{ x: 150, y: 225 },
{ x: 270, y: 55 },
{ x: 270, y: 130 },
{ x: 270, y: 200 },
{ x: 400, y: 130 },
] as const;
const FINAL_NODE = 10;
const DIM_NODES = [0, 2, 3, 5, 6, 7, 9];
const ALL_EDGES: [number, number][] = [
[0, 3], [0, 4], [1, 4], [1, 5], [2, 5], [2, 6],
[3, 7], [4, 7], [4, 8], [5, 8], [5, 9], [6, 9],
[7, 10], [8, 10], [9, 10],
];
const SURVIVOR_EDGES: [number, number][] = [
[1, 4],
[4, 8],
[8, 10],
];
const edgeLength = (a: number, b: number) =>
Math.hypot(NODES[b].x - NODES[a].x, NODES[b].y - NODES[a].y);
/** Conceptual preview of Workflow1's route optimization: many candidate
* routes converge into the single plan MileTruth keeps. Plays once on
* scroll-in — grey mesh appears, a soft sweep suggests evaluation, unused
* routes fade, the surviving path draws in red, the destination pulses
* once — then stops. No loop, no labels, respects prefers-reduced-motion. */
function RouteConverge() {
const wrapRef = useRef<HTMLDivElement>(null);
const sweepRef = useRef<HTMLDivElement>(null);
const edgeRefs = useRef<(SVGLineElement | null)[]>([]);
const survivorEdgeRefs = useRef<(SVGLineElement | null)[]>([]);
const nodeRefs = useRef<(SVGCircleElement | null)[]>([]);
const haloRef = useRef<SVGCircleElement>(null);
const pulseRef = useRef<SVGCircleElement>(null);
useEffect(() => {
const wrap = wrapRef.current;
const sweep = sweepRef.current;
const halo = haloRef.current;
const pulse = pulseRef.current;
const edges = edgeRefs.current.filter(Boolean) as SVGLineElement[];
const survivorEdges = survivorEdgeRefs.current.filter(Boolean) as SVGLineElement[];
const nodes = nodeRefs.current.filter(Boolean) as SVGCircleElement[];
if (!wrap || !sweep || !halo || !pulse || edges.length === 0 || nodes.length === 0) return;
const dimNodes = DIM_NODES.map((i) => nodeRefs.current[i]).filter(Boolean) as SVGCircleElement[];
const survivorNodes = [1, 4, 8].map((i) => nodeRefs.current[i]).filter(Boolean) as SVGCircleElement[];
const finalNode = nodeRefs.current[FINAL_NODE] as SVGCircleElement;
gsap.set(edges, { opacity: 0 });
gsap.set(nodes, { opacity: 0, attr: { fill: "#fdfdfd", stroke: "rgba(17, 17, 17, 0.3)" } });
survivorEdges.forEach((el, i) => {
const [a, b] = SURVIVOR_EDGES[i];
const len = edgeLength(a, b);
gsap.set(el, { attr: { "stroke-dasharray": len, "stroke-dashoffset": len } });
});
gsap.set(halo, { opacity: 0 });
gsap.set(pulse, { opacity: 0, attr: { r: 5 } });
gsap.set(sweep, { opacity: 0, left: "-30%" });
const showFinalState = () => {
gsap.set(edges, { opacity: 0.08 });
gsap.set(dimNodes, { opacity: 0.3 });
gsap.set(nodes, { opacity: 1 });
gsap.set([...survivorNodes, finalNode], { attr: { fill: "#C01227", stroke: "#C01227" } });
survivorEdges.forEach((el) => gsap.set(el, { attr: { "stroke-dashoffset": 0 } }));
gsap.set(halo, { opacity: 0.22 });
};
if (typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
showFinalState();
return;
}
let tl: gsap.core.Timeline | undefined;
const play = () => {
tl = gsap.timeline();
tl.to(edges, { opacity: 1, duration: 0.5, ease: "power1.out" }, 0)
.to(nodes, { opacity: 1, duration: 0.5, ease: "power1.out" }, 0.05)
.set(sweep, { opacity: 0.9 }, 0.55)
.to(sweep, { left: "104%", duration: 1, ease: "power1.inOut" }, 0.55)
.to(sweep, { opacity: 0, duration: 0.3 }, 1.35)
.to(dimNodes, { opacity: 0.28, duration: 0.6, ease: "power1.out" }, 1.3)
.to(edges, { opacity: 0.08, duration: 0.6, ease: "power1.out" }, 1.3)
.to(survivorNodes, { attr: { fill: "#C01227", stroke: "#C01227" }, duration: 0.35, ease: "power1.out" }, 1.5)
.to(survivorEdges[0], { attr: { "stroke-dashoffset": 0 }, duration: 0.4, ease: "power2.inOut" }, 1.55)
.to(survivorEdges[1], { attr: { "stroke-dashoffset": 0 }, duration: 0.4, ease: "power2.inOut" }, 1.85)
.to(survivorEdges[2], { attr: { "stroke-dashoffset": 0 }, duration: 0.4, ease: "power2.inOut" }, 2.15)
.to(finalNode, { attr: { fill: "#C01227", stroke: "#C01227" }, duration: 0.3, ease: "power1.out" }, 2.5)
.to(halo, { opacity: 0.22, duration: 0.4, ease: "power1.out" }, 2.55)
.fromTo(
pulse,
{ opacity: 0.7, attr: { r: 5 } },
{ opacity: 0, attr: { r: 22 }, duration: 0.7, ease: "power2.out" },
2.55,
);
};
const st = ScrollTrigger.create({
trigger: wrap,
start: "top 82%",
once: true,
onEnter: play,
});
const raf = requestAnimationFrame(() => {
const r = wrap.getBoundingClientRect();
const vh = window.innerHeight || document.documentElement.clientHeight;
if (r.top < vh && r.bottom > 0) {
play();
st.kill();
}
});
return () => {
cancelAnimationFrame(raf);
st.kill();
tl?.kill();
};
}, []);
return (
<div className="mti__viz" ref={wrapRef} aria-hidden="true">
<div className="mti__viz-frame">
<div className="mti__viz-sweep" ref={sweepRef} />
<svg className="mti__viz-svg" viewBox="0 0 440 260" preserveAspectRatio="xMidYMid meet">
<g>
{ALL_EDGES.map(([a, b], i) => (
<line
key={i}
ref={(el) => {
edgeRefs.current[i] = el;
}}
x1={NODES[a].x}
y1={NODES[a].y}
x2={NODES[b].x}
y2={NODES[b].y}
className="mti__viz-edge"
/>
))}
</g>
<g>
{SURVIVOR_EDGES.map(([a, b], i) => (
<line
key={i}
ref={(el) => {
survivorEdgeRefs.current[i] = el;
}}
x1={NODES[a].x}
y1={NODES[a].y}
x2={NODES[b].x}
y2={NODES[b].y}
className="mti__viz-edge-active"
/>
))}
</g>
<circle ref={haloRef} cx={NODES[FINAL_NODE].x} cy={NODES[FINAL_NODE].y} r={11} className="mti__viz-halo" />
<g>
{NODES.map((n, i) => (
<circle
key={i}
ref={(el) => {
nodeRefs.current[i] = el;
}}
cx={n.x}
cy={n.y}
r={i === FINAL_NODE ? 4.5 : 3.2}
className={i === FINAL_NODE ? "mti__viz-node mti__viz-node--final" : "mti__viz-node"}
/>
))}
</g>
<circle ref={pulseRef} cx={NODES[FINAL_NODE].x} cy={NODES[FINAL_NODE].y} r={5} className="mti__viz-pulse" />
</svg>
</div>
</div>
);
}
/** Short editorial bridge between the MileTruth hero/metrics and Workflow1 —
* a quick read, not a second hero. No motion, no media, no CTA.
*
* Spacing mirrors the workflow shells (EVSection): a 20px outer inset
* (width calc(100% - 40px) / margin 0 20px) and a 1280px inner with 48px
* horizontal padding, so the heading/body left-align with the workflow
* cards above and below instead of using an unrelated flat gutter. The
* shell also carries the same external top margin as EVSection's
* `.evnd-gap-top` (40 / 32 / 24 desktop-tablet-mobile) so the gap above
* this section matches the gap above every workflow section below it —
* otherwise the Hero sits flush against this section while every other
* section boundary on the page carries that gap.
*
* The right side carries a minimal "many routes -> one route" visualization
* (see RouteConverge above) instead of sitting empty — it never touches the
* heading/copy, spacing, or section height on the left. */
export default function MileTruthIntro() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.mti-shell {
width: calc(100% - 40px);
margin: 40px 20px 0;
}
.mti {
background: #fafafa;
padding: clamp(28px, 3.5vw, 40px) 0;
}
.mti__inner {
max-width: 1280px;
margin: 0 auto;
padding: 0 48px;
}
.mti__row {
display: flex;
align-items: center;
gap: clamp(32px, 5vw, 64px);
}
.mti__left {
flex: 1;
min-width: 0;
}
.mti__eyebrow {
display: inline-flex;
align-items: center;
gap: 12px;
color: #C01227 !important;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 13px;
margin-bottom: clamp(14px, 1.8vw, 18px);
}
.mti__eyebrow::before {
content: '';
width: 16px;
height: 2px;
background: #C01227;
}
.mti__divider {
border: 0;
height: 1px;
background: rgba(17, 17, 17, 0.12);
margin: 0 0 clamp(20px, 2.4vw, 28px);
}
.mti__heading {
margin: 0 0 clamp(18px, 2vw, 24px);
color: #111111 !important;
font-weight: 800 !important;
font-size: clamp(28px, 3.4vw, 46px) !important;
line-height: 1.15 !important;
letter-spacing: -0.02em;
text-transform: uppercase;
}
.mti__accent {
color: #C01227 !important;
}
.mti__copy {
max-width: 680px;
}
.mti__copy p {
margin: 0 0 14px;
color: rgba(17, 17, 17, 0.68) !important;
font-size: clamp(15px, 1.05vw, 17px) !important;
font-weight: 500 !important;
line-height: 1.6 !important;
}
.mti__copy p:last-child {
margin-bottom: 0;
}
.mti__lede {
margin-left: clamp(16px, 2vw, 24px);
}
.mti__viz {
flex: 0 1 38%;
min-width: 240px;
max-width: 460px;
display: flex;
align-items: center;
justify-content: center;
}
.mti__viz-frame {
position: relative;
width: 100%;
}
.mti__viz-svg {
display: block;
width: 100%;
height: auto;
overflow: visible;
}
.mti__viz-edge {
stroke: rgba(17, 17, 17, 0.16);
stroke-width: 1;
}
.mti__viz-edge-active {
fill: none;
stroke: #C01227;
stroke-width: 1.4;
}
.mti__viz-node {
fill: #fdfdfd;
stroke: rgba(17, 17, 17, 0.3);
stroke-width: 1.1;
}
.mti__viz-node--final {
stroke-width: 1.3;
}
.mti__viz-halo {
fill: #C01227;
opacity: 0;
filter: blur(6px);
}
.mti__viz-pulse {
fill: none;
stroke: #C01227;
stroke-width: 1.4;
opacity: 0;
}
.mti__viz-sweep {
position: absolute;
top: 0;
bottom: 0;
width: 24%;
background: linear-gradient(90deg, transparent, rgba(192, 18, 39, 0.14), transparent);
opacity: 0;
pointer-events: none;
}
@media (max-width: 1024px) {
.mti-shell { margin-top: 32px; }
.mti__inner { padding: 0 32px; }
}
@media (max-width: 900px) {
.mti__row {
flex-direction: column;
align-items: center;
gap: clamp(28px, 5vw, 40px);
}
.mti__left {
width: 100%;
}
.mti__viz {
flex: none;
width: 100%;
max-width: 360px;
}
}
@media (max-width: 767px) {
.mti-shell {
width: calc(100% - 20px);
margin: 24px 10px 0;
}
.mti__inner { padding: 0 20px; }
}
`,
}}
/>
<div className="mti-shell">
<section className="mti" aria-label="MileTruth AI introduction">
<div className="mti__inner">
<div className="mti__row">
<div className="mti__left">
<span className="mti__eyebrow">/ MILETRUTH AI /</span>
<hr className="mti__divider" />
<h2 className="mti__heading">
ROUTING IS A <span className="mti__accent">DECISION PROBLEM.</span>
</h2>
<div className="mti__copy">
<p className="mti__lede">Routing is not one path between two points.</p>
<p>
Orders change. Vehicles have different limits. Capacity, range
and time change what is possible.
</p>
<p>
MileTruth evaluates the options, checks what can actually work,
and moves the strongest plan forward.
</p>
</div>
</div>
<RouteConverge />
</div>
</div>
</section>
</div>
</>
);
}

View File

@@ -0,0 +1,69 @@
"use client";
import React, { useEffect, useRef, useState } from "react";
import dynamic from "next/dynamic";
/* ============================================================
MileTruthNetwork — gated mount for MileTruthCanvas (the lightweight
R3F data -> AI -> recommendations -> improvement scene). Mirrors
WorkflowScene.tsx: code-split, mounts a little before it scrolls
into view, pauses the render loop off-screen, and respects
prefers-reduced-motion.
============================================================ */
const MileTruthCanvas = dynamic(() => import("./MileTruthCanvas"), { ssr: false });
export default function MileTruthNetwork({ ariaLabel }: { ariaLabel?: string }) {
const wrapRef = useRef<HTMLDivElement>(null);
const [mountScene, setMountScene] = useState(false);
const [active, setActive] = useState(false);
const [isMobile, setIsMobile] = useState(false);
const [reduced, setReduced] = useState(false);
useEffect(() => {
const mqMobile = window.matchMedia("(max-width: 767px)");
const mqReduce = window.matchMedia("(prefers-reduced-motion: reduce)");
const sync = () => {
setIsMobile(mqMobile.matches);
setReduced(mqReduce.matches);
};
sync();
mqMobile.addEventListener("change", sync);
mqReduce.addEventListener("change", sync);
return () => {
mqMobile.removeEventListener("change", sync);
mqReduce.removeEventListener("change", sync);
};
}, []);
// Single observer: mount the scene a little before it scrolls into view and
// keep it active from then on (this scene is small/light enough that a
// second "pause when off-screen" observer isn't worth the added race risk
// between two independent IntersectionObservers on the same element).
useEffect(() => {
const el = wrapRef.current;
if (!el) return;
const mountIo = new IntersectionObserver(
(entries) => {
if (entries.some((e) => e.isIntersecting)) {
setMountScene(true);
setActive(true);
mountIo.disconnect();
}
},
{ rootMargin: "50% 0px" },
);
mountIo.observe(el);
return () => mountIo.disconnect();
}, []);
return (
<div ref={wrapRef} className="mtn-scene" role="img" aria-label={ariaLabel ?? "MileTruth AI network"}>
<style dangerouslySetInnerHTML={{ __html: `
.mtn-scene { position: relative; width: 100%; height: 100%; min-height: 320px; }
.mtn-scene canvas { display: block; width: 100% !important; height: 100% !important; }
`}} />
{mountScene && <MileTruthCanvas reduced={reduced} isMobile={isMobile} active={active} />}
</div>
);
}

View File

@@ -195,7 +195,7 @@ export default function Miles3() {
</div>
<div className="elementor-element elementor-element-63a9de5 elementor-widget elementor-widget-logico_heading" data-id="63a9de5" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container">
<h3 className="logico-title">Doormile connects first, mid, and last mile into a seamless delivery experience</h3>
<h3 className="logico-title">Doormile connects first, mid, and last mile into a seamless end-to-end logistics experience</h3>
</div>
</div>
</div>
@@ -243,7 +243,7 @@ export default function Miles3() {
</div>
<div className="elementor-element elementor-element-3ae1ce0 elementor-widget elementor-widget-text-editor" data-id="3ae1ce0" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
<div className="elementor-widget-container">
<p>Smooth inter-city delivery through strategically located hubs with live tracking.</p>
<p>Smooth inter-city logistics through strategically located hubs with live tracking.</p>
</div>
</div>
</div>
@@ -266,7 +266,7 @@ export default function Miles3() {
</div>
<div className="elementor-element elementor-element-1057c22 elementor-widget elementor-widget-text-editor" data-id="1057c22" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
<div className="elementor-widget-container">
<p>Packages are delivered to customers with real-time updates and proof of delivery.</p>
<p>Packages reach customers with real-time updates and proof of delivery.</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,164 @@
"use client";
import React, { useEffect, useRef } from "react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import WorkflowScene from "./WorkflowScene";
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
/* ============================================================
QuantumStage — the page's ONE true 3D moment. Wraps the existing
production "Logistics Brain" scene (glowing core, orbiting particle
shells, six parallel route strategies racing, live network) —
already built and already on-brand red — inside a near-full-viewport
frame, with a floating Traditional-vs-Quantum comparison overlaid.
GSAP drives only the entrance (fade/rise); the 3D scene animates
itself.
============================================================ */
export default function QuantumStage() {
const rootRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const root = rootRef.current;
if (!root) return;
const frame = root.querySelector(".qs-frame");
const tradCol = root.querySelector(".qs-col--trad");
const qSteps = Array.from(root.querySelectorAll(".qs-qstep"));
const qDot = root.querySelector(".qs-qdot");
if (!frame || !tradCol || qSteps.length === 0) return;
if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
gsap.set([frame, tradCol, ...qSteps], { opacity: 1, y: 0, scale: 1 });
return;
}
gsap.set(frame, { opacity: 0, y: 26 });
gsap.set(tradCol, { opacity: 0, y: 26 });
gsap.set(qSteps, { opacity: 0.25, y: 10 });
gsap.set(qDot, { scale: 0.6, opacity: 0 });
const play = () => {
const tl = gsap.timeline();
// Frame + traditional baseline settle in first (the "boring" case).
tl.to(frame, { opacity: 1, y: 0, duration: 0.9, ease: "power3.out" }, 0)
.to(tradCol, { opacity: 1, y: 0, duration: 0.7, ease: "power3.out" }, 0.15);
// Quantum steps light up one at a time — a process unfolding, not a fade group.
qSteps.forEach((el, i) => {
tl.to(el, { opacity: 1, y: 0, scale: 1.04, duration: 0.32, ease: "power2.out" }, 0.7 + i * 0.42)
.to(el, { scale: 1, duration: 0.22, ease: "power1.out" }, 0.7 + i * 0.42 + 0.32);
});
// Dispatch pulses brighter — the decisive moment.
const last = qSteps[qSteps.length - 1];
tl.to(qDot, { opacity: 1, scale: 1, duration: 0.4, ease: "back.out(2)" }, 0.7 + qSteps.length * 0.42)
.to(last, { color: "#ff5a6e", duration: 0.3 }, "<");
};
const st = ScrollTrigger.create({ trigger: root, start: "top 78%", once: true, onEnter: play });
return () => st.kill();
}, []);
return (
<div ref={rootRef} className="qs">
<style dangerouslySetInnerHTML={{ __html: CSS }} />
<div className="qs-frame">
<WorkflowScene variant="logistics" ariaLabel="Quantum decision engine — parallel route simulation" />
</div>
<div className="qs-compare">
<div className="qs-col qs-col--trad">
<span className="qs-col-tag">Traditional</span>
<div className="qs-col-steps">
<span>One Route</span>
<span className="qs-col-arrow"></span>
<span>Dispatch</span>
</div>
</div>
<div className="qs-col qs-col--q">
<span className="qs-col-tag qs-col-tag--accent">Quantum</span>
<div className="qs-col-steps qs-col-steps--accent">
<span className="qs-qstep">100+ Route Simulations</span>
<span className="qs-col-arrow"></span>
<span className="qs-qstep">AI Comparison</span>
<span className="qs-col-arrow"></span>
<span className="qs-qstep">Best Route</span>
<span className="qs-col-arrow"></span>
<span className="qs-qstep qs-col-final">
Dispatch<span className="qs-qdot" aria-hidden="true" />
</span>
</div>
</div>
</div>
</div>
);
}
const CSS = `
.qs { position: relative; }
/* --------------------------------------------------------------
Section 05 runs light — every other section on this page keeps
the shared dark "ground texture" system, but this one uses the
shared white .sw-bg--white variant (set via the Section's bg
prop in SolutionsWorkflow.tsx) so the workflow reads as a
dashboard panel, not a visualization sitting in a black canvas —
while still going through the exact same inset/rounded .sw-bg
card surface as every other section. Only the text colors need
a local override here, for readability on that white surface.
-------------------------------------------------------------- */
#quantum .sw-h { color: #14151a !important; }
#quantum .sw-lede { color: #5a5b64 !important; }
.qs-frame {
position: relative;
width: 100%;
aspect-ratio: auto;
min-height: min(84vh, 900px);
border-radius: 28px;
overflow: hidden;
background: #f6f6f7;
border: 1px solid rgba(20,21,26,0.08);
box-shadow: 0 30px 70px -45px rgba(20,21,26,0.25);
}
.qs-frame .wf-scene {
position: absolute;
inset: clamp(16px, 3vw, 32px);
width: auto;
height: auto;
aspect-ratio: auto;
border-radius: 16px;
}
.qs-compare {
position: relative;
margin-top: clamp(28px, 4vw, 48px);
display: grid;
grid-template-columns: 1fr 1.4fr;
gap: clamp(20px, 3vw, 40px);
}
.qs-col {
padding: clamp(20px, 2.4vw, 30px) clamp(22px, 2.6vw, 34px);
border-radius: 22px;
background: #f6f6f7;
border: 1px solid rgba(20,21,26,0.08);
box-shadow: 0 20px 44px -34px rgba(20,21,26,0.2);
display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center;
}
.qs-col--q { background: linear-gradient(180deg, rgba(192,18,39,0.06), rgba(246,246,247,0.4)); border-color: rgba(192,18,39,0.22); }
.qs-col-tag { font-size: 12px; font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase; color: #8a8b93; }
.qs-col-tag--accent { color: #C01227; }
.qs-col-steps { display: flex; flex-direction: column; align-items: center; gap: 8px; color: #4a4b53; font-weight: 700; font-size: 14px; }
.qs-col-steps--accent { color: #14151a; font-size: 15px; flex-direction: row; flex-wrap: wrap; justify-content: center; }
.qs-qstep { display: inline-flex; align-items: center; position: relative; }
.qs-col-arrow { color: rgba(20,21,26,0.28); font-size: 13px; }
.qs-col-final { color: #C01227; display: inline-flex; align-items: center; gap: 8px; }
.qs-qdot { width: 8px; height: 8px; border-radius: 50%; background: #E2354A; box-shadow: 0 0 12px 3px rgba(226,53,74,0.55); }
@media (max-width: 860px) {
.qs-compare { grid-template-columns: 1fr; }
.qs-col-steps--accent { flex-direction: column; }
}
@media (max-width: 767px) {
.qs-frame { min-height: 62vh; border-radius: 20px; }
.qs-frame .wf-scene { border-radius: 14px; }
}
`;

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@ export default function StatsBar() {
<div className="elementor-widget-container">
<div className="logico-title">
<CountUp end={99.2} decimals={1} suffix="%" duration={2.2} /> <br />
<span style={{ fontSize: "20px" }}>On-Time Delivery</span>
<span style={{ fontSize: "20px" }}>On-Time Performance</span>
</div>
</div>
</div>

View File

@@ -59,10 +59,10 @@ export default function TheDoormileWay() {
<p>
<strong>
We connect first mile and last mile into one seamless system, reducing delays and improving efficiency. With real-time tracking and digital workflows,
<br /> every delivery is faster, reliable, and fully transparent.
<br /> every shipment is faster, reliable, and fully transparent.
</strong>
</p>
<p>Seamless logistics powered by real-time tracking, digital processes, and reliable delivery execution.</p>
<p>Seamless logistics powered by real-time tracking, digital processes, and reliable logistics execution.</p>
</div>
</div>
</div>
@@ -118,7 +118,7 @@ export default function TheDoormileWay() {
</div>
<div className="elementor-element elementor-element-74d14e3 elementor-widget elementor-widget-text-editor" data-id="74d14e3" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
<div className="elementor-widget-container">
<p>Real-time monitoring helps prevent delays before they impact deliveries.</p>
<p>Real-time monitoring helps prevent delays before they impact operations.</p>
</div>
</div>
</div>
@@ -141,7 +141,7 @@ export default function TheDoormileWay() {
</div>
<div className="elementor-element elementor-element-74cfdf7 elementor-widget elementor-widget-text-editor" data-id="74cfdf7" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
<div className="elementor-widget-container">
<p>One unified system manages the entire delivery process seamlessly.</p>
<p>One unified system manages the entire logistics process seamlessly.</p>
</div>
</div>
</div>

View File

@@ -45,12 +45,12 @@ const STAGES: Stage[] = [
{
img: "/images/last-mile-approach.webp",
label: "Stage 03",
title: "Last Mile Delivery",
title: "Last Mile Logistics",
subtitle: "Hub to Doorstep",
desc: "The final handoff. Our routing engine optimizes multi-stop itineraries to deliver parcels directly to customers' doorsteps in record time.",
points: ["Multi-stop route optimisation", "Precise delivery windows", "Digital proof of delivery"],
desc: "The final handoff. Our routing engine optimizes multi-stop itineraries to move parcels directly to customers' doorsteps in record time.",
points: ["Multi-stop route optimisation", "Precise arrival windows", "Digital proof of delivery"],
stats: [
{ value: "450K+", label: "Happy Deliveries" },
{ value: "450K+", label: "Shipments Delivered" },
{ value: "2.8 Hours", label: "Average Turnaround" }
]
},

View File

@@ -465,7 +465,7 @@ export default function WingsHero() {
<p>
Linking India&apos;s major regional capitals with
AI-powered air movement and zero-emission EV
last-mile delivery.
last-mile transport.
</p>
</div>
</div>

View File

@@ -48,7 +48,7 @@ const STEPS = [
},
{
label: "EV Last-Mile",
desc: "Zero-emission electric vehicles complete the final delivery.",
desc: "Zero-emission electric vehicles complete the final mile.",
icon: (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round">
<path d="M3 13h13l3 4h2v3H3z" />
@@ -72,7 +72,7 @@ export default function WingsHowItWorks() {
<h2 className={styles.title}>
Pickup to
<br />
delivery, one
arrival, one
<br />
connected flow
</h2>

View File

@@ -3,7 +3,7 @@ import { ScrollReveal } from "@/animations/Reveal";
const INDUSTRIES = [
{
title: "Quick Commerce",
challenge: "Sub-3-hour delivery windows for dark stores and micro-warehouses.",
challenge: "Sub-3-hour arrival windows for dark stores and micro-warehouses.",
solution: "Dedicated same-day air capacity linking metros to fulfillment hubs.",
image: "/images/card 1.png",
},
@@ -34,7 +34,7 @@ const INDUSTRIES = [
{
title: "E-Commerce Logistics",
challenge: "Next-day and same-day fulfillment expectations across tier-1 and tier-2 cities.",
solution: "Direct sorting-hub-to-airport clearance network for faster regional delivery.",
solution: "Direct sorting-hub-to-airport clearance network for faster regional logistics.",
image: "/images/card6.png",
},
];

View File

@@ -475,7 +475,7 @@ export default function WingsMileTruth() {
<div className="wmt-inner dm-section-container">
<ScrollReveal delay={0.05} duration={0.75} yOffset={25} className="wmt-header">
<div className="wmt-eyebrow">/ MileTruth&trade; AI /</div>
<h2 className="wmt-title">The intelligence layer behind every delivery</h2>
<h2 className="wmt-title">The intelligence layer behind every shipment</h2>
</ScrollReveal>
<StaggerChildren stagger={0.08} duration={0.65} yOffset={25} className="wmt-grid">

View File

@@ -204,7 +204,7 @@ export default function WingsSpeedAdvantage() {
Max <CountUp end={3} duration={1.4} triggerOnce />
</div>
<div className="wsa-unit">Hours, Door-to-Door</div>
<p className="wsa-panel-sub">Same-day delivery between major regional capitals.</p>
<p className="wsa-panel-sub">Same-day logistics between major regional capitals.</p>
</div>
</div>
</div>

View File

@@ -37,7 +37,7 @@ const MAX_WAVE_AMP_FACTOR = 1 + 0.28 + 0.15;
const FEATURES = [
{
title: "Same-Day Air Logistics",
desc: "Max 3-hour door-to-door delivery between India's major regional capitals.",
desc: "Max 3-hour door-to-door transit between India's major regional capitals.",
icon: (
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="10" />
@@ -70,7 +70,7 @@ const FEATURES = [
},
{
title: "EV Last Mile",
desc: "Zero-emission electric vehicles complete every first- and final-mile delivery.",
desc: "Zero-emission electric vehicles complete every first- and final-mile leg.",
icon: (
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round">
<path d="M3 13h13l3 4h2v3H3z" />

View File

@@ -6,7 +6,7 @@ import IndustryWorldMap from "./IndustryWorldMap";
const WS_STATS = [
{ value: "500", plus: "+", label: "Women Partners" },
{ value: "35", plus: "+", label: "Cities" },
{ value: "10K", plus: "+", label: "Deliveries" },
{ value: "10K", plus: "+", label: "Shipments" },
];
const WS_CARDS = [

View File

@@ -54,7 +54,7 @@ const FEATURES: EVFeature[] = [
</>,
),
title: "Distance Reduction",
desc: "Same volume delivered with a leaner, better-used fleet.",
desc: "Same volume moved with a leaner, better-used fleet.",
},
{
icon: ico(
@@ -74,7 +74,7 @@ const FEATURES: EVFeature[] = [
</>,
),
title: "SLA Performance",
desc: "Real-time correction keeps deliveries on time.",
desc: "Real-time correction keeps shipments on time.",
},
];

View File

@@ -91,12 +91,12 @@ export default function Workflow2() {
gapBottom
bannerImage="/images/mid-mile-approach.webp"
cardTitle="CHOOSE THE BEST PLAN"
cardSubtitle="Analyze thousands of route possibilities and automatically select the most efficient delivery strategy."
cardSubtitle="Analyze thousands of route possibilities and automatically select the most efficient routing strategy."
eyebrow="/ Innovation /"
titleLead="MANY STRATEGIES. "
titleAccent="ONE BEST PLAN."
image="/videos/workflow-2-routing.mp4"
imageAlt="AI route-planning engine selecting the best delivery plan"
imageAlt="AI route-planning engine selecting the best route plan"
metrics={METRICS}
features={FEATURES}
cardsHeading="AI Decision Engine"

View File

@@ -18,7 +18,7 @@ export default function Workflow3() {
return (
<section
className="dm-wf3"
aria-label="Workflow 3 — Happier Riders. Higher Fulfillment."
aria-label="Workflow 3 — Happier Fleet Drivers. Higher Fulfillment."
>
<StrategySection />

View File

@@ -32,7 +32,7 @@ const METRICS: EVStat[] = [
/* Distinct copy for the bottom capability bar (not a repeat of the KPI row —
* Workflow 4's brief specifies separate content for each). */
const BAR_STATS: EVStat[] = [
{ text: "Multi-Rider", value: 0, suffix: "", label: "Dynamic Routing" },
{ text: "Multi-Driver", value: 0, suffix: "", label: "Dynamic Routing" },
{ text: "Optimized", value: 0, suffix: "", label: "Time Windows" },
{ text: "Real-Time", value: 0, suffix: "", label: "Fleet Balancing" },
{ text: "Cost + Distance + SLA", value: 0, suffix: "", label: "Objectives" },
@@ -62,7 +62,7 @@ const FEATURES: EVFeature[] = [
</>,
),
title: "Encode the Problem",
desc: "Rider assignments, delivery sequences, capacity, traffic, service time, and SLA constraints become part of one mathematical optimization model.",
desc: "Fleet driver assignments, stop sequences, capacity, traffic, service time, and SLA constraints become part of one mathematical optimization model.",
},
{
icon: ico(<path d="m8 3 4 8 5-5 5 15H2L8 3z" />),
@@ -105,7 +105,7 @@ export default function Workflow4() {
gapBottom
bannerImage="/images/workflow4.png"
image="/videos/Doormile-quantum-video3.mp4"
cardTitle="BUILDING QUANTUM INTELLIGENCE"
cardTitle="QUANTUM INTELLIGENCE"
cardSubtitle="Exploring a hybrid optimization layer that treats routing as an energy landscape, not a search problem."
eyebrow="/ Quantum Intelligence /"
titleLead="FROM ROUTE SEARCH. "