7 Commits

Author SHA1 Message Date
7587c622c3 fix workflow section 2026-07-13 15:10:13 +05:30
333460525a piller sectionn scroll update 2026-07-12 22:58:45 +05:30
1db8a466a5 update Entrepreneurship 2026-07-10 17:14:22 +05:30
ae881da02b update navber wings 2026-07-09 15:20:34 +05:30
d83b709245 update dropdown 2026-07-09 11:53:50 +05:30
6c267cc6f9 remove wings cta page 2026-07-08 20:24:43 +05:30
0fc09a934c navbar algin 2026-07-08 19:29:42 +05:30
36 changed files with 3099 additions and 355 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

View File

@@ -22,7 +22,7 @@ export default function AboutUsPage() {
<AboutHero />
<TheDoormileWay />
<EVLogisticSection />
<WomenSection />
{/* <WomenSection /> */}
<CompetitiveEdge />
<IntelligenceGrid />
<OurTeam />

View File

@@ -8,7 +8,6 @@ import WingsFleetStrategy from "@/components/sections/WingsFleetStrategy";
import WingsInfrastructure from "@/components/sections/WingsInfrastructure";
import WingsMileTruth from "@/components/sections/WingsMileTruth";
import WingsRoadmap from "@/components/sections/WingsRoadmap";
import WingsFinalCTA from "@/components/sections/WingsFinalCTA";
export const metadata = {
title: "Doormile Wings Redefining Domestic Air Logistics Through AI",
@@ -55,7 +54,6 @@ export default function DoormileWingsPage() {
<WingsInfrastructure />
<WingsMileTruth />
<WingsRoadmap />
<WingsFinalCTA />
</div>
</div>
</div>

View File

@@ -0,0 +1,123 @@
import EmpowermentHero from "@/components/sections/EmpowermentHero";
import EmpowermentVision from "@/components/sections/EmpowermentVision";
import EmpowermentStory from "@/components/sections/EmpowermentStory";
import WomenSection from "@/components/sections/WomenSection";
import EmpowermentPrograms from "@/components/sections/EmpowermentPrograms";
import EmpowermentImpact from "@/components/sections/EmpowermentImpact";
import EmpowermentHowItWorks from "@/components/sections/EmpowermentHowItWorks";
import EmpowermentStories from "@/components/sections/EmpowermentStories";
import EmpowermentPartners from "@/components/sections/EmpowermentPartners";
import EmpowermentCTA from "@/components/sections/EmpowermentCTA";
const WINGS_WOMEN_STATS = [
{ value: "500", plus: "+", label: "Women Founders" },
{ value: "35", plus: "+", label: "Cities Active" },
{ value: "100", plus: "+", label: "Enterprises Launched" },
];
const WINGS_WOMEN_CARDS = [
{
title: "Venture Building",
desc: "End-to-end support for women launching logistics enterprises — from ideation to market entry.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<path d="M4 19V5" />
<path d="M4 7h12l-2 4 2 4H4" />
<path d="M18 19h2" />
</svg>
),
},
{
title: "Entrepreneurship",
desc: "Women building, owning, and scaling sustainable businesses within the logistics ecosystem.",
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: "Founder Networks",
desc: "Peer communities and strategic connections that accelerate growth and open new markets.",
icon: (
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
<circle cx="8" cy="8" r="3" />
<circle cx="16" cy="8" r="3" />
<path d="M2.5 20c.7-3.1 2.8-5 5.5-5s4.8 1.9 5.5 5" />
<path d="M10.5 20c.7-3.1 2.8-5 5.5-5s4.8 1.9 5.5 5" />
</svg>
),
},
{
title: "Enterprise Leadership",
desc: "Strategic decision-making, operational excellence, and vision-driven leadership for women founders.",
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>
),
},
];
export const metadata = {
title: "Doormile Wings — Women Entrepreneurship Initiative",
description: "Doormile Wings empowers women to build, own, and lead enterprises within the logistics ecosystem through strategic partnerships, founder networks, and entrepreneurial infrastructure.",
alternates: {
canonical: "https://doormile.com/empowerment",
},
openGraph: {
title: "Doormile Wings — Women Entrepreneurship Initiative",
description: "An entrepreneurial ecosystem empowering women to launch, grow, and lead logistics enterprises with strategic partnerships and industry collaboration.",
url: "https://doormile.com/empowerment",
siteName: "Doormile",
type: "website",
images: [
{
url: "https://doormile.com/images/wings-logo.png",
width: 1200,
height: 630,
alt: "Doormile Wings — Women Entrepreneurship Initiative",
},
],
},
twitter: {
card: "summary_large_image",
title: "Doormile Wings — Women Entrepreneurship Initiative",
description: "An entrepreneurial ecosystem empowering women to launch, grow, and lead logistics enterprises with strategic partnerships and industry collaboration.",
images: ["https://doormile.com/images/wings-logo.png"],
},
};
export default function EmpowermentPage() {
return (
<div id="empowerment" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
<div className="content">
<div className="content-inner">
<div data-elementor-type="wp-page" data-elementor-id="86" className="elementor elementor-86 elementor-59 elementor-empowerment">
<EmpowermentHero />
<EmpowermentVision />
<EmpowermentStory />
<WomenSection
eyebrow="/ Doormile Wings /"
bannerLabel="Women Entrepreneurship"
bannerCopy="An ecosystem where women build, own, and scale enterprises across logistics."
ctaLabel="Explore the ecosystem"
ctaHref="#wings-empowerment-programs"
heading="Women Building The Next Mile"
stats={WINGS_WOMEN_STATS}
cards={WINGS_WOMEN_CARDS}
/>
<EmpowermentPrograms />
<EmpowermentImpact />
<EmpowermentHowItWorks />
<EmpowermentStories />
<EmpowermentPartners />
<EmpowermentCTA />
</div>
</div>
</div>
</div>
);
}

View File

@@ -10,6 +10,27 @@ html {
scroll-behavior: smooth;
}
/* ============================================================
SITE-WIDE STICKY FIX
The legacy Elementor build sets `.body-container { overflow: hidden }`
(public/css/site.css, generated — do not edit there). Any ancestor
with non-visible overflow becomes the containing block for
`position: sticky` descendants; since `.body-container` itself never
actually scrolls (the real scrollbar lives on <body>), that made every
`position: sticky` element on the site inert — it just scrolled away
in normal flow instead of pinning.
Note: setting overflow-x:hidden paired with overflow-y:visible gets
silently coerced to overflow-y:auto by the CSS spec (an "auto" value on
one axis when the other is non-visible) — which ALSO still counts as a
scroll container and breaks sticky the same way. So this must be fully
visible on both axes. <body> already has overflow-x: hidden site-wide
(from the same legacy stylesheet), so horizontal bleed is still safely
clipped there — this rule doesn't need to repeat it.
============================================================ */
.body-container {
overflow: visible !important;
}
/* ============================================================
GLOBAL SPACING SYSTEM
A single shared vertical-rhythm scale so every section uses
@@ -184,7 +205,11 @@ body {
}
#masthead .elementor-element.elementor-element-466de1b.dm-header-scrolled {
top: 0 !important;
top: 15px !important;
left: 20px !important;
right: 20px !important;
border-radius: 24px !important;
width: auto !important;
}
}
@@ -1215,28 +1240,3 @@ body {
}
}
/* Global Desktop Hero Formatting (Matches live site)
.miletruth-hero-container is deliberately excluded: unlike the other
hero wrappers it IS the visual card itself (background-image + a
flat bottom edge that the stats bar overlaps by -25px), not a
wrapper around a separate inner card, so it carries its own
correctly-tuned margin-top/padding/border-radius in MileTruthHero.tsx.
Including it here clobbered that with the wrapper values, collapsing
its top gap to 8px and its internal padding to 20px. */
@media (min-width: 1025px) {
/* Give every hero wrapper a consistent gap from the top and sides */
.elementor-element.elementor-element-741f56c,
.custom-standard-hero-container {
padding: 20px 24px !important;
margin-top: 8px !important;
}
/* Ensure all inner dark hero cards have elegant rounded corners */
.elementor-element.elementor-element-741f56c .owl-carousel.owl-theme .content-item,
.elementor-element.elementor-element-741f56c .content-item,
.custom-standard-hero-card,
.miletruth-hero .slide-content {
border-radius: 24px !important;
overflow: hidden !important;
}
}

View File

@@ -2,6 +2,7 @@ import React from "react";
import MileTruthHero from "../../components/sections/MileTruthHero";
import Workflow1 from "../../components/sections/Workflow1";
import Workflow2 from "../../components/sections/Workflow2";
import Workflow4 from "../../components/sections/Workflow4";
import Workflow3Lazy from "../../components/sections/Workflow3Lazy";
export const metadata = {
@@ -18,6 +19,7 @@ export default function MileTruthPage() {
<MileTruthHero />
<Workflow1 />
<Workflow2 />
<Workflow4 />
<Workflow3Lazy />
</div>
</div>

View File

@@ -20,6 +20,7 @@ const CURRENT_PAGE_MAP: Record<string, string> = {
"/miletruth": "miletruth",
"/solutions": "solutions",
"/doormile-wings": "doormile-wings",
"/empowerment": "entarpreneurship",
"/express": "express",
"/about-us": "about",
"/blog": "blogs",
@@ -30,11 +31,13 @@ const CURRENT_PAGE_ALIASES: Record<string, string[]> = {
home: ["home"],
"how-it-works": ["how-it-works", "how-its-works"],
miletruth: ["miletruth"],
// Solutions is a normal nav page and also owns the Wings/Express dropdown.
solutions: ["solutions", "doormile-wings", "express"],
// Solutions is now a plain top-level link — no child pages own its active state.
solutions: ["solutions"],
"doormile-wings": ["doormile-wings"],
about: ["about", "about-us", "women"],
entarpreneurship: ["entarpreneurship"],
blogs: ["blogs"],
// Company is the dropdown parent for About + Blogs + How It Works — active if any is.
company: ["blogs", "how-it-works", "about"],
};
export default function Header() {
@@ -82,20 +85,20 @@ export default function Header() {
const [visibleScrolled, setVisibleScrolled] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
// Solutions dropdown (desktop) / accordion (mobile). Local to Header —
// Company dropdown (desktop) / accordion (mobile). Local to Header —
// unlike isMenuOpen/isSidebarOpen (HeaderUIProvider), no sibling component
// needs to read this.
const [isDesktopSolutionsOpen, setDesktopSolutionsOpen] = useState(false);
const [isMobileSolutionsOpen, setMobileSolutionsOpen] = useState(false);
const [isDesktopCompanyOpen, setDesktopCompanyOpen] = useState(false);
const [isMobileCompanyOpen, setMobileCompanyOpen] = useState(false);
// Collapse the accordion whenever the off-canvas menu closes, so it isn't
// left expanded the next time the menu opens.
const closeMobileMenu = () => {
setMobileSolutionsOpen(false);
setMobileCompanyOpen(false);
closeAll();
};
const toggleMobileMenu = () => {
setMobileSolutionsOpen(false);
setMobileCompanyOpen(false);
toggleMenu();
};
@@ -457,57 +460,82 @@ export default function Header() {
<li id="menu-item-10508" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10508${dmHeaderActive("home")}`}>
<Link href="/#home" onClick={(event) => handleNavClick(event, "/", "home")}>Home</Link>
</li>
<li id="menu-item-10509" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("how-it-works")}`}>
<Link href="/how-it-works#how-it-works" onClick={(event) => handleNavClick(event, "/how-it-works", "how-it-works")}>How It Works</Link>
<li id="menu-item-10509" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("doormile-wings")}`}>
<Link href="/doormile-wings" prefetch>Wings</Link>
</li>
<li id="menu-item-10510" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10510${dmHeaderActive("miletruth")}`}>
<Link href="/miletruth#miletruth" onClick={(event) => handleNavClick(event, "/miletruth", "miletruth")}>MileTruth&trade; AI</Link>
</li>
<li id="menu-item-10511" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10511${dmHeaderActive("solutions")}`}>
<Link href="/solutions" prefetch>Solutions</Link>
</li>
<li id="menu-item-10513" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10513${dmHeaderActive("entarpreneurship")}`}>
<Link href="/empowerment" prefetch>Entrepreneurship</Link>
</li>
<li
id="menu-item-10511"
className={`menu-item menu-item-type-custom menu-item-has-children menu-item-10511${dmHeaderActive("solutions")}`}
onMouseEnter={() => setDesktopSolutionsOpen(true)}
onMouseLeave={() => setDesktopSolutionsOpen(false)}
id="menu-item-10535"
className={`menu-item menu-item-type-custom menu-item-has-children menu-item-10535${dmHeaderActive("company")}`}
onMouseEnter={() => setDesktopCompanyOpen(true)}
onMouseLeave={() => setDesktopCompanyOpen(false)}
onKeyDown={(event: KeyboardEvent<HTMLLIElement>) => {
if (event.key !== "Escape") return;
setDesktopSolutionsOpen(false);
setDesktopCompanyOpen(false);
event.currentTarget.querySelector<HTMLAnchorElement>(":scope > a")?.focus();
}}
onBlur={(event: FocusEvent<HTMLLIElement>) => {
if (!event.currentTarget.contains(event.relatedTarget as Node)) {
setDesktopSolutionsOpen(false);
setDesktopCompanyOpen(false);
}
}}
>
<Link
href="/solutions"
prefetch
<a
href="#"
aria-haspopup="true"
aria-expanded={isDesktopSolutionsOpen}
onFocus={() => setDesktopSolutionsOpen(true)}
onClick={() => setDesktopSolutionsOpen(false)}
aria-expanded={isDesktopCompanyOpen}
onFocus={() => setDesktopCompanyOpen(true)}
onClick={(event) => {
event.preventDefault();
setDesktopCompanyOpen((open) => !open);
}}
>
Solutions
</Link>
Company
</a>
<ul className="dm-solutions-dropdown">
<li className={currentPage === "doormile-wings" ? "dm-child-active" : ""}>
<Link href="/doormile-wings" prefetch onClick={() => setDesktopSolutionsOpen(false)}>
Doormile Wings
<li className={currentPage === "about" ? "dm-child-active" : ""}>
<Link
href="/about-us#about"
onClick={(event) => {
setDesktopCompanyOpen(false);
handleNavClick(event, "/about-us", "about");
}}
>
About
</Link>
</li>
<li className={currentPage === "express" ? "dm-child-active" : ""}>
<Link href="/express" prefetch onClick={() => setDesktopSolutionsOpen(false)}>
Express
<li className={currentPage === "blogs" ? "dm-child-active" : ""}>
<Link
href="/blog#blogs"
onClick={(event) => {
setDesktopCompanyOpen(false);
handleNavClick(event, "/blog", "blogs");
}}
>
Blogs
</Link>
</li>
<li className={currentPage === "how-it-works" ? "dm-child-active" : ""}>
<Link
href="/how-it-works#how-it-works"
onClick={(event) => {
setDesktopCompanyOpen(false);
handleNavClick(event, "/how-it-works", "how-it-works");
}}
>
How It Works
</Link>
</li>
</ul>
</li>
<li id="menu-item-10512" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10512${dmHeaderActive("about")}`}>
<Link href="/about-us#about" onClick={(event) => handleNavClick(event, "/about-us", "about")}>About</Link>
</li>
<li id="menu-item-10535" className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-10535${dmHeaderActive("blogs")}`}>
<Link href="/blog#blogs" onClick={(event) => handleNavClick(event, "/blog", "blogs")}>Blogs</Link>
</li>
</ul>
</nav>
</div>
@@ -541,45 +569,54 @@ export default function Header() {
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10508${dmHeaderActive("home")}`}>
<Link href="/#home" onClick={(event) => handleNavClick(event, "/", "home", true)}>Home</Link>
</li>
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("how-it-works")}`}>
<Link href="/how-it-works#how-it-works" onClick={(event) => handleNavClick(event, "/how-it-works", "how-it-works", true)}>How It Works</Link>
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("doormile-wings")}`}>
<Link href="/doormile-wings" prefetch onClick={closeMobileMenu}>Wings</Link>
</li>
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10510${dmHeaderActive("miletruth")}`}>
<Link href="/miletruth#miletruth" onClick={(event) => handleNavClick(event, "/miletruth", "miletruth", true)}>MileTruth&trade; AI</Link>
</li>
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10511${dmHeaderActive("solutions")}`}>
<Link href="/solutions" prefetch onClick={closeMobileMenu}>Solutions</Link>
</li>
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10513${dmHeaderActive("entarpreneurship")}`}>
<Link href="/empowerment" prefetch onClick={closeMobileMenu}>Entrepreneurship</Link>
</li>
<li
className={`menu-item menu-item-type-custom menu-item-10511 dm-mobile-solutions${dmHeaderActive("solutions")}${isMobileSolutionsOpen ? " dm-accordion-open" : ""}`}
className={`menu-item menu-item-type-custom menu-item-10535 dm-mobile-solutions${dmHeaderActive("company")}${isMobileCompanyOpen ? " dm-accordion-open" : ""}`}
>
<div className="dm-mobile-solutions-row">
<Link href="/solutions" prefetch onClick={closeMobileMenu}>
Solutions
</Link>
<a
href="#"
onClick={(event) => {
event.preventDefault();
setMobileCompanyOpen((open) => !open);
}}
>
Company
</a>
<button
type="button"
className="dm-mobile-solutions-toggle"
aria-label={isMobileSolutionsOpen ? "Close Solutions menu" : "Open Solutions menu"}
aria-label={isMobileCompanyOpen ? "Close Company menu" : "Open Company menu"}
aria-haspopup="true"
aria-expanded={isMobileSolutionsOpen}
onClick={() => setMobileSolutionsOpen((open) => !open)}
aria-expanded={isMobileCompanyOpen}
onClick={() => setMobileCompanyOpen((open) => !open)}
>
<span className="dm-accordion-chevron" aria-hidden="true"></span>
</button>
</div>
<ul className="dm-mobile-solutions-panel">
<li className={currentPage === "doormile-wings" ? "dm-child-active" : ""}>
<Link href="/doormile-wings" prefetch onClick={closeMobileMenu}>Doormile Wings</Link>
<li className={currentPage === "about" ? "dm-child-active" : ""}>
<Link href="/about-us#about" onClick={(event) => handleNavClick(event, "/about-us", "about", true)}>About</Link>
</li>
<li className={currentPage === "express" ? "dm-child-active" : ""}>
<Link href="/express" prefetch onClick={closeMobileMenu}>Express</Link>
<li className={currentPage === "blogs" ? "dm-child-active" : ""}>
<Link href="/blog#blogs" onClick={(event) => handleNavClick(event, "/blog", "blogs", true)}>Blogs</Link>
</li>
<li className={currentPage === "how-it-works" ? "dm-child-active" : ""}>
<Link href="/how-it-works#how-it-works" onClick={(event) => handleNavClick(event, "/how-it-works", "how-it-works", true)}>How It Works</Link>
</li>
</ul>
</li>
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-10512${dmHeaderActive("about")}`}>
<Link href="/about-us#about" onClick={(event) => handleNavClick(event, "/about-us", "about", true)}>About</Link>
</li>
<li className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-10535${dmHeaderActive("blogs")}`}>
<Link href="/blog#blogs" onClick={(event) => handleNavClick(event, "/blog", "blogs", true)}>Blogs</Link>
</li>
</ul>
</nav>
<div className="header-mobile-contacts">
@@ -797,13 +834,11 @@ export default function Header() {
grid-template-columns: 1fr auto 1fr !important;
align-items: center !important;
column-gap: clamp(16px, 2vw, 32px) !important;
/* Fixed 20px safe area on both sides — matches the Hero
card and Footer's outer band exactly (both use a flat
20px inset, uncapped, at every desktop width), so the
header aligns with the rest of the page instead of
drifting wider on large screens. Symmetric, so the
/* Equal left/right safe areas pull the logo and Contact
button inward off the viewport edges. Because the inset
is symmetric, the 1fr side columns shrink equally and the
centred nav does not shift. */
padding-inline: 20px !important;
padding-inline: clamp(24px, 3vw, 48px) !important;
/* Consistent top/bottom breathing room inside the bar; with
align-items:center every section stays vertically centred. */
padding-block: clamp(8px, 1vw, 16px) !important;
@@ -835,29 +870,9 @@ export default function Header() {
align-items: center !important;
}
/* navbar-right: Contact button, aligned to the right edge.
The vendor kit's own --margin-right:3% (site.css) would add
extra drift off the grid's 20px safe area — zero it so the
button's true right edge lands flush with that 20px inset. */
/* navbar-right: Contact button, aligned to the right edge. */
#masthead .elementor-element.elementor-element-f961133 {
justify-self: end !important;
margin-right: 0 !important;
}
}
/* Compact nav items at middle desktop widths (8 items fit without overflow).
Slightly tighter letter-spacing keeps the active underline animation intact. */
@media (min-width: 1025px) and (max-width: 1400px) {
#masthead .header-menu-container .main-menu > li > a {
letter-spacing: -0.01em;
}
}
@media (min-width: 1025px) and (max-width: 1200px) {
#masthead .header-menu-container .main-menu {
gap: clamp(4px, 0.8vw, 12px) !important;
}
#masthead .header-menu-container .main-menu > li > a {
font-size: clamp(12px, 0.95vw, 14px);
}
}
@@ -959,12 +974,15 @@ export default function Header() {
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cline x1='5' y1='5' x2='19' y2='19'/%3E%3Cline x1='19' y1='5' x2='5' y2='19'/%3E%3C/svg%3E");
}
/* ── Solutions dropdown (desktop) / accordion (mobile) ──
Solutions remains linked to /solutions while the nested menu opens
independently. It reuses site.css's dead .menu-item-has-children chevron (fontello
glyph, already coloured white for this exact header widget) instead
of inventing a new arrow, so it matches the site's existing premium
nav styling. Desktop opens on hover/focus; mobile is a
/* ── Company dropdown (desktop) / accordion (mobile) ──
Company (Blogs + How It Works) is a non-navigating parent —
its trigger is a plain anchor with no href target, only a
dropdown toggle. Class names below (.dm-solutions-dropdown,
.dm-mobile-solutions*) are unchanged from when this same
component/markup belonged to Solutions, reusing site.css's dead
.menu-item-has-children chevron (fontello glyph, already
coloured white for this exact header widget) instead of
inventing a new arrow. Desktop opens on hover/focus; mobile is a
height-collapsing accordion controlled by the chevron button. */
@media (min-width: 1025px) {
#masthead .header-menu-container nav {
@@ -1109,8 +1127,6 @@ export default function Header() {
font-weight: 700;
}
#masthead .header-menu-container .main-menu > li.menu-item-has-children:hover .dm-solutions-dropdown,
#masthead .header-menu-container .main-menu > li.menu-item-has-children:focus-within .dm-solutions-dropdown,
#masthead .header-menu-container .main-menu > li.menu-item-has-children > a[aria-expanded="true"] ~ .dm-solutions-dropdown {
opacity: 1;
visibility: visible;
@@ -1118,8 +1134,6 @@ export default function Header() {
transform: translate(-50%, 24px);
}
#masthead .header-menu-container .main-menu > li.menu-item-has-children:hover > a:after,
#masthead .header-menu-container .main-menu > li.menu-item-has-children:focus-within > a:after,
#masthead .header-menu-container .main-menu > li.menu-item-has-children > a[aria-expanded="true"]:after {
transform: rotate(180deg);
}

