Files
doormile_react/src/components/sections/WingsRoadmap.tsx
2026-07-08 20:24:43 +05:30

302 lines
9.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState } from "react";
const ROADMAP_DATA = [
{
year: "Year 1",
trackLeft: "10%",
phase: "Launch Phase",
phaseClass: "yellow",
desc: "Establish localized clearance hubs and launch cargo services connecting 56 key commercial cities.",
},
{
year: "Year 2",
trackLeft: "30%",
phase: "Network Growth",
phaseClass: "green",
desc: "Expand hub operations and airfield schedules, serving 15 regional and secondary cargo airports.",
},
{
year: "Year 3",
trackLeft: "50%",
phase: "Cross-Border Nodes",
phaseClass: "blue",
desc: "Add international regional routes, bridging key freight corridors in South Asia.",
},
{
year: "Year 5",
trackLeft: "70%",
phase: "Operational Scale",
phaseClass: "blue",
desc: "Expand to a fleet of 25 leased cargo aircraft, servicing over 50 regional airports nationwide.",
},
{
year: "Year 10",
trackLeft: "90%",
phase: "Global Duplication",
phaseClass: "white-pill",
desc: "Replicate our asset-light, AI-powered logistics framework across Asia, Africa, and the Middle East.",
glow: true,
},
];
export default function WingsRoadmap() {
const [active, setActive] = useState(ROADMAP_DATA.length - 1);
const fillPct = ((active + 1) / ROADMAP_DATA.length) * 100;
return (
<>
<style
dangerouslySetInnerHTML={{
__html: `
.wrm-section {
position: relative;
width: calc(100% - 40px);
margin: clamp(32px, 4vw, 56px) auto clamp(16px, 2vw, 32px);
border-radius: 28px;
overflow: hidden;
box-sizing: border-box;
background: #09090b;
padding: clamp(40px, 5vw, 64px) clamp(24px, 5vw, 48px);
}
.wrm-header {
margin: 0 auto 44px auto;
max-width: 720px;
text-align: center;
}
.wrm-eyebrow {
font-size: 13px;
font-weight: 800;
letter-spacing: 2.5px;
text-transform: uppercase;
color: #c8102e;
margin-bottom: 16px;
}
.wrm-title {
font-size: clamp(28px, 3.4vw, 48px) !important;
font-weight: 800 !important;
letter-spacing: -0.03em !important;
line-height: 1.15 !important;
text-transform: none !important;
color: #ffffff !important;
margin: 0;
}
.wrm-inner {
max-width: 1380px;
margin: 0 auto;
}
.wrm-track-wrap {
position: relative;
height: 4px;
background: rgba(255, 255, 255, 0.08);
border-radius: 2px;
margin: 0 auto 44px auto;
}
.wrm-track-fill {
position: absolute;
left: 0;
top: 0;
height: 100%;
background: #c8102e;
box-shadow: 0 0 10px #c8102e;
border-radius: 2px;
transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.wrm-nodes { position: absolute; inset: 0; }
.wrm-node {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
border-radius: 50%;
background: #18181b;
border: 2px solid rgba(255, 255, 255, 0.2);
transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
.wrm-node.is-active {
background: #c8102e;
border-color: #ffffff;
box-shadow: 0 0 10px #c8102e;
}
.wrm-grid {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 16px;
}
.wrm-card {
position: relative;
min-width: 0;
padding: 24px 20px;
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.07);
background: rgba(255, 255, 255, 0.03);
cursor: pointer;
transition: border-color 0.4s ease, background-color 0.4s ease, transform 0.4s ease, box-shadow 0.4s ease;
}
.wrm-card:hover,
.wrm-card.is-active {
transform: translateY(-6px);
border-color: rgba(200, 16, 46, 0.5);
background: rgba(200, 16, 46, 0.06);
box-shadow: 0 16px 32px rgba(0, 0, 0, 0.3);
}
.wrm-card-year {
font-size: 20px;
font-weight: 900;
color: #ffffff;
letter-spacing: -0.5px;
margin-bottom: 14px;
}
.wrm-phase-pill {
display: inline-block;
font-size: 10.5px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 4px 9px;
border-radius: 6px;
margin-bottom: 12px;
}
.wrm-phase-pill.yellow { background: rgba(234,179,8,0.12); color: #eab308; border: 1px solid rgba(234,179,8,0.2); }
.wrm-phase-pill.green { background: rgba(34,197,94,0.12); color: #22c55e; border: 1px solid rgba(34,197,94,0.2); }
.wrm-phase-pill.blue { background: rgba(59,130,246,0.12); color: #3b82f6; border: 1px solid rgba(59,130,246,0.2); }
.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;
color: rgba(255, 255, 255, 0.55);
margin: 0;
}
.wrm-card.wrm-glow {
background: linear-gradient(135deg, rgba(200, 16, 46, 0.95) 0%, rgba(110, 8, 26, 0.98) 100%);
border-color: rgba(255, 255, 255, 0.15);
}
.wrm-card.wrm-glow .wrm-card-desc { color: rgba(255, 255, 255, 0.85); }
.wrm-card.wrm-glow:hover,
.wrm-card.wrm-glow.is-active {
box-shadow: 0 20px 40px rgba(200, 16, 46, 0.45);
}
@media (max-width: 1024px) {
.wrm-section { width: calc(100% - 24px); border-radius: 22px; }
.wrm-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
}
@media (max-width: 767px) {
/* Both the outer margin-top and the internal vertical padding
clamp()s floor at fixed, sizeable values (56px + 64px = ~120px
combined) on any phone width — noticeably heavier than the
section rhythm near the footer. Horizontal padding is left
untouched (its own clamp already resolves small on phones). */
.wrm-section {
margin-top: 24px;
padding-top: 32px;
padding-bottom: 32px;
}
.wrm-track-wrap { display: none; }
.wrm-grid {
grid-template-columns: 1fr;
gap: 14px;
position: relative;
padding-left: 26px;
}
.wrm-grid::before {
content: '';
position: absolute;
left: 5px;
top: 8px;
bottom: 8px;
width: 2px;
border-radius: 2px;
background: rgba(255, 255, 255, 0.12);
}
.wrm-card { position: relative; }
.wrm-card::before {
content: '';
position: absolute;
left: -25px;
top: 22px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #18181b;
border: 2px solid rgba(255, 255, 255, 0.2);
}
.wrm-card.is-active::before,
.wrm-card:hover::before {
background: #c8102e;
border-color: #ffffff;
box-shadow: 0 0 10px rgba(200, 16, 46, 0.7);
}
}
`,
}}
/>
<section className="wrm-section" id="wings-roadmap">
<div className="dm-section-container">
<div className="wrm-header">
<div className="wrm-eyebrow">/ Future Roadmap /</div>
<h2 className="wrm-title">A ten-year path to national scale</h2>
</div>
<div className="wrm-inner">
<div className="wrm-track-wrap" aria-hidden="true">
<div className="wrm-track-fill" style={{ width: `${fillPct}%` }} />
<div className="wrm-nodes">
{ROADMAP_DATA.map((_, i) => (
<div
key={i}
className={`wrm-node${i <= active ? " is-active" : ""}`}
style={{ left: `${((i + 0.5) / ROADMAP_DATA.length) * 100}%` }}
/>
))}
</div>
</div>
<div className="wrm-grid">
{ROADMAP_DATA.map((item, i) => (
<div
key={item.year}
className={`wrm-card${item.glow ? " wrm-glow" : ""}${i === active ? " is-active" : ""}`}
onMouseEnter={() => setActive(i)}
onClick={() => setActive(i)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") setActive(i);
}}
>
<div className="wrm-card-year">{item.year}</div>
<span className={`wrm-phase-pill ${item.phaseClass}`}>{item.phase}</span>
<p className="wrm-card-desc">{item.desc}</p>
</div>
))}
</div>
</div>
</div>
</section>
</>
);
}