update home,about,solutions

This commit is contained in:
2026-06-01 20:20:14 +05:30
parent 8d74f7063e
commit a59a5e79dc
19 changed files with 3543 additions and 1381 deletions

View File

@@ -1932,10 +1932,10 @@ h1:where(.wp-block-heading).has-background,
--container-widget-flex-grow: 0; --container-widget-flex-grow: 0;
--container-widget-align-self: initial; --container-widget-align-self: initial;
--flex-wrap-mobile: wrap; --flex-wrap-mobile: wrap;
--padding-top: 20px; --padding-top: 32px;
--padding-bottom: 20px; --padding-bottom: 32px;
--padding-left: 20px; --padding-left: 32px;
--padding-right: 20px; --padding-right: 32px;
} }
.elementor .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-3264830 { .elementor .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-3264830 {
@@ -2095,7 +2095,7 @@ h1:where(.wp-block-heading).has-background,
} }
.elementor .elementor-element.elementor-element-6c7cbcb .owl-carousel .owl-stage-outer { .elementor .elementor-element.elementor-element-6c7cbcb .owl-carousel .owl-stage-outer {
border-radius: 25px 25px 25px 25px; border-radius: 32px 32px 32px 32px;
} }
.elementor .elementor-element.elementor-element-6c7cbcb .content-slider.nav-view-compact .owl-nav, .elementor .elementor-element.elementor-element-6c7cbcb .content-slider.nav-view-compact .owl-nav,
@@ -13053,20 +13053,20 @@ h1:where(.wp-block-heading).has-background,
} }
.elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 .slide-content-inner { .elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 .slide-content-inner {
max-width: 64%; max-width: 88%;
margin: 110px 0px 0px 75px; margin: 0 auto;
} }
.elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 .slide-content { .elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 .slide-content {
-webkit-align-items: flex-start; -webkit-align-items: center;
-moz-align-items: flex-start; -moz-align-items: center;
-ms-align-items: flex-start; -ms-align-items: center;
align-items: flex-start; align-items: center;
-webkit-justify-content: center; -webkit-justify-content: center;
-moz-justify-content: center; -moz-justify-content: center;
-ms-justify-content: center; -ms-justify-content: center;
justify-content: center; justify-content: center;
text-align: left; text-align: center;
} }
.elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 .content-slider-item-heading { .elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 .content-slider-item-heading {
@@ -19114,6 +19114,7 @@ img.wp-smiley,
--margin-bottom: 0px; --margin-bottom: 0px;
--margin-left: 0px; --margin-left: 0px;
--margin-right: 0px; --margin-right: 0px;
position: relative;
} }
.elementor-element.elementor-element-f35119c { .elementor-element.elementor-element-f35119c {
@@ -28753,8 +28754,8 @@ img.wp-smiley,
--margin-right: 0px; --margin-right: 0px;
--padding-top: 0px; --padding-top: 0px;
--padding-bottom: 0px; --padding-bottom: 0px;
--padding-left: 20px; --padding-left: 0px;
--padding-right: 20px; --padding-right: 0px;
} }
.elementor-element.elementor-element-13a7637 { .elementor-element.elementor-element-13a7637 {
@@ -38655,11 +38656,13 @@ body.rtl .elementor-6473 .elementor-element.elementor-element-13a7637 {
--column-gap: 0px; --column-gap: 0px;
--background-transition: 0s; --background-transition: 0s;
--border-radius: 25px 25px 25px 25px; --border-radius: 25px 25px 25px 25px;
border-radius: 25px;
overflow: hidden;
--z-index: 1; --z-index: 1;
} }
.elementor-6473 .elementor-element.elementor-element-7da6646:not(.elementor-motion-effects-element-type-background), .elementor-6473 .elementor-element.elementor-element-7da6646 > .elementor-motion-effects-container > .elementor-motion-effects-layer { .elementor-6473 .elementor-element.elementor-element-7da6646:not(.elementor-motion-effects-element-type-background), .elementor-6473 .elementor-element.elementor-element-7da6646 > .elementor-motion-effects-container > .elementor-motion-effects-layer {
background-image: url("/images/home4-banner-4.png"); background-image: url("/images/bg-header-5.png");
background-position: center center; background-position: center center;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;

View File

@@ -16806,7 +16806,7 @@ html.elementor-html {
} }
} }
/* .team-listing-wrapper.team-grid-listing { .team-listing-wrapper.team-grid-listing {
display: block; display: block;
margin: 0 -10px -20px margin: 0 -10px -20px
} }
@@ -17060,7 +17060,7 @@ html.elementor-html {
padding: 0 22px; padding: 0 22px;
margin-bottom: 78px margin-bottom: 78px
} }
} */ }
.body-container .single-team { .body-container .single-team {
display: -webkit-box; display: -webkit-box;

View File

@@ -19,6 +19,11 @@ export default function AnimationProvider({ children }: { children: React.ReactN
duration: 0.8, duration: 0.8,
}); });
// Mobile browsers fire `resize` when the address bar shows/hides while
// scrolling. Refreshing ScrollTrigger on every one of those caused jumpy /
// re-hidden animations on phones. Ignore those spurious resizes.
ScrollTrigger.config({ ignoreMobileResize: true });
const initDecorativeBlocks = () => { const initDecorativeBlocks = () => {
// Clean up previous block triggers to avoid duplicates // Clean up previous block triggers to avoid duplicates
ScrollTrigger.getAll().forEach((t) => { ScrollTrigger.getAll().forEach((t) => {
@@ -27,6 +32,7 @@ export default function AnimationProvider({ children }: { children: React.ReactN
} }
}); });
const vh = window.innerHeight || document.documentElement.clientHeight;
const decorativeBlocks = document.querySelectorAll(".block-decoration"); const decorativeBlocks = document.querySelectorAll(".block-decoration");
decorativeBlocks.forEach((block) => { decorativeBlocks.forEach((block) => {
ScrollTrigger.create({ ScrollTrigger.create({
@@ -50,6 +56,14 @@ export default function AnimationProvider({ children }: { children: React.ReactN
block.classList.remove("animated"); block.classList.remove("animated");
}, },
}); });
// ScrollTrigger does not fire onEnter for blocks already in view at
// creation — on larger / taller screens those stayed un-animated.
// Reveal any block already intersecting the viewport.
const r = block.getBoundingClientRect();
if (r.top < vh && r.bottom > 0) {
block.classList.add("animated");
}
}); });
}; };
@@ -83,15 +97,22 @@ export default function AnimationProvider({ children }: { children: React.ReactN
}; };
window.addEventListener("load", handleLoad); window.addEventListener("load", handleLoad);
// Also refresh on window resize // Refresh on window resize — debounced so dragging the window across
// breakpoints recomputes trigger positions once it settles, instead of
// thrashing on every intermediate pixel.
let resizeTimer: ReturnType<typeof setTimeout>;
const handleResize = () => { const handleResize = () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
initDecorativeBlocks(); initDecorativeBlocks();
ScrollTrigger.refresh(true); ScrollTrigger.refresh(true);
}, 200);
}; };
window.addEventListener("resize", handleResize); window.addEventListener("resize", handleResize);
return () => { return () => {
timeouts.forEach(clearTimeout); timeouts.forEach(clearTimeout);
clearTimeout(resizeTimer);
window.removeEventListener("load", handleLoad); window.removeEventListener("load", handleLoad);
window.removeEventListener("resize", handleResize); window.removeEventListener("resize", handleResize);
ScrollTrigger.getAll().forEach((t) => t.kill()); ScrollTrigger.getAll().forEach((t) => t.kill());

View File

@@ -9,6 +9,71 @@ if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollTrigger);
} }
/* ============================================================
Shared scroll-reveal trigger factory.
ScrollTrigger does NOT fire `onEnter` for elements that are ALREADY inside
the viewport when the trigger is created. On taller / larger screens more
content sits above the fold on load, so those elements stayed stuck at
opacity:0 (invisible). This was the root cause of "animations work on my
laptop but break on bigger screens / other devices".
This factory fixes it by revealing any element already intersecting the
viewport right after creation, so behaviour is identical on every screen
size. It also honours prefers-reduced-motion by revealing instantly.
============================================================ */
function createRevealTrigger(opts: {
trigger: Element;
start?: string;
show: () => void;
hide: () => void;
triggerOnce?: boolean;
}): () => void {
const { trigger, start = "top 88%", show, hide, triggerOnce = false } = opts;
// Reduced motion: reveal immediately, no scroll dependency.
if (
typeof window !== "undefined" &&
window.matchMedia?.("(prefers-reduced-motion: reduce)").matches
) {
show();
return () => {};
}
const st = ScrollTrigger.create({
trigger,
start,
onEnter: (self) => {
show();
if (triggerOnce) self.kill();
},
onEnterBack: () => {
if (!triggerOnce) show();
},
onLeave: () => {
if (!triggerOnce) hide();
},
onLeaveBack: () => {
if (!triggerOnce) hide();
},
});
// Reveal-if-already-in-view (deferred one frame so layout is measured).
const raf = requestAnimationFrame(() => {
const r = trigger.getBoundingClientRect();
const vh = window.innerHeight || document.documentElement.clientHeight;
if (r.top < vh && r.bottom > 0) {
show();
if (triggerOnce) st.kill();
}
});
return () => {
cancelAnimationFrame(raf);
st.kill();
};
}
/* ============================================================ /* ============================================================
1. ScrollReveal 1. ScrollReveal
Fade-in + slide-up on scroll. The workhorse animation. Fade-in + slide-up on scroll. The workhorse animation.
@@ -40,10 +105,7 @@ export function ScrollReveal({
gsap.set(el, { y: yOffset, x: xOffset, opacity: 0 }); gsap.set(el, { y: yOffset, x: xOffset, opacity: 0 });
const trigger = ScrollTrigger.create({ const show = () =>
trigger: el,
start: "top 88%",
onEnter: (self) => {
gsap.to(el, { gsap.to(el, {
y: 0, y: 0,
x: 0, x: 0,
@@ -53,34 +115,9 @@ export function ScrollReveal({
delay, delay,
overwrite: "auto", overwrite: "auto",
}); });
if (triggerOnce) self.kill(); const hide = () => gsap.set(el, { y: yOffset, x: xOffset, opacity: 0 });
},
onEnterBack: () => {
if (!triggerOnce) {
gsap.to(el, {
y: 0,
x: 0,
opacity: 1,
duration,
ease: "power3.out",
delay,
overwrite: "auto",
});
}
},
onLeave: () => {
if (!triggerOnce) {
gsap.set(el, { y: yOffset, x: xOffset, opacity: 0 });
}
},
onLeaveBack: () => {
if (!triggerOnce) {
gsap.set(el, { y: yOffset, x: xOffset, opacity: 0 });
}
},
});
return () => trigger?.kill(); return createRevealTrigger({ trigger: el, show, hide, triggerOnce });
}, [delay, duration, yOffset, xOffset, triggerOnce]); }, [delay, duration, yOffset, xOffset, triggerOnce]);
return ( return (
@@ -122,10 +159,7 @@ export function RevealText({
gsap.set(items, { y: "110%", opacity: 0 }); gsap.set(items, { y: "110%", opacity: 0 });
const trigger = ScrollTrigger.create({ const show = () =>
trigger: el,
start: "top 88%",
onEnter: (self) => {
gsap.to(items, { gsap.to(items, {
y: "0%", y: "0%",
opacity: 1, opacity: 1,
@@ -135,34 +169,9 @@ export function RevealText({
delay, delay,
overwrite: "auto", overwrite: "auto",
}); });
if (triggerOnce) self.kill(); const hide = () => gsap.set(items, { y: "110%", opacity: 0 });
},
onEnterBack: () => {
if (!triggerOnce) {
gsap.to(items, {
y: "0%",
opacity: 1,
duration,
ease: "power4.out",
stagger: type === "chars" ? 0.02 : 0.04,
delay,
overwrite: "auto",
});
}
},
onLeave: () => {
if (!triggerOnce) {
gsap.set(items, { y: "110%", opacity: 0 });
}
},
onLeaveBack: () => {
if (!triggerOnce) {
gsap.set(items, { y: "110%", opacity: 0 });
}
},
});
return () => trigger?.kill(); return createRevealTrigger({ trigger: el, show, hide, triggerOnce });
}, [children, type, delay, duration, triggerOnce]); }, [children, type, delay, duration, triggerOnce]);
const renderContent = () => { const renderContent = () => {
@@ -290,10 +299,7 @@ export function StaggerChildren({
gsap.set(items, { y: yOffset, opacity: 0 }); gsap.set(items, { y: yOffset, opacity: 0 });
const trigger = ScrollTrigger.create({ const show = () =>
trigger: el,
start: "top 85%",
onEnter: (self) => {
gsap.to(items, { gsap.to(items, {
y: 0, y: 0,
opacity: 1, opacity: 1,
@@ -302,33 +308,9 @@ export function StaggerChildren({
stagger, stagger,
overwrite: "auto", overwrite: "auto",
}); });
if (triggerOnce) self.kill(); const hide = () => gsap.set(items, { y: yOffset, opacity: 0 });
},
onEnterBack: () => {
if (!triggerOnce) {
gsap.to(items, {
y: 0,
opacity: 1,
duration,
ease: "power3.out",
stagger,
overwrite: "auto",
});
}
},
onLeave: () => {
if (!triggerOnce) {
gsap.set(items, { y: yOffset, opacity: 0 });
}
},
onLeaveBack: () => {
if (!triggerOnce) {
gsap.set(items, { y: yOffset, opacity: 0 });
}
},
});
return () => trigger?.kill(); return createRevealTrigger({ trigger: el, start: "top 85%", show, hide, triggerOnce });
}, [stagger, duration, yOffset, triggerOnce]); }, [stagger, duration, yOffset, triggerOnce]);
return ( return (
@@ -365,10 +347,7 @@ export function ScaleReveal({
gsap.set(el, { scale: 0.85, opacity: 0 }); gsap.set(el, { scale: 0.85, opacity: 0 });
const trigger = ScrollTrigger.create({ const show = () =>
trigger: el,
start: "top 88%",
onEnter: (self) => {
gsap.to(el, { gsap.to(el, {
scale: 1, scale: 1,
opacity: 1, opacity: 1,
@@ -377,33 +356,9 @@ export function ScaleReveal({
delay, delay,
overwrite: "auto", overwrite: "auto",
}); });
if (triggerOnce) self.kill(); const hide = () => gsap.set(el, { scale: 0.85, opacity: 0 });
},
onEnterBack: () => {
if (!triggerOnce) {
gsap.to(el, {
scale: 1,
opacity: 1,
duration,
ease: "power3.out",
delay,
overwrite: "auto",
});
}
},
onLeave: () => {
if (!triggerOnce) {
gsap.set(el, { scale: 0.85, opacity: 0 });
}
},
onLeaveBack: () => {
if (!triggerOnce) {
gsap.set(el, { scale: 0.85, opacity: 0 });
}
},
});
return () => trigger?.kill(); return createRevealTrigger({ trigger: el, show, hide, triggerOnce });
}, [delay, duration, triggerOnce]); }, [delay, duration, triggerOnce]);
return ( return (
@@ -443,10 +398,7 @@ export function SlideReveal({
const xStart = direction === "left" ? -60 : 60; const xStart = direction === "left" ? -60 : 60;
gsap.set(el, { x: xStart, opacity: 0 }); gsap.set(el, { x: xStart, opacity: 0 });
const trigger = ScrollTrigger.create({ const show = () =>
trigger: el,
start: "top 88%",
onEnter: (self) => {
gsap.to(el, { gsap.to(el, {
x: 0, x: 0,
opacity: 1, opacity: 1,
@@ -455,33 +407,9 @@ export function SlideReveal({
delay, delay,
overwrite: "auto", overwrite: "auto",
}); });
if (triggerOnce) self.kill(); const hide = () => gsap.set(el, { x: xStart, opacity: 0 });
},
onEnterBack: () => {
if (!triggerOnce) {
gsap.to(el, {
x: 0,
opacity: 1,
duration,
ease: "power3.out",
delay,
overwrite: "auto",
});
}
},
onLeave: () => {
if (!triggerOnce) {
gsap.set(el, { x: xStart, opacity: 0 });
}
},
onLeaveBack: () => {
if (!triggerOnce) {
gsap.set(el, { x: xStart, opacity: 0 });
}
},
});
return () => trigger?.kill(); return createRevealTrigger({ trigger: el, show, hide, triggerOnce });
}, [direction, delay, duration, triggerOnce]); }, [direction, delay, duration, triggerOnce]);
return ( return (
@@ -573,10 +501,7 @@ export function CountUp({
const el = elementRef.current; const el = elementRef.current;
if (!el) return; if (!el) return;
const trigger = ScrollTrigger.create({ const show = () => {
trigger: el,
start: "top 90%",
onEnter: (self) => {
const obj = { val: start }; const obj = { val: start };
gsap.to(obj, { gsap.to(obj, {
val: end, val: end,
@@ -584,32 +509,10 @@ export function CountUp({
ease: "power2.out", ease: "power2.out",
onUpdate: () => setValue(obj.val), onUpdate: () => setValue(obj.val),
}); });
if (triggerOnce) self.kill(); };
}, const hide = () => setValue(start);
onEnterBack: () => {
if (!triggerOnce) {
const obj = { val: start };
gsap.to(obj, {
val: end,
duration,
ease: "power2.out",
onUpdate: () => setValue(obj.val),
});
}
},
onLeave: () => {
if (!triggerOnce) {
setValue(start);
}
},
onLeaveBack: () => {
if (!triggerOnce) {
setValue(start);
}
},
});
return () => trigger?.kill(); return createRevealTrigger({ trigger: el, start: "top 90%", show, hide, triggerOnce });
}, [start, end, duration, triggerOnce]); }, [start, end, duration, triggerOnce]);
return ( return (

View File

@@ -18,7 +18,7 @@ export default function AboutUsPage() {
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none"> <div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
<div className="content"> <div className="content">
<div className="content-inner"> <div className="content-inner">
<div data-elementor-type="wp-page" data-elementor-id="86" className="elementor elementor-86"> <div data-elementor-type="wp-page" data-elementor-id="86" className="elementor elementor-86 elementor-59">
<AboutHero /> <AboutHero />
<TheDoormileWay /> <TheDoormileWay />
<EVLogisticSection /> <EVLogisticSection />

View File

@@ -767,7 +767,7 @@ body {
content: '' !important; content: '' !important;
position: absolute !important; position: absolute !important;
inset: 0 !important; inset: 0 !important;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0.78) 55%, rgba(0, 0, 0, 0.95) 100%) !important; background: var(--hero-overlay, linear-gradient(to bottom, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0.78) 55%, rgba(0, 0, 0, 0.95) 100%)) !important;
z-index: 1 !important; z-index: 1 !important;
} }
@@ -777,6 +777,13 @@ body {
} }
/* Responsive constraints to keep all heroes matching the home page carousel perfectly */ /* Responsive constraints to keep all heroes matching the home page carousel perfectly */
@media (max-width: 1536px) {
.custom-standard-hero-card {
height: 600px !important;
min-height: 600px !important;
}
}
@media (max-width: 1024px) { @media (max-width: 1024px) {
.custom-standard-hero-container { .custom-standard-hero-container {
padding: 10px 10px 10px 10px !important; padding: 10px 10px 10px 10px !important;

View File

@@ -1,5 +1,5 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Manrope, Space_Grotesk } from "next/font/google"; import { Manrope, Space_Grotesk, Syne, DM_Sans } from "next/font/google";
import "./globals.css"; import "./globals.css";
import Header from "@/components/layout/Header"; import Header from "@/components/layout/Header";
import Footer from "@/components/layout/Footer"; import Footer from "@/components/layout/Footer";
@@ -21,6 +21,19 @@ const spaceGrotesk = Space_Grotesk({
weight: ["400", "500", "600", "700"], weight: ["400", "500", "600", "700"],
}); });
// Fonts for the Solutions industry section (Syne headings, DM Sans body).
const syne = Syne({
subsets: ["latin"],
variable: "--font-syne",
weight: ["600", "700", "800"],
});
const dmSans = DM_Sans({
subsets: ["latin"],
variable: "--font-dm-sans",
weight: ["400", "500"],
});
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Doormile — Last-Mile Logistics Intelligence", title: "Doormile — Last-Mile Logistics Intelligence",
description: "Doormile powers last-mile logistics with MileTruth™ AI, providing connected miles, SLA protection, and carrier management.", description: "Doormile powers last-mile logistics with MileTruth™ AI, providing connected miles, SLA protection, and carrier management.",
@@ -36,7 +49,7 @@ export default function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
return ( return (
<html lang="en-US" className={`${manrope.variable} ${spaceGrotesk.variable}`}> <html lang="en-US" className={`${manrope.variable} ${spaceGrotesk.variable} ${syne.variable} ${dmSans.variable}`}>
<head> <head>
{/* FontAwesome icons */} {/* FontAwesome icons */}
<link <link

View File

@@ -515,6 +515,19 @@ export default function Header() {
background-color: #ffffff !important; background-color: #ffffff !important;
opacity: 1 !important; opacity: 1 !important;
} }
/* The theme reveals the mobile slide-in menu via Elementor's
body[data-elementor-device-mode="mobile"] rules, which are set by
Elementor's frontend JS — that JS isn't shipped in this Next port,
so the panel stayed display:none and the hamburger opened nothing.
Restore it with the same 1024px breakpoint the nav already switches
at. The panel sits off-screen (right:-320px) until .active slides
it in, matching production behaviour. */
@media (max-width: 1024px) {
#masthead .elementor-widget-logico_navigation_menu .mobile-header-menu-container {
display: block !important;
}
}
`, `,
}} }}
/> />