View File

@@ -42,6 +42,9 @@ export interface EVStat {
decimals?: number;
suffix: string;
label: string;
/** Optional static text override — when set, renders this text instead of
* an animated CountUp (for non-numeric KPI concepts, e.g. "QUBO"). */
text?: string;
}
/** Accent theming for the dashboard column so it matches the scene on the left
@@ -83,10 +86,19 @@ interface EVSectionProps {
* static homepage feature list. The bottom stat bar is dropped in this mode
* to avoid repeating the metrics. */
metrics?: EVStat[];
/** Optional distinct copy for the bottom `.evnd__bar` strip in dashboard
* mode. Defaults to reusing `metrics` (WF1/WF2 behaviour) when omitted. */
barStats?: EVStat[];
/** Heading above the dashboard, e.g. "PERFORMANCE INSIGHT". */
cardsHeading?: string;
/** Accent theme for the dashboard column (defaults to the section red). */
cardsTheme?: EVCardsTheme;
/** Dashboard system label, top-right of the header row. Defaults to "AI ENGINE". */
sysLabel?: string;
/** Extra class appended to `.evnd__imgwrap`, for workflow-specific media
* sizing overrides (e.g. video object-fit) defined in the caller's own
* scoped <style> tag rather than here. */
mediaClassName?: string;
}
/* ---- Default content = original homepage EV Logistics section ---- */
@@ -260,11 +272,13 @@ function DashboardPanel({
features,
heading,
theme,
sysLabel = "AI ENGINE",
}: {
metrics: EVStat[];
features: EVFeature[];
heading?: string;
theme?: EVCardsTheme;
sysLabel?: string;
}) {
const themeVars = theme
? ({
@@ -287,7 +301,7 @@ function DashboardPanel({
<span className="evnd__dash-livedot" />
{heading}
</span>
<span className="evnd__dash-sys">AI ENGINE</span>
<span className="evnd__dash-sys">{sysLabel}</span>
</div>
)}
@@ -295,12 +309,16 @@ function DashboardPanel({
<div className="evnd__dash-kpis">
{metrics.map((m) => (
<div className="evnd__kpi" key={m.label}>
<CountUp
value={m.value}
decimals={m.decimals}
suffix={m.suffix}
className="evnd__kpi-val"
/>
{m.text ? (
<b className="evnd__kpi-val evnd__kpi-val--text">{m.text}</b>
) : (
<CountUp
value={m.value}
decimals={m.decimals}
suffix={m.suffix}
className="evnd__kpi-val"
/>
)}
<span className="evnd__kpi-label">{m.label}</span>
</div>
))}
@@ -342,11 +360,15 @@ export default function EVSection({
ariaLabel,
mediaSlot,
metrics,
barStats,
cardsHeading,
cardsTheme,
sysLabel,
mediaClassName,
}: EVSectionProps) {
const bannerRef = useRef<HTMLDivElement>(null);
const useDashboard = !!metrics && metrics.length > 0;
const isVideo = image.endsWith(".mp4");
/* In dashboard mode the workflow's accent theme is applied at the .evnd
section level so the shared animated network backdrop (below) is tinted to
@@ -595,13 +617,31 @@ export default function EVSection({
background: #ef4444;
}
/* ---- Heading → content gap ----
Deliberately set here (on the wrapper div) rather than as
margin-bottom on .evnd__title (the <h2>): a global site.css rule
(.logico-front-end h2:not([class*="logico-title-h"]):last-child)
outweighs .evnd__title's own specificity and zeroes any bottom
margin placed on the heading itself, since the h2 is always the
last child of .evnd__heading. Setting it here sidesteps that
collision and gives every workflow section + Fleet Strategy one
shared, consistent gap. */
.evnd__heading {
margin-bottom: 40px;
}
@media (max-width: 991px) and (min-width: 768px) {
.evnd__heading {
margin-bottom: 34px;
}
}
.evnd__title {
color: #fff !important;
font-weight: 800 !important;
font-size: clamp(32px, 3.8vw, 48px) !important;
line-height: 1.15 !important;
letter-spacing: -0.01em;
margin: 0 0 36px 0;
margin: 0;
}
@media (min-width: 768px) {
.evnd__title {
@@ -752,7 +792,7 @@ export default function EVSection({
.evnd-feature__desc {
color: rgba(255,255,255,0.65) !important;
font-weight: 400 !important;
font-size: 14px !important;
font-size: 16px !important;
line-height: 1.6 !important;
margin: 0;
}
@@ -867,6 +907,13 @@ export default function EVSection({
font-size: 12.5px;
letter-spacing: 0.01em;
}
/* Non-numeric KPI concepts (EVStat.text) — same gradient treatment as
the counted values, sized down so short codes/words don't inherit
the numeric clamp() meant for 2-3 digit figures. */
.evnd__kpi-val--text {
font-size: clamp(18px, 1.6vw, 22px) !important;
letter-spacing: 0.02em;
}
/* ============================================================
Large-screen layout balance (WF1/WF2 dashboard only, ≥1440px).
@@ -969,8 +1016,8 @@ export default function EVSection({
.evnd__dfeat-desc {
color: rgba(255,255,255,0.6) !important;
font-weight: 400 !important;
font-size: 13px !important;
line-height: 1.45 !important;
font-size: 16px !important;
line-height: 1.55 !important;
margin: 0 !important;
}
@@ -1041,6 +1088,14 @@ export default function EVSection({
text-transform: none;
opacity: 0.9;
}
/* Non-numeric bar values (EVStat.text) — the bar's numeric clamp()
(up to 56px) is too large for words/phrases; size down and let
longer phrases (e.g. "Cost + Distance + SLA") wrap cleanly. */
.evnd__bar-val--text {
font-size: clamp(16px, 1.8vw, 22px);
line-height: 1.25;
white-space: normal;
}
@keyframes evndGlow { 0%,100% { opacity: 0.75; } 50% { opacity: 1; } }
@@ -1052,7 +1107,6 @@ export default function EVSection({
@media (max-width: 991px) {
.evnd { padding: 48px 32px 56px; }
.evnd__grid { grid-template-columns: 1fr; gap: 40px; }
.evnd__title { margin-bottom: 28px; }
.evnd__features { gap: 14px; }
/* Stacked: KPI row can spread to 4-up since it now has full width. */
.evnd__dash-kpis { grid-template-columns: repeat(4, 1fr); }
@@ -1331,7 +1385,7 @@ export default function EVSection({
<div
className={`evnd__inner${useDashboard ? " evnd__inner--cards" : ""}${
useDashboard && !mediaSlot ? " evnd__inner--img" : ""
useDashboard && !mediaSlot && !isVideo ? " evnd__inner--img" : ""
}`}
>
<div className="evnd__heading">
@@ -1345,7 +1399,7 @@ export default function EVSection({
{/* MAIN GRID */}
<div
className={`evnd__grid${useDashboard ? " evnd__grid--cards" : ""}${
useDashboard && !mediaSlot ? " evnd__grid--img" : ""
useDashboard && !mediaSlot && !isVideo ? " evnd__grid--img" : ""
}`}
>
{/* Left column */}
@@ -1353,11 +1407,11 @@ export default function EVSection({
<div className="evnd__media">
<div className="evnd__glow" />
<div
className={`evnd__imgwrap${mediaSlot ? " evnd__imgwrap--media" : ""}${image.endsWith(".mp4") ? " evnd__imgwrap--video" : ""}`}
className={`evnd__imgwrap${mediaSlot ? " evnd__imgwrap--media" : ""}${isVideo ? " evnd__imgwrap--video" : ""}${mediaClassName ? ` ${mediaClassName}` : ""}`}
>
{mediaSlot ? (
mediaSlot
) : image.endsWith(".mp4") ? (
) : isVideo ? (
<video
className="evnd__video"
autoPlay
@@ -1401,6 +1455,7 @@ export default function EVSection({
features={features}
heading={cardsHeading}
theme={cardsTheme}
sysLabel={sysLabel}
/>
) : (
<div className="evnd__features">
@@ -1434,15 +1489,19 @@ export default function EVSection({
all breakpoints. In dashboard mode it summarises the same workflow
metrics; the homepage section uses its own stat set. */}
<div className="evnd__bar">
{(useDashboard ? metrics! : stats).map((s) => (
{(useDashboard ? (barStats ?? metrics!) : stats).map((s) => (
<div className="evnd__bar-item" key={s.label}>
<span className="evnd__bar-label">{s.label}</span>
<CountUp
value={s.value}
decimals={s.decimals}
suffix={s.suffix}
className="evnd__bar-val"
/>
{s.text ? (
<b className="evnd__bar-val evnd__bar-val--text">{s.text}</b>
) : (
<CountUp
value={s.value}
decimals={s.decimals}
suffix={s.suffix}
className="evnd__bar-val"
/>
)}
</div>
))}
</div>

View File

@@ -0,0 +1,162 @@
export default function EmpowermentCTA() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.emp-cta-wrap {
width: calc(100% - 40px);
margin: clamp(24px, 4vw, 40px) auto clamp(40px, 5vw, 64px);
}
.emp-cta {
position: relative;
overflow: hidden;
border-radius: 28px;
min-height: clamp(480px, 48vw, 680px);
background: #09090b;
display: flex;
align-items: flex-end;
}
.emp-cta::before {
content: "";
position: absolute;
inset: 0;
background-image:
linear-gradient(180deg, rgba(9, 9, 11, 0.18) 0%, rgba(9, 9, 11, 0.52) 48%, rgba(9, 9, 11, 0.96) 100%),
linear-gradient(90deg, rgba(9, 9, 11, 0.88) 0%, rgba(9, 9, 11, 0.35) 58%, rgba(9, 9, 11, 0.12) 100%),
url("/images/bg-header-women.webp");
background-size: cover;
background-position: center;
transform: scale(1.02);
}
.emp-cta-inner {
position: relative;
z-index: 1;
max-width: 1380px;
width: 100%;
margin: 0 auto;
padding: clamp(46px, 7vw, 88px) clamp(24px, 5vw, 64px);
box-sizing: border-box;
}
.emp-cta-recap {
display: flex;
gap: clamp(28px, 4vw, 52px);
margin-bottom: clamp(28px, 4vw, 44px);
padding-bottom: clamp(24px, 3vw, 36px);
border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}
.emp-cta-recap-item {
display: flex;
align-items: baseline;
gap: 10px;
}
.emp-cta-recap-num {
font-size: clamp(22px, 2.4vw, 32px);
font-weight: 900;
letter-spacing: -0.02em;
color: transparent;
-webkit-text-stroke: 1.3px rgba(255, 255, 255, 0.85);
}
.emp-cta-recap-label {
font-size: 12px;
font-weight: 700;
letter-spacing: 0.6px;
color: rgba(255, 255, 255, 0.5);
}
.emp-cta-kicker {
font-size: 13px;
font-weight: 900;
letter-spacing: 2.4px;
text-transform: uppercase;
color: #ff5470;
margin-bottom: 22px;
}
.emp-cta-title {
max-width: 980px;
color: #ffffff !important;
font-size: clamp(44px, 7vw, 108px) !important;
font-weight: 900 !important;
line-height: 0.95 !important;
letter-spacing: -0.06em !important;
text-transform: uppercase !important;
margin: 0 0 clamp(24px, 3vw, 34px);
}
.emp-cta-title em {
color: #ff5470;
font-style: normal;
}
.emp-cta-bottom {
display: block;
max-width: 1120px;
}
.emp-cta-sub {
max-width: 620px;
font-size: 16px;
line-height: 1.68;
color: rgba(255, 255, 255, 0.68);
margin: 0;
}
@media (max-width: 1024px) {
.emp-cta-wrap { width: calc(100% - 24px); }
.emp-cta { border-radius: 22px; }
}
@media (max-width: 760px) {
.emp-cta { min-height: 600px; }
.emp-cta::before { background-position: 76% center; }
.emp-cta-title {
font-size: clamp(36px, 11vw, 44px) !important;
letter-spacing: -0.05em !important;
overflow-wrap: anywhere;
}
.emp-cta-recap { flex-wrap: wrap; row-gap: 14px; }
}
`,
}}
/>
<div className="emp-cta-wrap">
<section className="emp-cta" aria-labelledby="empowerment-final-cta">
<div className="emp-cta-inner">
<div className="emp-cta-recap">
<div className="emp-cta-recap-item">
<span className="emp-cta-recap-num">500+</span>
<span className="emp-cta-recap-label">Women Founders</span>
</div>
<div className="emp-cta-recap-item">
<span className="emp-cta-recap-num">100+</span>
<span className="emp-cta-recap-label">Enterprises Launched</span>
</div>
<div className="emp-cta-recap-item">
<span className="emp-cta-recap-num">25+</span>
<span className="emp-cta-recap-label">Industry Partners</span>
</div>
</div>
<div className="emp-cta-kicker">/ Build the next mile /</div>
<h2 className="emp-cta-title" id="empowerment-final-cta">
Build what&rsquo;s <em>next.</em>
</h2>
<div className="emp-cta-bottom">
<p className="emp-cta-sub">
Join Doormile Wings in building the entrepreneurial ecosystem where women launch, grow, and lead enterprises that create lasting value across logistics.
</p>
</div>
</div>
</section>
</div>
</>
);
}

View File

@@ -0,0 +1,183 @@
import Link from "next/link";
import { ScrollReveal, ShimmerText } from "@/animations/Reveal";
export default function EmpowermentHero() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.eh-outer {
box-sizing: border-box;
padding: 20px;
}
.eh-section {
position: relative;
border-radius: 25px;
overflow: hidden;
box-sizing: border-box;
height: 800px;
display: flex;
align-items: center;
justify-content: center;
background: #07080c;
}
.eh-bg {
position: absolute;
inset: 0;
background-image: url("/images/women-hero-slider-2.png");
background-size: cover;
background-position: 30% 72%;
z-index: 0;
}
.eh-scrim {
position: absolute;
inset: 0;
background:
linear-gradient(180deg, rgba(7, 8, 12, 0.72) 0%, rgba(7, 8, 12, 0.5) 40%, rgba(7, 8, 12, 0.86) 100%);
z-index: 1;
}
.eh-inner {
position: relative;
z-index: 2;
width: 100%;
max-width: 1000px;
margin: 0 auto;
padding: 0 15px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
box-sizing: border-box;
}
.eh-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.6px;
text-transform: uppercase;
color: #ff5470;
margin-bottom: 20px;
}
.eh-title {
width: 100%;
font-size: clamp(30px, 5.5vw, 80px) !important;
font-weight: 800 !important;
letter-spacing: -0.03em !important;
line-height: 1.08 !important;
text-transform: uppercase !important;
color: #ffffff !important;
margin: 0;
word-wrap: break-word;
overflow-wrap: break-word;
}
.eh-title .eh-soft {
color: rgba(255, 255, 255, 0.72);
}
.eh-desc {
width: 100%;
max-width: 680px;
margin: 23px auto 0;
font-size: clamp(16px, 1.35vw, 23px);
line-height: 1.65;
color: rgba(255, 255, 255, 0.78);
}
.eh-btns {
display: flex;
align-items: center;
justify-content: center;
gap: 14px;
flex-wrap: wrap;
margin-top: 32px;
}
.eh-btn-primary,
.eh-btn-outline {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 15px 28px;
border-radius: 100px;
font-weight: 800;
font-size: 14px;
text-decoration: none;
transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s ease, background-color 0.3s ease, border-color 0.3s ease;
}
.eh-btn-primary {
background: #c01227;
color: #ffffff !important;
border: 1.5px solid #c01227;
}
.eh-btn-primary:hover {
transform: translateY(-3px);
box-shadow: 0 14px 30px rgba(192, 18, 39, 0.4);
}
.eh-btn-outline {
background: rgba(255, 255, 255, 0.04);
color: #ffffff !important;
border: 1.5px solid rgba(255, 255, 255, 0.36);
}
.eh-btn-outline:hover {
border-color: rgba(255, 255, 255, 0.82);
background: rgba(255, 255, 255, 0.09);
transform: translateY(-3px);
}
@media (max-width: 1020px) {
.eh-outer { padding: 10px; }
}
@media (max-width: 840px) {
.eh-section { height: 600px; }
}
@media (max-width: 660px) {
.eh-title {
font-size: clamp(20px, 7vw, 32px) !important;
}
}
@media (max-width: 480px) {
.eh-section { height: 520px; }
.eh-btn-primary, .eh-btn-outline { width: 100%; justify-content: center; padding: 14px 22px; }
.eh-btns { width: 100%; }
}
`,
}}
/>
<div className="eh-outer">
<section className="eh-section" id="wings-empowerment-hero">
<div className="eh-bg" aria-hidden="true" />
<div className="eh-scrim" aria-hidden="true" />
<ScrollReveal delay={0.05} duration={0.85} yOffset={30} className="eh-inner">
{/* <div className="eh-eyebrow">Build the Next Mile</div> */}
<h1 className="eh-title">
Building <span className="eh-soft">Women</span><br />
<ShimmerText>Entrepreneurs.</ShimmerText>
</h1>
<p className="eh-desc">
Empowering ambitious women with the network, strategic partnerships, and opportunities to build, grow, and lead successful enterprises that shape the future of logistics.
</p>
{/* <div className="eh-btns">
<Link href="/contact" className="eh-btn-primary">Join Doormile Wings</Link>
<Link href="/contact" className="eh-btn-outline">Become a Partner</Link>
</div> */}
</ScrollReveal>
</section>
</div>
</>
);
}

View File

@@ -0,0 +1,259 @@
import { ScrollReveal, StaggerChildren } from "@/animations/Reveal";
const STEPS = [
{ step: "01", title: "Apply", desc: "Submit your venture idea and tell us about your entrepreneurial vision." },
{ step: "02", title: "Discovery", desc: "Identify the right market opportunity and validate your business model." },
{ step: "03", title: "Build", desc: "Develop your enterprise with ecosystem support, mentorship, and partnerships." },
{ step: "04", title: "Launch", desc: "Go to market with strategic backing, industry connections, and operational infrastructure." },
{ step: "05", title: "Scale", desc: "Grow your team, expand operations, and lead your enterprise to sustainable impact." },
];
export default function EmpowermentHowItWorks() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.ehw-section {
background: #ffffff;
padding: var(--space-section-lg, 80px) 0 calc(var(--space-section-lg, 80px) + 32px) 0;
overflow: hidden;
}
.ehw-inner {
max-width: 1380px;
margin: 0 auto;
}
.ehw-head {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-bottom: clamp(126px, calc(7vw + 60px), 172px);
}
.ehw-head-reveal {
width: 100%;
}
.ehw-divider {
width: 100%;
height: 1px;
margin: 18px 0 clamp(24px, 3.5vw, 40px) 0;
border: none;
background-color: rgba(17, 17, 17, 0.14);
}
.ehw-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.4px;
text-transform: uppercase;
color: rgba(17, 17, 17, 0.42);
}
.ehw-title {
max-width: 820px;
font-size: clamp(32px, 4vw, 54px) !important;
font-weight: 800 !important;
letter-spacing: -0.03em !important;
line-height: 1.08 !important;
text-transform: none !important;
color: #111111 !important;
margin: 0 !important;
}
/* ----------------------------------------------------------------
Premium editorial process row: five milestones in a single
sequence, separated by thin hairline dividers (no cards, no
shadows, no boxed containers). One flex-wrap sequence with
responsive flex-basis handles the composition at every size —
5-across on desktop, 3 + 2 (centered) on tablet, a single
vertical column on mobile — from one shared markup.
---------------------------------------------------------------- */
.ehw-sequence {
display: flex;
flex-wrap: wrap;
justify-content: center;
--ehw-gap: clamp(24px, 2.6vw, 48px);
column-gap: var(--ehw-gap);
row-gap: clamp(48px, 6vw, 84px);
}
.ehw-step {
position: relative;
flex: 0 1 calc((100% - 4 * var(--ehw-gap)) / 5);
min-width: 168px;
padding-left: clamp(20px, 2vw, 32px);
border-left: 1px solid rgba(17, 17, 17, 0.14);
transition: border-color 0.3s ease;
}
.ehw-step:first-child {
border-left: none;
padding-left: 0;
}
.ehw-step:hover {
border-left-color: rgba(200, 16, 46, 0.4);
}
.ehw-step-num {
font-size: clamp(48px, 4.6vw, 78px);
font-weight: 900;
line-height: 0.84;
letter-spacing: -0.03em;
color: transparent;
-webkit-text-stroke: 1.5px rgba(17, 17, 17, 0.24);
margin: 0 0 18px 0;
transition: -webkit-text-stroke-color 0.3s ease;
}
.ehw-step.is-accent .ehw-step-num {
-webkit-text-stroke: 1.5px rgba(200, 16, 46, 0.58);
}
.ehw-step-kicker {
display: flex;
align-items: center;
gap: 7px;
margin-bottom: 18px;
}
.ehw-step-kicker svg {
width: 13px;
height: 13px;
color: rgba(17, 17, 17, 0.36);
flex-shrink: 0;
}
.ehw-step-kicker span {
font-size: 11px;
font-weight: 800;
letter-spacing: 2px;
text-transform: uppercase;
color: rgba(17, 17, 17, 0.4);
}
.ehw-step.is-accent .ehw-step-kicker svg,
.ehw-step.is-accent .ehw-step-kicker span {
color: #c8102e;
}
.ehw-step-title {
font-size: clamp(18px, 1.4vw, 22px) !important;
font-weight: 800 !important;
letter-spacing: -0.02em !important;
line-height: 1.2 !important;
text-transform: none !important;
color: #111111 !important;
margin: 0 0 22px 0;
}
.ehw-step-desc {
max-width: 27ch;
font-size: 14px;
line-height: 1.6;
color: rgba(17, 17, 17, 0.55);
margin: 0;
}
/* Tablet: 3 + 2, centered — sever the divider at the start of each row. */
@media (max-width: 1100px) {
.ehw-step {
flex-basis: calc((100% - 2 * var(--ehw-gap)) / 3);
}
.ehw-step:nth-child(4) {
border-left: none;
padding-left: 0;
}
}
/* Mobile: single column — dividers rotate from vertical to horizontal. */
@media (max-width: 640px) {
.ehw-sequence {
row-gap: 0;
}
.ehw-step {
flex-basis: 100%;
padding-left: 0;
padding-top: clamp(28px, 8vw, 38px);
border-left: none;
border-top: 1px solid rgba(17, 17, 17, 0.14);
}
.ehw-step:first-child {
padding-top: 0;
border-top: none;
}
.ehw-step:nth-child(4) {
border-top: 1px solid rgba(17, 17, 17, 0.14);
}
.ehw-step:hover {
border-left-color: transparent;
}
.ehw-step-num {
font-size: clamp(44px, 13vw, 56px);
}
}
/* ---- Mobile title-to-description gap fix ----
.ehw-step-title is an <h3>, so it's matched by a global,
unscoped site.css rule (.logico-front-end h3:not(...) { margin:
0 0 30px }) that outranks this component's own single-class
".ehw-step-title { margin: 0 0 22px }" by specificity — bumping
the real margin-bottom to 30px everywhere, not just here. There
is no min-height, space-between, or fixed row height anywhere in
this component; the gap is purely that extra 8px of margin
reading as oversized once every other element around it (kicker,
description line-height) is tightly spaced. Overridden with
!important, matching how every other property on this selector
already has to defeat the same global rule. Scoped to mobile
only, per spec — desktop/tablet are left exactly as they were
(still resolving to the global 30px; out of scope here). */
@media (max-width: 767px) {
.ehw-step-title {
margin-bottom: 16px !important;
}
}
@media (max-width: 480px) {
.ehw-section { padding-top: 48px; padding-bottom: 68px; }
}
`,
}}
/>
<section className="ehw-section" id="wings-empowerment-how-it-works">
<div className="dm-section-container">
<div className="ehw-inner">
<div className="ehw-head">
<ScrollReveal delay={0.05} duration={0.75} yOffset={20} className="ehw-head-reveal">
<div className="ehw-eyebrow">/ The Founder Journey /</div>
<hr className="ehw-divider" />
</ScrollReveal>
<ScrollReveal delay={0.1} duration={0.85} yOffset={24}>
<h2 className="ehw-title">A clear path, from idea to enterprise</h2>
</ScrollReveal>
</div>
<StaggerChildren className="ehw-sequence" stagger={0.12} duration={0.7} yOffset={30} triggerOnce>
{STEPS.map((s, i) => (
<div className={`ehw-step${i === 2 ? " is-accent" : ""}`} key={s.step}>
<div className="ehw-step-num">{s.step}</div>
<div className="ehw-step-kicker" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M7 17 17 7M9 7h8v8" />
</svg>
<span>Step</span>
</div>
<h3 className="ehw-step-title">{s.title}</h3>
<p className="ehw-step-desc">{s.desc}</p>
</div>
))}
</StaggerChildren>
</div>
</div>
</section>
</>
);
}

View File

@@ -0,0 +1,192 @@
import { ScrollReveal, CountUp } from "@/animations/Reveal";
const SECONDARY_STATS = [
{ end: 100, suffix: "+", label: "Enterprises Launched", isCount: true },
{ end: 25, suffix: "+", label: "Industry Partners", isCount: true },
{ end: 15, suffix: "+", label: "Cities Active", isCount: true },
{ value: "Millions", label: "In Economic Value Created", isCount: false },
];
export default function EmpowermentImpact() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.eim-section {
position: relative;
width: calc(100% - 40px);
margin: clamp(24px, 4vw, 40px) auto;
border-radius: 28px;
overflow: hidden;
box-sizing: border-box;
background: #09090b;
padding: clamp(64px, 8vw, 100px) clamp(24px, 5vw, 48px);
}
.eim-inner {
position: relative;
z-index: 1;
max-width: 1380px;
margin: 0 auto;
}
.eim-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.5px;
text-transform: uppercase;
color: #c8102e;
margin-bottom: 20px;
}
.eim-title {
font-size: clamp(28px, 3.4vw, 46px) !important;
font-weight: 800 !important;
letter-spacing: -0.03em !important;
line-height: 1.15 !important;
text-transform: none !important;
color: #ffffff !important;
margin: 0 0 clamp(32px, 4vw, 48px) 0;
}
.eim-divider {
border: none;
border-top: 1px solid rgba(255, 255, 255, 0.12);
margin: 0 0 clamp(40px, 5vw, 56px) 0;
}
.eim-hero-row {
display: flex;
align-items: flex-end;
gap: clamp(20px, 3vw, 36px);
margin-bottom: clamp(48px, 6vw, 72px);
}
.eim-hero-num {
font-size: clamp(90px, 13vw, 190px);
font-weight: 800;
line-height: 0.85;
letter-spacing: -0.03em;
color: transparent;
-webkit-text-stroke: 2px #c8102e;
}
.eim-hero-label {
font-size: 13px;
font-weight: 700;
letter-spacing: 1.5px;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.55);
max-width: 90px;
line-height: 1.4;
padding-bottom: clamp(12px, 1.5vw, 24px);
}
.eim-divider-2 {
border: none;
border-top: 1px solid rgba(255, 255, 255, 0.12);
margin: 0 0 clamp(40px, 5vw, 56px) 0;
}
.eim-secondary-row {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.eim-secondary-item {
padding-right: 24px;
border-left: 1px solid rgba(255, 255, 255, 0.12);
padding-left: 24px;
}
.eim-secondary-item:first-child {
border-left: none;
padding-left: 0;
}
.eim-secondary-num {
display: block;
font-size: clamp(32px, 3vw, 44px);
font-weight: 800;
color: #ff5470;
letter-spacing: -0.02em;
margin-bottom: 10px;
}
.eim-secondary-label {
font-size: 13px;
font-weight: 600;
color: rgba(255, 255, 255, 0.5);
line-height: 1.4;
}
.eim-copy {
max-width: 720px;
margin-top: clamp(48px, 6vw, 72px);
font-size: 15.5px;
line-height: 1.7;
color: rgba(255, 255, 255, 0.55);
}
@media (max-width: 1024px) {
.eim-section { width: calc(100% - 24px); border-radius: 22px; }
}
@media (max-width: 700px) {
.eim-hero-row { align-items: flex-start; flex-direction: column; gap: 12px; }
.eim-hero-label { padding-bottom: 0; max-width: none; }
.eim-secondary-row { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 28px; }
.eim-secondary-item:nth-child(3) { border-left: none; padding-left: 0; }
}
@media (max-width: 460px) {
.eim-section { padding-top: 48px; padding-bottom: 48px; }
}
`,
}}
/>
<section className="eim-section" id="wings-empowerment-impact">
<div className="eim-inner dm-section-container">
<ScrollReveal delay={0.05} duration={0.75} yOffset={20}>
<div className="eim-eyebrow">/ Our Impact /</div>
<h2 className="eim-title">Growth we can measure</h2>
</ScrollReveal>
<hr className="eim-divider" />
<ScrollReveal delay={0.08} duration={0.8} yOffset={20} className="eim-hero-row">
<span className="eim-hero-num">
<CountUp end={500} suffix="+" duration={2.2} triggerOnce />
</span>
<span className="eim-hero-label">Women-Led Enterprises In The Ecosystem</span>
</ScrollReveal>
<hr className="eim-divider-2" />
<ScrollReveal delay={0.1} duration={0.8} yOffset={20}>
<div className="eim-secondary-row">
{SECONDARY_STATS.map((s) => (
<div className="eim-secondary-item" key={s.label}>
<span className="eim-secondary-num">
{s.isCount ? <CountUp end={s.end as number} suffix={s.suffix} duration={2} triggerOnce /> : s.value}
</span>
<span className="eim-secondary-label">{s.label}</span>
</div>
))}
</div>
</ScrollReveal>
<ScrollReveal delay={0.12} duration={0.75} yOffset={20} className="eim-copy">
<p>
Every number on this page represents a woman who walked into a room with an idea and
walked out with a business. An enterprise launched, a partnership secured, a market entered each is a
marker of real economic impact, not a statistic collected for its own sake.
</p>
</ScrollReveal>
</div>
</section>
</>
);
}

View File

@@ -0,0 +1,290 @@
import Link from "next/link";
import { ScrollReveal } from "@/animations/Reveal";
const PARTNER_TYPES = [
{
title: "Industry Partners",
desc: "Strategic alliances with logistics operators, supply chain leaders, and distribution networks that open doors for women-led enterprises.",
},
{
title: "Technology Partners",
desc: "Platforms, tools, and infrastructure that give founders the operational edge to compete and scale efficiently.",
},
{
title: "Community Networks",
desc: "Founder communities, women's business networks, and ecosystem builders who extend reach and amplify impact.",
},
{
title: "Investment Partners",
desc: "Funding access, grant programs, angel networks, and capital partners aligned with women-led enterprise growth.",
},
];
export default function EmpowermentPartners() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.epn-section {
position: relative;
width: calc(100% - 40px);
margin: clamp(24px, 4vw, 40px) auto;
border-radius: 28px;
overflow: hidden;
box-sizing: border-box;
background: #09090b;
padding: clamp(68px, 8vw, 112px) 0;
}
.epn-section::before {
content: "";
position: absolute;
inset: 0;
background:
linear-gradient(120deg, rgba(9, 9, 11, 0.98) 0%, rgba(9, 9, 11, 0.88) 54%, rgba(192, 18, 39, 0.18) 100%),
url("/images/wings-heroslider3.png");
background-size: cover;
background-position: center 70%;
opacity: 1;
}
.epn-inner {
position: relative;
z-index: 1;
max-width: 1380px;
margin: 0 auto;
}
.epn-head {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-bottom: clamp(50px, 7vw, 84px);
}
.epn-head-reveal {
width: 100%;
}
.epn-divider {
width: 100%;
height: 1px;
margin: 18px 0 clamp(24px, 3.5vw, 40px) 0;
border: none;
background-color: rgba(255, 255, 255, 0.16);
}
.epn-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.5px;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.52);
}
.epn-title {
max-width: 930px;
font-size: clamp(42px, 6.3vw, 90px) !important;
font-weight: 800 !important;
letter-spacing: -0.055em !important;
line-height: 0.98 !important;
text-transform: uppercase !important;
color: #ffffff !important;
margin: 0;
}
.epn-title em {
color: #ff5470;
font-style: normal;
}
.epn-body {
display: grid;
grid-template-columns: minmax(280px, 0.46fr) minmax(0, 1fr);
gap: clamp(32px, 5vw, 72px);
align-items: stretch;
}
.epn-manifesto {
border-left: 4px solid #c8102e;
padding-left: clamp(22px, 3vw, 36px);
align-self: start;
}
.epn-intro {
font-size: clamp(22px, 2.5vw, 36px);
font-weight: 800;
line-height: 1.12;
letter-spacing: -0.035em;
color: #ffffff;
margin: 0 0 22px;
}
.epn-note {
font-size: 15.5px;
line-height: 1.68;
color: rgba(255, 255, 255, 0.62);
margin: 0;
max-width: 38ch;
}
.epn-grid {
display: flex;
flex-direction: column;
border-top: 1px solid rgba(255, 255, 255, 0.16);
}
.epn-card {
position: relative;
display: grid;
grid-template-columns: 70px minmax(0, 1fr) 32px;
align-items: center;
gap: clamp(18px, 3vw, 40px);
padding: clamp(22px, 2.6vw, 32px) clamp(4px, 1vw, 16px);
border-bottom: 1px solid rgba(255, 255, 255, 0.16);
border-left: 2px solid transparent;
transition: border-color 0.3s ease, padding-left 0.3s ease, background-color 0.3s ease;
}
.epn-card:hover {
border-left-color: #c8102e;
background: rgba(200, 16, 46, 0.06);
padding-left: clamp(20px, 2.5vw, 32px);
}
.epn-card-index {
font-size: 15px;
font-weight: 900;
color: rgba(255, 255, 255, 0.35);
}
.epn-card-title {
font-size: clamp(22px, 2.2vw, 30px) !important;
font-weight: 900 !important;
line-height: 1.1 !important;
letter-spacing: -0.03em !important;
text-transform: none !important;
color: #ffffff !important;
margin: 0 0 8px;
}
.epn-card-desc {
max-width: 46ch;
font-size: 14.5px;
line-height: 1.6;
color: rgba(255, 255, 255, 0.58);
margin: 0;
}
.epn-card-arrow {
display: flex;
color: rgba(255, 255, 255, 0.3);
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), color 0.3s ease;
}
.epn-card:hover .epn-card-arrow {
transform: translateX(4px);
color: #ff5470;
}
.epn-cta {
margin-top: clamp(42px, 5vw, 64px);
}
.epn-cta-btn {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 16px 36px;
border-radius: 100px;
background: #c01227;
color: #ffffff !important;
font-weight: 800;
font-size: 15px;
text-decoration: none !important;
transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s ease;
}
.epn-cta-btn:hover {
transform: translateY(-3px);
box-shadow: 0 14px 30px rgba(192, 18, 39, 0.35);
}
@media (max-width: 1024px) {
.epn-section { width: calc(100% - 24px); border-radius: 22px; }
}
@media (max-width: 900px) {
.epn-head,
.epn-body { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
.epn-title {
font-size: clamp(34px, 10vw, 40px) !important;
letter-spacing: -0.045em !important;
overflow-wrap: anywhere;
}
.epn-card {
grid-template-columns: 44px minmax(0, 1fr);
}
.epn-card-arrow { display: none; }
}
@media (max-width: 460px) {
.epn-section { padding-top: 54px; padding-bottom: 54px; }
}
`,
}}
/>
<section className="epn-section" id="wings-empowerment-partners">
<div className="dm-section-container">
<div className="epn-inner">
<div className="epn-head">
<ScrollReveal delay={0.05} duration={0.75} yOffset={20} className="epn-head-reveal">
<div className="epn-eyebrow">/ Collaboration /</div>
<hr className="epn-divider" />
</ScrollReveal>
<ScrollReveal delay={0.1} duration={0.85} yOffset={24}>
<h2 className="epn-title">Partnership is how <em>ecosystems grow.</em></h2>
</ScrollReveal>
</div>
<div className="epn-body">
<ScrollReveal delay={0.08} duration={0.8} yOffset={22} className="epn-manifesto">
<p className="epn-intro">The strongest ecosystems are built by many hands.</p>
<p className="epn-note">
Wings partners bring industry access, strategic infrastructure, capital, and networks. Together, we build the foundation women-led enterprises need to thrive.
</p>
{/* <div className="epn-cta">
<Link href="/contact" className="epn-cta-btn">Become a Partner</Link>
</div> */}
</ScrollReveal>
<ScrollReveal delay={0.12} duration={0.8} yOffset={22}>
<div className="epn-grid">
{PARTNER_TYPES.map((p, i) => (
<article className="epn-card" key={p.title}>
<span className="epn-card-index">{String(i + 1).padStart(2, "0")}</span>
<div>
<h3 className="epn-card-title">{p.title}</h3>
<p className="epn-card-desc">{p.desc}</p>
</div>
<span className="epn-card-arrow" aria-hidden="true">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round">
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</span>
</article>
))}
</div>
</ScrollReveal>
</div>
</div>
</div>
</section>
</>
);
}

View File

@@ -0,0 +1,405 @@
import Link from "next/link";
import { ScrollReveal } from "@/animations/Reveal";
import IndustryWorldMap from "./IndustryWorldMap";
const PROGRAMS = [
{
title: "Venture Launchpad",
desc: "Business model validation, market entry strategy, entity formation, and go-to-market execution for women-led logistics enterprises.",
type: "Start building",
},
{
title: "Strategic Partnerships",
desc: "Direct access to supply chain networks, B2B relationships, industry alliances, and commercial agreements that accelerate growth.",
type: "Connect and grow",
},
{
title: "Founder Mentorship",
desc: "One-on-one guidance from established entrepreneurs, operators, and investors who understand what it takes to scale.",
type: "Learn from builders",
},
{
title: "Growth & Scale",
desc: "Operational expansion frameworks, team building, funding readiness, and sustainable unit economics for ventures ready to grow.",
type: "Scale with confidence",
},
{
title: "Industry Immersion",
desc: "Real exposure to logistics operations, supply chain infrastructure, and distribution networks before founders commit to a vertical.",
type: "See the opportunity",
},
];
export default function EmpowermentPrograms() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.epr-section {
background: #ffffff;
padding: clamp(78px, 9vw, 132px) 0;
overflow: visible;
}
.epr-inner {
max-width: 1380px;
min-width: 0;
margin: 0 auto;
}
.epr-head {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-bottom: clamp(54px, 7vw, 86px);
}
.epr-head-reveal {
width: 100%;
}
.epr-divider {
width: 100%;
height: 1px;
margin: 18px 0 clamp(24px, 3.5vw, 40px) 0;
border: none;
background-color: rgba(17, 17, 17, 0.14);
}
.epr-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.4px;
text-transform: uppercase;
color: rgba(17, 17, 17, 0.42);
}
.epr-title {
max-width: 950px;
font-size: clamp(42px, 6.2vw, 88px) !important;
font-weight: 800 !important;
letter-spacing: -0.055em !important;
line-height: 0.98 !important;
text-transform: uppercase !important;
color: #111111 !important;
margin: 0;
}
.epr-stage {
display: grid;
grid-template-columns: minmax(300px, 0.38fr) minmax(0, 0.62fr);
gap: clamp(32px, 5vw, 78px);
align-items: start;
min-width: 0;
}
.epr-stage > * {
min-width: 0;
}
.epr-aside {
position: sticky;
top: 110px;
min-width: 0;
min-height: clamp(480px, 44vw, 660px);
padding: clamp(18px, 3vw, 34px) 0 clamp(24px, 3.5vw, 42px);
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
color: #111111;
}
.epr-aside-map {
position: absolute;
inset: 8% -22% 8% -28%;
z-index: 0;
opacity: 0.22;
pointer-events: none;
}
.epr-aside-map canvas {
display: block;
}
.epr-aside-content {
position: relative;
z-index: 1;
display: grid;
gap: clamp(18px, 2.2vw, 28px);
}
.epr-aside-num {
position: relative;
font-size: clamp(164px, 17vw, 300px);
font-weight: 900;
line-height: 0.78;
letter-spacing: -0.06em;
color: transparent;
-webkit-text-stroke: 2px rgba(200, 16, 46, 0.2);
}
.epr-aside-copy {
position: relative;
max-width: 12ch;
font-size: clamp(30px, 3.6vw, 56px);
font-weight: 800;
line-height: 0.98;
letter-spacing: -0.055em;
text-transform: uppercase;
color: #111111;
margin: 0;
}
.epr-aside-copy em {
font-style: normal;
color: #c8102e;
}
.epr-aside-desc {
position: relative;
max-width: 34ch;
font-size: 15.5px;
line-height: 1.65;
color: rgba(17, 17, 17, 0.58);
margin: 0;
}
.epr-list {
display: grid;
gap: clamp(28px, 4vw, 52px);
}
.epr-row {
display: grid;
grid-template-columns: 110px minmax(0, 1fr);
gap: clamp(22px, 4vw, 58px);
padding-bottom: clamp(28px, 4vw, 52px);
border-bottom: 1px solid rgba(17, 17, 17, 0.14);
}
.epr-row:nth-child(even) {
margin-left: clamp(0px, 7vw, 96px);
}
.epr-row-index {
font-size: clamp(38px, 4.2vw, 62px);
font-weight: 900;
line-height: 1;
letter-spacing: -0.05em;
color: #c8102e;
}
.epr-row-featured {
padding: clamp(28px, 4vw, 44px) clamp(24px, 3vw, 40px);
background: #09090b;
border-radius: 22px;
border-bottom: none;
margin-bottom: clamp(28px, 4vw, 52px);
}
.epr-row-featured .epr-row-index {
color: rgba(255, 255, 255, 0.22);
-webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.5);
}
.epr-row-featured .epr-row-title {
font-size: clamp(32px, 4vw, 64px) !important;
color: #ffffff !important;
}
.epr-row-featured .epr-row-desc {
color: rgba(255, 255, 255, 0.62);
}
.epr-row-flag {
display: inline-block;
font-size: 12px;
font-weight: 800;
letter-spacing: 1.3px;
text-transform: uppercase;
color: #ffffff;
background: #c8102e;
padding: 6px 14px;
border-radius: 100px;
margin-bottom: 16px;
}
.epr-row-type {
display: block;
font-size: 12px;
font-weight: 800;
letter-spacing: 1.7px;
text-transform: uppercase;
color: rgba(17, 17, 17, 0.42);
margin-bottom: 14px;
}
.epr-row-featured .epr-row-type {
color: rgba(255, 255, 255, 0.42);
}
.epr-row-title {
font-size: clamp(28px, 3.4vw, 52px) !important;
font-weight: 800 !important;
letter-spacing: -0.045em !important;
line-height: 1.02 !important;
text-transform: uppercase !important;
color: #111111 !important;
margin: 0 0 14px 0;
}
.epr-row-desc {
max-width: 660px;
font-size: 15.5px;
line-height: 1.65;
color: rgba(17, 17, 17, 0.58);
margin: 0;
}
.epr-cta {
margin-top: clamp(48px, 6vw, 72px);
}
.epr-cta-link {
display: inline-flex;
align-items: center;
gap: 10px;
font-size: 15px;
font-weight: 800;
color: #111111 !important;
text-decoration: none !important;
border-bottom: 1.5px solid rgba(17, 17, 17, 0.2);
padding-bottom: 5px;
transition: border-color 0.3s ease, color 0.3s ease;
}
.epr-cta-link:hover {
color: #c8102e !important;
border-color: #c8102e;
}
/* Laptop: sticky stays enabled, just a narrower gutter. */
@media (max-width: 1180px) {
.epr-stage { grid-template-columns: minmax(220px, 0.34fr) minmax(0, 0.66fr); gap: clamp(28px, 4vw, 46px); }
.epr-aside { min-height: 420px; }
.epr-row:nth-child(even) { margin-left: 0; }
}
/* Tablet: sticky disabled — the aside scrolls in normal flow instead
of pinning, since there's no longer enough vertical runway next to
the (now narrower, shorter) program list for pinning to read well. */
@media (max-width: 1023px) {
.epr-aside {
position: relative;
top: auto;
}
}
@media (max-width: 767px) {
.epr-stage { grid-template-columns: 1fr; }
.epr-aside {
position: relative;
top: auto;
min-height: 300px;
padding-top: 4px;
padding-bottom: clamp(24px, 7vw, 38px);
}
.epr-aside-map {
inset: -8% -18% 0 -20%;
opacity: 0.18;
}
.epr-aside-content {
gap: 20px;
}
.epr-aside-num {
font-size: clamp(128px, 34vw, 180px);
}
.epr-aside-copy {
max-width: 11ch;
font-size: clamp(34px, 10vw, 48px);
}
.epr-aside-desc {
max-width: 32ch;
font-size: 14.5px;
}
}
@media (max-width: 640px) {
.epr-section { padding-top: 54px; padding-bottom: 54px; }
.epr-title {
font-size: clamp(34px, 10vw, 40px) !important;
letter-spacing: -0.045em !important;
overflow-wrap: anywhere;
}
.epr-row-title {
font-size: clamp(27px, 8.5vw, 36px) !important;
overflow-wrap: anywhere;
}
.epr-row { grid-template-columns: 1fr; gap: 12px; }
}
`,
}}
/>
<section className="epr-section" id="wings-empowerment-programs">
<div className="dm-section-container">
<div className="epr-inner">
<div className="epr-head">
<ScrollReveal delay={0.05} duration={0.75} yOffset={20} className="epr-head-reveal">
<div className="epr-eyebrow">/ Entrepreneurship Pillars /</div>
<hr className="epr-divider" />
</ScrollReveal>
<ScrollReveal delay={0.1} duration={0.85} yOffset={24}>
<h2 className="epr-title">Every pillar is built around ownership.</h2>
</ScrollReveal>
</div>
<div className="epr-stage">
<aside className="epr-aside">
<div className="epr-aside-map" aria-hidden="true">
<IndustryWorldMap />
</div>
<ScrollReveal delay={0.05} duration={0.8} yOffset={24} className="epr-aside-content">
<div className="epr-aside-num">05</div>
<p className="epr-aside-copy">Building tomorrow&rsquo;s <em>women entrepreneurs.</em></p>
<p className="epr-aside-desc">
Every enterprise starts with one decision. Our pillars move women from idea to ownership through mentorship, real industry partnerships, and hands-on venture building across the logistics ecosystem.
</p>
</ScrollReveal>
</aside>
<div>
<ScrollReveal delay={0.1} duration={0.8} yOffset={24}>
<div className="epr-list">
{PROGRAMS.map((p, i) => (
<article className={`epr-row${i === 0 ? " epr-row-featured" : ""}`} key={p.title}>
<div className="epr-row-index">{String(i + 1).padStart(2, "0")}</div>
<div>
{i === 0 && <span className="epr-row-flag">Where most founders begin</span>}
<span className="epr-row-type">{p.type}</span>
<h3 className="epr-row-title">{p.title}</h3>
<p className="epr-row-desc">{p.desc}</p>
</div>
</article>
))}
</div>
</ScrollReveal>
<div className="epr-cta">
<Link href="/contact" className="epr-cta-link">
Start your venture
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.25" strokeLinecap="round" strokeLinejoin="round">
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</Link>
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
}

View File

@@ -0,0 +1,335 @@
import Image from "next/image";
import { ScrollReveal } from "@/animations/Reveal";
export default function EmpowermentStories() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.est-section {
position: relative;
background: #ffffff;
padding-top: clamp(24px, 3vw, 48px);
padding-bottom: clamp(78px, 9vw, 132px);
overflow: hidden;
}
.est-inner {
max-width: 1380px;
margin: 0 auto;
}
.est-head {
display: flex;
flex-direction: column;
align-items: flex-start;
margin-bottom: clamp(54px, 7vw, 86px);
}
.est-head-reveal {
width: 100%;
}
.est-divider {
width: 100%;
height: 1px;
margin: 18px 0 clamp(24px, 3.5vw, 40px) 0;
border: none;
background-color: rgba(17, 17, 17, 0.14);
}
.est-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.4px;
text-transform: uppercase;
color: rgba(17, 17, 17, 0.42);
}
.est-title {
max-width: 940px;
font-size: clamp(42px, 6.3vw, 90px) !important;
font-weight: 800 !important;
letter-spacing: -0.055em !important;
line-height: 0.98 !important;
text-transform: uppercase !important;
color: #111111 !important;
margin: 0;
}
.est-feature {
display: grid;
grid-template-columns: minmax(0, 0.94fr) minmax(340px, 0.64fr);
gap: clamp(28px, 4vw, 62px);
align-items: stretch;
margin-bottom: clamp(44px, 6vw, 76px);
}
.est-photo {
position: relative;
min-height: clamp(460px, 48vw, 680px);
border-radius: 26px;
overflow: hidden;
background: #09090b;
}
.est-photo img {
object-fit: cover;
object-position: center;
}
.est-photo::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgba(9, 9, 11, 0) 34%, rgba(9, 9, 11, 0.72) 100%);
pointer-events: none;
}
.est-photo-caption {
position: absolute;
left: clamp(24px, 3vw, 42px);
right: clamp(24px, 3vw, 42px);
bottom: clamp(24px, 3vw, 42px);
z-index: 1;
color: #ffffff;
}
.est-photo-caption span {
display: block;
font-size: 12px;
font-weight: 800;
letter-spacing: 1.7px;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.6);
margin-bottom: 8px;
}
.est-photo-caption strong {
display: block;
font-size: clamp(24px, 3vw, 42px);
font-weight: 900;
line-height: 1.02;
letter-spacing: -0.04em;
}
.est-copy {
border-radius: 26px;
background: #09090b;
color: #ffffff;
padding: clamp(34px, 5vw, 62px);
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
position: relative;
}
.est-copy::before {
content: "";
position: absolute;
width: 320px;
height: 320px;
right: -120px;
top: -120px;
background: radial-gradient(circle, rgba(200, 16, 46, 0.42), transparent 68%);
pointer-events: none;
}
.est-quote-mark {
position: relative;
font-family: Georgia, serif;
font-size: 92px;
line-height: 0.8;
color: #c8102e;
display: block;
margin-bottom: 20px;
}
.est-quote-text {
position: relative;
font-size: clamp(25px, 3vw, 44px);
font-weight: 800;
line-height: 1.12;
letter-spacing: -0.04em;
color: #ffffff;
margin: 0 0 28px 0;
}
.est-narrative {
position: relative;
font-size: 15.5px;
line-height: 1.68;
color: rgba(255, 255, 255, 0.66);
margin: 0;
max-width: 46ch;
}
.est-person {
position: relative;
padding-top: clamp(38px, 5vw, 64px);
}
.est-person-name {
font-size: 18px;
font-weight: 900;
color: #ffffff;
}
.est-person-role {
font-size: 13.5px;
color: rgba(255, 255, 255, 0.52);
margin-top: 3px;
}
.est-list-label {
font-size: 12px;
font-weight: 800;
letter-spacing: 1.8px;
text-transform: uppercase;
color: rgba(17, 17, 17, 0.42);
padding-top: clamp(24px, 3vw, 38px);
border-top: 1px solid rgba(17, 17, 17, 0.14);
margin-bottom: clamp(20px, 3vw, 30px);
}
.est-list {
display: flex;
gap: 18px;
overflow-x: auto;
scroll-snap-type: x mandatory;
padding-bottom: 12px;
margin-bottom: clamp(6px, 1vw, 10px);
-webkit-overflow-scrolling: touch;
}
.est-list::-webkit-scrollbar {
height: 4px;
}
.est-list::-webkit-scrollbar-thumb {
background: rgba(17, 17, 17, 0.18);
border-radius: 100px;
}
.est-row {
scroll-snap-align: start;
flex: 0 0 clamp(260px, 30vw, 340px);
min-height: 220px;
padding: clamp(24px, 2.6vw, 32px);
border: 1px solid rgba(17, 17, 17, 0.14);
border-radius: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
transition: border-color 0.3s ease, transform 0.3s ease;
}
.est-row:hover {
border-color: rgba(200, 16, 46, 0.4);
transform: translateY(-4px);
}
.est-row-name {
font-size: 20px;
font-weight: 900;
color: #111111;
}
.est-row-role {
font-size: 13px;
font-weight: 800;
letter-spacing: 1.4px;
text-transform: uppercase;
color: #c8102e;
margin-top: 6px;
}
.est-row-line {
font-size: 15px;
line-height: 1.6;
color: rgba(17, 17, 17, 0.62);
margin: 28px 0 0;
}
@media (max-width: 1000px) {
.est-head,
.est-feature { grid-template-columns: 1fr; }
.est-row {
min-height: 0;
flex-basis: 78vw;
}
}
@media (max-width: 640px) {
.est-section { padding-top: 54px; padding-bottom: 54px; }
.est-title {
font-size: clamp(34px, 10vw, 40px) !important;
letter-spacing: -0.045em !important;
overflow-wrap: anywhere;
}
.est-quote-text {
font-size: clamp(25px, 8vw, 34px);
overflow-wrap: anywhere;
}
.est-photo,
.est-copy { border-radius: 20px; }
.est-photo { min-height: 420px; }
}
`,
}}
/>
<section className="est-section" id="wings-empowerment-stories">
<div className="dm-section-container">
<div className="est-inner">
<div className="est-head">
<ScrollReveal delay={0.05} duration={0.75} yOffset={20} className="est-head-reveal">
<div className="est-eyebrow">/ Women in Motion /</div>
<hr className="est-divider" />
</ScrollReveal>
<ScrollReveal delay={0.1} duration={0.85} yOffset={24}>
<h2 className="est-title">Small steps. Lasting careers.</h2>
</ScrollReveal>
</div>
<div className="est-feature">
<ScrollReveal delay={0.05} duration={0.85} yOffset={24} className="est-photo">
<Image
src="/images/women-hero-slider-3.png"
alt="A Wings program participant on the operations floor at a Doormile logistics hub"
fill
sizes="(max-width: 1000px) 100vw, 58vw"
style={{ objectPosition: "80% 22%" }}
/>
<div className="est-photo-caption">
<span>Wings Participant</span>
<strong> building a career, one milestone at a time.</strong>
</div>
</ScrollReveal>
<ScrollReveal delay={0.12} duration={0.85} yOffset={24} className="est-copy">
<div>
<span className="est-quote-mark" aria-hidden="true">&ldquo;</span>
<p className="est-quote-text">I came in looking for a way forward. I found the confidence to lead.</p>
<p className="est-narrative">
She started with limited exposure to logistics. Through structured training, mentorship, and hands-on experience, she built real operational skills and now supports other women stepping into the industry.
</p>
</div>
{/* <div className="est-person">
<div className="est-person-name">Kavya</div>
<div className="est-person-role">Logistics Coordinator, Wings Program</div>
</div> */}
</ScrollReveal>
</div>
</div>
</div>
</section>
</>
);
}

View File

@@ -0,0 +1,164 @@
import { ScrollReveal } from "@/animations/Reveal";
export default function EmpowermentStory() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.esy-section {
position: relative;
width: calc(100% - 40px);
margin: 0 auto clamp(24px, 4vw, 40px);
border-radius: 28px;
overflow: hidden;
box-sizing: border-box;
min-height: clamp(500px, 50vw, 690px);
display: flex;
align-items: stretch;
background: #09090b;
}
.esy-bg {
position: absolute;
inset: 0;
background-image:
linear-gradient(100deg, rgba(9, 9, 11, 0.96) 0%, rgba(9, 9, 11, 0.84) 43%, rgba(192, 18, 39, 0.28) 100%),
url("/images/wings-heroslider4.png");
background-size: cover;
background-position: center;
z-index: 0;
}
.esy-inner {
position: relative;
z-index: 1;
max-width: 1380px;
margin: 0 auto;
width: 100%;
padding-top: clamp(60px, 7vw, 98px);
padding-bottom: clamp(60px, 7vw, 98px);
display: grid;
grid-template-columns: minmax(0, 0.9fr) minmax(280px, 0.52fr);
gap: clamp(36px, 6vw, 96px);
align-items: end;
}
.esy-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.5px;
text-transform: uppercase;
color: #ff5470;
margin-bottom: 24px;
}
.esy-statement {
max-width: 920px;
font-size: clamp(38px, 5.7vw, 86px);
font-weight: 800;
letter-spacing: -0.055em;
line-height: 0.98;
text-transform: uppercase;
color: #ffffff;
margin: 0;
}
.esy-statement em {
color: #ff5470;
font-style: normal;
}
.esy-side {
border-left: 1px solid rgba(255, 255, 255, 0.18);
padding-left: clamp(24px, 3vw, 42px);
}
.esy-label {
display: block;
font-size: 12px;
font-weight: 800;
letter-spacing: 1.8px;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.45);
margin-bottom: 18px;
}
.esy-pull {
font-size: clamp(22px, 2.3vw, 34px);
font-weight: 800;
line-height: 1.16;
letter-spacing: -0.03em;
color: #ffffff;
margin: 0 0 22px 0;
}
.esy-sub {
font-size: 15.5px;
line-height: 1.65;
color: rgba(255, 255, 255, 0.64);
margin: 0;
}
/* ---- Desktop-only inner spacing compaction ----
.esy-section never set its own padding, so it was silently
inheriting 96px top/bottom from the global bare-tag "section"
padding rule (6rem 0) in site.css — stacking with .esy-inner's
own clamp(60-98px) padding into a huge, unbalanced inset. Cancel
that leak here. Also tighten .esy-inner's own padding and widen its
max-width (so a fixed padding, not a narrow centered column,
controls the left/right inset at every desktop width) — and bring
min-height down to match the now-tighter natural content height,
since the old 690px floor was itself forcing extra empty space
once the padding was reduced. Scoped to desktop only; tablet/
mobile keep their original spacing untouched below. */
@media (min-width: 1025px) {
.esy-section {
padding: 0;
min-height: clamp(420px, 38vw, 500px);
}
.esy-inner {
max-width: 1900px;
padding-top: 64px;
padding-bottom: 56px;
padding-left: 64px;
padding-right: 64px;
}
}
@media (max-width: 1024px) {
.esy-section { width: calc(100% - 24px); border-radius: 22px; }
.esy-inner { grid-template-columns: 1fr; align-items: start; }
.esy-side { max-width: 640px; }
}
@media (max-width: 640px) {
.esy-section { min-height: 560px; }
.esy-side { border-left: none; padding-left: 0; border-top: 1px solid rgba(255, 255, 255, 0.18); padding-top: 24px; }
}
`,
}}
/>
<section className="esy-section" id="wings-empowerment-story">
<div className="esy-bg" aria-hidden="true" />
<div className="esy-inner dm-section-container">
<ScrollReveal delay={0.05} duration={0.85} yOffset={25}>
<div className="esy-eyebrow">/ Our Approach /</div>
<p className="esy-statement">
Not a program on a brochure. <em>An ecosystem women can build in.</em>
</p>
</ScrollReveal>
<ScrollReveal delay={0.15} duration={0.8} yOffset={25} className="esy-side">
<span className="esy-label">Manifesto</span>
<p className="esy-pull">A venture that starts with conviction. A network that turns it into momentum.</p>
<p className="esy-sub">
Wings is designed around the moments that define a founder: the first partnership signed, the first client won, the first team hired, the first enterprise scaled.
</p>
</ScrollReveal>
</div>
</section>
</>
);
}

View File

@@ -0,0 +1,215 @@
import { ScrollReveal } from "@/animations/Reveal";
import IndustryWorldMap from "./IndustryWorldMap";
export default function EmpowermentVision() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.ev-section {
position: relative;
background: #ffffff;
padding: clamp(96px, 11vw, 150px) 0;
overflow: hidden;
}
.ev-map {
position: absolute;
inset: 0;
z-index: 0;
opacity: 0.4;
pointer-events: none;
}
.ev-inner {
position: relative;
z-index: 1;
max-width: 1380px;
min-width: 0;
margin: 0 auto;
}
.ev-eyebrow {
margin: 0 0 18px 0;
font-size: 14px;
font-weight: 500;
letter-spacing: 1.5px;
color: rgba(17, 17, 17, 0.6);
}
.ev-divider {
width: 100%;
height: 1px;
margin: 0 0 clamp(64px, 7.8vw, 92px) 0;
border: none;
background-color: rgba(17, 17, 17, 0.16);
}
.ev-title {
margin: 0 0 clamp(92px, 11.5vw, 156px) 0 !important;
max-width: 1320px;
display: block;
font-weight: 800 !important;
font-style: normal !important;
letter-spacing: -0.018em !important;
word-spacing: 0.02em;
line-height: 1.04em !important;
text-transform: none !important;
color: #ffffff !important;
-webkit-text-stroke: 2px #c01227;
paint-order: stroke fill;
font-size: clamp(48px, 8.5vw, 128px) !important;
white-space: normal;
overflow-wrap: normal;
text-wrap: balance;
}
@media (max-width: 1280px) {
.ev-title {
font-size: 118px !important;
}
}
@media (max-width: 1020px) {
.ev-title {
font-size: 96px !important;
}
}
@media (max-width: 767px) {
.ev-title {
font-size: 72px !important;
}
}
.ev-columns {
display: grid;
grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr);
gap: clamp(60px, 8vw, 122px);
align-items: start;
}
.ev-columns > * {
min-width: 0;
}
.ev-statement {
margin: 0;
font-size: clamp(28px, 3vw, 52px);
font-weight: 600;
line-height: 1.2;
letter-spacing: -0.03em;
color: #111111;
overflow-wrap: break-word;
}
.ev-support {
display: grid;
gap: clamp(34px, 3.8vw, 52px);
min-width: 0;
}
.ev-block {
display: grid;
gap: 12px;
}
.ev-block-label {
margin: 0;
font-size: 12px;
font-weight: 700;
letter-spacing: 1.4px;
line-height: 1;
text-transform: uppercase;
color: rgba(192, 18, 39, 0.86);
}
.ev-lead,
.ev-note {
font-size: clamp(17px, 1.3vw, 20px);
line-height: 1.6;
color: #333333;
margin: 0;
overflow-wrap: break-word;
}
.ev-lead {
font-weight: 700;
}
.ev-note {
font-weight: 400;
}
@media (max-width: 900px) {
.ev-columns {
grid-template-columns: 1fr;
}
}
@media (max-width: 600px) {
.ev-section { padding-top: 64px; padding-bottom: 64px; }
.ev-title {
max-width: calc(100vw - (var(--dm-mobile-gutter, 10px) * 2));
font-size: 56px !important;
letter-spacing: -0.025em !important;
line-height: 1.02em !important;
-webkit-text-stroke-width: 1.5px;
}
}
`,
}}
/>
<section className="ev-section" id="wings-empowerment-vision">
<div className="ev-map" aria-hidden="true">
<IndustryWorldMap />
</div>
<div className="dm-section-container">
<div className="ev-inner">
<ScrollReveal delay={0.05} duration={0.7} yOffset={20}>
<p className="ev-eyebrow">/ Our Vision /</p>
<hr className="ev-divider" />
</ScrollReveal>
<ScrollReveal delay={0.12} duration={0.85} yOffset={30}>
<h2 className="ev-title">Women Own The Future.</h2>
</ScrollReveal>
<div className="ev-columns">
<ScrollReveal delay={0.18} duration={0.8} yOffset={25}>
<p className="ev-statement">
A logistics ecosystem where women don&rsquo;t just participate &mdash; they own, build, and lead.
</p>
</ScrollReveal>
<ScrollReveal delay={0.26} duration={0.8} yOffset={25} className="ev-support">
<div className="ev-block">
<p className="ev-block-label">The vision</p>
<p className="ev-lead">
We are building an entrepreneurial ecosystem where women launch enterprises, scale operations, and shape the future of logistics from the inside.
</p>
</div>
<div className="ev-block">
<p className="ev-block-label">Why it matters</p>
<p className="ev-note">
Industries transform when founders emerge from every corner. Women-led enterprises bring fresh perspective, operational resilience, and long-term economic impact to logistics.
</p>
</div>
<div className="ev-block">
<p className="ev-block-label">How Wings contributes</p>
<p className="ev-note">
Wings provides the infrastructure &mdash; strategic partnerships, funding access, founder networks, and industry connections &mdash; that turns ambition into enterprise.
</p>
</div>
</ScrollReveal>
</div>
</div>
</div>
</section>
</>
);
}

View File

@@ -68,7 +68,7 @@ export default function MileTruthHero() {
flex-direction: column;
justify-content: center;
border-radius: 25px 25px 0 0;
margin-top: 28px;
margin-top: 20px;
padding: 100px 0;
}
.miletruth-hero-container::before {

View File

@@ -20,10 +20,9 @@
.eyebrow {
margin: 0 0 18px 0;
font-size: 13px;
font-weight: 700;
letter-spacing: 2.5px;
text-transform: uppercase;
font-size: 14px;
font-weight: 500;
letter-spacing: 1.5px;
color: rgba(23, 20, 15, 0.6);
}
@@ -44,19 +43,33 @@
.heading {
margin: 0;
max-width: 1220px;
font-family: var(--font-syne), "Syne", sans-serif !important;
font-weight: 800 !important;
font-family: "Manrope Alt", Sans-serif !important;
font-weight: 700 !important;
font-style: normal !important;
letter-spacing: -0.03em !important;
line-height: 0.86 !important;
line-height: 1em !important;
text-transform: none !important;
color: transparent !important;
-webkit-text-stroke: 2px #c01227;
font-size: clamp(72px, 14vw, 240px) !important;
-webkit-text-stroke-width: 2px;
-webkit-text-stroke-color: #c01227;
font-size: 180px !important;
}
@media (max-width: 1020px) {
.heading {
font-size: 120px !important;
}
}
@media (max-width: 767px) {
.heading {
font-size: 80px !important;
}
}
@media (max-width: 640px) {
.heading {
font-size: 56px !important;
-webkit-text-stroke-width: 1.5px;
}
}

View File

@@ -16,8 +16,21 @@ export default function TheDoormileWay() {
<p className={styles.eyebrow}>/ Doormile Approach /</p>
<hr className={styles.divider} />
</ScrollReveal>
<ScrollReveal delay={0.15} duration={0.85} yOffset={30} className={styles.headingWrap}>
<h2 className={styles.heading}>The Doormile Way</h2>
<ScrollReveal delay={0.15} duration={0.85} yOffset={30}>
<div className="elementor-element elementor-element-1cc335a elementor-widget elementor-widget-logico_heading" data-id="1cc335a" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container">
<div
className="logico-title"
style={{
WebkitTextStroke: "4px #c01227",
color: "#fff",
fontWeight: 800,
}}
>
The Doormile Way
</div>
</div>
</div>
</ScrollReveal>
</div>
<div className="elementor-element elementor-element-4c3e632 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="4c3e632" data-element_type="container" data-e-type="container">

View File

@@ -1,121 +0,0 @@
import Link from "next/link";
export default function WingsFinalCTA() {
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
/* dm-section-container replaces the vendor .we-container class here
(which is otherwise reused verbatim on the About page CTA), so this
section's edges line up with the Footer's shared container instead
of that widget's own 1320px width. It carries no vertical margin,
so restore the same top spacing .we-container provided. */
.wfcta-container {
margin-top: 50px;
}
.wfcta-box {
position: relative;
overflow: hidden;
/* Placeholder — swap for a sourced photo/illustration with a dark
overlay once real Doormile Wings imagery exists. */
background: linear-gradient(150deg, #0b0b0d 0%, #1f1f1f 60%, #0b0b0d 100%) !important;
padding: clamp(72px, 9vw, 120px) clamp(24px, 5vw, 48px) !important;
}
.wfcta-box::before {
content: '';
position: absolute;
inset: 0;
z-index: 0;
background: radial-gradient(60% 80% at 50% 0%, rgba(200,16,46,0.18) 0%, transparent 70%);
pointer-events: none;
}
.wfcta-box .we-cta-inner {
position: relative;
z-index: 1;
}
.wfcta-title {
font-size: clamp(32px, 4.5vw, 60px) !important;
color: #ffffff !important;
}
.wfcta-title em {
color: #ffffff !important;
}
.wfcta-sub {
max-width: 640px;
margin-left: auto !important;
margin-right: auto !important;
}
@media (max-width: 768px) {
.wfcta-container {
/* Raised to dominate the collapsed margin with the previous
section (Roadmap's own 24px bottom margin) so the gap above
the CTA card reads the same as the gap below it. */
margin-top: 14px !important;
/* There's ~110px of unexplained extra space rendered between this
container and the Footer that follows on mobile (verified with
Playwright — no element/padding/margin in the DOM accounts for
it, so it isn't coming from either section's own box). Pulling
the CTA up with a negative bottom margin closes most of that
gap directly instead of chasing the underlying cause, without
touching the shared Footer component (used on every page) or
either card's internal padding. Tuned so the resulting visible
gap below the card matches the ~44px gap above it. */
margin-bottom: -96px !important;
padding: 0 10px !important;
}
.wfcta-box {
/* Vertical padding cut ~25% (48px -> 36px) to close the excessive
gap above the heading and below the button on mobile — the
card felt loose relative to the rest of the Wings page.
Horizontal padding/border-radius/width untouched. */
padding: 36px 20px !important;
border-radius: 22px !important;
}
.wfcta-title {
font-size: clamp(28px, 6vw, 38px) !important;
line-height: 1.25 !important;
margin-bottom: 16px !important;
}
.wfcta-sub {
font-size: 15px !important;
line-height: 1.5 !important;
margin-bottom: 24px !important;
}
}
`,
}}
/>
<div className="dm-section-container wfcta-container" id="wings-final-cta">
<div className="we-cta wfcta-box">
<div className="we-cta-inner">
<h2 className="we-cta-title wfcta-title">
Ready to move at<br />
<em>the speed of now?</em>
</h2>
<p className="we-cta-sub wfcta-sub">
Partner with Doormile Wings for same-day air logistics across India&rsquo;s major
regional capitals.
</p>
<div className="we-cta-btns">
<Link href="/contact" className="btn-we-primary" style={{ textDecoration: "none" }}>
Get Started
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ marginLeft: "8px", display: "inline-block", verticalAlign: "middle" }}>
<line x1="5" y1="12" x2="19" y2="12" />
<polyline points="12 5 19 12 12 19" />
</svg>
</Link>
</div>
</div>
</div>
</div>
</>
);
}

View File

@@ -65,9 +65,8 @@ export default function WingsFleetStrategy() {
/>
<EVSection
bannerImage="/images/pahse1.png"
cardNumber="Phase 1"
cardTitle="Initial Fleet"
cardSubtitle="2x ATR72 + 1x Q400 Freighters"
cardTitle="Quick Logistics"
cardSubtitle="Same-Day Air Network"
eyebrow="/ Fleet Strategy /"
titleLead="Purpose-Built for "
titleAccent="Regional Speed"

View File

@@ -71,14 +71,14 @@ export default function WingsHero() {
return (
<>
<link rel="preload" as="image" href="/images/wings-heroslider3.png" />
<link rel="preload" as="image" href="/images/wings-heroslider4.png" />
<link rel="preload" as="image" href="/images/wings-heroslide2.png" />
<style
dangerouslySetInnerHTML={{
__html: `
.wings-hero-bg.elementor-repeater-item-3264830,
.wings-hero-bg.elementor-repeater-item-6867061 {
background-image: linear-gradient(rgba(0, 0, 0, 0.38), rgba(0, 0, 0, 0.06)), url('/images/wings-heroslider3.png') !important;
background-image: linear-gradient(rgba(0, 0, 0, 0.38), rgba(0, 0, 0, 0.06)), url('/images/wings-heroslider4.png') !important;
background-position: center !important;
background-repeat: no-repeat !important;
background-size: cover !important;
@@ -228,8 +228,7 @@ export default function WingsHero() {
@media (min-width: 1025px) {
.wings-hero-page.elementor-element-741f56c {
padding: 20px 24px !important;
margin-top: 8px !important;
padding: 20px !important;
}
.wings-hero-page .owl-carousel.owl-theme .content-item {
@@ -410,24 +409,19 @@ export default function WingsHero() {
<div className="slide-content-inner">
<h1 className="content-slider-item-heading logico-content-wrapper-1">
<span className="heading-content">
Doormile Wings
Where Quick Commerce
<br />
<ShimmerText className="font-extrabold">
Same-Day Air
</ShimmerText>
<br className="wings-mobile-break" />
{" "}
<ShimmerText className="font-extrabold">
Logistics
Meets Quick Logistics
</ShimmerText>
</span>
</h1>
<div className="content-slider-item-text logico-content-wrapper-2">
<div className="text-content">
<p>
Linking India&apos;s major regional capitals with
AI-powered air movement and zero-emission EV
last-mile delivery.
MileTruth AI forecasts demand, protects promises,
and coordinates every handoff from runway to
doorstep.
</p>
</div>
</div>
@@ -454,19 +448,24 @@ export default function WingsHero() {
<div className="slide-content-inner">
<h1 className="content-slider-item-heading logico-content-wrapper-1">
<span className="heading-content">
Where Quick Commerce
Doormile Wings
<br />
<ShimmerText className="font-extrabold">
Meets Quick Logistics
Same-Day Air
</ShimmerText>
<br className="wings-mobile-break" />
{" "}
<ShimmerText className="font-extrabold">
Logistics
</ShimmerText>
</span>
</h1>
<div className="content-slider-item-text logico-content-wrapper-2">
<div className="text-content">
<p>
MileTruth AI forecasts demand, protects promises,
and coordinates every handoff from runway to
doorstep.
Linking India&apos;s major regional capitals with
AI-powered air movement and zero-emission EV
last-mile delivery.
</p>
</div>
</div>

View File

@@ -200,6 +200,26 @@
margin: 0;
}
/* ---- Step 04 / Step 05 title-alignment fix ----
.stepBottom sits in .step's 1fr grid row with align-self:end, so its
title starts wherever the leftover space above it runs out — driven by
its OWN content height, not a shared position. Steps 01-03's
descriptions wrap to 3 lines, giving .stepBottom a natural height of
~101px; "Destination Hub" (04) and "EV Last-Mile" (05) wrap to only 2
lines (~79px) at several desktop widths, so under that same
end-alignment they're left with ~22px more leftover space above them
and their titles land visibly lower. Reserving that same ~101px on
.stepBottom for these two steps only — a floor, not a cap, so it's
inert wherever their content is already taller — reproduces Steps
01-03's exact title position without touching their CSS, the shared
grid, or align-self. */
@media (min-width: 1200px) {
.step:nth-child(4) .stepBottom,
.step:nth-child(5) .stepBottom {
min-height: 102px;
}
}
@media (max-width: 1024px) {
.headerRow {
flex-direction: column;

View File

@@ -160,7 +160,7 @@
}
.cardDesc {
font-size: 14px;
font-size: 16px;
line-height: 1.6;
color: rgba(255, 255, 255, 0.45);
margin: 0;

View File

@@ -1,6 +1,7 @@
"use client";
import { useEffect, useRef } from "react";
import gsap from "gsap";
import { ScrollReveal, StaggerChildren } from "@/animations/Reveal";
const CAPABILITIES = [
@@ -64,6 +65,114 @@ const CAPABILITIES = [
},
];
function TiltCard({ children, className }: { children: React.ReactNode, className: string }) {
const cardRef = useRef<HTMLDivElement>(null);
const glareRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const card = cardRef.current;
const glare = glareRef.current;
if (!card || !glare) return;
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
if (reduced) return;
const handleMouseMove = (e: MouseEvent) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
// Softer, more premium 3D tilt
const rotateX = ((y - centerY) / centerY) * -3;
const rotateY = ((x - centerX) / centerX) * 3;
gsap.to(card, {
duration: 0.4,
rotateX,
rotateY,
y: -4,
transformPerspective: 1000,
ease: "power2.out"
});
// Dynamic glare tracking
gsap.set(glare, {
"--mx": `${x}px`,
"--my": `${y}px`,
});
gsap.to(glare, {
duration: 0.3,
opacity: 1,
ease: "power2.out"
});
// Z-axis pop
gsap.to(card.querySelector('.wmt-card-icon'), {
duration: 0.4,
z: 25,
ease: "power2.out"
});
gsap.to(card.querySelector('.wmt-card-title'), {
duration: 0.4,
z: 15,
ease: "power2.out"
});
};
const handleMouseLeave = () => {
gsap.to(card, {
duration: 0.8,
rotateX: 0,
rotateY: 0,
y: 0,
ease: "power3.out"
});
gsap.to(glare, {
duration: 0.5,
opacity: 0,
ease: "power3.out"
});
gsap.to(card.querySelectorAll('.wmt-card-icon, .wmt-card-title'), {
duration: 0.8,
z: 0,
ease: "power3.out"
});
};
card.addEventListener("mousemove", handleMouseMove);
card.addEventListener("mouseleave", handleMouseLeave);
return () => {
card.removeEventListener("mousemove", handleMouseMove);
card.removeEventListener("mouseleave", handleMouseLeave);
};
}, []);
return (
<div ref={cardRef} className={className}>
<div
ref={glareRef}
style={{
position: "absolute",
inset: 0,
borderRadius: "inherit",
background: "radial-gradient(circle 220px at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.08) 0%, rgba(200, 16, 46, 0.03) 40%, transparent 100%)",
opacity: 0,
pointerEvents: "none",
zIndex: 0,
transform: "translateZ(1px)",
mixBlendMode: "screen"
}}
/>
<div style={{ position: "relative", zIndex: 1, transformStyle: "preserve-3d" }}>
{children}
</div>
</div>
);
}
export default function WingsMileTruth() {
const canvasRef = useRef<HTMLCanvasElement>(null);
@@ -238,11 +347,12 @@ export default function WingsMileTruth() {
border: 1px solid rgba(255, 255, 255, 0.07);
border-radius: 18px;
padding: 26px 22px;
transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.5s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.5s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1);
transition: border-color 0.5s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.5s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1);
transform-style: preserve-3d;
will-change: transform;
}
.wmt-card:hover {
transform: translateY(-6px);
border-color: rgba(255, 255, 255, 0.16);
background-color: rgba(255, 255, 255, 0.055);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);
@@ -270,7 +380,7 @@ export default function WingsMileTruth() {
}
.wmt-card-desc {
font-size: 13px;
font-size: 16px;
line-height: 1.55;
color: rgba(255, 255, 255, 0.55);
margin: 0;
@@ -370,11 +480,11 @@ export default function WingsMileTruth() {
<StaggerChildren stagger={0.08} duration={0.65} yOffset={25} className="wmt-grid">
{CAPABILITIES.map((c) => (
<div key={c.title} className="wmt-card">
<TiltCard key={c.title} className="wmt-card">
<div className="wmt-card-icon" aria-hidden="true">{c.icon}</div>
<h3 className="wmt-card-title">{c.title}</h3>
<p className="wmt-card-desc">{c.desc}</p>
</div>
</TiltCard>
))}
</StaggerChildren>

View File

@@ -53,12 +53,12 @@ export default function WingsRoadmap() {
.wrm-section {
position: relative;
width: calc(100% - 40px);
margin: clamp(56px, 7vw, 96px) auto clamp(24px, 4vw, 40px);
margin: clamp(32px, 4vw, 56px) auto clamp(16px, 2vw, 32px);
border-radius: 28px;
overflow: hidden;
box-sizing: border-box;
background: #09090b;
padding: clamp(64px, 8vw, 100px) clamp(24px, 5vw, 48px);
padding: clamp(40px, 5vw, 64px) clamp(24px, 5vw, 48px);
}
.wrm-header {
@@ -180,8 +180,8 @@ export default function WingsRoadmap() {
.wrm-phase-pill.white-pill { background: rgba(255,255,255,0.12); color: #ffffff; border: 1px solid rgba(255,255,255,0.2); }
.wrm-card-desc {
font-size: 12.5px;
line-height: 1.5;
font-size: 14.5px;
line-height: 1.55;
color: rgba(255, 255, 255, 0.55);
margin: 0;
}
@@ -209,9 +209,9 @@ export default function WingsRoadmap() {
section rhythm near the footer. Horizontal padding is left
untouched (its own clamp already resolves small on phones). */
.wrm-section {
margin-top: 40px;
padding-top: 48px;
padding-bottom: 48px;
margin-top: 24px;
padding-top: 32px;
padding-bottom: 32px;
}
.wrm-track-wrap { display: none; }
.wrm-grid {

View File

@@ -118,7 +118,7 @@ export default function WingsSpeedAdvantage() {
line-height: 1;
}
.wsa-panel-surface .wsa-value { color: #b3b6bf; }
.wsa-panel-surface .wsa-value { color: #c8102e; }
.wsa-panel-wings .wsa-value { color: #ffffff; }
.wsa-unit {

View File

@@ -25,6 +25,14 @@ const MOBILE_BQ = 600;
const AIRCRAFT_ROTATION_OFFSET = 90; // glyph's rest pose points "up"
const WAVE_AMPLITUDE_MIN = 20;
const WAVE_AMPLITUDE_MAX = 38;
// Row-wrapped grid layouts only (e.g. the 601-1024px 2-column tablet
// breakpoint) — single-row layouts (desktop, mobile) never use these.
const ROW_Y_TOLERANCE = 12; // px tolerance for clustering card anchors into the same row
const ROW_CLEARANCE_PADDING = 6; // safety margin between a crest and the row above's card bottom
// Exact max of buildWavePoints' ampFactor (1 + 0.28 + 0.15), used to clamp a
// row's wave amplitude so no crest can ever reach into the row above it,
// regardless of segment index/phase.
const MAX_WAVE_AMP_FACTOR = 1 + 0.28 + 0.15;
const FEATURES = [
{
@@ -79,6 +87,20 @@ interface Point {
y: number;
}
// A non-mobile card anchor, carrying its source card's full box (wrap-
// relative) alongside the {x,y} route point — top/bottom are needed to
// group anchors into rows and clamp a row's wave amplitude against the row
// above it; left/right are needed to find the empty column gutter (the
// icon's own x sits near the left edge of its card, not the card's true
// horizontal center, so card edges — not icon x — must drive that
// calculation). Never leaves measure(); only plain Point[] is returned.
interface CardAnchor extends Point {
top: number;
bottom: number;
left: number;
right: number;
}
function buildPathD(points: Point[]): string {
if (points.length < 2) return "";
let d = `M ${points[0].x} ${points[0].y}`;
@@ -126,6 +148,87 @@ function buildWavePoints(points: Point[], amplitude: number): Point[] {
return waved;
}
// Clusters card anchors into visual rows by their shared top edge. CSS grid
// auto-flow is row-major and `align-items: stretch` (the grid default) makes
// same-row cards share cardRect.top exactly, so a single-pass walk against
// the current row's reference y (with a small tolerance for sub-pixel
// getBoundingClientRect noise) is sufficient — no need for full clustering.
function groupIntoRows(anchors: CardAnchor[]): CardAnchor[][] {
const rows: CardAnchor[][] = [];
for (const a of anchors) {
const row = rows[rows.length - 1];
if (row && Math.abs(row[0].top - a.top) <= ROW_Y_TOLERANCE) {
row.push(a);
} else {
rows.push([a]);
}
}
return rows;
}
// The x midpoint of the empty strip between two adjacent columns in a row —
// i.e. a real, always-card-free gutter, derived from actual card edges (not
// icon x, which sits near each card's left padding rather than its true
// horizontal center). `side` picks which internal gutter: "right" is
// between the two rightmost columns, "left" between the two leftmost — for
// the current 2-column layout these are the same single gutter, but this
// stays correct if a wider grid (3+ columns) ever wraps into multiple rows.
function computeColumnGutterX(row: CardAnchor[], side: "left" | "right"): number {
const sorted = [...row].sort((a, b) => a.left - b.left);
if (sorted.length < 2) return (sorted[0].left + sorted[0].right) / 2;
return side === "right"
? (sorted[sorted.length - 2].right + sorted[sorted.length - 1].left) / 2
: (sorted[0].right + sorted[1].left) / 2;
}
// Builds a safe serpentine (boustrophedon) route across a row-wrapped grid:
// each row is traversed in alternating direction so consecutive rows' ends
// line up on the same side, and the vertical drop between rows is routed
// through the always-empty column gutter on that side rather than through
// either column's own x — the only way to guarantee the connector never
// crosses a card, since a card anchor sits only ~10px below the card above
// it in the same column. Each row's own wave amplitude is clamped to the
// measured clearance above it so no crest can reach into the row above.
function buildMultiRowRoute(rows: CardAnchor[][], baseAmplitude: number): Point[] {
const out: Point[] = [];
let prevRowBottom: number | null = null;
rows.forEach((row, ri) => {
const ordered = ri % 2 === 0 ? row : [...row].reverse();
const rowAnchorY = ordered[0].y;
const amplitude =
prevRowBottom === null
? baseAmplitude
: Math.max(
0,
Math.min(baseAmplitude, (rowAnchorY - prevRowBottom - ROW_CLEARANCE_PADDING) / MAX_WAVE_AMP_FACTOR)
);
const waved = buildWavePoints(
ordered.map(({ x, y }) => ({ x, y })),
amplitude
);
if (out.length > 0) {
const prevPoint = out[out.length - 1];
const nextPoint = waved[0];
// Row (ri-1) ends at its right extreme when it traveled left-to-right
// (even index, unreversed), left extreme when it traveled
// right-to-left (odd index, reversed) — the gutter must sit on that
// same side so the dogleg never has to cross back over a card.
const side: "left" | "right" = (ri - 1) % 2 === 0 ? "right" : "left";
const gutterX = computeColumnGutterX(rows[ri - 1], side);
out.push({ x: gutterX, y: prevPoint.y }, { x: gutterX, y: nextPoint.y });
}
out.push(...waved);
prevRowBottom = Math.max(...row.map((a) => a.bottom));
});
return out;
}
export default function WingsWhyGrid() {
const wrapRef = useRef<HTMLDivElement>(null);
const svgRef = useRef<SVGSVGElement>(null);
@@ -198,24 +301,43 @@ export default function WingsWhyGrid() {
const wrapRect = wrap.getBoundingClientRect();
const isMobile = isMobileLayout();
const points = cardRefs.current
// Card box (wrap-relative) is captured alongside x/y for every card,
// mobile included, so the shape is uniform — only the non-mobile
// branch below actually reads top/bottom/left/right (to group into
// rows, clamp wave amplitude against the row above, and find the
// empty column gutter for inter-row transitions).
const anchors = cardRefs.current
.map((card, i) => {
const icon = iconRefs.current[i];
if (!card || !icon) return null;
const cardRect = card.getBoundingClientRect();
const iconRect = icon.getBoundingClientRect();
const top = cardRect.top - wrapRect.top;
const bottom = cardRect.bottom - wrapRect.top;
const left = cardRect.left - wrapRect.left;
const right = cardRect.right - wrapRect.left;
if (isMobile) {
return {
x: 12,
y: iconRect.top + iconRect.height / 2 - wrapRect.top,
top,
bottom,
left,
right,
};
}
return {
x: iconRect.left + iconRect.width / 2 - wrapRect.left,
y: cardRect.top - wrapRect.top - 14,
top,
bottom,
left,
right,
};
})
.filter((p): p is Point => p !== null);
.filter((p): p is CardAnchor => p !== null);
const points: Point[] = anchors.map(({ x, y }) => ({ x, y }));
svg.setAttribute("width", String(wrapRect.width));
svg.setAttribute("height", String(wrapRect.height));
@@ -228,7 +350,18 @@ export default function WingsWhyGrid() {
const amplitude = isMobile
? 0
: Math.max(WAVE_AMPLITUDE_MIN, Math.min(WAVE_AMPLITUDE_MAX, wrapRect.width / 20));
const routePoints = isMobile ? points : buildWavePoints(points, amplitude);
let routePoints: Point[];
if (isMobile) {
routePoints = points;
} else {
const rows = groupIntoRows(anchors);
// A single row (desktop, always 4-up) takes the exact original
// path — no behavior change there. Only a row-wrapped layout (the
// tablet/small-laptop 2-column breakpoint) uses the row-aware
// serpentine route.
routePoints = rows.length <= 1 ? buildWavePoints(points, amplitude) : buildMultiRowRoute(rows, amplitude);
}
const d = buildPathD(routePoints);
path.setAttribute("d", d);
illum.setAttribute("d", d);
@@ -236,11 +369,15 @@ export default function WingsWhyGrid() {
return { points, isMobile };
};
// Keep the (static, or already-settled) line in sync with layout reflow.
// Only ever updates geometry — never restarts or replays the animation.
ro = new ResizeObserver(() => {
cancelAnimationFrame(resizeRaf);
resizeRaf = requestAnimationFrame(measure);
resizeRaf = requestAnimationFrame(() => {
if (!reduced) {
buildSequence();
} else {
measure();
}
});
});
ro.observe(wrap);
@@ -293,9 +430,8 @@ export default function WingsWhyGrid() {
gsap.delayedCall(0.95, () => card.classList.remove("wwg-card-pulse"));
};
const runSequence = () => {
if (played) return;
played = true;
const buildSequence = () => {
if (playedTimeline) playedTimeline.kill();
const { points, isMobile } = measure();
if (points.length < 2) return;
@@ -327,7 +463,14 @@ export default function WingsWhyGrid() {
let currentAngle = 0;
let angleInit = false;
const tl = gsap.timeline();
const tl = gsap.timeline({
scrollTrigger: {
trigger: wrap,
start: "top 75%",
end: "bottom 35%",
scrub: 1,
},
});
playedTimeline = tl;
// The energy pulse's own journey — calm and deliberate, ~4.8-5.5s so
@@ -413,6 +556,10 @@ export default function WingsWhyGrid() {
if (!fired[i] && p >= f) {
fired[i] = true;
activateCard(i);
} else if (fired[i] && p < f) {
fired[i] = false;
// Reset card state if scrubbed backwards
cardRefs.current[i]?.classList.remove("wwg-card-flown", "wwg-card-pulse");
}
});
},
@@ -443,26 +590,8 @@ export default function WingsWhyGrid() {
gsap.set(traveler, { opacity: 0 });
gsap.set(illum, { opacity: 0 });
// Starts as soon as the section is mostly in view (matches the cards'
// own "top 85%" stagger-reveal trigger) rather than waiting for it to
// be ~centered — the ~6s draw+flight sequence needs that extra lead
// time to actually be seen during a normal scroll pass, not just
// triggered and then scrolled straight past.
st = ScrollTrigger.create({
trigger: wrap,
start: "top 85%",
once: true,
onEnter: runSequence,
});
rafIn = requestAnimationFrame(() => {
const r = wrap.getBoundingClientRect();
const vh = window.innerHeight || document.documentElement.clientHeight;
if (r.top < vh * 0.85 && r.bottom > 0) {
runSequence();
st?.kill();
}
});
// Build the scrubbing sequence immediately
buildSequence();
}
}, wrap);

View File

@@ -1,6 +1,6 @@
import React from "react";
import Image from "next/image";
import { ScrollReveal, StaggerChildren } from "@/animations/Reveal";
import { CountUp, ScrollReveal, StaggerChildren } from "@/animations/Reveal";
import IndustryWorldMap from "./IndustryWorldMap";
const WS_STATS = [
@@ -42,7 +42,7 @@ const WS_CARDS = [
},
{
title: "Community Growth",
desc: "Creating local opportunities through training, employment, and empowerment.",
desc: "Creating local opportunities through entrepreneurship, collaboration, and community-driven growth.",
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" />
@@ -52,7 +52,48 @@ const WS_CARDS = [
},
];
export default function WomenSection() {
interface WomenSectionStat {
value: string;
plus: string;
label: string;
}
interface WomenSectionCard {
title: string;
desc: string;
icon: React.ReactNode;
}
interface WomenSectionProps {
eyebrow?: string;
bannerLabel?: string;
bannerCopy?: string;
ctaLabel?: string;
ctaHref?: string;
heading?: string;
stats?: WomenSectionStat[];
cards?: WomenSectionCard[];
}
function parseStatValue(value: string) {
const match = value.trim().match(/^(\d+(?:\.\d+)?)(.*)$/);
if (!match) return null;
return {
end: Number(match[1]),
suffix: match[2],
};
}
export default function WomenSection({
eyebrow = "/ Women Empowerment /",
bannerLabel = "Empowering Women",
bannerCopy = "Doormile empowers women to lead the future of logistics.",
ctaLabel = "Explore more",
ctaHref = "#",
heading = "Women Leading the Way",
stats = WS_STATS,
cards = WS_CARDS,
}: WomenSectionProps = {}) {
return (
<>
<style dangerouslySetInnerHTML={{ __html: `
@@ -419,12 +460,12 @@ export default function WomenSection() {
</div>
<div className="elementor-element elementor-element-239afbb elementor-widget elementor-widget-logico_heading" data-id="239afbb" data-element_type="widget" data-e-type="widget" data-widget_type="logico_heading.default">
<div className="elementor-widget-container">
<h5 className="logico-title">Empowering Women</h5>
<h5 className="logico-title">{bannerLabel}</h5>
</div>
</div>
<div className="elementor-element elementor-element-0d307dd elementor-widget elementor-widget-text-editor" data-id="0d307dd" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
<div className="elementor-widget-container">
<p>Doormile empowers women to lead the future of logistics.</p>
<p>{bannerCopy}</p>
</div>
</div>
</div>
@@ -433,8 +474,8 @@ export default function WomenSection() {
<div className="elementor-widget-container">
<div className="button-widget">
<div className="button-container">
<a href="#" className="logico-small-button">
Explore more
<a href={ctaHref} className="logico-small-button">
{ctaLabel}
<svg viewBox="0 0 13 20">
<polyline points="0.5 19.5 3 19.5 12.5 10 3 0.5"></polyline>
</svg>
@@ -455,7 +496,7 @@ export default function WomenSection() {
<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-widget-container">
<div className="logico-title">/ Women Empowerment /</div>
<div className="logico-title">{eyebrow}</div>
</div>
</div>
@@ -464,7 +505,7 @@ export default function WomenSection() {
<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-widget-container">
<h3 className="logico-title">Women Leading the Way</h3>
<h3 className="logico-title">{heading}</h3>
</div>
</div>
</ScrollReveal>
@@ -484,16 +525,30 @@ export default function WomenSection() {
<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 id="ws-stories">
<StaggerChildren className="ws__stats" stagger={0.1} duration={0.6} yOffset={20} triggerOnce>
{WS_STATS.map((s) => (
{stats.map((s) => (
<div className="ws__stat" key={s.label}>
<div className="ws__stat-num">{s.value}<span>{s.plus}</span></div>
<div className="ws__stat-num">
{(() => {
const parsed = parseStatValue(s.value);
if (!parsed) return s.value;
return (
<CountUp
end={parsed.end}
suffix={parsed.suffix}
duration={1.8}
triggerOnce
/>
);
})()}
<span>{s.plus}</span>
</div>
<div className="ws__stat-label">{s.label}</div>
</div>
))}
</StaggerChildren>
<StaggerChildren className="ws__cards" stagger={0.08} duration={0.6} yOffset={24} triggerOnce>
{WS_CARDS.map((c) => (
{cards.map((c) => (
<div className="ws__card" key={c.title}>
<span className="ws__card-icon" aria-hidden="true">{c.icon}</span>
<div className="ws__card-title">{c.title}</div>

View File

@@ -0,0 +1,123 @@
"use client";
import React from "react";
import EVSection, { EVStat, EVBadge, EVFeature, EVCardsTheme } from "./EVSection";
/* Violet / Electric Purple — distinct from WF1 (cyan/teal) and WF2 (red/crimson). */
const THEME: EVCardsTheme = {
accent: "#7C5CFF",
accent2: "#4C3AE3",
glow: "rgba(124,92,255,0.20)",
};
/**
* Workflow 4 — Quantum Intelligence (hybrid split-screen).
*
* • Left — video: the hybrid optimization / energy-landscape visual.
* • Right — a COMPACT DASHBOARD: a quick KPI row (QUBO / Global / Hybrid /
* Multi) over feature cards describing the encode → energy
* landscape → global minimum → hybrid intelligence pipeline,
* sitting on the animated network backdrop (violet).
*
* Messaging is deliberately framed as work-in-progress ("building",
* "exploring") rather than a shipped quantum-computing claim.
*/
const METRICS: EVStat[] = [
{ text: "QUBO", value: 0, suffix: "", label: "Problem Model" },
{ text: "GLOBAL", value: 0, suffix: "", label: "Minimum Search" },
{ text: "HYBRID", value: 0, suffix: "", label: "Intelligence" },
{ text: "MULTI", value: 0, suffix: "", label: "Objective" },
];
/* Distinct copy for the bottom capability bar (not a repeat of the KPI row —
* Workflow 4's brief specifies separate content for each). */
const BAR_STATS: EVStat[] = [
{ text: "Multi-Rider", value: 0, suffix: "", label: "Dynamic Routing" },
{ text: "Optimized", value: 0, suffix: "", label: "Time Windows" },
{ text: "Real-Time", value: 0, suffix: "", label: "Fleet Balancing" },
{ text: "Cost + Distance + SLA", value: 0, suffix: "", label: "Objectives" },
];
const ico = (path: React.ReactNode) => (
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
{path}
</svg>
);
const FEATURES: EVFeature[] = [
{
icon: ico(
<>
<rect x="3" y="3" width="7" height="7" />
<rect x="14" y="3" width="7" height="7" />
<rect x="14" y="14" width="7" height="7" />
<rect x="3" y="14" width="7" height="7" />
</>,
),
title: "Encode the Problem",
desc: "Rider assignments, delivery sequences, capacity, traffic, service time, and SLA constraints become part of one mathematical optimization model.",
},
{
icon: ico(<path d="m8 3 4 8 5-5 5 15H2L8 3z" />),
title: "Build the Energy Landscape",
desc: "Each feasible routing solution is represented as a state with its own energy through a QUBO formulation.",
},
{
icon: ico(
<>
<circle cx="12" cy="12" r="9" />
<circle cx="12" cy="12" r="5" />
<circle cx="12" cy="12" r="1" />
</>,
),
title: "Search the Global Minimum",
desc: "Optimization becomes the search for the lowest-energy state instead of evaluating route combinations one by one.",
},
{
icon: ico(
<>
<polygon points="12 2 2 7 12 12 22 7 12 2" />
<polyline points="2 17 12 22 22 17" />
<polyline points="2 12 12 17 22 12" />
</>,
),
title: "Hybrid Intelligence",
desc: "Classical algorithms, AI models, and quantum optimization work together using the right computational model for each problem.",
},
];
const BADGES: EVBadge[] = [
{ value: "QUBO", label: "PROBLEM MODEL" },
{ value: "HYBRID", label: "INTELLIGENCE" },
];
export default function Workflow4() {
return (
<EVSection
ariaLabel="Workflow 4 — Quantum Intelligence"
gapBottom
image="/videos/Doormile-quantum-video3.mp4"
cardTitle="BUILDING QUANTUM INTELLIGENCE"
cardSubtitle="Exploring a hybrid optimization layer that treats routing as an energy landscape, not a search problem."
eyebrow="/ Quantum Intelligence /"
titleLead="FROM ROUTE SEARCH. "
titleAccent="TO ENERGY MINIMIZATION."
imageAlt="Hybrid quantum-classical optimization engine visualizing an energy landscape"
metrics={METRICS}
barStats={BAR_STATS}
features={FEATURES}
cardsHeading="Quantum Intelligence"
sysLabel="HYBRID ENGINE"
cardsTheme={THEME}
badges={BADGES}
mediaClassName="evnd__imgwrap--wf4"
/>
);
}

View File

@@ -24,6 +24,9 @@ const ROUTE_CLASSES: Record<string, string> = {
"/solutions": `${SHARED} page-id-59 elementor-page-59`,
// PHP source quirk: about-us.php has `home` class (upstream bug, preserved)
"/about-us": `home ${SHARED} page-id-59 elementor-page-59`,
// Reuse the About page Elementor/runtime context for the Wings Empowerment
// page sections that intentionally share the same migrated Elementor markup.
"/empowerment": `home ${SHARED} page-id-59 elementor-page-59`,
"/blog": `${SHARED} page-id-59 elementor-page-59`,
"/contact": `${SHARED} page-id-59 elementor-page-59`,
};