View File

@@ -8,18 +8,18 @@ export default function AboutHero() {
width: 100% !important; width: 100% !important;
text-align: center !important; text-align: center !important;
color: #fff !important; color: #fff !important;
padding: 60px 40px !important; padding: 60px 40px 100px 40px !important;
z-index: 2; z-index: 2;
display: flex !important; display: flex !important;
flex-direction: column !important; flex-direction: column !important;
justify-content: center !important; justify-content: flex-end !important;
align-items: center !important; align-items: center !important;
height: 100% !important; height: 100% !important;
} }
.about-us-hero-title { .about-us-hero-title {
margin: 0 !important; margin: 0 !important;
font-family: var(--font-manrope), sans-serif !important; font-family: "Manrope", Sans-serif !important;
font-size: clamp(34px, 5.5vw, 68px) !important; font-size: clamp(34px, 5.5vw, 68px) !important;
font-weight: 850 !important; font-weight: 850 !important;
line-height: 1.1 !important; line-height: 1.1 !important;
@@ -33,7 +33,8 @@ export default function AboutHero() {
<div className="custom-standard-hero-container"> <div className="custom-standard-hero-container">
<div <div
style={{ style={{
backgroundImage: "linear-gradient(to bottom, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0.78) 55%, rgba(0, 0, 0, 0.95) 100%), url('/images/about-bg.png')" backgroundImage: "url('/images/about-bg.png')",
["--hero-overlay" as any]: "linear-gradient(to bottom, rgba(0, 0, 0, 0.15) 0%, rgba(0, 0, 0, 0.15) 60%, rgba(0, 0, 0, 0.55) 100%)"
}} }}
className="custom-standard-hero-card" className="custom-standard-hero-card"
> >

View File

@@ -1,12 +1,81 @@
import React from "react"; "use client";
import React, { useEffect, useRef } from "react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
export default function CompetitiveEdge() { export default function CompetitiveEdge() {
const sectionRef = useRef<HTMLDivElement>(null);
const tableWrapperRef = useRef<HTMLDivElement>(null);
const moatRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const section = sectionRef.current;
const tableWrapper = tableWrapperRef.current;
const moat = moatRef.current;
if (!section || !tableWrapper || !moat) return;
// GSAP Timeline ScrollTrigger for viewport entrances
const entryTl = gsap.timeline({
scrollTrigger: {
trigger: section,
start: "top 78%",
toggleActions: "play none none none",
}
});
entryTl
// 1. Reveal Table & Right panel
.fromTo([tableWrapper, moat], {
opacity: 0,
y: 45,
}, {
opacity: 1,
y: 0,
duration: 0.95,
stagger: 0.12,
ease: "power4.out",
})
// 2. Stagger slide up row items
.fromTo(section.querySelectorAll(".table-row-hover"), {
opacity: 0,
y: 20,
}, {
opacity: 1,
y: 0,
duration: 0.75,
stagger: 0.05,
ease: "power3.out",
}, "-=0.6")
// 3. Pop checkmarks and badges cleanly
.fromTo(section.querySelectorAll(".yes-badge, .advanced-badge"), {
opacity: 0,
scale: 0.8,
}, {
opacity: 1,
scale: 1,
duration: 0.55,
stagger: 0.03,
ease: "back.out(1.6)",
}, "-=0.45");
}, []);
return ( return (
<section id="comparison" className="comparison-section"> <section id="comparison" className="comparison-section" ref={sectionRef}>
{/* Visual background layers */}
<div className="comparison-bg-glow" />
<div className="comparison-bg-dots" />
<div className="container"> <div className="container">
<div className="comparison-layout"> <div className="comparison-layout">
{/* Comparison matrix Table */} {/* Comparison Matrix Table (69% on Desktop) */}
<div className="table-wrapper"> <div className="table-wrapper" ref={tableWrapperRef}>
<table className="comparison-table"> <table className="comparison-table">
<thead> <thead>
<tr> <tr>
@@ -20,7 +89,7 @@ export default function CompetitiveEdge() {
<tbody> <tbody>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<rect x="1" y="3" width="15" height="13"></rect> <rect x="1" y="3" width="15" height="13"></rect>
<polygon points="16 8 20 8 23 11 23 16 16 16 16 8"></polygon> <polygon points="16 8 20 8 23 11 23 16 16 16 16 8"></polygon>
<circle cx="5.5" cy="18.5" r="2.5"></circle> <circle cx="5.5" cy="18.5" r="2.5"></circle>
@@ -35,7 +104,7 @@ export default function CompetitiveEdge() {
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"></path> <path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"></path>
<path d="M12 6v6l4 2"></path> <path d="M12 6v6l4 2"></path>
</svg> </svg>
@@ -48,7 +117,7 @@ export default function CompetitiveEdge() {
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon> <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon>
</svg> </svg>
EV-aware planning EV-aware planning
@@ -60,8 +129,8 @@ export default function CompetitiveEdge() {
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h32a2 2 0 0 0 2-2V8z"></path> <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline> <polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line> <line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line> <line x1="16" y1="17" x2="8" y2="17"></line>
@@ -76,7 +145,7 @@ export default function CompetitiveEdge() {
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="10"></circle> <circle cx="12" cy="12" r="10"></circle>
<polyline points="12 6 12 12 16 14"></polyline> <polyline points="12 6 12 12 16 14"></polyline>
</svg> </svg>
@@ -89,20 +158,20 @@ export default function CompetitiveEdge() {
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg> </svg>
Verified handling Verified handling
</td> </td>
<td className="col-highlight"><span className="yes-badge"> Yes</span></td> <td className="col-highlight"><span className="yes-badge"> Yes</span></td>
<td className="no-text">No</td>
<td className="partial-text">Partial</td> <td className="partial-text">Partial</td>
<td className="no-text">No</td> <td className="no-text">No</td>
<td className="no-text">No</td>
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h38s-3-2-3-9"></path> <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path>
<path d="M13.73 21a2 2 0 0 1-3.46 0"></path> <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
</svg> </svg>
Hyperlocal learning Hyperlocal learning
@@ -114,7 +183,7 @@ export default function CompetitiveEdge() {
</tr> </tr>
<tr className="table-row-hover"> <tr className="table-row-hover">
<td className="capability-cell"> <td className="capability-cell">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginRight: "8px", display: "inline-block", verticalAlign: "middle" }}> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="10"></circle> <circle cx="12" cy="12" r="10"></circle>
<line x1="22" y1="12" x2="18" y2="12"></line> <line x1="22" y1="12" x2="18" y2="12"></line>
<line x1="6" y1="12" x2="2" y2="12"></line> <line x1="6" y1="12" x2="2" y2="12"></line>
@@ -132,20 +201,379 @@ export default function CompetitiveEdge() {
</table> </table>
</div> </div>
{/* Strategic Moat Side cards */} {/* Moat Highlight Card (28% on Desktop) */}
<div className="moat-panel"> <div className="moat-panel" ref={moatRef}>
<div className="elementor-element elementor-element-54d05ac elementor-widget elementor-widget-logico_heading" data-id="54d05ac" data-element_type="widget" data-widget_type="logico_heading.default"> <div className="moat-accent-line" />
<div className="elementor-widget-container"> <div className="advantage-badge">DoorMile Advantage</div>
<div className="section-header"> <h3 className="moat-heading">WHERE DOORMILE SITS AND WHY IT WINS</h3>
<span className="section-tag">Competitive Edge</span> <p className="moat-desc">
<h3 className="logico-title" style={{ marginTop: "10px", marginBottom: "15px" }}>Where Doormile Sits And Why It Wins</h3> A side-by-side technical capabilities comparison showing how operational fleet ownership and dynamic AI planning disrupt basic aggregators.
<p className="section-desc">A side-by-side technical capabilities comparison showing how operational fleet ownership and dynamic AI planning disrupt basic aggregators.</p> </p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<style dangerouslySetInnerHTML={{ __html: `
/* --- HIGH-IMPACT PREMIUM CAPABILITIES SECTION STYLE --- */
.comparison-section {
position: relative;
padding: 120px 0;
background-color: #fafafa;
overflow: hidden;
font-family: "Manrope", sans-serif;
}
/* Spotlight radial background glow */
.comparison-bg-glow {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 900px;
height: 900px;
background: radial-gradient(circle, rgba(200, 16, 46, 0.03) 0%, transparent 70%);
z-index: 0;
pointer-events: none;
}
/* Subtle logistics dot grid overlay */
.comparison-bg-dots {
position: absolute;
inset: 0;
background-image: radial-gradient(#e2e4e8 1.5px, transparent 1.5px);
background-size: 32px 32px;
opacity: 0.45;
z-index: 0;
pointer-events: none;
}
.comparison-section .container {
position: relative;
z-index: 2;
max-width: 1400px;
margin: 0 auto;
padding: 0 40px;
}
/* Proportional flex layout scaling */
.comparison-layout {
display: flex;
align-items: stretch;
justify-content: space-between;
gap: 32px;
}
/* Spacious table styling wrapper (69% width) */
.table-wrapper {
flex: 0 0 69%;
max-width: 69%;
background: #ffffff;
border-radius: 24px;
border: 1px solid rgba(0, 0, 0, 0.05);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.015), 0 1px 3px rgba(0, 0, 0, 0.01);
overflow: hidden;
transition: box-shadow 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.table-wrapper:hover {
box-shadow: 0 35px 70px rgba(0, 0, 0, 0.035), 0 1px 3px rgba(0, 0, 0, 0.01);
}
.comparison-table {
width: 100%;
border-collapse: collapse;
text-align: left;
}
/* Enlarge row paddings and metrics size */
.comparison-table th,
.comparison-table td {
padding: 22px 24px;
border-bottom: 1px solid #f0f0f4;
font-size: 0.96rem;
color: #2b2b2b;
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.comparison-table tr:last-child td {
border-bottom: none;
}
.comparison-table th {
font-family: 'Manrope', sans-serif;
font-weight: 700;
text-transform: uppercase;
font-size: 0.8rem;
letter-spacing: 0.1em;
color: #8a8f9d;
background: rgba(15, 23, 42, 0.02);
}
/* High weight column header highlights */
th.col-highlight {
background: #c8102e !important;
color: #ffffff !important;
text-align: center;
font-weight: 800;
font-size: 0.85rem;
letter-spacing: 0.1em;
border-left: 2.5px solid #c8102e;
border-right: 2.5px solid #c8102e;
box-shadow: 0 4px 20px rgba(200, 16, 46, 0.1);
}
/* High weight cells gradient & highlights */
td.col-highlight {
text-align: center;
color: #c8102e !important;
font-weight: 700;
background: linear-gradient(180deg, rgba(200, 16, 46, 0.02) 0%, rgba(200, 16, 46, 0.005) 100%) !important;
border-left: 2.5px solid rgba(200, 16, 46, 0.12);
border-right: 2.5px solid rgba(200, 16, 46, 0.12);
position: relative;
will-change: transform, box-shadow, background;
animation: doormile-glow-pulse 4s infinite ease-in-out;
}
/* Row Hover Enhancements: brighten row & trigger DoorMile glow expand */
.table-row-hover {
transition: background-color 0.3s ease;
}
.table-row-hover:hover {
background-color: #fafbfd;
}
.table-row-hover:hover td.col-highlight {
background: linear-gradient(180deg, rgba(200, 16, 46, 0.045) 0%, rgba(200, 16, 46, 0.015) 100%) !important;
border-left-color: rgba(200, 16, 46, 0.35);
border-right-color: rgba(200, 16, 46, 0.35);
box-shadow: inset 0 0 16px rgba(200, 16, 46, 0.04);
transform: scale(1.015);
z-index: 10;
}
/* Soft Breathing Box Shadow Red Glow Pulse Loop */
@keyframes doormile-glow-pulse {
0% {
box-shadow: inset 0 0 0 0px rgba(200, 16, 46, 0);
}
50% {
box-shadow: inset 0 0 15px 1.5px rgba(200, 16, 46, 0.045);
}
100% {
box-shadow: inset 0 0 0 0px rgba(200, 16, 46, 0);
}
}
.capability-cell {
display: flex;
align-items: center;
gap: 12px;
font-weight: 700;
color: #111111;
font-size: 1.05rem;
}
.capability-cell svg {
color: #c8102e;
transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
flex-shrink: 0;
}
.table-row-hover:hover .capability-cell svg {
transform: scale(1.18) rotate(4deg);
}
/* Premium Badge styles */
.yes-badge {
display: inline-flex;
align-items: center;
gap: 6px;
color: #c8102e;
font-weight: 700;
font-size: 0.95rem;
background: rgba(200, 16, 46, 0.05);
padding: 4px 12px;
border-radius: 6px;
border: 1px solid rgba(200, 16, 46, 0.1);
will-change: transform, opacity;
}
.advanced-badge {
display: inline-flex;
align-items: center;
gap: 6px;
background: rgba(200, 16, 46, 0.075);
border: 1.5px solid #c8102e;
padding: 4px 12px;
border-radius: 8px;
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.06em;
font-weight: 800;
color: #c8102e;
will-change: transform, opacity;
box-shadow: 0 4px 12px rgba(200, 16, 46, 0.06);
}
.no-text {
color: #8e94a5;
font-weight: 500;
}
.partial-text {
color: #4b5262;
font-weight: 500;
}
/* --- RIGHT SIDE ADVANTAGE CARD PANEL (Centered content alignment) --- */
.moat-panel {
flex: 0 0 28%;
max-width: 28%;
background: linear-gradient(135deg, #ffffff 0%, #fbfbfc 100%);
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 24px;
padding: 40px 24px;
box-shadow: 0 20px 45px rgba(0, 0, 0, 0.025), inset 0 1px 0 #ffffff;
display: flex;
flex-direction: column;
align-items: center; /* Centers items horizontally */
justify-content: center;
text-align: center; /* Centers all text */
position: relative;
overflow: hidden;
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease;
will-change: transform;
}
.moat-panel:hover {
transform: translateY(-5px);
box-shadow: 0 35px 70px rgba(0, 0, 0, 0.045);
}
.moat-accent-line {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: #c8102e;
}
/* DoorMile Advantage Badge */
.advantage-badge {
font-family: 'Manrope', sans-serif;
font-weight: 800;
font-size: 0.72rem;
letter-spacing: 0.12em;
text-transform: uppercase;
color: #c8102e;
background: rgba(200, 16, 46, 0.06);
padding: 6px 14px;
border-radius: 30px;
margin: 0 auto 24px auto;
border: 1.5px solid rgba(200, 16, 46, 0.15);
display: inline-block;
white-space: nowrap;
}
/* Centered heading with bottom accent underline instead of left bar */
.moat-heading {
font-family: 'Manrope', sans-serif;
font-size: clamp(1.4rem, 2.3vw, 2.1rem);
font-weight: 800;
line-height: 1.25;
color: #111111;
margin: 0 auto 20px auto;
letter-spacing: -0.025em;
text-transform: uppercase;
word-wrap: break-word;
overflow-wrap: break-word;
display: flex;
flex-direction: column;
align-items: center;
}
/* Centered horizontal red underline accent decoration */
.moat-heading::after {
content: "";
display: block;
width: 48px;
height: 3.5px;
background: #c8102e;
margin-top: 16px;
border-radius: 2px;
}
.moat-desc {
font-family: 'Manrope', sans-serif;
font-size: 0.98rem;
line-height: 1.62;
color: #585c67;
margin: 8px auto 0 auto;
max-width: 340px; /* Bounded width for beautiful block wrapping */
}
/* --- RESPONSIVE WORKFLOWS & BREAKPOINTS --- */
@media (max-width: 1200px) {
.comparison-section .container {
padding: 0 24px;
}
.comparison-layout {
gap: 24px;
}
}
@media (max-width: 1024px) {
.comparison-layout {
flex-direction: column-reverse;
gap: 40px;
}
.table-wrapper,
.moat-panel {
flex: 0 0 100%;
max-width: 100%;
}
.moat-panel {
padding: 48px;
}
.moat-heading {
font-size: 2.2rem;
}
}
@media (max-width: 768px) {
.comparison-section {
padding: 80px 0;
}
/* Capability Matrix table gains responsive horizontal swipe scrolls */
.table-wrapper {
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.comparison-table {
min-width: 720px; /* Forces optimal reading width swipe trail */
}
.comparison-table th,
.comparison-table td {
padding: 16px 18px;
font-size: 0.9rem;
}
.capability-cell {
font-size: 0.98rem;
}
}
`}} />
</section> </section>
); );
} }

View File

@@ -1,206 +1,535 @@
"use client"; "use client";
import React, { useState } from "react"; import React, { useState, useEffect, useRef } from "react";
import Image from "next/image"; import Image from "next/image";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
const ACCORDION_DATA = [
{
index: 1,
num: "01",
title: "Battery-First Planning",
desc: "Routes are optimized around battery levels and charging windows, not retrofitted as an afterthought."
},
{
index: 2,
num: "02",
title: "Energy-Aware Routing",
desc: "Our algorithms factor in terrain, traffic, and payload weight to maximize range efficiency."
},
{
index: 3,
num: "03",
title: "Smart Charging Integration",
desc: "Seamless coordination with charging infrastructure to eliminate range anxiety for drivers."
},
{
index: 4,
num: "04",
title: "Carbon Footprint Tracking",
desc: "Real-time emissions monitoring and sustainability reports for every delivery."
}
];
export default function EVLogisticSection() { export default function EVLogisticSection() {
const [openIndex, setOpenIndex] = useState<number | null>(1); const [openIndex, setOpenIndex] = useState<number | null>(4); // Default to item 4 open to match user's screenshot layout
const containerRef = useRef<HTMLDivElement>(null);
const imageWrapperRef = useRef<HTMLDivElement>(null);
const imageRef = useRef<HTMLImageElement>(null);
const toggleAccordion = (index: number) => { const toggleAccordion = (index: number) => {
setOpenIndex((prev) => (prev === index ? null : index)); setOpenIndex((prev) => (prev === index ? null : index));
}; };
useEffect(() => {
const container = containerRef.current;
const img = imageRef.current;
const imgWrapper = imageWrapperRef.current;
if (!container || !img || !imgWrapper) return;
// 1. Parent Wrapper Loop: Slow Looping float
const floatAnim = gsap.to(imgWrapper, {
y: "-=10",
duration: 4.5,
ease: "sine.inOut",
yoyo: true,
repeat: -1,
});
// 2. Premium Entrance Animation on Scroll (ScrollTrigger based)
const entryTl = gsap.timeline({
scrollTrigger: {
trigger: container,
start: "top 80%",
toggleActions: "play none none none",
}
});
entryTl
.to(container.querySelector(".ev-logistic-kicker"), {
opacity: 1,
y: 0,
letterSpacing: "3px", // Kinetic letter-spacing track expand effect!
duration: 0.8,
ease: "power3.out",
})
.to(container.querySelectorAll(".ev-char"), {
y: "0%",
opacity: 1,
duration: 0.95,
stagger: 0.02, // Rapid letter-by-letter wave reveal!
ease: "power4.out",
}, "-=0.45")
.to(container.querySelectorAll(".ev-logistic-accordion-item"), {
opacity: 1,
y: 0,
duration: 0.6,
stagger: 0.08,
ease: "power3.out",
}, "-=0.6")
.fromTo(img, {
opacity: 0,
scale: 0.95,
}, {
opacity: 1,
scale: 1,
duration: 1.0,
ease: "power4.out",
}, "-=0.8");
return () => {
floatAnim.kill();
};
}, []);
const headingText = "LOGISTICS BUILT FOR ELECTRIC VEHICLES";
const headingWords = headingText.split(" ");
return ( return (
<div className="elementor-63 miletruth-hero about-us-hero" style={{ position: "relative", zIndex: 1 }}> <>
<style dangerouslySetInnerHTML={{ __html: `
/* Custom CSS Scoped to EV Logistics Section - New Premium Look */
.ev-logistic-section {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 1320px;
margin: 10px auto 120px auto; /* Centered horizontally with auto margins */
padding: 80px 60px; /* Restored original balanced left/right paddings */
box-sizing: border-box;
background: #ffffff;
font-family: 'Manrope', sans-serif;
gap: 60px;
position: relative;
}
/* ENLARGED Left Column - Image columns takes up 60% for high visual weight */
.ev-logistic-image-col {
flex: 1 1 60%;
max-width: 40%;
display: flex;
align-items: center;
justify-content: flex-start; /* Align left edge */
position: relative;
min-height: 580px;
margin-left: -150px; /* Shifted left towards boundary */
}
/* Branded glow spotlight halo behind the vehicle */
.ev-logistic-image-glow {
position: absolute;
left: 50%;
top: 50%;
width: 80%;
height: 70%;
transform: translate(-50%, -50%);
background: radial-gradient(circle, rgba(192, 18, 39, 0.05) 0%, rgba(192, 18, 39, 0.01) 55%, transparent 75%);
filter: blur(54px);
z-index: 0;
pointer-events: none;
}
/* Increased max-width wrapper so image scales much larger */
.ev-logistic-image-wrapper {
width: 100%;
height: 100%;
max-width: 1000px; /* Enlarged vehicle size */
display: flex;
align-items: center;
justify-content: flex-start;
overflow: visible;
position: relative;
will-change: transform;
transform: scale(1.25);
transform-origin: left center;
}
.ev-logistic-image-wrapper img {
width: 100%;
height: auto;
object-fit: contain;
filter: none; /* Blends solid white JPEG edges seamlessly into pure white background */
will-change: transform;
}
/* Balanced right column - takes up 40% for crisp textual reading */
.ev-logistic-content-col {
flex: 1 1 40%;
max-width: 40%;
display: flex;
flex-direction: column;
justify-content: center;
}
.ev-logistic-kicker {
font-size: 13px;
font-weight: 700;
letter-spacing: 0px; /* Expands to 3px on scroll */
text-transform: lowercase;
color: #888888;
margin-bottom: 20px;
margin-left: 10px; /* Shifted exactly 10px to the right as requested */
opacity: 0;
transform: translateY(-12px);
will-change: transform, opacity, letter-spacing;
}
.ev-logistic-title-wrapper {
margin-bottom: 48px;
}
/* Expanded clean headings look from the screenshot */
.ev-logistic-title {
font-size: clamp(45px, 6.2vw, 96px);
font-weight: 500;
line-height: 0.95;
text-transform: uppercase;
color: #111111;
margin: 0 10px 0 0; /* Clean margin-right to shift title away from borders */
letter-spacing: -1.8px;
}
/* CSS for robust letter-by-letter animation wrapping */
.ev-word-inline {
display: inline-block;
white-space: nowrap; /* Prevents awkward character line breaks */
}
.ev-char-wrapper {
display: inline-block;
overflow: hidden;
vertical-align: top;
}
.ev-char {
display: inline-block;
transform: translateY(110%);
opacity: 0;
will-change: transform, opacity;
}
.ev-char-space {
display: inline-block;
}
.ev-logistic-accordion {
display: flex;
flex-direction: column;
width: 100%;
}
/* Sleek horizontal grid borders */
.ev-logistic-accordion-item {
width: 100%;
border-top: 1px solid #e5e7eb;
opacity: 0;
transform: translateY(20px);
will-change: transform, opacity;
transition: background-color 0.4s cubic-bezier(0.25, 1, 0.5, 1);
}
.ev-logistic-accordion-item:last-child {
border-bottom: 1px solid #e5e7eb;
}
/* Soft highlight on row hover */
.ev-logistic-accordion-item:hover {
background: rgba(192, 18, 39, 0.015);
}
/* Spacious row padding for luxurious design - INCREASED font size for headers */
.ev-logistic-accordion-header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 28px 16px;
cursor: pointer;
background: transparent;
border: none;
text-align: left;
outline: none;
font-family: 'Manrope', sans-serif;
font-size: clamp(24px, 2.2vw, 30px); /* Increased to clamp up to 30px! */
font-weight: 700;
color: #111111;
transition: color 0.3s ease;
}
.ev-logistic-accordion-header span:first-child {
transition: transform 0.35s cubic-bezier(0.25, 1, 0.5, 1);
display: inline-block;
}
/* Row text horizontal slide nudge */
.ev-logistic-accordion-header:hover {
color: #c01227;
}
.ev-logistic-accordion-header:hover span:first-child {
transform: translateX(10px);
}
.ev-logistic-accordion-item.active .ev-logistic-accordion-header {
color: #111111;
}
.ev-logistic-accordion-arrow-container {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), color 0.3s ease;
}
.ev-logistic-accordion-arrow-container svg {
width: 20px;
height: 20px;
stroke-width: 2.5;
}
/* Inactive arrows: point down-right ↘ */
.ev-logistic-accordion-item:not(.active) .ev-logistic-accordion-arrow-container {
transform: rotate(90deg);
color: #111111;
}
/* Active arrows: point up-right ↗ in brand red */
.ev-logistic-accordion-item.active .ev-logistic-accordion-arrow-container {
transform: rotate(0deg);
color: #c01227;
}
/* Hover: rotate smooth to diagonal up-right */
.ev-logistic-accordion-header:hover .ev-logistic-accordion-arrow-container {
transform: rotate(0deg);
color: #c01227;
}
.ev-logistic-accordion-content {
overflow: hidden;
max-height: 0;
opacity: 0;
transition: max-height 0.45s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.45s ease;
}
.ev-logistic-accordion-item.active .ev-logistic-accordion-content {
max-height: 160px;
opacity: 1;
}
/* Balanced text spacing inside descriptions - INCREASED font size for descriptions */
.ev-logistic-accordion-content-inner {
padding: 0 16px 28px 16px;
font-size: clamp(18px, 1.5vw, 20px); /* Increased to clamp up to 20px! */
line-height: 1.6;
color: #555555;
font-weight: 500;
}
/* Underline track & sweeping active red bar */
.ev-logistic-accordion-progress-track {
position: relative;
width: 100%;
height: 1.5px;
background: transparent;
margin-top: -1.5px;
overflow: hidden;
}
.ev-logistic-accordion-progress-bar {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
background: #c01227;
transform: scaleX(0);
transform-origin: left center;
transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1);
will-change: transform;
}
.ev-logistic-accordion-item.active .ev-logistic-accordion-progress-bar {
transform: scaleX(1);
}
/* Responsiveness constraints */
@media (max-width: 1024px) {
.ev-logistic-section {
flex-direction: column;
padding: 60px 24px;
gap: 50px;
margin-bottom: 60px;
}
.ev-logistic-image-col {
flex: 1 1 100%;
max-width: 100%;
min-height: auto;
margin-left: 0; /* Reset margins on mobile */
justify-content: center; /* Center layout on mobile */
}
.ev-logistic-image-wrapper {
max-width: 580px;
transform: none; /* Reset scaling on mobile */
}
.ev-logistic-content-col {
flex: 1 1 100%;
max-width: 100%;
}
.ev-logistic-title {
font-size: 38px;
}
}
@media (max-width: 768px) {
.ev-logistic-section {
padding: 40px 16px;
gap: 40px;
}
.ev-logistic-image-wrapper {
max-width: 100%;
}
.ev-logistic-title {
font-size: 32px;
}
.ev-logistic-accordion-header {
font-size: 19px;
padding: 22px 8px;
}
.ev-logistic-accordion-content-inner {
padding: 0;
font-size: 15.5px;
}
}
`}} />
<div <div
style={{ marginBottom: "180px" }} ref={containerRef}
className="elementor-element ev-log elementor-element-ead59d3 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" className="ev-logistic-section"
data-id="ead59d3"
data-element_type="container"
data-e-type="container"
> >
<div {/* Left Column: Enlarged Floating Wrapper & Ambient glow */}
className="elementor-element elementor-element-f35119c elementor-widget__width-initial elementor-absolute elementor-widget elementor-widget-image" <div className="ev-logistic-image-col">
data-id="f35119c" <div className="ev-logistic-image-glow"></div>
data-element_type="widget"
data-e-type="widget" <div ref={imageWrapperRef} className="ev-logistic-image-wrapper">
style={{ position: "absolute" }}
>
<div className="elementor-widget-container">
<Image <Image
ref={imageRef as any}
src="/images/ev.jpeg" src="/images/ev.jpeg"
alt="EV Logistics" alt="EV Logistics"
width={1050} width={1050}
height={854} height={854}
style={{ width: "100%", height: "auto" }} priority
/> />
</div> </div>
</div> </div>
{/* Right Column: Refined Accordion list with letter-by-letter animation */}
<div className="ev-logistic-content-col">
{/* Animated features kicker */}
<div className="ev-logistic-kicker">/ features /</div>
{/* Character-by-character masked entrance wave reveal on scroll */}
<div className="ev-logistic-title-wrapper">
<h3 className="ev-logistic-title">
{headingWords.map((word, wordIndex) => (
<span key={wordIndex} className="ev-word-inline">
{word.split("").map((letter, letterIndex) => (
<span key={letterIndex} className="ev-char-wrapper">
<span className="ev-char">{letter}</span>
</span>
))}
<span className="ev-char-space">&nbsp;</span>
</span>
))}
</h3>
</div>
<div className="ev-logistic-accordion">
{ACCORDION_DATA.map((item) => (
<div <div
className="elementor-element elementor-element-56ecbb3 e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-child" key={item.index}
data-id="56ecbb3" className={`ev-logistic-accordion-item ${openIndex === item.index ? "active" : ""}`}
data-element_type="container"
data-e-type="container"
> >
<div className="e-con-inner"> <button
<div className="ev-logistic-accordion-header"
className="elementor-element elementor-element-47f8cbe e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" onClick={() => toggleAccordion(item.index)}
data-id="47f8cbe" aria-expanded={openIndex === item.index}
data-element_type="container"
data-e-type="container"
> >
<div <span>{item.num}. {item.title}</span>
className="elementor-element elementor-element-cd6daaf elementor-widget elementor-widget-logico_heading" <span className="ev-logistic-accordion-arrow-container">
data-id="cd6daaf" <svg
data-element_type="widget" viewBox="0 0 24 24"
data-e-type="widget" fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
> >
<div className="elementor-widget-container"> <line x1="7" y1="17" x2="17" y2="7"></line>
<div className="logico-title">/ features /</div> <polyline points="7 7 17 7 17 17"></polyline>
</div> </svg>
</div> </span>
</button>
<div
className="elementor-element elementor-element-1b3f232 elementor-widget__width-initial elementor-widget elementor-widget-logico_heading" <div className="ev-logistic-accordion-content">
data-id="1b3f232" <div className="ev-logistic-accordion-content-inner">
data-element_type="widget" {/* Kinetic slide-up and fade subtitle reveal */}
data-e-type="widget" <p style={{
> transform: openIndex === item.index ? "translateY(0)" : "translateY(12px)",
<div className="elementor-widget-container"> opacity: openIndex === item.index ? 1 : 0,
<h3 className="logico-title">Logistics Built for Electric Vehicles</h3> transition: "transform 0.5s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.5s ease",
</div> transitionDelay: "0.08s",
</div> margin: 0
}}>
<div {item.desc}
className="elementor-element elementor-element-9b7e9c9 elementor-widget__width-initial elementor-widget elementor-widget-accordion" </p>
data-id="9b7e9c9"
data-element_type="widget"
data-e-type="widget"
>
<div className="elementor-widget-container">
<div className="elementor-accordion">
{/* Accordion 1 */}
<div className="elementor-accordion-item">
<div
className={`elementor-tab-title ${openIndex === 1 ? "elementor-active" : ""}`}
role="button"
aria-expanded={openIndex === 1}
onClick={() => toggleAccordion(1)}
style={{ cursor: "pointer" }}
>
<span className="elementor-accordion-icon elementor-accordion-icon-right" aria-hidden="true">
<span className="elementor-accordion-icon-closed" style={{ display: openIndex === 1 ? "none" : "inline" }}>
<i className="fontello icon-arrow-x-r-down"></i>
</span>
<span className="elementor-accordion-icon-opened" style={{ display: openIndex === 1 ? "inline" : "none" }}>
<i className="fontello icon-arrow-x-r-top"></i>
</span>
</span>
<span className="elementor-accordion-title">01. Battery-First Planning</span>
</div>
<div
className="elementor-tab-content elementor-clearfix"
role="region"
style={{ display: openIndex === 1 ? "block" : "none" }}
>
<p>Routes are optimized around battery levels and charging windows, not retrofitted as an afterthought.</p>
</div>
</div>
{/* Accordion 2 */}
<div className="elementor-accordion-item">
<div
className={`elementor-tab-title ${openIndex === 2 ? "elementor-active" : ""}`}
role="button"
aria-expanded={openIndex === 2}
onClick={() => toggleAccordion(2)}
style={{ cursor: "pointer" }}
>
<span className="elementor-accordion-icon elementor-accordion-icon-right" aria-hidden="true">
<span className="elementor-accordion-icon-closed" style={{ display: openIndex === 2 ? "none" : "inline" }}>
<i className="fontello icon-arrow-x-r-down"></i>
</span>
<span className="elementor-accordion-icon-opened" style={{ display: openIndex === 2 ? "inline" : "none" }}>
<i className="fontello icon-arrow-x-r-top"></i>
</span>
</span>
<span className="elementor-accordion-title">02. Energy-Aware Routing</span>
</div>
<div
className="elementor-tab-content elementor-clearfix"
role="region"
style={{ display: openIndex === 2 ? "block" : "none" }}
>
<p>Our algorithms factor in terrain, traffic, and payload weight to maximize range efficiency.</p>
</div>
</div>
{/* Accordion 3 */}
<div className="elementor-accordion-item">
<div
className={`elementor-tab-title ${openIndex === 3 ? "elementor-active" : ""}`}
role="button"
aria-expanded={openIndex === 3}
onClick={() => toggleAccordion(3)}
style={{ cursor: "pointer" }}
>
<span className="elementor-accordion-icon elementor-accordion-icon-right" aria-hidden="true">
<span className="elementor-accordion-icon-closed" style={{ display: openIndex === 3 ? "none" : "inline" }}>
<i className="fontello icon-arrow-x-r-down"></i>
</span>
<span className="elementor-accordion-icon-opened" style={{ display: openIndex === 3 ? "inline" : "none" }}>
<i className="fontello icon-arrow-x-r-top"></i>
</span>
</span>
<span className="elementor-accordion-title">03. Smart Charging Integration</span>
</div>
<div
className="elementor-tab-content elementor-clearfix"
role="region"
style={{ display: openIndex === 3 ? "block" : "none" }}
>
<p>Seamless coordination with charging infrastructure to eliminate range anxiety for drivers.</p>
</div>
</div>
{/* Accordion 4 */}
<div className="elementor-accordion-item">
<div
className={`elementor-tab-title ${openIndex === 4 ? "elementor-active" : ""}`}
role="button"
aria-expanded={openIndex === 4}
onClick={() => toggleAccordion(4)}
style={{ cursor: "pointer" }}
>
<span className="elementor-accordion-icon elementor-accordion-icon-right" aria-hidden="true">
<span className="elementor-accordion-icon-closed" style={{ display: openIndex === 4 ? "none" : "inline" }}>
<i className="fontello icon-arrow-x-r-down"></i>
</span>
<span className="elementor-accordion-icon-opened" style={{ display: openIndex === 4 ? "inline" : "none" }}>
<i className="fontello icon-arrow-x-r-top"></i>
</span>
</span>
<span className="elementor-accordion-title">04. Carbon Footprint Tracking</span>
</div>
<div
className="elementor-tab-content elementor-clearfix"
role="region"
style={{ display: openIndex === 4 ? "block" : "none" }}
>
<p>Real-time emissions monitoring and sustainability reports for every delivery.</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
{/* Underline track & sweep animated red bar */}
<div className="ev-logistic-accordion-progress-track">
<div className="ev-logistic-accordion-progress-bar"></div>
</div> </div>
</div> </div>
))}
</div> </div>
</div> </div>
</div> </div>
</>
); );
} }

View File

@@ -0,0 +1,138 @@
"use client";
import React, { useEffect, useRef } from "react";
/**
* EV-Native Design background — drifting SQUARE particles with 3D depth.
* Each square has a depth (0.31): nearer squares are larger, brighter, and
* parallax further on mouse-move + a slow auto-sway, creating a layered 3D
* field. Mix of brand-red (#dc2626) and soft gray/white squares. Full section,
* pointer-events:none, behind content.
*/
export default function EVParticles() {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
const parent = canvas?.parentElement;
if (!canvas || !parent) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
const COUNT = 120;
type P = { x: number; y: number; vx: number; vy: number; s: number; red: boolean; a: number; d: number };
let particles: P[] = [];
let w = 0, h = 0, raf = 0, startTs = 0;
// mouse parallax (canvas is pointer-events:none, so track on window)
const mouse = { x: 0, y: 0 };
const cur = { x: 0, y: 0 };
const onMove = (e: MouseEvent) => {
mouse.x = (e.clientX / window.innerWidth) * 2 - 1;
mouse.y = (e.clientY / window.innerHeight) * 2 - 1;
};
const init = () => {
particles = [];
for (let i = 0; i < COUNT; i++) {
const t = Math.random();
const s = t > 0.92 ? 12 + Math.random() * 6 : t > 0.68 ? 7 + Math.random() * 5 : 3 + Math.random() * 4;
const red = Math.random() < 0.3;
particles.push({
x: Math.random() * w,
y: Math.random() * h,
vx: (Math.random() - 0.5) * 0.22,
vy: (Math.random() - 0.5) * 0.22,
s,
red,
a: red ? Math.random() * 0.4 + 0.35 : Math.random() * 0.28 + 0.12,
d: Math.random() * 0.7 + 0.3, // depth 0.3 (far) .. 1 (near)
});
}
};
const resize = () => {
const rect = parent.getBoundingClientRect();
w = Math.max(1, rect.width);
h = Math.max(1, rect.height);
const dpr = Math.min(window.devicePixelRatio || 1, 2);
canvas.width = Math.round(w * dpr);
canvas.height = Math.round(h * dpr);
canvas.style.width = w + "px";
canvas.style.height = h + "px";
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
if (!particles.length) init();
};
const render = (time: number, move: boolean) => {
ctx.clearRect(0, 0, w, h);
// ease the parallax origin toward the pointer
cur.x += (mouse.x - cur.x) * 0.04;
cur.y += (mouse.y - cur.y) * 0.04;
// slow auto-sway so the 3D depth animates even without mouse input
const swayX = Math.sin(time * 0.00026) * 0.6;
const swayY = Math.cos(time * 0.0002) * 0.45;
const ox = (cur.x + swayX) * 34;
const oy = (cur.y + swayY) * 26;
for (const p of particles) {
if (move) {
p.x += p.vx * p.d;
p.y += p.vy * p.d;
const m = p.s + 6;
if (p.x < -m) p.x = w + m;
else if (p.x > w + m) p.x = -m;
if (p.y < -m) p.y = h + m;
else if (p.y > h + m) p.y = -m;
}
// depth-scaled size + parallax offset (near squares move/scale more)
const size = p.s * (0.55 + p.d * 0.75);
const dx = p.x + ox * p.d;
const dy = p.y + oy * p.d;
const alpha = p.a * (0.55 + p.d * 0.45);
if (p.red) {
ctx.shadowColor = "rgba(220,38,38,0.55)";
ctx.shadowBlur = 8 * p.d;
ctx.fillStyle = `rgba(220,38,38,${alpha})`;
} else {
ctx.shadowBlur = 0;
ctx.fillStyle = `rgba(200,202,210,${alpha})`;
}
ctx.fillRect(dx - size / 2, dy - size / 2, size, size);
}
ctx.shadowBlur = 0;
};
const loop = (ts: number) => {
if (!startTs) startTs = ts;
render(ts - startTs, true);
raf = requestAnimationFrame(loop);
};
resize();
init();
if (reduced) {
render(0, false);
} else {
window.addEventListener("mousemove", onMove, { passive: true });
raf = requestAnimationFrame(loop);
}
const ro = new ResizeObserver(() => {
resize();
if (reduced) render(0, false);
});
ro.observe(parent);
return () => {
cancelAnimationFrame(raf);
ro.disconnect();
window.removeEventListener("mousemove", onMove);
};
}, []);
return <canvas ref={canvasRef} className="evnd__canvas" aria-hidden="true" />;
}

View File

@@ -1,46 +1,122 @@
"use client"; "use client";
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef, useState } from "react";
import Link from "next/link"; import dynamic from "next/dynamic";
import { ScrollReveal, SlideReveal } from "@/animations/Reveal";
import gsap from "gsap"; import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger"; import { ScrollTrigger } from "gsap/ScrollTrigger";
// Drifting particle background — client-only, mounted behind the section.
const EVParticles = dynamic(() => import("./EVParticles"), { ssr: false });
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollTrigger);
} }
const PILLS: { value: string; label: string }[] = [
{ value: "100%", label: "Electric Fleet" },
{ value: "Live", label: "Route Sync" },
{ value: "Real-time", label: "Battery Monitoring" },
];
const MINI_STATS: { value: number; decimals?: number; suffix: string; label: string }[] = [
{ value: 94, suffix: "K+", label: "Routes Optimised" },
{ value: 23, suffix: "%", label: "Avg Battery Saved" },
{ value: 1.4, decimals: 1, suffix: "x", label: "Charging Stops Saved" },
];
const FEATURES: { icon: string; title: string; desc: string }[] = [
{
icon: "⚡",
title: "Battery-Aware Routing",
desc: "Battery level, health, and degradation are first-class inputs to route optimization — not afterthoughts.",
},
{
icon: "🔌",
title: "Charging Integration",
desc: "Seamlessly integrate charging stops without compromising delivery windows or SLA commitments.",
},
{
icon: "⛰",
title: "Energy-Optimized Paths",
desc: "Factor in elevation, speed limits, payload weight, and live weather for maximum range efficiency.",
},
{
icon: "🛡",
title: "Predictable Operations",
desc: "EVs become predictable assets, not operational risks. Full visibility from depot to doorstep.",
},
];
const BOTTOM_STATS: { value: number; decimals?: number; suffix: string; label: string }[] = [
{ value: 120, suffix: "K+", label: "Deliveries Completed" },
{ value: 98, suffix: "%", label: "On-Time Rate" },
{ value: 31, suffix: "%", label: "Range Efficiency Gain" },
{ value: 340, suffix: "ms", label: "Avg Route Calc Time" },
];
/** Count-up that fires once when scrolled ~20% into view (ease-out cubic). */
function CountUp({
value,
decimals = 0,
suffix = "",
duration = 1700,
className,
}: {
value: number;
decimals?: number;
suffix?: string;
duration?: number;
className?: string;
}) {
const [n, setN] = useState(0);
const ref = useRef<HTMLElement>(null);
const done = useRef(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
if (reduced) {
setN(value);
return;
}
const io = new IntersectionObserver(
(entries) => {
for (const e of entries) {
if (e.isIntersecting && !done.current) {
done.current = true;
const start = performance.now();
const ease = (t: number) => 1 - Math.pow(1 - t, 3);
const tick = (now: number) => {
const p = Math.min(1, (now - start) / duration);
setN(value * ease(p));
if (p < 1) requestAnimationFrame(tick);
else setN(value);
};
requestAnimationFrame(tick);
io.disconnect();
}
}
},
{ threshold: 0.2 }
);
io.observe(el);
return () => io.disconnect();
}, [value, duration]);
return (
<b ref={ref as React.RefObject<HTMLElement>} className={className}>
{n.toFixed(decimals)}
{suffix}
</b>
);
}
export default function EVSection() { export default function EVSection() {
const headingContainerRef = useRef<HTMLDivElement>(null);
const bannerRef = useRef<HTMLDivElement>(null); const bannerRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
// 1. Heading Scroll-Triggered Animation (Up & Down, Replay) // Banner Scroll-Triggered Parallax (Replicating background_image_parallax from theme.js exactly)
const headingEl = headingContainerRef.current;
if (headingEl) {
const trigger = ScrollTrigger.create({
trigger: headingEl,
start: "top 88%",
onEnter: () => {
headingEl.classList.add("animated");
},
onEnterBack: () => {
headingEl.classList.add("animated");
},
onLeave: () => {
headingEl.classList.remove("animated");
},
onLeaveBack: () => {
headingEl.classList.remove("animated");
},
});
return () => trigger?.kill();
}
}, []);
useEffect(() => {
// 2. Banner Native Background Parallax (GSAP ScrollTrigger)
const banner = bannerRef.current; const banner = bannerRef.current;
if (!banner) return; if (!banner) return;
@@ -49,86 +125,279 @@ export default function EVSection() {
start: "top bottom", start: "top bottom",
end: "bottom top", end: "bottom top",
scrub: true, scrub: true,
onUpdate: (self) => { onUpdate: () => {
// Subtle background offset to create beautiful native parallax depth if (window.innerWidth >= 1021) {
const yOffset = self.progress * 120; const scrollTop = window.scrollY;
gsap.set(banner, { const rect = banner.getBoundingClientRect();
backgroundPosition: `center ${yOffset}px`, const offsetTop = rect.top + scrollTop;
}); const from_top = scrollTop - offsetTop;
const yOffset = 0.3 * from_top;
gsap.set(banner, { backgroundPosition: `center ${yOffset}px` });
} else {
gsap.set(banner, { backgroundPosition: "" });
}
}, },
}); });
return () => parallaxTrigger?.kill(); return () => parallaxTrigger?.kill();
}, []); }, []);
const renderAnimatedText = () => {
const lines = [
{ text: "Built for Electric.", highlight: true },
{ text: "Not Adapted.", highlight: false }
];
let letterCount = 0;
return lines.map((line, lineIdx) => {
const words = line.text.split(/\s+/);
return (
<div key={lineIdx} style={{ display: "block" }}>
{words.map((word, wordIdx) => {
const letters = word.split("");
return (
<span key={wordIdx} className="word" style={{ display: "inline-block", marginRight: "0.2em", whiteSpace: "nowrap" }}>
{letters.map((letter, letterIdx) => {
const delay = `${letterCount / 50}s`;
letterCount++;
return (
<span
key={letterIdx}
className="letter"
style={{
animationDelay: delay,
["--delay" as any]: delay,
}}
>
{letter}
</span>
);
})}
{/* Non-breaking space */}
&nbsp;
</span>
);
})}
</div>
);
});
};
return ( return (
<> <>
<style dangerouslySetInnerHTML={{ __html: ` <style dangerouslySetInnerHTML={{ __html: `
.logico-title .word { /* ============================================================
display: inline-block; EV-Native Design — redesigned section
white-space: nowrap; bg #0d0d0d · red #dc2626 / #ef4444 · Syne + DM Sans
margin-right: 0.15em; ============================================================ */
}
.letter {
display: inline-block;
}
/* Native, scroll-triggered heading reveal matching WordPress/Elementor */ #evnd, #evnd * { font-family: "Manrope", Sans-serif !important; }
.logico_heading_animation .word .letter {
opacity: 0 !important; .evnd {
transform: translateY(120%) !important; position: relative;
animation: none !important; isolation: isolate;
overflow: hidden;
background: #0d0d0d;
/* flat top so it connects seamlessly to the banner above; rounded
bottom only, and no top margin so there is no white gap */
border-radius: 0 0 clamp(16px, 2vw, 28px) clamp(16px, 2vw, 28px);
margin: 0 0 clamp(28px, 5vw, 64px);
padding: 56px 48px 64px;
} }
.logico_heading_animation.animated .word .letter { /* subtle diagonal light band for depth (matches reference) */
opacity: 0 !important; .evnd::before {
transform: translateY(120%) !important; content: '';
animation: fadeIn 0.35s forwards, logico_heading_animation 0.7s cubic-bezier(.26, -.14, 0, 1.01) forwards !important; position: absolute;
inset: 0;
z-index: 0;
pointer-events: none;
background: linear-gradient(120deg, transparent 28%, rgba(255,255,255,0.025) 50%, transparent 72%);
}
.evnd__canvas {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 0;
pointer-events: none;
}
.evnd__inner { position: relative; z-index: 1; max-width: 1280px; margin: 0 auto; }
/* ---- TOP ROW ---- */
.evnd__top {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 44px;
align-items: center;
margin-bottom: 48px;
}
.evnd__eyebrow {
display: inline-flex;
align-items: center;
gap: 12px;
color: #dc2626 !important;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: 13px;
margin-bottom: 16px;
}
.evnd__eyebrow::before { content: ''; width: 24px; height: 2px; background: #dc2626; }
.evnd__title {
color: #fff !important;
font-weight: 800 !important;
font-size: clamp(30px, 4.4vw, 56px) !important;
line-height: 1.04 !important;
letter-spacing: -0.01em;
margin: 0;
}
.evnd__title .accent { color: #ef4444 !important; }
.evnd__pills { display: flex; flex-direction: column; gap: 12px; }
.evnd__pill {
display: flex;
align-items: center;
gap: 12px;
padding: 13px 20px;
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 100px;
}
.evnd__pill .dot {
flex: 0 0 auto;
width: 8px; height: 8px;
border-radius: 50%;
background: #22c55e;
box-shadow: 0 0 8px #22c55e;
animation: evndBlink 1.4s ease-in-out infinite;
}
.evnd__pill b { color: #ef4444 !important; font-weight: 800; font-size: 15px; }
.evnd__pill span { color: rgba(255,255,255,0.62) !important; font-size: 13px; }
/* ---- MAIN GRID ---- */
.evnd__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: start; }
.evnd__media { position: relative; }
.evnd__glow {
position: absolute;
left: 50%; bottom: -4%;
width: 72%; height: 64px;
transform: translateX(-50%);
background: radial-gradient(50% 50% at 50% 50%, rgba(220,38,38,0.5), transparent 72%);
filter: blur(30px);
z-index: 0;
animation: evndGlow 4s ease-in-out infinite;
}
.evnd__imgwrap { position: relative; z-index: 1; animation: evndFloat 7s ease-in-out infinite; will-change: transform; }
.evnd__img {
display: block;
width: 100%;
height: auto;
border-radius: 14px;
box-shadow: 0 30px 60px -25px rgba(0,0,0,0.7);
}
.evnd__badge {
position: absolute;
z-index: 2;
display: flex;
flex-direction: column;
gap: 2px;
padding: 10px 14px;
background: rgba(10,10,10,0.88);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 8px;
}
.evnd__badge b { color: #ef4444 !important; font-weight: 800; font-size: 24px; line-height: 1; }
.evnd__badge span { color: rgba(255,255,255,0.55) !important; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
.evnd__badge--tl { top: 14px; left: 14px; }
.evnd__badge--br { bottom: 14px; right: 14px; }
.evnd__ministats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 20px; }
.evnd__mini {
position: relative;
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.06);
border-radius: 10px;
padding: 18px 14px 14px;
overflow: hidden;
}
.evnd__mini::before {
content: '';
position: absolute; top: 0; left: 0; right: 0;
height: 2px;
background: linear-gradient(90deg, #dc2626, transparent);
}
.evnd__mini b { display: block; color: #fff !important; font-weight: 800; font-size: clamp(20px, 2.3vw, 28px); line-height: 1; margin-bottom: 6px; }
.evnd__mini span { color: rgba(255,255,255,0.5) !important; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; line-height: 1.3; display: block; }
/* ---- Feature cards ---- */
.evnd__features { display: flex; flex-direction: column; gap: 10px; }
.evnd-feature {
position: relative;
display: grid;
grid-template-columns: 40px 1fr auto;
gap: 16px;
align-items: start;
background: rgba(255,255,255,0.028);
border: 1px solid rgba(255,255,255,0.07);
border-radius: 12px;
padding: 18px 20px;
overflow: hidden;
transition: background-color 0.35s ease, border-color 0.35s ease, transform 0.35s cubic-bezier(.25,1,.5,1);
}
.evnd-feature::before {
content: '';
position: absolute;
left: 0; top: 0; bottom: 0;
width: 3px;
background: #dc2626;
transform: scaleY(0);
transform-origin: bottom;
transition: transform 0.35s ease;
}
.evnd-feature:hover { background: rgba(220,38,38,0.06); border-color: rgba(220,38,38,0.25); transform: translateX(4px); }
.evnd-feature:hover::before { transform: scaleY(1); }
.evnd-feature__icon {
width: 40px; height: 40px;
display: flex; align-items: center; justify-content: center;
background: rgba(220,38,38,0.1);
border: 1px solid rgba(220,38,38,0.2);
border-radius: 10px;
font-size: 18px;
}
.evnd-feature__title {
color: #fff !important;
font-weight: 700;
font-size: 15px !important;
text-transform: uppercase;
letter-spacing: 0.04em;
margin: 3px 0 7px;
transition: color 0.3s ease;
}
.evnd-feature:hover .evnd-feature__title { color: #ef4444 !important; }
.evnd-feature__desc {
color: rgba(255,255,255,0.75) !important;
font-weight: 400 !important;
font-size: 14.5px !important;
line-height: 1.65 !important;
margin: 0;
}
.evnd-feature__arrow {
color: rgba(255,255,255,0.2);
font-size: 14px;
align-self: flex-start;
transition: color 0.3s ease, transform 0.3s ease;
}
.evnd-feature:hover .evnd-feature__arrow { color: #ef4444; transform: translate(3px, -3px); }
/* ---- BOTTOM BAR ---- */
.evnd__bar {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1px;
background: rgba(255,255,255,0.06);
border-radius: 12px;
overflow: hidden;
margin-top: 40px;
}
.evnd__bar-item {
background: #0d0d0d;
padding: 24px 22px;
display: flex;
flex-direction: column;
gap: 8px;
align-items: flex-start;
}
.evnd__bar-item .dot {
width: 7px; height: 7px;
border-radius: 50%;
background: #dc2626;
box-shadow: 0 0 8px rgba(220,38,38,0.85);
animation: evndBlink 1.4s ease-in-out infinite;
}
.evnd__bar-item b { color: #fff !important; font-weight: 800; font-size: clamp(22px, 2.6vw, 30px); line-height: 1; }
.evnd__bar-item span { color: rgba(255,255,255,0.45) !important; font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; }
@keyframes evndFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes evndGlow { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }
@keyframes evndBlink { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }
/* ---- Responsive ---- */
@media (max-width: 900px) {
.evnd { padding: 48px 28px 52px; }
.evnd__top { grid-template-columns: 1fr; gap: 28px; margin-bottom: 36px; }
.evnd__grid { grid-template-columns: 1fr; gap: 36px; }
}
@media (max-width: 600px) {
.evnd { padding: 40px 18px 44px; }
.evnd__bar { grid-template-columns: repeat(2, 1fr); }
.evnd__pill { padding: 11px 16px; }
}
@media (prefers-reduced-motion: reduce) {
.evnd__imgwrap, .evnd__glow, .evnd__pill .dot, .evnd__bar-item .dot { animation: none !important; }
} }
`}} /> `}} />
<div className="elementor-element elementor-element-bbc6760 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="bbc6760" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-bbc6760 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="bbc6760" data-element_type="container" data-e-type="container" style={{ backgroundColor: "#0d0d0d", width: "calc(100% - 40px)", marginLeft: "20px", marginRight: "20px", borderRadius: "25px", overflow: "hidden" }}>
{/* Background Banner with Native GSAP Background Scroll Parallax */} {/* Background Banner with Native GSAP Background Scroll Parallax */}
<div <div
@@ -140,9 +409,13 @@ export default function EVSection() {
data-settings="{&quot;background_background&quot;:&quot;classic&quot;}" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"
style={{ style={{
backgroundPosition: "center 0px", backgroundPosition: "center 0px",
backgroundImage: "url(/images/home4-banner-4.png)", backgroundImage: "url(/images/bg-header-5.png)",
backgroundSize: "cover", backgroundSize: "cover",
backgroundRepeat: "no-repeat" backgroundRepeat: "no-repeat",
position: "relative",
zIndex: 2,
borderRadius: "25px 25px 0 0",
overflow: "hidden"
}} }}
></div> ></div>
@@ -169,164 +442,89 @@ export default function EVSection() {
</div> </div>
</div> </div>
<div className="elementor-element elementor-element-b6e14bd e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-child" data-id="b6e14bd" data-element_type="container" data-e-type="container" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"> {/* ===== EV-Native Design (redesigned) ===== */}
<div className="e-con-inner"> <section className="evnd" id="evnd" aria-label="EV-Native Design">
<div className="elementor-element elementor-element-90cc867 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="90cc867" data-element_type="container" data-e-type="container"> <div className="evnd__canvas-wrap" style={{ position: "absolute", inset: 0, zIndex: 0, pointerEvents: "none" }}>
<EVParticles />
</div>
<ScrollReveal delay={0.05} duration={0.7} yOffset={20}> <div className="evnd__inner">
<div className="elementor-element elementor-element-24c0280 elementor-widget__width-inherit elementor-widget elementor-widget-logico_heading" data-id="24c0280" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default"> {/* TOP ROW */}
<div className="elementor-widget-container"> <div className="evnd__top">
<div className="logico-title">/ EV-Native Design /</div> <div className="evnd__head">
<span className="evnd__eyebrow">/ EV-Native Design /</span>
<div className="evnd__title">
BUILT FOR ELECTRIC. <span className="accent">NOT ADAPTED.</span>
</div>
</div>
<div className="evnd__pills">
{PILLS.map((p) => (
<div className="evnd__pill" key={p.label}>
<span className="dot" />
<b>{p.value}</b>
<span>{p.label}</span>
</div>
))}
</div> </div>
</div> </div>
</ScrollReveal>
<div className="elementor-element elementor-element-2ed47f3 e-con-full e-grid cut-corner-no sticky-container-off e-con e-child" data-id="2ed47f3" data-element_type="container" data-e-type="container"> {/* MAIN GRID */}
<div className="elementor-element elementor-element-36efec7 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="36efec7" data-element_type="container" data-e-type="container"> <div className="evnd__grid">
<div ref={headingContainerRef} className="elementor-element elementor-element-778840d elementor-widget elementor-widget-logico_heading logico_heading_animation" data-id="778840d" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default"> {/* Left column */}
<div className="elementor-widget-container"> <div className="evnd__left">
<h3 className="logico-title" data-animate="true"> <div className="evnd__media">
{renderAnimatedText()} <div className="evnd__glow" />
</h3> <div className="evnd__imgwrap">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img className="evnd__img" src="/images/premium-ev-van.png" alt="DoorMile electric delivery van" decoding="async" />
<div className="evnd__badge evnd__badge--tl">
<b>100%</b>
<span>Electric Fleet</span>
</div> </div>
</div> <div className="evnd__badge evnd__badge--br">
<div className="elementor-element elementor-element-bbfb67f elementor-widget elementor-widget-image" data-id="bbfb67f" data-element_type="widget" data-e-type="widget" data-widget_type="image.default"> <b>&minus;40%</b>
<div className="elementor-widget-container"> <span>Cost / Mile</span>
<img decoding="async" width="626" height="692" src="/images/home4-pic-1.png" className="attachment-full size-full wp-image-6789" alt="EV Truck" style={{ objectFit: "cover", width: "100%", height: "auto" }} />
</div> </div>
</div> </div>
</div> </div>
<SlideReveal direction="right" delay={0.15} duration={0.9}> <div className="evnd__ministats">
<div className="elementor-element elementor-element-b2c956f e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="b2c956f" data-element_type="container" data-e-type="container"> {MINI_STATS.map((s) => (
<div className="elementor-element elementor-element-1a450c2 elementor-absolute elementor-widget elementor-widget-image" data-id="1a450c2" data-element_type="widget" data-e-type="widget" data-settings="{&quot;_position&quot;:&quot;absolute&quot;}" data-widget_type="image.default"> <div className="evnd__mini" key={s.label}>
<div className="elementor-widget-container"> <CountUp value={s.value} decimals={s.decimals} suffix={s.suffix} />
<img loading="lazy" decoding="async" width="965" height="474" src="/images/bg-map.png" className="attachment-full size-full wp-image-1148" alt="Map Grid" /> <span>{s.label}</span>
</div>
))}
</div> </div>
</div> </div>
{/* Icon Boxes */} {/* Right column */}
<div className="elementor-element elementor-element-6b51278 elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-mobile-position-block-start elementor-widget elementor-widget-icon-box" data-id="6b51278" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default"> <div className="evnd__features">
<div className="elementor-widget-container"> {FEATURES.map((f) => (
<div className="elementor-icon-box-wrapper"> <div className="evnd-feature" key={f.title}>
<div className="elementor-icon-box-icon"> <span className="evnd-feature__icon" aria-hidden="true">{f.icon}</span>
<span className="elementor-icon"> <div className="evnd-feature__body">
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i> <div className="evnd-feature__title">{f.title}</div>
</span> <p className="evnd-feature__desc">{f.desc}</p>
</div>
<div className="elementor-icon-box-content">
<div className="elementor-icon-box-title">
<span>Battery-Aware Routing</span>
</div>
<p className="elementor-icon-box-description">
Battery level, health, and degradation are first-class inputs to route optimization.
</p>
</div> </div>
<span className="evnd-feature__arrow" aria-hidden="true"></span>
</div> </div>
))}
</div> </div>
</div> </div>
<div className="elementor-element elementor-element-e34beb2 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="e34beb2" data-element_type="widget" data-e-type="widget" data-widget_type="divider.default"> {/* BOTTOM BAR */}
<div className="elementor-widget-container"> <div className="evnd__bar">
<div className="elementor-divider"> {BOTTOM_STATS.map((s) => (
<span className="elementor-divider-separator"></span> <div className="evnd__bar-item" key={s.label}>
</div> <span className="dot" />
</div> <CountUp value={s.value} decimals={s.decimals} suffix={s.suffix} />
</div> <span>{s.label}</span>
</div>
<div className="elementor-element elementor-element-27ba815 elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-mobile-position-block-start elementor-widget elementor-widget-icon-box" data-id="27ba815" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default"> ))}
<div className="elementor-widget-container">
<div className="elementor-icon-box-wrapper">
<div className="elementor-icon-box-icon">
<span className="elementor-icon">
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i>
</span>
</div>
<div className="elementor-icon-box-content">
<div className="elementor-icon-box-title">
<span>Charging Integration</span>
</div>
<p className="elementor-icon-box-description">
Seamlessly integrate charging stops without compromising delivery windows.
</p>
</div>
</div>
</div>
</div>
<div className="elementor-element elementor-element-6895eb5 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="6895eb5" data-element_type="widget" data-e-type="widget" data-widget_type="divider.default">
<div className="elementor-widget-container">
<div className="elementor-divider">
<span className="elementor-divider-separator"></span>
</div>
</div>
</div>
<div className="elementor-element elementor-element-332c78f elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-mobile-position-block-start elementor-widget elementor-widget-icon-box" data-id="332c78f" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default">
<div className="elementor-widget-container">
<div className="elementor-icon-box-wrapper">
<div className="elementor-icon-box-icon">
<span className="elementor-icon">
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i>
</span>
</div>
<div className="elementor-icon-box-content">
<div className="elementor-icon-box-title">
<span>Energy-Optimized Paths</span>
</div>
<p className="elementor-icon-box-description">
Factor in elevation, speed limits, and weather for maximum efficiency.
</p>
</div>
</div>
</div>
</div>
<div className="elementor-element elementor-element-6895eb5 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="6895eb5" data-element_type="widget" data-e-type="widget" data-widget_type="divider.default">
<div className="elementor-widget-container">
<div className="elementor-divider">
<span className="elementor-divider-separator"></span>
</div>
</div>
</div>
<div className="elementor-element elementor-element-332c78f elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-mobile-position-block-start elementor-widget elementor-widget-icon-box" data-id="332c78f" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default">
<div className="elementor-widget-container">
<div className="elementor-icon-box-wrapper">
<div className="elementor-icon-box-icon">
<span className="elementor-icon">
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i>
</span>
</div>
<div className="elementor-icon-box-content">
<div className="elementor-icon-box-title">
<span>Predictable Operations</span>
</div>
<p className="elementor-icon-box-description">
EVs become predictable assets, not operational risks.
</p>
</div>
</div>
</div>
</div>
<div className="elementor-element elementor-element-e70d3b7 elementor-widget elementor-widget-logico_button" data-id="e70d3b7" data-element_type="widget" data-e-type="widget" data-widget_type="logico_button.default">
<div className="elementor-widget-container">
<div className="button-widget">
<div className="button-container">
<Link href="/solutions" className="logico-alter-button">Explore more</Link>
</div>
</div>
</div>
</div>
</div>
</SlideReveal>
</div>
</div>
</div> </div>
</div> </div>
</section>
</div> </div>
</> </>

View File

@@ -83,16 +83,16 @@ export default function IndexHero() {
backgroundSize: "cover" backgroundSize: "cover"
}} }}
> >
<div className="slide-content"> <div className="slide-content" style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", width: "100%", height: "100%" }}>
<div className="slide-content-inner"> <div className="slide-content-inner" style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", textAlign: "center", margin: "0 auto", width: "100%", maxWidth: "1000px" }}>
<h1 className="content-slider-item-heading logico-content-wrapper-1"> <h1 className="content-slider-item-heading logico-content-wrapper-1" style={{ textAlign: "center", width: "100%" }}>
<span className="heading-content block"> <span className="heading-content block">
ONE CONNECTED SYSTEM.<br /> ONE CONNECTED SYSTEM.<br />
<ShimmerText className="font-extrabold">ONE PROMISE KEPT.</ShimmerText> <ShimmerText className="font-extrabold">ONE PROMISE KEPT.</ShimmerText>
</span> </span>
</h1> </h1>
<div className="content-slider-item-text logico-content-wrapper-2"> <div className="content-slider-item-text logico-content-wrapper-2" style={{ display: "flex", justifyContent: "center", width: "100%", marginTop: "23px" }}>
<div className="text-content"> <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 delivery system powered by MileTruth AI.</p>
</div> </div>
</div> </div>
@@ -124,16 +124,16 @@ export default function IndexHero() {
backgroundSize: "cover" backgroundSize: "cover"
}} }}
> >
<div className="slide-content"> <div className="slide-content" style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", width: "100%", height: "100%" }}>
<div className="slide-content-inner"> <div className="slide-content-inner" style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", textAlign: "center", margin: "0 auto", width: "100%", maxWidth: "1000px" }}>
<h1 className="content-slider-item-heading logico-content-wrapper-1"> <h1 className="content-slider-item-heading logico-content-wrapper-1" style={{ textAlign: "center", width: "100%" }}>
<span className="heading-content block"> <span className="heading-content block">
<ShimmerText className="font-extrabold">AI-POWERED</ShimmerText><br /> <ShimmerText className="font-extrabold">AI-POWERED</ShimmerText><br />
CONNECTED LOGISTICS CONNECTED LOGISTICS
</span> </span>
</h1> </h1>
<div className="content-slider-item-text logico-content-wrapper-2"> <div className="content-slider-item-text logico-content-wrapper-2" style={{ display: "flex", justifyContent: "center", width: "100%", marginTop: "23px" }}>
<div className="text-content"> <div className="text-content" style={{ textAlign: "center", maxWidth: "680px", margin: "0 auto" }}>
<p>Behind every successful business is a strong supply chain. Logistics turns plans into reality.</p> <p>Behind every successful business is a strong supply chain. Logistics turns plans into reality.</p>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,226 @@
"use client";
import React, { useEffect, useRef } from "react";
/**
* Animated dotted world map (Canvas 2D) for the Solutions industry section.
* - Continents drawn as a grid of dots clipped to rough continent polygons.
* - Major logistics hub cities with continuous double red pulse rings.
* - Red glowing packets travelling along arced quadratic-bezier routes.
* - Low-opacity dashed connection lines between hubs.
* Continent / city coordinates are normalized (0..1): x west→east, y north→south.
*/
const CONTINENTS: number[][][] = [
// North America
[[0.04,0.20],[0.10,0.12],[0.18,0.10],[0.24,0.13],[0.29,0.12],[0.30,0.18],
[0.27,0.22],[0.26,0.28],[0.22,0.30],[0.20,0.38],[0.17,0.44],[0.15,0.40],
[0.16,0.32],[0.12,0.30],[0.09,0.26],[0.06,0.24]],
// South America
[[0.21,0.50],[0.27,0.48],[0.31,0.52],[0.31,0.60],[0.29,0.66],[0.27,0.74],
[0.24,0.82],[0.22,0.80],[0.22,0.70],[0.205,0.62],[0.20,0.55]],
// Europe
[[0.45,0.16],[0.50,0.13],[0.55,0.15],[0.57,0.19],[0.55,0.24],[0.50,0.27],
[0.47,0.25],[0.455,0.20]],
// Africa
[[0.46,0.34],[0.53,0.32],[0.58,0.36],[0.585,0.44],[0.56,0.52],[0.53,0.60],
[0.50,0.66],[0.47,0.62],[0.46,0.52],[0.45,0.44],[0.45,0.38]],
// Asia
[[0.56,0.14],[0.64,0.10],[0.74,0.10],[0.84,0.14],[0.90,0.20],[0.92,0.26],
[0.86,0.30],[0.80,0.30],[0.74,0.34],[0.70,0.34],[0.66,0.30],[0.60,0.30],
[0.575,0.24],[0.565,0.18]],
// Australia
[[0.81,0.66],[0.87,0.64],[0.92,0.68],[0.92,0.74],[0.86,0.77],[0.81,0.74],[0.80,0.70]],
];
const CITIES: [number, number][] = [
[0.115, 0.30], // 0 Los Angeles
[0.265, 0.255],// 1 New York
[0.285, 0.66], // 2 São Paulo
[0.475, 0.185],// 3 London
[0.605, 0.345],// 4 Dubai
[0.655, 0.40], // 5 Mumbai
[0.745, 0.50], // 6 Singapore
[0.815, 0.275],// 7 Shanghai
[0.865, 0.715],// 8 Sydney
];
const ROUTES: [number, number][] = [
[0, 1], [1, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [1, 2], [3, 7], [0, 7],
];
function pointInPoly(x: number, y: number, poly: number[][]) {
let inside = false;
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
const xi = poly[i][0], yi = poly[i][1];
const xj = poly[j][0], yj = poly[j][1];
const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
if (intersect) inside = !inside;
}
return inside;
}
export default function IndustryWorldMap() {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
const parent = canvas?.parentElement;
if (!canvas || !parent) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
let w = 0, h = 0;
let dots: { x: number; y: number }[] = [];
let raf = 0;
let startTs = 0;
const buildDots = () => {
dots = [];
const gap = Math.max(11, Math.min(17, w / 70));
for (let gx = gap / 2; gx < w; gx += gap) {
for (let gy = gap / 2; gy < h; gy += gap) {
const nx = gx / w, ny = gy / h;
for (const poly of CONTINENTS) {
if (pointInPoly(nx, ny, poly)) { dots.push({ x: gx, y: gy }); break; }
}
}
}
};
const resize = () => {
const rect = parent.getBoundingClientRect();
w = Math.max(1, rect.width);
h = Math.max(1, rect.height);
const dpr = Math.min(window.devicePixelRatio || 1, 2);
canvas.width = Math.round(w * dpr);
canvas.height = Math.round(h * dpr);
canvas.style.width = w + "px";
canvas.style.height = h + "px";
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
buildDots();
};
const cityPx = () => CITIES.map(([cx, cy]) => ({ x: cx * w, y: cy * h }));
const ctrl = (p0: { x: number; y: number }, p1: { x: number; y: number }) => {
const mx = (p0.x + p1.x) / 2, my = (p0.y + p1.y) / 2;
const lift = Math.hypot(p1.x - p0.x, p1.y - p0.y) * 0.28;
return { x: mx, y: my - lift };
};
const bezier = (p0: any, c: any, p1: any, t: number) => {
const u = 1 - t;
return {
x: u * u * p0.x + 2 * u * t * c.x + t * t * p1.x,
y: u * u * p0.y + 2 * u * t * c.y + t * t * p1.y,
};
};
const draw = (time: number) => {
ctx.clearRect(0, 0, w, h);
// Continent dots
ctx.fillStyle = "rgba(120,122,130,0.55)";
for (const d of dots) {
ctx.beginPath();
ctx.arc(d.x, d.y, 1.15, 0, Math.PI * 2);
ctx.fill();
}
const cs = cityPx();
// Dashed connection lines (low opacity)
ctx.save();
ctx.setLineDash([4, 7]);
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(239,68,68,0.13)";
for (const [a, b] of ROUTES) {
const c = ctrl(cs[a], cs[b]);
ctx.beginPath();
ctx.moveTo(cs[a].x, cs[a].y);
ctx.quadraticCurveTo(c.x, c.y, cs[b].x, cs[b].y);
ctx.stroke();
}
ctx.restore();
// Travelling red glowing packets
ctx.save();
for (let r = 0; r < ROUTES.length; r++) {
const [a, b] = ROUTES[r];
const c = ctrl(cs[a], cs[b]);
const t = ((time * 0.11 + r * 0.137) % 1 + 1) % 1;
const p = bezier(cs[a], c, cs[b], t);
// soft trail
const tt = Math.max(0, t - 0.04);
const pt = bezier(cs[a], c, cs[b], tt);
const grad = ctx.createLinearGradient(pt.x, pt.y, p.x, p.y);
grad.addColorStop(0, "rgba(239,68,68,0)");
grad.addColorStop(1, "rgba(239,68,68,0.5)");
ctx.strokeStyle = grad;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(pt.x, pt.y);
ctx.lineTo(p.x, p.y);
ctx.stroke();
ctx.shadowColor = "#ef4444";
ctx.shadowBlur = 12;
ctx.fillStyle = "#ef4444";
ctx.beginPath();
ctx.arc(p.x, p.y, 2.6, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
ctx.restore();
// City hub nodes + double pulse rings
for (const c of cs) {
for (let k = 0; k < 2; k++) {
const period = 2.6;
const phase = (((time + (k * period) / 2) % period) + period) % period / period;
const radius = 3 + phase * 24;
const alpha = (1 - phase) * 0.45;
ctx.beginPath();
ctx.strokeStyle = `rgba(239,68,68,${alpha})`;
ctx.lineWidth = 1.5;
ctx.arc(c.x, c.y, radius, 0, Math.PI * 2);
ctx.stroke();
}
ctx.fillStyle = "#ef4444";
ctx.shadowColor = "#ef4444";
ctx.shadowBlur = 8;
ctx.beginPath();
ctx.arc(c.x, c.y, 2.6, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
};
const loop = (ts: number) => {
if (!startTs) startTs = ts;
draw((ts - startTs) / 1000);
raf = requestAnimationFrame(loop);
};
resize();
if (reduced) {
draw(0);
} else {
raf = requestAnimationFrame(loop);
}
const ro = new ResizeObserver(() => {
resize();
if (reduced) draw(0);
});
ro.observe(parent);
return () => {
cancelAnimationFrame(raf);
ro.disconnect();
};
}, []);
return <canvas ref={canvasRef} className="ind__map" aria-hidden="true" />;
}

View File

@@ -1,198 +1,851 @@
import React from "react"; "use client";
import React, { useState, useEffect, useRef } from "react";
import Image from "next/image";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
const ROADMAP_DATA = [
{
year: 2026,
pct: 25,
trackLeft: "12.5%",
phase: "Pilot Phase",
phaseClass: "yellow",
title: "Hyderabad Pilot",
desc: "Launch operations in Hyderabad with dedicated EV hubs and MileTruth AI v1.0.",
icon: (
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M4.5 16.5c-1.5 1.5-2.5 3.5-2.5 5.5C4 22 6 21 7.5 19.5" />
<path d="M12 12l9-9-9 9z" />
<path d="M12 12c-2.3 2.3-3.4 5.3-3.5 8.5l12-12c-3.2-.1-6.2-1.2-8.5-3.5z" />
</svg>
),
stats: [
{ text: "50-80 orders/day", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> },
{ text: "1 city", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M3 21h18M19 21v-2a4 4 0 0 0-3-3.87M5 21v-2a4 4 0 0 1 3-3.87M9 21v-5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v5"></path></svg> },
{ text: "10+ women partners", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle></svg> }
]
},
{
year: 2027,
pct: 50,
trackLeft: "37.5%",
phase: "Multi-City",
phaseClass: "green",
title: "Multi-City Scale",
desc: "Expand to Bengaluru and Chennai, securing key B2B enterprise traction.",
icon: (
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12" y2="16"></line>
<line x1="8" y1="12" x2="16" y2="12"></line>
</svg>
),
stats: [
{ text: "300-500 orders/day", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> },
{ text: "3 cities", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M3 21h18M19 21v-2a4 4 0 0 0-3-3.87M5 21v-2a4 4 0 0 1 3-3.87M9 21v-5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v5"></path></svg> },
{ text: "50+ EVs", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg> }
]
},
{
year: 2028,
pct: 75,
trackLeft: "62.5%",
phase: "Platform",
phaseClass: "blue",
title: "Platform Expansion",
desc: "Scale to 5+ cities. Launch developer API marketplace and Series A readiness.",
icon: (
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
</svg>
),
stats: [
{ text: "1,200+ orders/day", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> },
{ text: "5+ cities", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M3 21h18M19 21v-2a4 4 0 0 0-3-3.87M5 21v-2a4 4 0 0 1 3-3.87M9 21v-5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v5"></path></svg> },
{ text: "API marketplace", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg> }
]
},
{
year: 2030,
pct: 100,
trackLeft: "87.5%",
phase: "Vision State",
phaseClass: "white-pill",
title: "AI Pulse Layer",
desc: "Nationwide AI logistics grid reaching 15+ cities, empowering female micro-entrepreneurs.",
icon: (
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M2 4l3 12h14l3-12-6 7-4-7-4 7-6-7z" />
<path d="M3 20h18" strokeWidth="3" />
</svg>
),
stats: [
{ text: "5,000+ orders/day", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> },
{ text: "Rs 65 Cr+ revenue", icon: <span className="currency-symbol" style={{ marginRight: "4px", fontSize: "11px", fontWeight: 800 }}>Rs</span> },
{ text: "2,000+ women partners", icon: <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg> }
]
}
];
export default function IntelligenceGrid() { export default function IntelligenceGrid() {
const [activeYear, setActiveYear] = useState<number>(2030);
const containerRef = useRef<HTMLDivElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
// Map year to target percent
const getActivePercent = () => {
if (activeYear === 2026) return 25;
if (activeYear === 2027) return 50;
if (activeYear === 2028) return 75;
return 100;
};
// Map year to timeline horizontal track width
const getTrackWidth = () => {
if (activeYear === 2026) return "12.5%";
if (activeYear === 2027) return "37.5%";
if (activeYear === 2028) return "62.5%";
return "87.5%";
};
useEffect(() => {
const container = containerRef.current;
if (!container) return;
// 1. Dotted City Connections Canvas loops
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
let animationFrameId: number;
let width = (canvas.width = canvas.offsetWidth);
let height = (canvas.height = canvas.offsetHeight);
const handleResize = () => {
if (!canvas) return;
width = canvas.width = canvas.offsetWidth;
height = canvas.height = canvas.offsetHeight;
};
window.addEventListener("resize", handleResize);
const nodes = [
{ name: "Hyderabad", x: 0.18, y: 0.55 },
{ name: "Chennai", x: 0.42, y: 0.72 },
{ name: "Bengaluru", x: 0.64, y: 0.42 },
{ name: "Mumbai", x: 0.82, y: 0.62 }
];
const particles = [
{ from: 0, to: 1, t: 0, speed: 0.005 },
{ from: 1, to: 2, t: 0.3, speed: 0.004 },
{ from: 2, to: 3, t: 0.6, speed: 0.006 }
];
const draw = () => {
ctx.clearRect(0, 0, width, height);
// Draw faint connection lines
ctx.lineWidth = 1.5;
ctx.setLineDash([6, 6]);
ctx.strokeStyle = "rgba(220, 38, 38, 0.12)";
ctx.beginPath();
for (let i = 0; i < nodes.length - 1; i++) {
const startX = nodes[i].x * width;
const startY = nodes[i].y * height;
const endX = nodes[i + 1].x * width;
const endY = nodes[i + 1].y * height;
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
}
ctx.stroke();
ctx.setLineDash([]);
// Draw flowing sparks along connections
particles.forEach((p) => {
p.t += p.speed;
if (p.t >= 1) p.t = 0;
const startNode = nodes[p.from];
const endNode = nodes[p.to];
const startX = startNode.x * width;
const startY = startNode.y * height;
const endX = endNode.x * width;
const endY = endNode.y * height;
const curX = startX + (endX - startX) * p.t;
const curY = startY + (endY - startY) * p.t;
ctx.beginPath();
ctx.arc(curX, curY, 4, 0, Math.PI * 2);
ctx.fillStyle = "#c01227";
ctx.shadowColor = "#c01227";
ctx.shadowBlur = 10;
ctx.fill();
ctx.shadowBlur = 0;
});
// City labels & glow halos
nodes.forEach((n) => {
const xCoord = n.x * width;
const yCoord = n.y * height;
ctx.beginPath();
ctx.arc(xCoord, yCoord, 8, 0, Math.PI * 2);
ctx.fillStyle = "rgba(220, 38, 38, 0.08)";
ctx.fill();
ctx.beginPath();
ctx.arc(xCoord, yCoord, 3, 0, Math.PI * 2);
ctx.fillStyle = "rgba(255, 255, 255, 0.25)";
ctx.fill();
ctx.fillStyle = "rgba(255, 255, 255, 0.12)";
ctx.font = "bold 11px 'Manrope', sans-serif";
ctx.textAlign = "center";
ctx.fillText(n.name, xCoord, yCoord - 14);
});
animationFrameId = requestAnimationFrame(draw);
};
draw();
return () => {
window.removeEventListener("resize", handleResize);
cancelAnimationFrame(animationFrameId);
};
}, []);
// Circular progress calculations
const activePercent = getActivePercent();
const radius = 30;
const circumference = 2 * Math.PI * radius; // 188.49
const strokeOffset = circumference * (1 - activePercent / 100);
return ( return (
<div className="elementor-element elementor-element-bbc6760 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="bbc6760" data-element_type="container" data-e-type="container"> <div
ref={containerRef}
className="elementor-element elementor-element-bbc6760 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent"
data-id="bbc6760"
data-element_type="container"
data-e-type="container"
style={{ position: "relative", zIndex: 1 }}
>
<section id="hero" className="roadmap-hero-section"> <section id="hero" className="roadmap-hero-section">
{/* Concentric crimson vector curves background */} {/* Subtle Canvas Dotted Logistics Network Background */}
<div className="crimson-arc-bg"></div> <canvas ref={canvasRef} className="ce-canvas-bg" aria-hidden="true"></canvas>
<div className="crimson-arc-bg inner"></div>
<div className="container"> {/* Floating background glowing spotlights */}
{/* Screen Header Bar */} <div className="roadmap-glow-spot top-left"></div>
<div className="screen-header-bar"></div> <div className="roadmap-glow-spot bottom-right"></div>
{/* Content Titles */}
<div className="vision-tag-top">VISION / 2030</div>
<style dangerouslySetInnerHTML={{ __html: ` <style dangerouslySetInnerHTML={{ __html: `
/* Buttery-Smooth Hardware-Accelerated 3D AI Logistics Timeline Styles */
.roadmap-hero-section {
position: relative;
background: #09090b !important;
width: 100%;
padding: 100px 40px;
box-sizing: border-box;
font-family: 'Manrope', sans-serif;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: stretch;
}
/* Connection Grid Canvas Overlay */
.ce-canvas-bg {
position: absolute;
inset: 0;
z-index: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0.08;
}
/* Spotlights */
.roadmap-glow-spot {
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
pointer-events: none;
filter: blur(140px);
z-index: 0;
opacity: 0.05;
}
.roadmap-glow-spot.top-left {
left: -10%;
top: -10%;
background: radial-gradient(circle, #C8102E 0%, transparent 70%);
}
.roadmap-glow-spot.bottom-right {
right: -10%;
bottom: -10%;
background: radial-gradient(circle, #ff0033 0%, transparent 70%);
}
.roadmap-hero-section .container {
max-width: 1320px;
width: 100%;
margin: 0 auto;
position: relative;
z-index: 1;
box-sizing: border-box;
}
/* Header Styles */
.vision-tag-top {
font-size: 13px;
font-weight: 800;
letter-spacing: 3px;
color: #C8102E;
text-transform: uppercase;
margin-bottom: 16px;
text-align: center;
}
.roadmap-hero-section .intelligence-grid-title { .roadmap-hero-section .intelligence-grid-title {
color: #ffffff !important; color: #ffffff !important;
font-size: clamp(34px, 3.8vw, 54px) !important;
font-weight: 900 !important;
line-height: 1.1 !important;
text-align: center;
letter-spacing: -1.8px !important;
margin: 0 0 20px 0 !important;
text-transform: none !important;
} }
.roadmap-hero-section .intelligence-grid-title-highlight { .roadmap-hero-section .intelligence-grid-title-highlight {
color: #c01227 !important; color: #C8102E !important;
}
.vision-main-subtitle {
font-size: clamp(16px, 1.4vw, 20px);
font-weight: 500;
line-height: 1.5;
color: #a1a1aa !important;
text-align: center;
max-width: 720px;
margin: 0 auto 60px auto !important;
}
/* Glowing 3D Timeline Track - Overflow Visible Guarantees No Halo Cutoffs */
.roadmap-track-container {
display: flex;
align-items: center;
justify-content: space-between;
gap: 30px;
width: 100%;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(255, 255, 255, 0.04);
border-radius: 20px;
padding: 24px 34px;
box-sizing: border-box;
backdrop-filter: blur(8px);
margin-bottom: 60px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
overflow: visible !important; /* Extremely important to prevent cropping timeline child elements */
}
.roadmap-track-label {
font-size: 13.5px;
font-weight: 800;
letter-spacing: 2px;
color: #71717a;
white-space: nowrap;
}
.timeline-horizontal-wrapper {
flex: 1 1 auto;
height: 6px;
background: rgba(255, 255, 255, 0.05);
border-radius: 3px;
position: relative;
display: flex;
align-items: center;
overflow: visible !important; /* Critical to let pulsing halo overlay expand outside the 6px wrapper */
}
.timeline-horizontal-fill {
position: absolute;
left: 0;
top: 0;
height: 100%;
background: #C8102E;
box-shadow: 0 0 12px #C8102E;
border-radius: 3px;
transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1);
will-change: width;
}
.node-dots-row {
position: absolute;
inset: 0;
pointer-events: none;
overflow: visible !important; /* Dynamic expansion */
}
.node-dot-item {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 14px;
height: 14px;
border-radius: 50%;
background: #18181b;
border: 2px solid rgba(255, 255, 255, 0.15);
transition: border-color 0.4s cubic-bezier(0.16, 1, 0.3, 1),
background-color 0.4s cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 0.4s cubic-bezier(0.16, 1, 0.3, 1);
will-change: border-color, background-color, box-shadow;
overflow: visible !important;
}
.node-dot-item.active {
background: #C8102E;
border-color: #ffffff;
box-shadow: 0 0 10px #C8102E;
}
/* Pulsing crown node halo - Smoothly decays opacity to 0 to prevent visual pops/blinks */
.node-pulse-crown {
position: absolute;
inset: -4px;
border-radius: 50%;
border: 1.5px solid #C8102E;
animation: node-breather 2s infinite ease-out;
pointer-events: none;
box-sizing: border-box;
overflow: visible !important;
}
@keyframes node-breather {
0% { transform: scale(0.95); opacity: 0.9; }
80% { opacity: 0.25; }
100% { transform: scale(1.6); opacity: 0; }
}
/* Progress Ring */
.roadmap-complete-pct-container {
display: flex;
align-items: center;
gap: 12px;
white-space: nowrap;
}
.roadmap-complete-pct {
font-size: 14px;
font-weight: 800;
letter-spacing: 1px;
color: #C8102E;
text-transform: uppercase;
}
.progress-ring-circle {
transition: stroke-dashoffset 0.6s cubic-bezier(0.16, 1, 0.3, 1);
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke: #C8102E;
filter: drop-shadow(0 0 4px #C8102E);
}
/* 4-Column Grid container */
.roadmap-grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
width: 100%;
box-sizing: border-box;
}
/* GPU Hardware-Accelerated Breathtakingly Smooth 3D Floating Cards */
.roadmap-col-card {
position: relative;
background: rgba(255, 255, 255, 0.035);
border: 1px solid rgba(255, 255, 255, 0.06);
backdrop-filter: blur(16px);
border-radius: 20px;
padding: 30px 24px;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-start;
transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1),
border-color 0.6s cubic-bezier(0.16, 1, 0.3, 1),
background-color 0.6s cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 0.6s cubic-bezier(0.16, 1, 0.3, 1);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
cursor: pointer;
will-change: transform, box-shadow;
}
/* Ultra-Smooth CSS scale and translation lifts on hover */
.roadmap-col-card:hover {
transform: translateY(-8px) scale(1.03);
border-color: rgba(255, 255, 255, 0.15);
background-color: rgba(255, 255, 255, 0.055);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.45);
}
/* Active card highlight state */
.roadmap-col-card.active {
border-color: rgba(200, 16, 46, 0.65);
background: rgba(200, 16, 46, 0.04);
box-shadow: 0 20px 40px rgba(200, 16, 46, 0.1);
}
.card-top-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.year-num {
font-size: 26px;
font-weight: 900;
color: #ffffff;
letter-spacing: -0.5px;
}
.card-icon-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.05);
color: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.phase-badge-pill {
align-self: flex-start;
font-size: 11px;
font-weight: 800;
text-transform: uppercase;
padding: 5px 10px;
border-radius: 6px;
margin-bottom: 18px;
letter-spacing: 0.5px;
}
.phase-badge-pill.yellow {
background: rgba(234, 179, 8, 0.12);
color: #eab308;
border: 1px solid rgba(234, 179, 8, 0.2);
}
.phase-badge-pill.green {
background: rgba(34, 197, 94, 0.12);
color: #22c55e;
border: 1px solid rgba(34, 197, 94, 0.2);
}
.phase-badge-pill.blue {
background: rgba(59, 130, 246, 0.12);
color: #3b82f6;
border: 1px solid rgba(59, 130, 246, 0.2);
}
.phase-badge-pill.white-pill {
background: rgba(255, 255, 255, 0.12);
color: #ffffff;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.card-heading {
font-size: 18px;
font-weight: 800;
margin: 0 0 10px 0 !important;
letter-spacing: -0.3px;
}
.card-text {
font-size: 13.5px;
line-height: 1.5;
color: #a1a1aa !important;
margin: 0 0 20px 0 !important;
}
.card-pills-stack {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: auto;
}
.card-stat-pill-mini {
display: flex;
align-items: center;
font-size: 12.5px;
font-weight: 700;
color: #e4e4e7;
padding: 8px 12px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.4s ease;
will-change: transform;
}
.roadmap-col-card:hover .card-stat-pill-mini {
background: rgba(255, 255, 255, 0.06);
transform: translateY(-2px);
}
/* Special destination: Glowing 2030 AI Pulse Layer card */
.glowing-vision-card {
background: linear-gradient(135deg, rgba(200, 16, 46, 0.95) 0%, rgba(120, 10, 30, 0.98) 100%) !important;
border: 1px solid rgba(255, 255, 255, 0.15) !important;
animation: red-breath 4s infinite ease-in-out;
}
/* Hover scale override for 2030 vision card */
.glowing-vision-card:hover {
transform: translateY(-8px) scale(1.03) !important;
box-shadow: 0 20px 50px rgba(200, 16, 46, 0.7) !important;
}
/* Laser sweeping neon borders on 2030 vision card */
.glowing-vision-card::after {
content: "";
position: absolute;
inset: -1.5px;
border-radius: 20px;
background: linear-gradient(90deg, #C8102E, #ff3366, #ff0033, #C8102E);
background-size: 300% 100%;
animation: border-sweep 5s linear infinite;
z-index: -1;
opacity: 0.65;
}
@keyframes border-sweep {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes red-breath {
0%, 100% { box-shadow: 0 10px 40px rgba(200, 16, 46, 0.25), inset 0 0 15px rgba(255,255,255,0.05); }
50% { box-shadow: 0 10px 60px rgba(200, 16, 46, 0.6), inset 0 0 25px rgba(255,255,255,0.1); }
}
.glowing-vision-card .card-stat-pill-mini {
background: rgba(255, 255, 255, 0.08) !important;
border: 1px solid rgba(255, 255, 255, 0.1) !important;
}
.glowing-vision-card:hover .card-stat-pill-mini {
background: rgba(255, 255, 255, 0.14) !important;
}
.glowing-vision-card .card-text {
color: rgba(255, 255, 255, 0.8) !important;
}
/* Floating sparks/particles inside the 2030 vision card */
.ce-sparkle {
position: absolute;
width: 4px;
height: 4px;
background: rgba(255, 255, 255, 0.85);
border-radius: 50%;
pointer-events: none;
filter: blur(0.5px);
}
.sparkle-1 { left: 15%; bottom: 8%; animation: float-spark 3s infinite ease-in; }
.sparkle-2 { left: 52%; bottom: 18%; animation: float-spark 4s infinite ease-in; animation-delay: 1.2s; }
.sparkle-3 { left: 82%; bottom: 12%; animation: float-spark 3.5s infinite ease-in; animation-delay: 2s; }
@keyframes float-spark {
0% { transform: translateY(0); opacity: 0; }
50% { opacity: 0.9; }
100% { transform: translateY(-70px); opacity: 0; }
}
/* Responsive Constraints */
@media (max-width: 1024px) {
.roadmap-hero-section {
padding: 80px 24px;
}
.roadmap-grid-container {
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.roadmap-track-container {
padding: 20px 24px;
}
}
@media (max-width: 768px) {
.roadmap-hero-section {
padding: 60px 16px;
}
.roadmap-grid-container {
grid-template-columns: 1fr;
gap: 16px;
}
.roadmap-track-container {
flex-direction: column;
align-items: flex-start;
gap: 20px;
}
.timeline-horizontal-wrapper {
width: 100%;
}
} }
`}} /> `}} />
<div className="container">
{/* Header tag and Titles */}
<div className="vision-tag-top">VISION / 2030</div>
<div className="elementor-element elementor-element-54d05ac elementor-widget elementor-widget-logico_heading" data-id="54d05ac" data-element_type="widget" data-widget_type="logico_heading.default"> <div className="elementor-element elementor-element-54d05ac elementor-widget elementor-widget-logico_heading" data-id="54d05ac" data-element_type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container"> <div className="elementor-widget-container">
<h3 className="logico-title intelligence-grid-title">The <span className="intelligence-grid-title-highlight">Intelligence Grid</span> Behind Every Urban Mile</h3> <h3 className="logico-title intelligence-grid-title">
The <span className="intelligence-grid-title-highlight">Intelligence Grid</span> Behind Every Urban Mile
</h3>
<p className="vision-main-subtitle"> <p className="vision-main-subtitle">
From Hyderabad EV pilot to nationwide AI logistics intelligence by 2030 From Hyderabad EV pilot to nationwide AI logistics intelligence by 2030
</p> </p>
</div> </div>
</div> </div>
{/* Horizontal Timeline Track Widget */} {/* Interactive glowing timeline progress track */}
<div className="roadmap-track-container"> <div className="roadmap-track-container">
<span className="roadmap-track-label">ROADMAP TO 2030</span> <span className="roadmap-track-label">ROADMAP TO 2030</span>
<div className="timeline-horizontal-wrapper"> <div className="timeline-horizontal-wrapper">
{/* Timeline Track fillers */}
<div className="timeline-horizontal-line"></div> <div className="timeline-horizontal-line"></div>
<div className="timeline-horizontal-fill"></div> <div
className="timeline-horizontal-fill"
style={{ width: getTrackWidth() }}
></div>
{/* Nodes aligned above card columns */} {/* Glowing active year nodes */}
<div className="node-dots-row"> <div className="node-dots-row">
<div className="node-dot-item dot-active" style={{ left: "12.5%" }}> {ROADMAP_DATA.map((node) => (
<div className="node-pulse-inner"></div> <div
</div> key={node.year}
<div className="node-dot-item dot-active" style={{ left: "37.5%" }}> className={`node-dot-item ${activeYear >= node.year ? "active" : ""}`}
<div className="node-pulse-inner"></div> style={{ left: node.trackLeft }}
</div> >
<div className="node-dot-item dot-active" style={{ left: "62.5%" }}> {activeYear === node.year && (
<div className="node-pulse-inner"></div>
</div>
<div className="node-dot-item dot-vision-active" style={{ left: "87.5%" }}>
<div className="node-pulse-crown"></div> <div className="node-pulse-crown"></div>
)}
</div> </div>
))}
</div> </div>
</div> </div>
<span className="roadmap-complete-pct">75% COMPLETE &rarr;</span>
</div>
{/* 4-Column Card Grid Side-by-Side */} {/* Circular glowing progress SVG ring */}
<div className="roadmap-complete-pct-container">
<span className="roadmap-complete-pct">{activePercent}% COMPLETE &rarr;</span>
<svg width="40" height="40" viewBox="0 0 80 80">
<circle
cx="40"
cy="40"
r="30"
fill="none"
stroke="rgba(255,255,255,0.06)"
strokeWidth="6"
/>
<circle
className="progress-ring-circle"
cx="40"
cy="40"
r="30"
fill="none"
strokeWidth="6"
strokeDasharray={circumference}
strokeDashoffset={strokeOffset}
strokeLinecap="round"
/>
</svg>
</div>
</div>
{/* 3D Floating Grid cards */}
<div className="roadmap-grid-container"> <div className="roadmap-grid-container">
{ROADMAP_DATA.map((card) => {
const is2030 = card.year === 2030;
const isActive = activeYear === card.year;
return (
<div
key={card.year}
onMouseEnter={() => setActiveYear(card.year)}
className={`roadmap-col-card ${is2030 ? "glowing-vision-card" : ""} ${isActive ? "active" : ""}`}
data-card={card.year}
>
{/* Sparkles particles loop (for 2030 only) */}
{is2030 && (
<>
<span className="ce-sparkle sparkle-1"></span>
<span className="ce-sparkle sparkle-2"></span>
<span className="ce-sparkle sparkle-3"></span>
</>
)}
{/* Card 1: 2026 */}
<div className="roadmap-col-card" data-card="2026">
<div className="card-top-row"> <div className="card-top-row">
<span className="year-num">2026</span> <span className="year-num">{card.year}</span>
<div className="card-icon-badge"> <div className={`card-icon-badge ${is2030 ? "translucent-white" : ""}`}>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"> {card.icon}
<path d="M4.5 16.5c-1.5 1.5-2.5 3.5-2.5 5.5C4 22 6 21 7.5 19.5" />
<path d="M12 12l9-9-9 9z" />
<path d="M12 12c-2.3 2.3-3.4 5.3-3.5 8.5l12-12c-3.2-.1-6.2-1.2-8.5-3.5z" />
</svg>
</div>
</div>
<span className="phase-badge-pill yellow">Pilot Phase</span>
<h5 className="card-heading" style={{ color: "white" }}>Hyderabad Pilot</h5>
<p className="card-text">
Launch operations in Hyderabad with dedicated EV hubs and MileTruth AI v1.0.
</p>
<div className="card-pills-stack">
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
50-80 orders/day
</div>
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><path d="M3 21h18M19 21v-2a4 4 0 0 0-3-3.87M5 21v-2a4 4 0 0 1 3-3.87M9 21v-5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v5"></path></svg>
1 city
</div>
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle></svg>
10+ women partners
</div>
</div> </div>
</div> </div>
{/* Card 2: 2027 */} <span className={`phase-badge-pill ${card.phaseClass}`}>
<div className="roadmap-col-card" data-card="2027"> {card.phase}
<div className="card-top-row"> </span>
<span className="year-num">2027</span>
<div className="card-icon-badge">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12" y2="16"></line>
<line x1="8" y1="12" x2="16" y2="12"></line>
</svg>
</div>
</div>
<span className="phase-badge-pill green">Multi-City</span>
<h5 className="card-heading" style={{ color: "white" }}>Multi-City Scale</h5>
<p className="card-text">
Expand to Bengaluru and Chennai, securing key B2B enterprise traction.
</p>
<div className="card-pills-stack">
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
300-500 orders/day
</div>
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><path d="M3 21h18M19 21v-2a4 4 0 0 0-3-3.87M5 21v-2a4 4 0 0 1 3-3.87M9 21v-5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v5"></path></svg>
3 cities
</div>
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
50+ EVs
</div>
</div>
</div>
{/* Card 3: 2028 */} <h5 className="card-heading" style={{ color: "white" }}>
<div className="roadmap-col-card" data-card="2028"> {card.title}
<div className="card-top-row"> </h5>
<span className="year-num">2028</span>
<div className="card-icon-badge">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
</svg>
</div>
</div>
<span className="phase-badge-pill blue">Platform</span>
<h5 className="card-heading" style={{ color: "white" }}>Platform Expansion</h5>
<p className="card-text">
Scale to 5+ cities. Launch developer API marketplace and Series A readiness.
</p>
<div className="card-pills-stack">
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
1,200+ orders/day
</div>
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><path d="M3 21h18M19 21v-2a4 4 0 0 0-3-3.87M5 21v-2a4 4 0 0 1 3-3.87M9 21v-5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v5"></path></svg>
5+ cities
</div>
<div className="card-stat-pill-mini">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
API marketplace
</div>
</div>
</div>
{/* Card 4: 2030 */}
<div className="roadmap-col-card glowing-vision-card" data-card="2030">
<div className="card-top-row">
<span className="year-num">2030</span>
<div className="card-icon-badge translucent-white">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M2 4l3 12h14l3-12-6 7-4-7-4 7-6-7z" />
<path d="M3 20h18" strokeWidth="3"/>
</svg>
</div>
</div>
<span className="phase-badge-pill white-pill">Vision State</span>
<h5 className="card-heading" style={{ color: "white" }}>AI Pulse Layer</h5>
<p className="card-text"> <p className="card-text">
Nationwide AI logistics grid reaching 15+ cities, empowering female micro-entrepreneurs. {card.desc}
</p> </p>
<div className="card-pills-stack"> <div className="card-pills-stack">
<div className="card-stat-pill-mini translucent-crimson"> {card.stats.map((stat, sIndex) => (
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg> <div
5,000+ orders/day key={sIndex}
</div> className={`card-stat-pill-mini ${is2030 ? "translucent-crimson" : ""}`}
<div className="card-stat-pill-mini translucent-crimson"> >
<span className="currency-symbol" style={{ marginRight: "4px" }}>Rs</span> 65 Cr+ revenue {stat.icon}
</div> <span>{stat.text}</span>
<div className="card-stat-pill-mini translucent-crimson">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" style={{ marginRight: "4px" }}><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
2,000+ women partners
</div>
</div> </div>
))}
</div> </div>
</div> </div>
);
})}
</div>
</div> </div>
</section> </section>
</div> </div>

View File

@@ -31,6 +31,52 @@ export default function OurTeam() {
]; ];
return ( return (
<>
<style dangerouslySetInnerHTML={{ __html: `
/* Team photos: grayscale by default, full colour on hover (matches design) */
.team-listing-wrapper.team-grid-listing .team-item .post-media img {
filter: grayscale(100%);
transition: filter 0.45s ease;
}
.team-listing-wrapper.team-grid-listing .team-item:hover .post-media img {
filter: grayscale(0%);
}
/* Self-contained layout (does not rely on the cached vendor CSS). */
/* Grid: three columns that wrap, with tightened row/column gaps. */
.team-listing-wrapper.team-grid-listing {
display: flex;
flex-wrap: wrap;
margin: 0 -16px -44px;
}
.team-listing-wrapper.team-grid-listing .team-item-wrapper {
width: 33.3333%;
padding: 0 16px;
margin-bottom: 44px;
box-sizing: border-box;
}
@media (max-width: 1020px) {
.team-listing-wrapper.team-grid-listing .team-item-wrapper { width: 50%; }
}
@media (max-width: 660px) {
.team-listing-wrapper.team-grid-listing .team-item-wrapper { width: 100%; }
}
/* Card: photo on the LEFT, name/position on the RIGHT (side by side). */
.team-listing-wrapper.team-grid-listing .team-item {
display: flex;
flex-direction: row;
align-items: center;
gap: 16px;
}
.team-listing-wrapper.team-grid-listing .team-item-media {
flex-shrink: 0;
width: 160px;
}
.team-listing-wrapper.team-grid-listing .team-item-content {
flex: 1;
}
`}} />
<div className="elementor-element elementor-element-c2c601a e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-parent" data-id="c2c601a" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-c2c601a e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-parent" data-id="c2c601a" data-element_type="container" data-e-type="container">
<div className="e-con-inner"> <div className="e-con-inner">
<div className="elementor-element elementor-element-3306a27 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="3306a27" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-3306a27 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="3306a27" data-element_type="container" data-e-type="container">
@@ -42,7 +88,7 @@ export default function OurTeam() {
<div style={{ alignSelf: "flex-start", width: "100%" }} className="elementor-element elementor-element-c46350e elementor-widget__width-initial elementor-widget elementor-widget-logico_heading" data-id="c46350e" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default"> <div style={{ alignSelf: "flex-start", width: "100%" }} className="elementor-element elementor-element-c46350e elementor-widget__width-initial elementor-widget elementor-widget-logico_heading" data-id="c46350e" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container"> <div className="elementor-widget-container">
<h3 className="logico-title" style={{ textAlign: "left" }}>Meet our best crew</h3> <h3 className="logico-title" style={{ textAlign: "left" }}>Meet our the best crew</h3>
</div> </div>
</div> </div>
@@ -93,5 +139,6 @@ export default function OurTeam() {
</div> </div>
</div> </div>
</div> </div>
</>
); );
} }

View File

@@ -1,432 +1,498 @@
"use client"; "use client";
import React, { useState } from "react"; import React, { useState } from "react";
import Image from "next/image"; import IndustryWorldMap from "./IndustryWorldMap";
type Tab = "challenges" | "solutions";
interface Industry {
id: string;
tab: string;
eyebrow: string;
title: string;
image: string;
alt: string;
desc: string;
chips: [string, string];
challenges: string[];
solutions: string[];
}
const INDUSTRIES: Industry[] = [
{
id: "fmcg",
tab: "FMCG",
eyebrow: "Fast-Moving Consumer Goods",
title: "FMCG",
image: "/images/tab-pic-1-solution.jpeg",
alt: "FMCG logistics",
desc:
"FMCG logistics demands speed, precision, and continuous fulfillment across high-volume delivery networks — balancing tight timelines, inventory movement, and efficiency without compromising availability.",
chips: ["99.2% On-Time", "Live Route Sync"],
challenges: [
"Unpredictable demand spikes create delivery pressure during peak periods.",
"Fresh-product expiry constraints require faster, precisely timed deliveries.",
"Multi-stop route complexity increases travel time and coordination cost.",
"Inventory stockout risks rise when delays disrupt fast-moving distribution.",
],
solutions: [
"AI demand forecasting adapts delivery 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.",
],
},
{
id: "pharma",
tab: "Pharma",
eyebrow: "Pharmaceutical Logistics",
title: "Pharma",
image: "/images/tab-pic-2-solution.jpeg",
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.",
chips: ["Cold Chain Active", "Zero Delay SLA"],
challenges: [
"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.",
"Emergency shipments need instant dispatch and zero-delay execution.",
],
solutions: [
"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.",
"Priority dispatch queue fast-tracks urgent, life-critical shipments.",
],
},
{
id: "b2b",
tab: "Enterprise & B2B",
eyebrow: "Enterprise & B2B",
title: "Enterprise & B2B",
image: "/images/tab-pic-3-solution.jpeg",
alt: "Enterprise and B2B logistics",
desc:
"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.",
chips: ["SLA Guaranteed", "White-Glove Ready"],
challenges: [
"Appointment scheduling requires precise timing across many locations.",
"White-glove delivery 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.",
],
solutions: [
"Intelligent appointment engine streamlines and automates delivery slots.",
"White-glove workflow module enforces premium handling end to end.",
"Enterprise route planner coordinates efficient multi-location delivery.",
"SLA monitoring dashboard tracks commitments and flags risk in real time.",
],
},
];
export default function SolutionCard1() { export default function SolutionCard1() {
const [activeTabFmcg, setActiveTabFmcg] = useState<"challenges" | "solutions">("challenges"); const [active, setActive] = useState(0);
const [activeTabPharma, setActiveTabPharma] = useState<"challenges" | "solutions">("challenges"); const [tab, setTab] = useState<Tab>("challenges");
const [activeTabB2b, setActiveTabB2b] = useState<"challenges" | "solutions">("challenges");
const ind = INDUSTRIES[active];
const selectIndustry = (i: number) => {
setActive(i);
setTab("challenges"); // reset to Challenges on industry switch
};
return ( return (
<> <>
<style dangerouslySetInnerHTML={{ __html: ` <style dangerouslySetInnerHTML={{ __html: `
/* Alternate tabs style: full-width blue tabs, larger size and font */ /* ============================================================
.solution-freight-tabs-alt { Solutions — Industry section (FMCG / Pharma / Enterprise & B2B)
Brand red #dc2626 / #ef4444 · bg #0d0d0d · Syne + DM Sans
============================================================ */
/* The theme forces Manrope on every element via a high-specificity
universal :not() !important rule; re-assert Syne / DM Sans from the
ID selector (which outranks it) directly on each text node. */
#ind-solutions .ind__eyebrow,
#ind-solutions .ind__title,
#ind-solutions .ind__tab,
#ind-solutions .ind__toggle-btn {
font-family: var(--font-syne), 'Syne', sans-serif !important;
}
#ind-solutions .ind__desc,
#ind-solutions .ind__chip,
#ind-solutions .ind__list li {
font-family: var(--font-dm-sans), 'DM Sans', sans-serif !important;
}
/* kit-5 also forces heading color/size on the title (an <h3>). */
#ind-solutions .ind__title {
color: #fff !important;
font-size: clamp(34px, 5.5vw, 68px) !important;
font-weight: 800 !important;
line-height: 1.02 !important;
margin: 0 0 16px !important;
letter-spacing: -0.01em !important;
}
#ind-solutions .ind__list li { color: #c9c9c9 !important; }
.ind {
position: relative;
isolation: isolate;
overflow: hidden;
background: #0d0d0d;
border-radius: clamp(16px, 2vw, 26px);
max-width: 1400px;
margin: clamp(24px, 4vw, 56px) auto;
padding: clamp(34px, 5vw, 76px) clamp(18px, 4vw, 64px);
}
.ind__map {
position: absolute;
inset: 0;
width: 100%; width: 100%;
margin: 18px 0 28px; height: 100%;
font-family: 'Manrope', sans-serif; opacity: 0.55;
z-index: 0;
pointer-events: none;
}
.ind__inner {
position: relative;
z-index: 1;
max-width: 1240px;
margin: 0 auto;
} }
/* Centered, non-full-width tabs */ /* ---- Top tab bar ---- */
.solution-freight-tabs-alt .solution-freight-tabs__nav { .ind__tabs {
display: flex; display: flex;
gap: 12px; gap: clamp(10px, 3vw, 36px);
align-items: flex-end; border-bottom: 1px solid rgba(255,255,255,0.1);
width: auto; margin-bottom: clamp(28px, 4vw, 52px);
margin: 0 auto 6px; flex-wrap: wrap;
} }
.ind__tab {
.solution-freight-tabs-alt .solution-freight-tabs__button {
appearance: none; appearance: none;
border: 1px solid rgba(0, 0, 0, 0.06); background: none;
background: linear-gradient(180deg, #f9ccd1, #f9ccd1); border: none;
color: #111;
padding: 12px 36px;
display: inline-block;
min-width: 180px;
text-align: center;
border-radius: 6px 6px 0 0;
cursor: pointer; cursor: pointer;
font-weight: 800; padding: 10px 2px 16px;
text-transform: uppercase; font-weight: 700;
letter-spacing: 0.6px; font-size: clamp(14px, 1.4vw, 18px);
box-shadow: none; color: #888;
transition: background-color 0.12s ease, color 0.12s ease, transform 0.08s ease; position: relative;
letter-spacing: 0.01em;
transition: color 0.3s ease;
}
.ind__tab::after {
content: '';
position: absolute;
left: 0; right: 0; bottom: -1px;
height: 2px;
background: #dc2626;
transform: scaleX(0);
transform-origin: left;
transition: transform 0.35s cubic-bezier(.25,1,.5,1);
}
.ind__tab:hover { color: #ccc; }
.ind__tab.active { color: #fff; }
.ind__tab.active::after { transform: scaleX(1); }
/* ---- Grid ---- */
.ind__grid {
display: grid;
grid-template-columns: 0.9fr 1.1fr;
gap: clamp(28px, 4vw, 64px);
align-items: center;
} }
.solution-freight-tabs-alt .solution-freight-tabs__button h6 { /* ---- Left media ---- */
margin: 0; .ind__media {
font-size: 16px; position: relative;
color: inherit; display: flex;
font-weight: 800; align-items: center;
justify-content: center;
min-height: 300px;
} }
.ind__glow {
.solution-freight-tabs-alt .solution-freight-tabs__button:hover { position: absolute;
transform: translateY(-2px); left: 50%; bottom: 4%;
background: linear-gradient(180deg, #f9ccd1, #f9ccd1); width: 74%; height: 70px;
transform: translateX(-50%);
background: radial-gradient(50% 50% at 50% 50%, rgba(220,38,38,0.5), transparent 72%);
filter: blur(32px);
z-index: 0;
animation: indGlow 4s ease-in-out infinite;
} }
.ind__img-wrap {
.solution-freight-tabs-alt .solution-freight-tabs__button.active { position: relative;
background: #C01227; z-index: 1;
color: #ffffff; width: 100%;
border-color: #C01227; max-width: 460px;
box-shadow: none; animation: indFloat 6s ease-in-out infinite;
transform: none; will-change: transform;
}
.ind__img-wrap::before,
.ind__img-wrap::after {
content: '';
position: absolute;
width: 44px; height: 44px;
border: 2px solid #dc2626;
z-index: 3; z-index: 3;
} }
.ind__img-wrap::before {
.solution-freight-tabs-alt .solution-freight-tabs__content { top: -10px; left: -10px;
margin-top: 2px; border-right: none; border-bottom: none;
padding: 18px 20px; border-radius: 10px 0 0 0;
border: 1px solid rgba(0, 0, 0, 0.06);
border-top: none;
border-radius: 0 6px 6px 6px;
background: #ffffff00;
max-width: 620px;
margin-right: auto;
} }
.ind__img-wrap::after {
.solution-freight-tabs-alt .point-box li::before { bottom: -10px; right: -10px;
content: ""; border-left: none; border-top: none;
width: 8px; border-radius: 0 0 10px 0;
height: 8px;
border-radius: 50%;
background: #C01227;
left: 6px;
top: 8px;
} }
.ind__img {
@media (max-width: 767px) { display: block;
.solution-freight-tabs-alt .solution-freight-tabs__button { width: 100%;
padding: 10px 18px; height: auto;
min-width: 120px; border-radius: 12px;
object-fit: cover;
box-shadow: 0 30px 60px -25px rgba(0,0,0,0.7);
animation: indImgFade 0.55s ease both;
} }
.ind__chip {
.solution-freight-tabs-alt .solution-freight-tabs__content {
max-width: 100%;
margin: 0 12px;
}
}
@media (max-width: 767px) {
.solution-freight-tabs-alt .solution-freight-tabs__button {
padding: 12px 0;
font-size: 14px;
}
.solution-freight-tabs-alt .solution-freight-tabs__button h6 {
font-size: 14px;
}
}
@media (max-width: 1024px) {
.solution-freight-tabs__button {
font-size: 18px;
}
.point-box li {
font-size: 15px;
}
}
@media (max-width: 480px) {
.solution-freight-tabs__button {
font-size: 14px;
}
.solution-freight-tabs__panel p {
font-size: 14px;
}
.point-box li {
font-size: 14px;
}
}
/* Point Box List Styling */
.point-box {
list-style: none;
padding: 0;
margin: 0;
}
.point-box li {
position: relative;
margin: 0 0 20px 0;
padding-left: 32px;
color: #666;
font-size: 16px;
font-weight: 500;
line-height: 1.7;
}
.point-box li:last-child {
margin-bottom: 0;
}
.point-box li::before {
content: "✓";
position: absolute; position: absolute;
left: 0; z-index: 4;
top: -2px; display: inline-flex;
color: #C01227; align-items: center;
font-size: 18px; gap: 8px;
padding: 9px 16px;
border-radius: 999px;
background: rgba(16,16,16,0.82);
border: 1px solid rgba(239,68,68,0.4);
backdrop-filter: blur(8px);
color: #fff;
font-weight: 500;
font-size: 13px;
white-space: nowrap;
box-shadow: 0 12px 28px -12px rgba(0,0,0,0.7);
animation: indFloat 6s ease-in-out infinite;
}
.ind__chip .dot {
width: 7px; height: 7px;
border-radius: 50%;
background: #ef4444;
box-shadow: 0 0 8px #ef4444;
animation: indDot 1.6s ease-in-out infinite;
}
.ind__chip--1 { top: 7%; left: -5%; animation-delay: 0.4s; }
.ind__chip--2 { bottom: 12%; right: -5%; animation-delay: 1.3s; }
/* ---- Right text ---- */
.ind__text { min-width: 0; }
.ind__eyebrow {
display: inline-flex;
align-items: center;
gap: 12px;
color: #ef4444;
font-weight: 700; font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.16em;
font-size: clamp(11px, 1vw, 13px);
margin-bottom: 14px;
}
.ind__eyebrow::before {
content: '';
width: 30px; height: 2px;
background: #ef4444;
}
.ind__desc {
color: #b4b4b4;
font-size: clamp(15px, 1.2vw, 18px);
line-height: 1.7;
font-weight: 400;
margin: 0 0 24px;
max-width: 580px;
} }
.point-box li.spacer { /* ---- Challenges / Solutions toggle ---- */
height: 12px; .ind__toggle {
margin: 10px 0 0; display: inline-flex;
padding-left: 32px; gap: 4px;
visibility: hidden; padding: 5px;
border-radius: 999px;
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.09);
margin-bottom: 24px;
}
.ind__toggle-btn {
appearance: none;
border: none;
cursor: pointer;
padding: 9px 28px;
border-radius: 999px;
font-weight: 700;
font-size: 14px;
color: #9a9a9a;
background: transparent;
transition: color 0.3s ease, background-color 0.3s ease, box-shadow 0.3s ease;
}
.ind__toggle-btn:hover { color: #ddd; }
.ind__toggle-btn.active {
background: #dc2626;
color: #fff;
box-shadow: 0 8px 20px -8px rgba(220,38,38,0.6);
} }
.point-box li.spacer::before { /* ---- Sliding panels ---- */
content: none; .ind__slider { overflow: hidden; }
.ind__track {
display: flex;
width: 200%;
transition: transform 0.4s cubic-bezier(.4,0,.2,1);
}
.ind__panel { width: 50%; flex: 0 0 50%; }
.ind__list { list-style: none; margin: 0; padding: 0; }
.ind__list li {
position: relative;
padding-left: 30px;
margin-bottom: 16px;
font-size: clamp(14px, 1.1vw, 16px);
line-height: 1.6;
opacity: 0;
transform: translateX(-16px);
}
.ind__list li:last-child { margin-bottom: 0; }
.ind__list li::before {
content: '';
position: absolute;
left: 4px; top: 8px;
width: 8px; height: 8px;
border-radius: 50%;
background: #dc2626;
box-shadow: 0 0 8px rgba(220,38,38,0.7);
}
.ind__panel.is-active .ind__list li {
animation: indBullet 0.5s cubic-bezier(.25,1,.5,1) forwards;
}
.ind__panel.is-active .ind__list li:nth-child(1) { animation-delay: 0.05s; }
.ind__panel.is-active .ind__list li:nth-child(2) { animation-delay: 0.13s; }
.ind__panel.is-active .ind__list li:nth-child(3) { animation-delay: 0.21s; }
.ind__panel.is-active .ind__list li:nth-child(4) { animation-delay: 0.29s; }
.ind__panel.is-active .ind__list li:nth-child(5) { animation-delay: 0.37s; }
@keyframes indFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }
@keyframes indGlow { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }
@keyframes indDot { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
@keyframes indBullet { to { opacity: 1; transform: translateX(0); } }
@keyframes indImgFade { from { opacity: 0; transform: scale(0.97); } to { opacity: 1; transform: scale(1); } }
/* ---- Responsive ---- */
@media (max-width: 900px) {
.ind__grid { grid-template-columns: 1fr; gap: clamp(40px, 8vw, 56px); }
.ind__media { order: -1; }
.ind__img-wrap { max-width: 380px; }
}
@media (max-width: 600px) {
.ind__chip { font-size: 12px; padding: 7px 12px; }
.ind__chip--1 { left: 0; }
.ind__chip--2 { right: 0; }
.ind__toggle-btn { padding: 9px 20px; }
}
@media (prefers-reduced-motion: reduce) {
.ind__img-wrap, .ind__glow, .ind__chip, .ind__chip .dot { animation: none !important; }
.ind__track { transition: none !important; }
.ind__panel.is-active .ind__list li { animation: none !important; opacity: 1; transform: none; }
} }
`}} /> `}} />
<div className="elementor-61"> <section id="ind-solutions" className="ind" aria-label="Industry solutions">
<IndustryWorldMap />
{/* FMCG Section */} <div className="ind__inner">
<div style={{ marginTop: "0px" }} className="elementor-element elementor-element-89a0ca1 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="89a0ca1" data-element_type="container" data-e-type="container"> {/* Top tab bar */}
<div className="elementor-element elementor-element-9ffed33 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="9ffed33" data-element_type="container" data-e-type="container" data-settings='{"background_background":"classic"}'> <div className="ind__tabs" role="tablist" aria-label="Industries">
<div className="elementor-element elementor-element-96343ba e-con-full e-flex cut-corner-no sticky-container-off e-con e-child elementor-image-section" data-id="96343ba" data-element_type="container" data-e-type="container"> {INDUSTRIES.map((it, i) => (
<div className="elementor-element elementor-element-99768ba elementor-widget elementor-widget-image" data-id="99768ba" data-element_type="widget" data-e-type="widget" data-widget_type="image.default" style={{ width: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
<div className="elementor-widget-container" style={{ margin: 0, width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
<Image
src="/images/tab-pic-1-solution.jpeg"
alt="FMCG Solutions"
width={578}
height={790}
priority
style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain" }}
/>
</div>
</div>
</div>
<div className="elementor-element elementor-element-71c3e1d e-con-full e-flex cut-corner-no sticky-container-off e-con e-child section-2-content" data-id="71c3e1d" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-fdb2e58 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="fdb2e58" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-7500280 elementor-widget elementor-widget-logico_heading" data-id="7500280" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container" style={{ margin: 0 }}>
<h3 className="logico-title">FMCG</h3>
</div>
</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" style={{ margin: 0, fontSize: "20px", lineHeight: 1.7 }}>
<p>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.</p>
</div>
</div>
{/* FMCG Tabs */}
<div className="solution-freight-tabs-alt">
<div className="solution-freight-tabs__nav" role="tablist" aria-label="FMCG Details">
<button <button
className={`solution-freight-tabs__button ${activeTabFmcg === "challenges" ? "active" : ""}`} key={it.id}
type="button" type="button"
role="tab" role="tab"
aria-selected={activeTabFmcg === "challenges"} aria-selected={i === active}
onClick={() => setActiveTabFmcg("challenges")} className={`ind__tab ${i === active ? "active" : ""}`}
onClick={() => selectIndustry(i)}
> >
<h6>Challenges</h6> {it.tab}
</button> </button>
))}
</div>
<div className="ind__grid">
{/* Left media */}
<div className="ind__media">
<div className="ind__glow" />
<div className="ind__img-wrap">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img key={active} className="ind__img" src={ind.image} alt={ind.alt} decoding="async" />
</div>
<div className="ind__chip ind__chip--1">
<span className="dot" />
{ind.chips[0]}
</div>
<div className="ind__chip ind__chip--2">
<span className="dot" />
{ind.chips[1]}
</div>
</div>
{/* Right text */}
<div className="ind__text">
<span className="ind__eyebrow">{ind.eyebrow}</span>
<h3 className="ind__title">{ind.title}</h3>
<p className="ind__desc">{ind.desc}</p>
<div className="ind__toggle" role="tablist" aria-label="Challenges or Solutions">
<button <button
className={`solution-freight-tabs__button ${activeTabFmcg === "solutions" ? "active" : ""}`}
type="button" type="button"
role="tab" role="tab"
aria-selected={activeTabFmcg === "solutions"} aria-selected={tab === "challenges"}
onClick={() => setActiveTabFmcg("solutions")} className={`ind__toggle-btn ${tab === "challenges" ? "active" : ""}`}
onClick={() => setTab("challenges")}
> >
<h6>Solutions</h6> Challenges
</button>
</div>
<div className="solution-freight-tabs__content">
{activeTabFmcg === "challenges" ? (
<div className="solution-freight-tabs__panel active" role="tabpanel">
<ul className="point-box">
<li>Unpredictable demand spikes create delivery pressure and reduce operational efficiency during peak periods.</li>
<li>Fresh product expiry constraints require faster, precisely timed deliveries to maintain product quality.</li>
<li>Multi-stop route complexity increases travel time, operational costs, and delivery coordination challenges.</li>
<li>Inventory stockout risks increase when delivery delays disrupt fast-moving product distribution.</li>
<li className="spacer" aria-hidden="true"></li>
</ul>
</div>
) : (
<div className="solution-freight-tabs__panel active" role="tabpanel">
<ul className="point-box">
<li>AI-driven demand-responsive routing adapts delivery plans instantly based on real-time order demand.</li>
<li>Freshness-aware delivery prioritization ensures perishable products are delivered at the right time.</li>
<li>Dynamic batch optimization intelligently groups orders to maximize delivery efficiency and reduce costs.</li>
<li>Real-time inventory visibility helps prevent stockouts and improves fulfillment accuracy across delivery zones.</li>
<li className="spacer" aria-hidden="true"></li>
</ul>
</div>
)}
</div>
</div>
</div>
</div>
</div>
</div>
{/* Pharma Section */}
<div style={{ marginTop: "20px" }} className="elementor-element elementor-element-89a0ca1 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="89a0ca1" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-9ffed33 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="9ffed33" data-element_type="container" data-e-type="container" data-settings='{"background_background":"classic"}'>
<div className="elementor-element elementor-element-96343ba e-con-full e-flex cut-corner-no sticky-container-off e-con e-child elementor-image-section" data-id="96343ba" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-99768ba elementor-widget elementor-widget-image" data-id="99768ba" data-element_type="widget" data-e-type="widget" data-widget_type="image.default" style={{ width: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
<div className="elementor-widget-container" style={{ margin: 0, width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
<Image
src="/images/tab-pic-2-solution.jpeg"
alt="Pharma Solutions"
width={578}
height={790}
style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain" }}
/>
</div>
</div>
</div>
<div style={{ paddingRight: "60px", paddingLeft: "0px" }} className="elementor-element elementor-element-71c3e1d e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="71c3e1d" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-fdb2e58 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="fdb2e58" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-7500280 elementor-widget elementor-widget-logico_heading" data-id="7500280" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container" style={{ margin: 0 }}>
<h3 className="logico-title">Pharma</h3>
</div>
</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" style={{ margin: 0, fontSize: "20px", lineHeight: 1.7 }}>
<p>Pharma logistics requires precision, compliance, and real-time monitoring to ensure every shipment reaches safely and on time. From temperature-sensitive medicines to emergency deliveries, operational reliability is critical at every stage.</p>
</div>
</div>
{/* Pharma Tabs */}
<div className="solution-freight-tabs-alt">
<div className="solution-freight-tabs__nav" role="tablist" aria-label="Pharma Details">
<button
className={`solution-freight-tabs__button ${activeTabPharma === "challenges" ? "active" : ""}`}
type="button"
role="tab"
aria-selected={activeTabPharma === "challenges"}
onClick={() => setActiveTabPharma("challenges")}
>
<h6>Challenges</h6>
</button> </button>
<button <button
className={`solution-freight-tabs__button ${activeTabPharma === "solutions" ? "active" : ""}`}
type="button" type="button"
role="tab" role="tab"
aria-selected={activeTabPharma === "solutions"} aria-selected={tab === "solutions"}
onClick={() => setActiveTabPharma("solutions")} className={`ind__toggle-btn ${tab === "solutions" ? "active" : ""}`}
onClick={() => setTab("solutions")}
> >
<h6>Solutions</h6> Solutions
</button> </button>
</div> </div>
<div className="solution-freight-tabs__content">
{activeTabPharma === "challenges" ? (
<div className="solution-freight-tabs__panel active" role="tabpanel">
<ul className="point-box">
<li>Cold chain integrity requirements demand precise temperature-controlled delivery management throughout transit.</li>
<li>Regulatory compliance tracking ensures every delivery meets industry standards and operational guidelines.</li>
<li>Critical delivery time windows require highly accurate scheduling and real-time route coordination.</li>
<li>Emergency and high-priority medical shipments require instant dispatch coordination and zero-delay execution.</li>
<li className="spacer" aria-hidden="true"></li>
</ul>
</div>
) : (
<div className="solution-freight-tabs__panel active" role="tabpanel">
<ul className="point-box">
<li>Real-time temperature monitoring ensures sensitive shipments remain within safe delivery conditions at all times.</li>
<li>Chain-of-custody documentation provides complete shipment visibility and compliance tracking throughout transit.</li>
<li>Priority override for critical shipments enables faster response and immediate routing for urgent deliveries.</li>
<li>Automated compliance alerts help teams proactively identify temperature deviations and delivery risks in real time.</li>
<li className="spacer" aria-hidden="true"></li>
</ul>
</div>
)}
</div>
</div>
</div> <div className="ind__slider">
</div> <div
</div> className="ind__track"
</div> key={active}
style={{ transform: tab === "challenges" ? "translateX(0)" : "translateX(-50%)" }}
{/* Enterprise & B2B Section */}
<div style={{ marginTop: "20px" }} className="elementor-element elementor-element-89a0ca1 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="89a0ca1" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-9ffed33 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="9ffed33" data-element_type="container" data-e-type="container" data-settings='{"background_background":"classic"}'>
<div className="elementor-element elementor-element-96343ba e-con-full e-flex cut-corner-no sticky-container-off e-con e-child elementor-image-section" data-id="96343ba" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-99768ba elementor-widget elementor-widget-image" data-id="99768ba" data-element_type="widget" data-e-type="widget" data-widget_type="image.default" style={{ width: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
<div className="elementor-widget-container" style={{ margin: 0, width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
<Image
src="/images/tab-pic-3-solution.jpeg"
alt="Enterprise & B2B Solutions"
width={578}
height={790}
style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain" }}
/>
</div>
</div>
</div>
<div className="elementor-element elementor-element-71c3e1d e-con-full e-flex cut-corner-no sticky-container-off e-con e-child section-2-content" data-id="71c3e1d" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-fdb2e58 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="fdb2e58" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-7500280 elementor-widget elementor-widget-logico_heading" data-id="7500280" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container" style={{ margin: 0 }}>
<h3 className="logico-title">Enterprise & B2B</h3>
</div>
</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" style={{ margin: 0, fontSize: "20px", lineHeight: 1.7 }}>
<p>Enterprise and B2B logistics require precision, coordination, and reliability to manage high-value shipments at scale. Complex delivery expectations, appointment scheduling, and service-level commitments demand intelligent operational control.</p>
</div>
</div>
{/* Enterprise & B2B Tabs */}
<div className="solution-freight-tabs-alt">
<div className="solution-freight-tabs__nav" role="tablist" aria-label="B2B Details">
<button
className={`solution-freight-tabs__button ${activeTabB2b === "challenges" ? "active" : ""}`}
type="button"
role="tab"
aria-selected={activeTabB2b === "challenges"}
onClick={() => setActiveTabB2b("challenges")}
> >
<h6>Challenges</h6> <div className={`ind__panel ${tab === "challenges" ? "is-active" : ""}`}>
</button> <ul className="ind__list">
<button {ind.challenges.map((c, idx) => (
className={`solution-freight-tabs__button ${activeTabB2b === "solutions" ? "active" : ""}`} <li key={idx}>{c}</li>
type="button" ))}
role="tab"
aria-selected={activeTabB2b === "solutions"}
onClick={() => setActiveTabB2b("solutions")}
>
<h6>Solutions</h6>
</button>
</div>
<div className="solution-freight-tabs__content">
{activeTabB2b === "challenges" ? (
<div className="solution-freight-tabs__panel active" role="tabpanel">
<ul className="point-box">
<li>Appointment scheduling coordination requires precise timing and seamless delivery planning across multiple customer locations.</li>
<li>White-glove delivery standards demand high-quality handling, accuracy, and premium customer service execution.</li>
<li>Multi-location routing complexity increases operational challenges in managing efficient large-scale deliveries.</li>
<li>Strict SLA commitments increase pressure on teams to maintain timely and error-free deliveries across multiple locations.</li>
<li className="spacer" aria-hidden="true"></li>
</ul> </ul>
</div> </div>
) : ( <div className={`ind__panel ${tab === "solutions" ? "is-active" : ""}`}>
<div className="solution-freight-tabs__panel active" role="tabpanel"> <ul className="ind__list">
<ul className="point-box"> {ind.solutions.map((s, idx) => (
<li>Automated appointment optimization streamlines delivery scheduling for faster and more efficient operations.</li> <li key={idx}>{s}</li>
<li>Service level guarantee tracking ensures every delivery meets committed SLA and customer expectations.</li> ))}
<li>Enterprise integration APIs enable seamless connectivity across logistics, warehouse, and business systems.</li>
<li>Real-time SLA monitoring helps teams proactively manage delays and maintain enterprise delivery commitments.</li>
<li className="spacer" aria-hidden="true"></li>
</ul> </ul>
</div> </div>
)}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section>
</> </>
); );
} }

View File

@@ -1,9 +1,196 @@
import React from "react"; import React from "react";
import Image from "next/image"; import Image from "next/image";
import { ScrollReveal, StaggerChildren } from "@/animations/Reveal";
import IndustryWorldMap from "./IndustryWorldMap";
const WS_STATS = [
{ value: "500", plus: "+", label: "Women Partners" },
{ value: "35", plus: "+", label: "Cities" },
{ value: "10K", plus: "+", label: "Deliveries" },
];
const WS_CARDS = [
{
title: "Women Leadership",
desc: "Women driving decisions across operations, routing, and last-mile delivery every day.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="9" r="5" />
<path d="M9 13.5 7.5 21 12 18l4.5 3-1.5-7.5" />
</svg>
),
},
{
title: "Entrepreneurship",
desc: "Enabling women to build, own, and scale their own delivery businesses.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<rect x="3" y="7" width="18" height="13" rx="2" />
<path d="M8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M3 12h18" />
</svg>
),
},
{
title: "Innovation",
desc: "Fresh thinking that reshapes how first and last-mile logistics actually work.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<path d="M9 18h6M10 21h4" />
<path d="M12 3a6 6 0 0 0-3.8 10.6c.5.5.8 1.2.8 1.9v.5h6v-.5c0-.7.3-1.4.8-1.9A6 6 0 0 0 12 3Z" />
</svg>
),
},
{
title: "Community Growth",
desc: "Local hiring and training that lifts entire neighbourhoods, not just routes.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<circle cx="9" cy="8" r="3" />
<path d="M3.5 20c0-3 2.5-5 5.5-5s5.5 2 5.5 5M16 5.5a3 3 0 0 1 0 5.8M20.5 20c0-2.3-1.4-3.9-3.3-4.6" />
</svg>
),
},
];
export default function WomenSection() { export default function WomenSection() {
return ( return (
<div className="elementor-element elementor-element-bbc6760 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="bbc6760" data-element_type="container" data-e-type="container"> <>
<style dangerouslySetInnerHTML={{ __html: `
/* ============================================================
Success Stories — redesigned right column (stats + 2x2 cards)
Dark section · red accent #dc2626 / #ef4444 · Manrope
============================================================ */
/* Neutralise the right column's asymmetric 140px left padding so the
box group can be centered instead of pushed to one side. */
.elementor-element.elementor-element-b2c956f { padding: 0 !important; }
/* Vertically center the two columns so the right content lines up with
the image instead of needing a big top gap; tighten row gap. */
.elementor-element.elementor-element-2ed47f3 { align-items: center !important; }
/* Animated map background behind the Success Stories content */
.elementor-element.elementor-element-b6e14bd { position: relative; overflow: hidden; }
.elementor-element.elementor-element-b6e14bd > .e-con-inner { position: relative; z-index: 1; }
.ws-map { position: absolute; inset: 0; z-index: 0; opacity: 0.5; pointer-events: none; }
.ws-map canvas { display: block; }
#ws-stories {
display: flex;
flex-direction: column;
gap: 16px;
width: 100%;
max-width: 620px;
margin: 0 auto; /* center the 7 boxes as a group — no negative margins */
}
#ws-stories .ws__stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
#ws-stories .ws__stat {
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 14px;
padding: 20px 16px;
transition: border-color 0.3s ease, background-color 0.3s ease;
}
#ws-stories .ws__stat:hover { border-color: rgba(220,38,38,0.28); background: rgba(220,38,38,0.05); }
#ws-stories .ws__stat-num {
color: #fff !important;
font-weight: 900;
font-size: clamp(28px, 3vw, 38px);
line-height: 1;
letter-spacing: -0.01em;
}
#ws-stories .ws__stat-num span { color: #dc2626 !important; }
#ws-stories .ws__stat-label {
margin-top: 9px;
color: rgba(255,255,255,0.7) !important;
font-size: 14px !important;
font-weight: 700;
letter-spacing: 0.03em;
text-transform: uppercase;
}
#ws-stories .ws__cards {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
#ws-stories .ws__card {
position: relative;
overflow: hidden;
background: rgba(255,255,255,0.035);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 16px;
padding: 22px 20px;
transition: transform 0.35s cubic-bezier(.25,1,.5,1), border-color 0.35s ease, background-color 0.35s ease, box-shadow 0.35s ease;
}
#ws-stories .ws__card::after {
content: '';
position: absolute;
top: -45%; left: -25%;
width: 150px; height: 150px;
background: radial-gradient(circle, rgba(220,38,38,0.2), transparent 70%);
opacity: 0;
transition: opacity 0.35s ease;
pointer-events: none;
}
#ws-stories .ws__card:hover {
transform: translateY(-4px);
border-color: rgba(220,38,38,0.3);
background: rgba(220,38,38,0.05);
box-shadow: 0 18px 44px -20px rgba(0,0,0,0.7);
}
#ws-stories .ws__card:hover::after { opacity: 1; }
#ws-stories .ws__card-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 44px; height: 44px;
border-radius: 12px;
background: rgba(220,38,38,0.12);
border: 1px solid rgba(220,38,38,0.25);
color: #ef4444;
margin-bottom: 14px;
transition: background-color 0.3s ease, color 0.3s ease;
}
#ws-stories .ws__card:hover .ws__card-icon { background: #dc2626; color: #fff; }
#ws-stories .ws__card-icon svg { width: 22px; height: 22px; }
#ws-stories .ws__card-title {
color: #fff !important;
font-weight: 900;
font-size: 17px;
letter-spacing: -0.01em;
margin-bottom: 8px;
}
#ws-stories .ws__card-desc {
color: rgba(255,255,255,0.6) !important;
font-size: 13.5px;
line-height: 1.6;
margin: 0;
font-weight: 900;
font-family: 'Manrope', sans-serif;
font-size: 16px;
}
/* Stack the two columns below the desktop breakpoint so the box group
always gets full width and stays centered — never clipped. */
@media (max-width: 1024px) {
.elementor-element.elementor-element-2ed47f3 { grid-template-columns: 1fr !important; }
#ws-stories { max-width: 640px; margin: 0 auto; }
}
@media (max-width: 600px) {
#ws-stories .ws__stats { grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
#ws-stories .ws__stat { padding: 14px 10px; }
#ws-stories .ws__stat-label { font-size: 11px !important; letter-spacing: 0.02em; }
#ws-stories .ws__cards { grid-template-columns: 1fr; }
}
`}} />
<div className="elementor-element elementor-element-bbc6760 e-con-full e-flex cut-corner-no sticky-container-off e-con e-parent" data-id="bbc6760" data-element_type="container" data-e-type="container" style={{ backgroundColor: "#1f1f1f", width: "calc(100% - 40px)", marginLeft: "20px", marginRight: "20px", borderRadius: "25px", overflow: "hidden" }}>
<div <div
className="elementor-element elementor-element-13a7637 elementor-widget__width-auto elementor-absolute elementor-widget elementor-widget-logico_decorative_block" className="elementor-element elementor-element-13a7637 elementor-widget__width-auto elementor-absolute elementor-widget elementor-widget-logico_decorative_block"
data-id="13a7637" data-id="13a7637"
@@ -65,6 +252,9 @@ export default function WomenSection() {
</div> </div>
<div className="elementor-element elementor-element-b6e14bd e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-child" data-id="b6e14bd" data-element_type="container" data-e-type="container" data-settings='{"background_background":"classic"}'> <div className="elementor-element elementor-element-b6e14bd e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-child" data-id="b6e14bd" data-element_type="container" data-e-type="container" data-settings='{"background_background":"classic"}'>
<div className="ws-map" aria-hidden="true">
<IndustryWorldMap />
</div>
<div className="e-con-inner"> <div className="e-con-inner">
<div className="elementor-element elementor-element-90cc867 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="90cc867" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-90cc867 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="90cc867" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-24c0280 elementor-widget__width-inherit elementor-widget elementor-widget-logico_heading" data-id="24c0280" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default"> <div className="elementor-element elementor-element-24c0280 elementor-widget__width-inherit elementor-widget elementor-widget-logico_heading" data-id="24c0280" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
@@ -75,11 +265,13 @@ export default function WomenSection() {
<div className="elementor-element elementor-element-2ed47f3 e-con-full e-grid cut-corner-no sticky-container-off e-con e-child" data-id="2ed47f3" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-2ed47f3 e-con-full e-grid cut-corner-no sticky-container-off e-con e-child" data-id="2ed47f3" data-element_type="container" data-e-type="container">
<div className="elementor-element elementor-element-36efec7 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="36efec7" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-36efec7 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="36efec7" data-element_type="container" data-e-type="container">
<ScrollReveal duration={0.8} yOffset={28} triggerOnce>
<div className="elementor-element elementor-element-778840d elementor-widget elementor-widget-logico_heading" data-id="778840d" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default"> <div className="elementor-element elementor-element-778840d elementor-widget elementor-widget-logico_heading" data-id="778840d" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container"> <div className="elementor-widget-container">
<h3 className="logico-title">Women Leading the Way</h3> <h3 className="logico-title">Women Leading the Way</h3>
</div> </div>
</div> </div>
</ScrollReveal>
<div className="elementor-element elementor-element-bbfb67f elementor-widget elementor-widget-image" data-id="bbfb67f" data-element_type="widget" data-e-type="widget" data-widget_type="image.default"> <div className="elementor-element elementor-element-bbfb67f elementor-widget elementor-widget-image" data-id="bbfb67f" data-element_type="widget" data-e-type="widget" data-widget_type="image.default">
<div className="elementor-widget-container"> <div className="elementor-widget-container">
<Image <Image
@@ -94,108 +286,32 @@ export default function WomenSection() {
</div> </div>
<div className="elementor-element elementor-element-b2c956f e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="b2c956f" data-element_type="container" data-e-type="container"> <div className="elementor-element elementor-element-b2c956f e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="b2c956f" data-element_type="container" data-e-type="container">
<div <div id="ws-stories">
className="elementor-element elementor-element-1a450c2 elementor-absolute elementor-widget elementor-widget-image" <StaggerChildren className="ws__stats" stagger={0.1} duration={0.6} yOffset={20} triggerOnce>
data-id="1a450c2" {WS_STATS.map((s) => (
data-element_type="widget" <div className="ws__stat" key={s.label}>
data-e-type="widget" <div className="ws__stat-num">{s.value}<span>{s.plus}</span></div>
style={{ position: "absolute" }} <div className="ws__stat-label">{s.label}</div>
>
<div className="elementor-widget-container">
<Image
src="/images/bg-map.png"
alt="World Map"
width={965}
height={474}
style={{ width: "100%", height: "auto" }}
/>
</div>
</div> </div>
))}
</StaggerChildren>
{/* Card 1 */} <StaggerChildren className="ws__cards" stagger={0.08} duration={0.6} yOffset={24} triggerOnce>
<div className="elementor-element elementor-element-6b51278 elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-widget elementor-widget-icon-box" data-id="6b51278" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default"> {WS_CARDS.map((c) => (
<div className="elementor-widget-container"> <div className="ws__card" key={c.title}>
<div className="elementor-icon-box-wrapper"> <span className="ws__card-icon" aria-hidden="true">{c.icon}</span>
<div className="elementor-icon-box-icon"> <div className="ws__card-title">{c.title}</div>
<span className="elementor-icon"> <p className="ws__card-desc">{c.desc}</p>
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i>
</span>
</div> </div>
<div className="elementor-icon-box-content"> ))}
<div className="elementor-icon-box-title"> </StaggerChildren>
<span>Women Entrepreneurship</span>
</div>
<p className="elementor-icon-box-description">
Empowering women to lead, manage, and grow in modern logistics operations.
</p>
</div>
</div>
</div>
</div>
<div className="elementor-element elementor-element-e34beb2 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="e34beb2" data-element_type="widget" data-e-type="widget" data-widget_type="divider.default">
<div className="elementor-widget-container">
<div className="elementor-divider">
<span className="elementor-divider-separator"></span>
</div>
</div>
</div>
{/* Card 2 */}
<div className="elementor-element elementor-element-27ba815 elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-widget elementor-widget-icon-box" data-id="27ba815" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default">
<div className="elementor-widget-container">
<div className="elementor-icon-box-wrapper">
<div className="elementor-icon-box-icon">
<span className="elementor-icon">
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i>
</span>
</div>
<div className="elementor-icon-box-content">
<div className="elementor-icon-box-title">
<span>Leadership in Logistics</span>
</div>
<p className="elementor-icon-box-description">
Creating opportunities for women to drive innovation in last-mile delivery.
</p>
</div>
</div>
</div>
</div>
<div className="elementor-element elementor-element-6895eb5 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="6895eb5" data-element_type="widget" data-e-type="widget" data-widget_type="divider.default">
<div className="elementor-widget-container">
<div className="elementor-divider">
<span className="elementor-divider-separator"></span>
</div>
</div>
</div>
{/* Card 3 */}
<div className="elementor-element elementor-element-332c78f elementor-view-stacked elementor-position-inline-start elementor-shape-circle elementor-widget elementor-widget-icon-box" data-id="332c78f" data-element_type="widget" data-e-type="widget" data-widget_type="icon-box.default">
<div className="elementor-widget-container">
<div className="elementor-icon-box-wrapper">
<div className="elementor-icon-box-icon">
<span className="elementor-icon">
<i aria-hidden="true" className="fontello icon-arrow-x-r-top"></i>
</span>
</div>
<div className="elementor-icon-box-content">
<div className="elementor-icon-box-title">
<span>Stronger Together</span>
</div>
<p className="elementor-icon-box-description">
Building a future where women power smarter, faster, and reliable logistics.
</p>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</>
); );
} }