/* ═══════════════════════════════════════════════════════════
   NEO — New Engineering Order
   Design system per SpaceX-style brand guidelines:
   monochrome, full-bleed, industrial geometric type, zero elevation.
   ═══════════════════════════════════════════════════════════ */

:root {
  /* Palette — monochrome by design. No chromatic accent. */
  /* Contrast ratios are measured against --void. Every value that carries
     meaning clears WCAG AA; only --gunmetal is allowed to fall below, and it
     is reserved for texture that carries none. */
  --void:      #000000;   /* page canvas, every section background       */
  --star:      #f0f0fa;   /* primary text, primary rules      18.9:1 AAA */
  --steel:     #a0a0aa;   /* secondary text, labels, eyebrows   8.1:1 AAA*/
  --slate:     #7c7c86;   /* tertiary text, de-emphasised       5.1:1 AA */
  --edge:      #5e5e66;   /* borders that bound a control       3.3:1 AA */
  --gunmetal:  #46464c;   /* texture only — ticks, lead lines, the ring  */

  /* Type */
  --font: 'D-DIN', 'Barlow', 'DIN Next LT Pro', 'Helvetica Neue', Arial, sans-serif;
  --font-display: 'D-DIN-Bold', 'Barlow', 'DIN Next LT Pro', 'Helvetica Neue', Arial, sans-serif;

  --fs-caption: 10px;
  --fs-body-sm: 12px;
  --fs-body:    13px;
  --fs-body-lg: 16px;

  --track-ui:   0.10em;   /* nav, labels, buttons, body                  */
  --track-nav:  0.09em;
  --track-disp: 0.02em;   /* display headlines                           */

  /* Rhythm */
  --gap:        18px;
  --pad-card:   20px;
  --section:    60px;
  --gutter:     clamp(24px, 6vw, 96px);

  --radius:     4px;
  --radius-pill: 32px;

  --nav-h: 68px;
}

/* ── reset ─────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* nav is fixed — offset anchor targets so headings clear it */
  scroll-padding-top: var(--nav-h);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--void);
  color: var(--star);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.7;
  letter-spacing: var(--track-ui);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p, ul, dl, dd, figure { margin: 0; }
ul { padding: 0; list-style: none; }
button { font: inherit; color: inherit; }

::selection { background: var(--star); color: var(--void); }

:focus-visible {
  outline: 1px solid var(--star);
  outline-offset: 3px;
}

.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 200;
  padding: 10px 16px;
  border: 1px solid var(--star);
  background: var(--void);
  font-size: var(--fs-body-sm); font-weight: 700;
  text-transform: uppercase; letter-spacing: var(--track-ui);
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }

/* ── type primitives ───────────────────────────────────── */
.display {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(34px, 5.2vw, 48px);
  line-height: 1.05;
  letter-spacing: var(--track-disp);
  text-transform: uppercase;
  margin: 0;
}

.eyebrow {
  font-size: var(--fs-caption);
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
  color: var(--steel);
}

.lede {
  font-size: var(--fs-body);
  line-height: 1.7;
  letter-spacing: var(--track-ui);
  max-width: 460px;
  color: var(--star);
}
.lede--wide { max-width: 620px; }

/* ── buttons — outlined ghosts only, never filled ──────── */
.btn {
  display: inline-block;
  padding: 12px 20px;
  border: 1px solid var(--star);
  border-radius: var(--radius);
  background: transparent;
  color: var(--star);
  font-size: var(--fs-body-sm);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
  cursor: pointer;
  transition: color .25s, border-color .25s, box-shadow .25s;
}
.btn:hover { box-shadow: inset 0 0 0 1px currentColor; }

.btn--muted { border-color: var(--steel); color: var(--steel); }
.btn--muted:hover { border-color: var(--star); color: var(--star); }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: var(--gap); }

/* ═══════════════════════ NAV ═══════════════════════════ */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  height: var(--nav-h);
  display: flex; align-items: center; gap: var(--gutter);
  padding: 0 var(--gutter);
  /* sits naked on the void — no fill, no shadow, no backdrop blur */
  background: transparent;
  transition: border-color .3s;
  border-bottom: 1px solid transparent;
}

/* Functional legibility scrim — not decoration, and not a fill. The nav is
   naked by design, but above 1080px there is no ground behind it, so anything
   in normal flow travels under the links and collides with them. The pinned
   stages dodge this by fading their copy where it sits; a plain scrolling
   section like Capabilities cannot, so it is knocked back instead. Invisible
   over the void, and over full-bleed footage it does the same job as the
   domain scrims. Sits inside the nav's own stacking context, so it covers
   page content without ever covering the nav's links. */
.nav::before {
  content: '';
  position: absolute; inset: 0 0 auto 0;
  z-index: -1;
  height: calc(var(--nav-h) + 28px);
  /* Stops are keyed to --nav-h, not to percentages of the box, and the shape
     is pinned by two measurements taken from the page:

       - It must stay near-opaque across the ENTIRE bar. A percentage curve put
         the falloff's midpoint on the bar's own bottom edge, which is exactly
         where a heading scrolling up comes to rest, and "The team" stayed
         readable straight through the links at 2.6:1.
       - It must be spent by nav-h + 24px, where the domain and VIPA slide
         counters sit. Running the falloff past them dragged that 10px label
         from 8.1:1 down to 3.4:1, under the AA floor. It now clears at 6.6:1.

     So: hold to the bar, then fall off inside 28px. Over the void none of it
     is visible; over footage it reads as the domain scrims already do. */
  background: linear-gradient(180deg,
      rgba(0,0,0,.96) 0,
      rgba(0,0,0,.94) calc(var(--nav-h) - 14px),
      rgba(0,0,0,.86) var(--nav-h),
      rgba(0,0,0,.30) calc(var(--nav-h) + 16px),
      rgba(0,0,0,0)   calc(var(--nav-h) + 28px));
  opacity: 0;
  transition: opacity .3s;
  pointer-events: none;
}
/* Naked at the top of the hero, where the brand moment is; earns its ground
   only once the page has actually moved. */
.nav.is-scrolled::before { opacity: 1; }
.nav.is-scrolled { border-bottom-color: var(--edge); }

.nav__logo { flex: 0 0 auto; display: block; }
.nav__logo img { height: 22px; width: auto; }

.nav__links {
  display: flex; align-items: center; gap: 26px;
  margin-right: auto;
}
.nav__links a {
  font-size: var(--fs-body-sm);
  font-weight: 400;
  letter-spacing: var(--track-nav);
  text-transform: uppercase;
  color: var(--star);
  opacity: .72;
  transition: opacity .2s;
  white-space: nowrap;
}
.nav__links a:hover,
.nav__links a.is-active { opacity: 1; }

.nav__cta { padding: 10px 16px; font-size: var(--fs-caption); }

.nav__toggle {
  display: none;
  width: 34px; height: 34px;
  padding: 8px 5px;
  border: 0; background: transparent; cursor: pointer;
  flex-direction: column; justify-content: space-between;
}
.nav__toggle span { display: block; height: 1px; background: var(--star); transition: transform .3s, opacity .3s; }
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

.nav-mobile {
  position: fixed; inset: var(--nav-h) 0 auto 0; z-index: 99;
  background: var(--void);
  border-bottom: 1px solid var(--edge);
}
.nav-mobile nav { display: flex; flex-direction: column; padding: 8px var(--gutter) 24px; }
.nav-mobile a {
  padding: 14px 0;
  border-bottom: 1px solid var(--edge);
  font-size: var(--fs-body-lg);
  font-weight: 700;
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
}
.nav-mobile a:last-child { border-bottom: 0; }

/* ═══════════════════════ HERO ══════════════════════════ */
/* The hero scrubs like the domain sections: a tall scroller with a sticky
   full-viewport stage, so the pull-back shot plays as the visitor scrolls. */
.hero__scroller { position: relative; height: 260vh; }

.hero__stage {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  display: flex; align-items: center;
  padding: calc(var(--nav-h) + 40px) var(--gutter) 120px;
  overflow: hidden;
}

.hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  will-change: contents;
}

/* Functional legibility scrim — not decoration. */
.scrim { position: absolute; inset: 0; pointer-events: none; }
/* The hero footage is already dusk-dark, so this is lighter than the domain
   scrim — enough to hold white type over the left third, no more. */
.scrim--hero {
  background:
    linear-gradient(90deg, rgba(0,0,0,.80) 0%, rgba(0,0,0,.46) 42%, rgba(0,0,0,.10) 100%),
    linear-gradient(0deg,  rgba(0,0,0,.78) 0%, rgba(0,0,0,0) 45%);
}
/* Scrim strength is per-section: bright daylight footage needs far more hold
   than dusk footage does. Sections override these four values below. */
.scrim--domain {
  background:
    linear-gradient(90deg,
      rgba(0,0,0,var(--scrim-l,  .88)) 0%,
      rgba(0,0,0,var(--scrim-m,  .62)) 40%,
      rgba(0,0,0,var(--scrim-r2, .28)) 70%,
      rgba(0,0,0,var(--scrim-r,  .12)) 100%),
    linear-gradient(0deg,
      rgba(0,0,0,var(--scrim-b, .75)) 0%,
      rgba(0,0,0,0) 40%);
}

/* Land — Challenger 2 in full daylight, and the hull tracks straight through
   the text column. A gradient alone would have to crush the left half to near
   black to hold the type, so the clip is graded down slightly first and the
   gradient then only has to do the remaining work. The grade also pulls the
   stock-daylight green toward the monochrome system. */
/* The 40% stop sits just past the right edge of the text column, so the hold
   covers the type and the falloff to 70% hands the frame back to the tank. */
#land { --scrim-l: .94; --scrim-m: .84; --scrim-r2: .34; --scrim-r: .10; --scrim-b: .72; }
#land .domain__video { filter: brightness(.80) saturate(.82) contrast(1.04); }

/* Air — simulator hall, already dark and low-key, so this needs far less hold
   than Land and no grade at all. */
#air { --scrim-l: .90; --scrim-m: .74; --scrim-r2: .30; --scrim-r: .08; --scrim-b: .70; }

/* Naval — split-level shot: bright overcast sky and white superstructure above
   the waterline, deep blue below. The copy straddles that waterline, so it gets
   the same treatment as Land. */
#naval { --scrim-l: .94; --scrim-m: .84; --scrim-r2: .34; --scrim-r: .10; --scrim-b: .72; }
#naval .domain__video { filter: brightness(.80) saturate(.82) contrast(1.04); }

/* Space — night side of Earth, so mostly dark, but cloud and the sunrise limb
   pass through the text column. Middling hold, and no grade: the warm limb is
   the whole point of the shot and grading it flattens it. */
#space { --scrim-l: .93; --scrim-m: .83; --scrim-r2: .32; --scrim-r: .08; --scrim-b: .70; }

/* --scrub-o is written by js/main.js from the section's scroll progress.
   Each section decides in CSS which of its children ride that value. */
.hero__body {
  position: relative; z-index: 1;
  /* text block floats in the left third */
  width: min(100%, 520px);
  display: flex; flex-direction: column; gap: var(--gap);
  opacity: var(--scrub-o, 1);
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(40px, 7.4vw, 76px);
  line-height: 1.0;
  letter-spacing: var(--track-disp);
  text-transform: uppercase;
}

.hero__meta {
  position: absolute; z-index: 1;
  left: var(--gutter); right: var(--gutter); bottom: 34px;
  opacity: var(--scrub-o, 1);
}
/* Member logos have wildly different aspect ratios (5.5:1 down to 1.33:1),
   so they are sized by width to read as optically even rather than by height. */
.hero__orgs { display: flex; align-items: center; gap: clamp(20px, 4vw, 46px); flex-wrap: wrap; }
.hero__orgs img { height: auto; opacity: .72; transition: opacity .3s; }
.hero__orgs img:hover { opacity: 1; }
.hero__orgs img[alt="Infinity 6 Ltd"]          { width: 142px; }
.hero__orgs img[alt="WireNexus"]               { width: 124px; }
.hero__orgs img[alt="Infinite Precision Ltd"]  { width: 78px;  }

.scroll-cue {
  position: absolute; z-index: 1; right: var(--gutter); bottom: 34px;
  opacity: var(--scrub-o, 1);
  display: flex; align-items: center; gap: 10px;
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
  transition: color .25s;
}
.scroll-cue:hover { color: var(--star); }
.scroll-cue svg { width: 10px; height: 24px; animation: cue 2.4s ease-in-out infinite; }
@keyframes cue {
  0%, 100% { transform: translateY(0);   opacity: .45; }
  50%      { transform: translateY(5px); opacity: 1;   }
}

/* ═══════════════════ DOMAIN SECTIONS ═══════════════════ */
/* Each domain is a tall scroller with a sticky full-viewport stage.
   Scroll position through the scroller drives video.currentTime. */
/* Scroll distance is paced to clip length (~20vh of scroll per second of
   footage) so a short clip does not crawl. Override per section. */
.domain__scroller { position: relative; height: var(--scroll-span, 320vh); }

#land { --scroll-span: 200vh; }   /* 5.0s clip */
#air  { --scroll-span: 200vh; }   /* 5.0s clip */
#naval{ --scroll-span: 200vh; }   /* 5.0s clip */
#space{ --scroll-span: 200vh; }   /* 5.0s clip */

.domain__stage {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
}

.domain__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  will-change: contents;
}

.domain__hud {
  position: absolute; z-index: 2; top: calc(var(--nav-h) + 24px); left: var(--gutter);
  display: flex; align-items: center; gap: 14px;
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
}
.domain__index { color: var(--star); }
.domain__rule { width: 46px; height: 1px; background: var(--edge); }

.domain__body {
  position: absolute; z-index: 2;
  left: var(--gutter);
  top: 50%;
  transform: translateY(calc(-50% + (1 - var(--scrub-o, 1)) * 12px));
  opacity: var(--scrub-o, 1);
  width: min(calc(100% - var(--gutter) * 2), 480px);
  display: flex; flex-direction: column; gap: var(--gap);
  align-items: flex-start;
}

/* technical spec list — hairline rules, no boxes */
.spec { display: flex; flex-direction: column; }
.spec li {
  display: grid; grid-template-columns: 92px 1fr; gap: 14px;
  padding: 11px 0;
  border-top: 1px solid var(--edge);
  font-size: var(--fs-body-sm);
  line-height: 1.6;
  letter-spacing: var(--track-ui);
}
.spec li:last-child { border-bottom: 1px solid var(--edge); }
.spec span {
  font-weight: 700; text-transform: uppercase;
  font-size: var(--fs-caption); color: var(--steel);
  padding-top: 2px;
}

.domain__progress {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--edge);
}
.domain__progress i {
  display: block; height: 100%; width: 0%;
  background: var(--star);
  transform-origin: left;
}

/* ═══════════════════ GENERIC SECTION ═══════════════════ */
.section {
  padding: calc(var(--section) * 2) var(--gutter);
  border-top: 1px solid var(--edge);
}

.section__head {
  display: flex; flex-direction: column; gap: var(--gap);
  margin-bottom: calc(var(--section) + 20px);
  max-width: 720px;
}

/* ── SLIDE STAGE ───────────────────────────────────────── */
/* One pinned stage, slides cross-fading in place. Copy never travels up under
   the transparent nav — it fades where it sits, as the domain sections do. */
.vipa { border-top: 1px solid var(--edge); }

/* 460vh over five slides gives each about 700px of scroll — enough for the
   six callouts on slide 03 to arrive one at a time without feeling rushed. */
.slides__scroller { position: relative; height: var(--slides-span, 460vh); }

.slides__stage {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
}

.slide {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  padding: calc(var(--nav-h) + 34px) var(--gutter) 64px;
  opacity: 0;
}
/* opacity is written every frame while scrubbing, so a transition would lag it */
.vipa:not(.is-static) .slide { transition: none; }

/* A slide can carry a full-bleed still behind its copy. The media sits inside
   the slide, so it fades with it and needs no separate handling. */
.slide--media { padding-left: var(--gutter); padding-right: var(--gutter); }
.slide__media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.slide__media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(.94) saturate(.82) contrast(1.03);
}
/* same four-stop hold the domain scrims use, tuned to this frame */
.slide__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg,
      rgba(0,0,0,var(--scrim-l,  .90)) 0%,
      rgba(0,0,0,var(--scrim-m,  .74)) 40%,
      rgba(0,0,0,var(--scrim-r2, .34)) 70%,
      rgba(0,0,0,var(--scrim-r,  .10)) 100%),
    linear-gradient(0deg,  rgba(0,0,0,var(--scrim-b, .70)) 0%, rgba(0,0,0,0) 42%),
    /* just enough at the top to hold the nav, without flattening the sky */
    linear-gradient(180deg, rgba(0,0,0,.55) 0%, rgba(0,0,0,0) 20%);
}

.slide__inner { position: relative; z-index: 1; width: 100%; max-width: 1360px; }
.slide__inner--intro { display: flex; flex-direction: column; gap: var(--gap); }
.slide__inner--intro .lede + .lede { margin-top: -4px; }

/* slide counter, mirroring the domain HUD */
.slides__hud {
  position: absolute; z-index: 3; top: calc(var(--nav-h) + 24px); left: var(--gutter);
  display: flex; align-items: center; gap: 14px;
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
}
.slides__idx { color: var(--star); }
.slides__rule { width: 46px; height: 1px; background: var(--edge); }

.slides__progress {
  position: absolute; z-index: 3; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--edge);
}
.slides__progress i { display: block; height: 100%; width: 0%; background: var(--star); }

/* the chart runs when its slide takes the stage, not when the section does */
.slide.is-active .gauge__fill,
.is-static .slide.is-in .gauge__fill { width: var(--w); }

/* Slide 04 carries the tallest content. Trim it to clear a pinned stage on a
   720p laptop without dropping any of the copy. */
.slide__inner--delivery .delivery__head { margin-bottom: 26px; gap: 10px; }
.slide__inner--delivery .layer { padding: 18px clamp(20px, 2.4vw, 34px); }
.slide__inner--delivery .layer__desc { line-height: 1.6; }
.slide__inner--delivery .tags { margin-top: 12px; }


/* A pinned stage on a 720p laptop leaves ~550px once the nav is clear, so the
   two tallest slides are trimmed to fit rather than clipped. */
@media (max-height: 800px) {
  .slide { padding: calc(var(--nav-h) + 18px) var(--gutter) 44px; }

  .gauge { padding: 22px clamp(20px, 3vw, 40px); }
  .gauge__title { padding-bottom: 14px; margin-bottom: 20px; }
  .gauge__row + .gauge__row { margin-top: 18px; }
  .gauge__foot { margin-top: 22px; padding-top: 20px; }
  .gauge__scale { margin-top: 14px; }

  .slide__inner--delivery .layer { padding: 12px clamp(20px, 2.4vw, 34px); }
  .slide__inner--delivery .layer__desc { font-size: var(--fs-caption); line-height: 1.55; }
  .slide__inner--delivery .tag { padding: 4px 10px; }
  .slide__inner--delivery .delivery__head { margin-bottom: 18px; }
}

/* 720p leaves almost nothing spare on the delivery slide — buy back ~40px so a
   font substitution or an extra wrapped line cannot push it over. */
@media (max-height: 740px) {
  .slide__inner--delivery .layer { padding: 9px clamp(20px, 2.4vw, 34px); }
  .slide__inner--delivery .layer__role { margin-bottom: 6px; }
  .slide__inner--delivery .tags { margin-top: 8px; }
  .summation__converge { height: 46px; margin-bottom: 16px; }
  .summation__orgs { margin-bottom: 10px; }
  .slide__inner--delivery .delivery__head { margin-bottom: 14px; }
}

/* Static fallback — below the breakpoint and for reduced motion the stage
   un-pins and the slides simply stack. */
.vipa.is-static .slides__scroller { height: auto; }
.vipa.is-static .slides__stage { position: static; height: auto; overflow: visible; }
/* relative, not static: a slide with a full-bleed still needs to stay the
   containing block for it, or the media escapes and covers the whole section */
.vipa.is-static .slide {
  position: relative; opacity: 0;
  padding: var(--section) var(--gutter);
  place-items: stretch;
}
.vipa.is-static .slide.is-in { opacity: 1; }
.vipa.is-static .slide + .slide { border-top: 1px solid var(--edge); }
.vipa.is-static .slides__hud,
.vipa.is-static .slides__progress { display: none; }

/* ── VIPA ──────────────────────────────────────────────── */
.vipa__expansion {
  font-size: var(--fs-body-sm);
  font-weight: 700;
  letter-spacing: var(--track-ui);
  text-transform: uppercase;
  color: var(--steel);
  margin-top: -6px;
}

/* Headline claim, drawn to scale. Three weeks is 504 hours, so the VIPA bar is
   0.397% of the other one — the gap between the two is the argument, and it
   lands harder than two numbers sitting in a box ever did. */
.gauge {
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: clamp(26px, 3.6vw, 42px) clamp(20px, 3vw, 40px);
  margin-bottom: calc(var(--section) + 30px);
}
.gauge__title {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
  padding-bottom: 20px; margin-bottom: 28px;
  border-bottom: 1px solid var(--edge);
}

.gauge__row + .gauge__row { margin-top: 26px; }
.gauge__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 10px;
}
.gauge__name {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
}
.gauge__val {
  font-family: var(--font-display);
  font-size: clamp(26px, 4.4vw, 44px); font-weight: 700;
  line-height: 1; letter-spacing: var(--track-disp);
  text-transform: uppercase;
}
.gauge__val--was { color: var(--steel); }

.gauge__track {
  position: relative;
  height: 14px;
  background: rgba(240,240,250,.12);
}
.gauge__fill {
  position: absolute; inset: 0 auto 0 0;
  width: 0;
  min-width: 3px;   /* 0.397% would otherwise render as nothing at all */
  background: var(--star);
  transition: width var(--dur, 1.5s) cubic-bezier(.22,.61,.36,1) var(--delay, .1s);
}
.gauge__fill--was { background: var(--steel); --dur: 1.7s; }
/* the fast bar arrives fast — the animation carries the same point as the length */
.gauge__fill--now {
  --dur: .34s; --delay: 1.5s;
  top: -4px; bottom: -4px;   /* overhangs the track so 0.397% is unmissable */
  min-width: 4px;
}

[data-reveal].is-in .gauge__fill { width: var(--w); }

/* scale beneath, ticked at exact week positions */
.gauge__scale { margin-top: 20px; }
.gauge__ticks {
  height: 5px;
  background-image: linear-gradient(90deg, var(--gunmetal) 1px, transparent 1px);
  background-size: 33.3333% 100%;
  border-right: 1px solid var(--gunmetal);
}
.gauge__marks { position: relative; height: 18px; margin-top: 3px; }
.gauge__marks span {
  position: absolute; top: 4px; left: var(--p);
  font-size: var(--fs-caption); letter-spacing: var(--track-ui);
  text-transform: uppercase; color: var(--steel);
  white-space: nowrap;
}
.gauge__marks span:first-child { transform: none; }
.gauge__marks span:not(:first-child):not(:last-child) { transform: translateX(-50%); }
.gauge__marks span:last-child { transform: translateX(-100%); }

.gauge__foot {
  display: flex; align-items: center; gap: clamp(20px, 3vw, 40px);
  margin-top: 32px; padding-top: 26px;
  border-top: 1px solid var(--edge);
}
.gauge__ratio { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.gauge__ratio-n {
  font-family: var(--font-display);
  font-size: clamp(34px, 5vw, 52px); font-weight: 700;
  line-height: .9; letter-spacing: var(--track-disp);
}
.gauge__ratio-l {
  font-size: var(--fs-caption); font-weight: 700;
  line-height: 1.4; letter-spacing: var(--track-ui);
  text-transform: uppercase; color: var(--steel);
}
.gauge__note {
  font-size: var(--fs-body-sm); line-height: 1.7;
  letter-spacing: var(--track-ui);
  padding-left: clamp(20px, 3vw, 40px);
  border-left: 1px solid var(--edge);
}

/* vehicle at the centre, capability around it */
.vipa__diagram {
  display: grid;
  grid-template-columns: 1fr clamp(240px, 26vw, 380px) 1fr;
  gap: clamp(24px, 3.5vw, 60px);
  align-items: center;
}
.vipa__col { display: flex; flex-direction: column; gap: clamp(26px, 3.4vw, 48px); }

.vnode { position: relative; }
.vnode__num {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); color: var(--steel);
  margin-bottom: 8px;
}
.vnode__title {
  font-family: var(--font-display);
  font-size: var(--fs-body-lg); font-weight: 700;
  line-height: 1.25; letter-spacing: var(--track-disp);
  text-transform: uppercase;
  margin-bottom: 10px;
}
.vnode p { font-size: var(--fs-body-sm); line-height: 1.7; letter-spacing: var(--track-ui); }

/* lead lines pointing in toward the vehicle, with a node dot on the inner end */
.vipa__col--left  .vnode { text-align: right; padding-right: 26px; }
.vipa__col--right .vnode { text-align: left;  padding-left: 26px;  }

.vnode::before, .vnode::after {
  content: ''; position: absolute; top: 8px;
  width: 1px; height: calc(100% - 8px);
  background: var(--gunmetal);
}
.vipa__col--left  .vnode::before { right: 0; }
.vipa__col--right .vnode::before { left: 0; }

.vnode::after {
  top: 12px; height: 5px; width: 5px;
  border-radius: 50%; background: var(--star);
}
.vipa__col--left  .vnode::after { right: -2px; }
.vipa__col--right .vnode::after { left: -2px; }

/* the core */
.vipa__core {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1;
}
/* The vehicle is a cut-out, so it sits free rather than in a framed disc, and
   breaks the ring slightly — the platform is inside the network, not beside it. */
.vipa__vehicle {
  position: relative; z-index: 1;
  width: 108%; max-width: none; height: auto;
  /* pull the stock-photo green toward the monochrome system */
  filter: saturate(.68) brightness(.96) contrast(1.04);
}

/* a slowly turning dashed ring — reads as a live network boundary */
.vipa__ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1px dashed var(--gunmetal);
  animation: ring 90s linear infinite;
}
@keyframes ring { to { transform: rotate(360deg); } }

.vipa__core-label {
  position: absolute; bottom: -30px; left: 0; right: 0;
  text-align: center;
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
}

/* ── who builds what ───────────────────────────────────── */
.delivery {
  margin-top: calc(var(--section) * 2 + 20px);
  padding-top: var(--section);
  border-top: 1px solid var(--edge);
}
.delivery__head {
  display: flex; flex-direction: column; gap: var(--gap);
  max-width: 720px; margin-bottom: calc(var(--section) + 10px);
}
.delivery__title {
  font-family: var(--font-display);
  font-size: clamp(24px, 3.4vw, 34px); font-weight: 700;
  line-height: 1.1; letter-spacing: var(--track-disp);
  text-transform: uppercase;
}
/* Three layers of one system. The stack reads top-down the way it is actually
   built — logical layer, physical layer, then onto the platform — and closes
   with the three rolling up into a single deliverable. */
.stack {
  border: 1px solid var(--edge);
  border-radius: var(--radius);
}

.layer {
  position: relative;
  display: grid;
  grid-template-columns: 76px 1fr 160px;
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
  padding: clamp(26px, 3vw, 36px) clamp(20px, 2.4vw, 34px);
  border-bottom: 1px solid var(--edge);
  transition: background-color .35s;
}
.layer:hover { background-color: rgba(240,240,250,.03); }

/* a bar lights down the leading edge of the layer under the cursor */
.layer::before {
  content: ''; position: absolute; left: 0; top: -1px; bottom: -1px; width: 2px;
  background: var(--star);
  transform: scaleY(0); transform-origin: top;
  transition: transform .4s cubic-bezier(.22,.61,.36,1);
}
.layer:hover::before { transform: scaleY(1); }

.layer__idx {
  font-family: var(--font-display);
  font-size: clamp(32px, 4vw, 46px); font-weight: 700;
  line-height: .85; letter-spacing: var(--track-disp);
  color: var(--edge);
  transition: color .35s;
}
.layer:hover .layer__idx { color: var(--star); }

.layer__role {
  font-family: var(--font-display);
  font-size: var(--fs-body-lg); font-weight: 700;
  line-height: 1.25; letter-spacing: var(--track-disp);
  text-transform: uppercase;
  margin-bottom: 10px;
}
.layer__desc {
  font-size: var(--fs-body-sm); line-height: 1.7;
  letter-spacing: var(--track-ui);
  max-width: 68ch;
}

/* pills are the one place the system allows a 32px radius */
.tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.tag {
  border: 1px solid var(--edge);
  border-radius: var(--radius-pill);
  padding: 5px 13px;
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
  transition: color .3s, border-color .3s;
}
.layer:hover .tag { color: var(--star); border-color: var(--steel); }

/* one fixed box for every mark, so wildly different aspects still line up */
.layer__logo {
  width: 160px; height: 46px;
  object-fit: contain; object-position: right center;
  opacity: .82; align-self: start;
  transition: opacity .3s;
}
.layer:hover .layer__logo { opacity: 1; }

/* Staged reveal — js/main.js writes opacity and transform per item from the
   slide's own scroll progress, so the six callouts arrive one at a time. */
[data-stagger-item] { will-change: opacity, transform; }
/* stacked fallback: no staging, the slide reveal covers it */
.is-static [data-stagger-item] { opacity: 1 !important; transform: none !important; }

/* ── SUMMATION ─────────────────────────────────────────── */
/* The payoff line, lifted out of the stack so it reads as a conclusion rather
   than a final table row. Three ticks rise from the layers above, a rule draws
   outward, and a single line drops into the NEO mark — three becoming one. */
.summation { text-align: center; max-width: 1040px; }

/* the three members, sitting above the lines that carry them down */
.summation__orgs {
  display: grid; grid-template-columns: repeat(3, 1fr);
  align-items: center;
  margin-bottom: clamp(14px, 1.8vw, 22px);
}
.summation__orgs img {
  width: clamp(120px, 15vw, 208px); height: auto;
  margin: 0 auto; opacity: .92;
}
/* Infinite Precision is far squarer than the other two, so match by eye */
.summation__orgs img[alt="Infinite Precision Ltd"] { width: clamp(74px, 8.6vw, 122px); }

.summation__converge {
  position: relative;
  height: clamp(78px, 13vh, 132px);
  margin: 0 auto clamp(20px, 2.6vw, 32px);
}

/* dropping from each member, with a terminal at the top of every run */
.summation__tick {
  position: absolute; top: 0; left: var(--x);
  width: 2px; margin-left: -1px; height: 26px;
  background: var(--star);
  transform: scaleY(0); transform-origin: top;
  transition: transform .4s cubic-bezier(.22,.61,.36,1);
}
.summation__tick::before {
  content: ''; position: absolute; top: -4px; left: -4px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--star);
}

/* the rule they all meet on, drawn outward from the middle */
/* brackets the outer two ticks exactly, rather than overshooting them */
/* top must equal the tick height, or the runs overshoot the bus they meet on */
.summation__rule {
  position: absolute; top: 26px; left: 16.667%; right: 16.667%;
  height: 2px; background: var(--star);
  transform: scaleX(0); transform-origin: center;
  transition: transform .55s cubic-bezier(.22,.61,.36,1) .30s;
}

/* and the single bright line that carries on down — the "one" in one contract */
.summation__drop {
  position: absolute; top: 26px; left: 50%; bottom: 0;
  width: 2px; margin-left: -1px;
  background: var(--star);
  transform: scaleY(0); transform-origin: top;
  transition: transform .45s cubic-bezier(.22,.61,.36,1) .78s;
}
/* every run is terminated at the logo it serves, NEO's included */
.summation__drop::before {
  content: ''; position: absolute; bottom: -4px; left: -4px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--star);
}

.summation__mark {
  height: clamp(46px, 6.2vw, 88px); width: auto;
  margin: 0 auto clamp(20px, 2.8vw, 34px);
  opacity: 0; transform: translateY(10px);
  transition: opacity .5s ease 1.05s, transform .5s cubic-bezier(.22,.61,.36,1) 1.05s;
}

.summation__line {
  font-family: var(--font-display);
  font-size: clamp(26px, 4.2vw, 54px);
  font-weight: 700; line-height: 1.1;
  letter-spacing: var(--track-disp);
  text-transform: uppercase;
  max-width: 20ch; margin: 0 auto;
  opacity: 0; transform: translateY(10px);
  transition: opacity .5s ease 1.22s, transform .5s cubic-bezier(.22,.61,.36,1) 1.22s;
}

/* runs when slide 04 takes the stage, or on reveal in the stacked fallback */
.slide.is-active .summation__tick,
.is-static .slide.is-in .summation__tick { transform: scaleY(1); }
.slide.is-active .summation__rule,
.is-static .slide.is-in .summation__rule { transform: scaleX(1); }
.slide.is-active .summation__drop,
.is-static .slide.is-in .summation__drop { transform: scaleY(1); }
.slide.is-active .summation__mark,
.slide.is-active .summation__line,
.is-static .slide.is-in .summation__mark,
.is-static .slide.is-in .summation__line { opacity: 1; transform: none; }

/* the ticks arrive left to right, in the order of the layers they leave */
.summation__tick:nth-child(1) { transition-delay: .05s; }
.summation__tick:nth-child(2) { transition-delay: .15s; }
.summation__tick:nth-child(3) { transition-delay: .25s; }

/* ── TEAM ──────────────────────────────────────────────── */
.team__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: calc(var(--section) - 10px) var(--gutter);
}
.person { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }

.person__portrait {
  position: relative;
  width: 100%; aspect-ratio: 4 / 5;
  border: 1px solid var(--edge);
  overflow: hidden;
  filter: grayscale(1) contrast(1.05);
}
.person__portrait img { width: 100%; height: 100%; object-fit: cover; }
.person__initials {
  position: absolute; inset: 0;
  display: none; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-size: 44px; font-weight: 700;
  letter-spacing: var(--track-disp);
  color: var(--slate);
}
/* shown when no portrait file is present yet */
.person__portrait.is-empty img { display: none; }
.person__portrait.is-empty .person__initials { display: flex; }

.person__name {
  font-family: var(--font-display);
  font-size: var(--fs-body-lg); font-weight: 700;
  letter-spacing: var(--track-disp); text-transform: uppercase;
  line-height: 1.25;
}
.person__role {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel);
}
.person__bio { font-size: var(--fs-body-sm); line-height: 1.7; letter-spacing: var(--track-ui); }
.person__links { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 2px; }
.person__link {
  font-size: var(--fs-caption); letter-spacing: var(--track-ui);
  text-transform: uppercase; color: var(--steel);
  border-bottom: 1px solid var(--edge); padding-bottom: 2px;
  transition: color .25s, border-color .25s;
}
.person__link:hover { color: var(--star); border-color: var(--star); }

/* ── CAPABILITIES ──────────────────────────────────────────
   Six groups, thirty-six line items. As a flat list nobody read it, so it is
   an index the visitor drives: a numbered rail on the left, one capability on
   the stage at a time. Real ARIA tabs, so it is keyboard and screen-reader
   navigable, and it degrades to the plain stacked list without JS.
   ───────────────────────────────────────────────────────── */
.capidx {
  display: grid;
  --cap-gap: clamp(28px, 4vw, 64px);
  grid-template-columns: clamp(240px, 22vw, 320px) minmax(0, 1fr);
  gap: var(--cap-gap);
  align-items: start;
}

/* ── the rail ──────────────────────────────────────────── */
.capnav { display: flex; flex-direction: column; position: sticky; top: calc(var(--nav-h) + 28px); }

.capnav__item {
  position: relative;
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 14px;
  align-items: baseline;
  width: 100%;
  padding: 16px 0;
  border: 0;
  border-top: 1px solid var(--gunmetal);
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: border-color .3s;
}
.capnav__item:last-child { border-bottom: 1px solid var(--gunmetal); }

.capnav__n {
  font-family: var(--font-display);
  font-size: var(--fs-body-sm); font-weight: 700;
  letter-spacing: var(--track-ui);
  color: var(--edge);
  transition: color .3s;
}
.capnav__t {
  font-size: var(--fs-caption); font-weight: 700;
  line-height: 1.45; letter-spacing: var(--track-ui);
  text-transform: uppercase;
  color: var(--steel);
  transition: color .3s;
}

/* Lead line out toward the stage — the same device the VIPA diagram uses to
   say "this one connects to that". Scales from the left so it draws itself. */
.capnav__lead {
  position: absolute; left: 0; bottom: -1px;
  width: calc(100% + var(--cap-gap)); height: 1px;
  background: var(--star);
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s cubic-bezier(.22,.61,.36,1);
}
.capnav__lead::after {
  content: ''; position: absolute; right: 0; top: -2px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--star);
  opacity: 0; transition: opacity .2s .34s;
}
.capnav__item[aria-selected="true"] .capnav__lead::after { opacity: 1; }

.capnav__item:hover .capnav__n,
.capnav__item:hover .capnav__t { color: var(--star); }

.capnav__item[aria-selected="true"] .capnav__n,
.capnav__item[aria-selected="true"] .capnav__t { color: var(--star); }
.capnav__item[aria-selected="true"] .capnav__lead { transform: scaleX(1); }

/* ── the stage ─────────────────────────────────────────── */
.cappanel__h {
  font-family: var(--font-display);
  font-size: var(--fs-body-lg); font-weight: 700;
  letter-spacing: var(--track-disp); text-transform: uppercase;
  line-height: 1.25;
  margin-bottom: 18px;
}
/* On the wide layout the rail already names the active group, so repeating it
   over the stage is noise. It stays in the DOM to label the panel. */
@media (min-width: 861px) {
  .cappanel__h {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
}

.capfig {
  position: relative;
  margin: 0;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: min(52vh, 540px);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--void);
}
.capfig img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  background: var(--void);
  filter: grayscale(1) contrast(1.06);
}

/* Loading skeleton behind the photograph — the frame keeps its shape and its
   index number while a lazily-loaded image is still on the wire, so switching
   panels never collapses the layout. The photograph sits above it on z-index
   and covers it whole. */
.capfig__ph {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: clamp(20px, 3vw, 34px);
  border: 1px solid var(--gunmetal);
  border-radius: var(--radius);
}
.capfig__n {
  font-family: var(--font-display);
  font-size: clamp(40px, 7vw, 76px); font-weight: 700;
  line-height: .85; letter-spacing: var(--track-disp);
  color: var(--gunmetal);
}

/* ── the line items ────────────────────────────────────── */
.capitems {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 12px clamp(24px, 3vw, 44px);
  margin-top: 28px;
}
@media (max-width: 1180px) { .capitems { grid-template-columns: repeat(2, 1fr); } }
.capitems li {
  position: relative;
  padding-left: 18px;
  font-size: var(--fs-body-sm); line-height: 1.6;
  letter-spacing: var(--track-ui);
  color: var(--star);
}
.capitems li::before {
  content: ''; position: absolute; left: 0; top: .72em;
  width: 8px; height: 1px; background: var(--steel);
}

/* Items arrive one at a time when a panel takes the stage — the same staged
   reveal the VIPA callouts use, driven here by index rather than by scroll. */
.cappanel .capitems li,
.cappanel .capfig {
  opacity: 0; transform: translateY(12px);
}
.cappanel.is-live .capfig {
  opacity: 1; transform: none;
  transition: opacity .5s ease-out, transform .5s cubic-bezier(.22,.61,.36,1);
}
.cappanel.is-live .capitems li {
  opacity: 1; transform: none;
  transition: opacity .45s ease-out, transform .45s cubic-bezier(.22,.61,.36,1);
  transition-delay: calc(140ms + var(--i) * 55ms);
}

/* Before the section has ever been reached the stage sits idle; the reveal
   observer starts it, so the first panel animates in like everything else. */
.capstage:not(.is-in) .cappanel .capitems li,
.capstage:not(.is-in) .cappanel .capfig { transition: none; }

@media (max-width: 860px) {
  /* The rail becomes a row of numbers and the panel names itself. Six long
     labels will not sit side by side, but six two-digit numbers will. */
  .capidx { grid-template-columns: 1fr; gap: 26px; }
  .capnav {
    position: static;
    flex-direction: row; gap: 0;
    border-top: 1px solid var(--gunmetal);
    border-bottom: 1px solid var(--gunmetal);
  }
  .capnav__item {
    display: block; width: auto; flex: 1 1 0;
    padding: 14px 4px; text-align: center;
    border-top: 0; border-bottom: 0;
  }
  .capnav__item:last-child { border-bottom: 0; }
  .capnav__n { font-size: var(--fs-body); }
  .capnav__t { display: none; }
  .capnav__lead { bottom: 0; }
  .capitems { grid-template-columns: 1fr; }
}

@media (max-width: 520px) {
  .capfig { aspect-ratio: 4 / 3; max-height: none; }
}

/* Hairline-by-gap: the column count must divide the 4 stats exactly. */
.stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; margin-top: calc(var(--section) + 20px);
  background: var(--edge); border: 1px solid var(--edge);
}
@media (max-width: 860px) { .stats { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .stats { grid-template-columns: 1fr; } }
.stat { background: var(--void); padding: var(--pad-card); display: flex; flex-direction: column; gap: 6px; }
.stat__n {
  font-family: var(--font-display);
  font-size: 40px; font-weight: 700; line-height: 1;
  letter-spacing: var(--track-disp);
}
.stat__l {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase; color: var(--steel);
}

/* ── CONTACT ───────────────────────────────────────────── */
.contact__inner {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: calc(var(--section) + 20px) var(--gutter);
  align-items: start;
}
.contact__intro { display: flex; flex-direction: column; gap: var(--gap); }

.contact__details { display: flex; flex-wrap: wrap; gap: 34px; margin-top: 10px; }
.contact__details dt {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel); margin-bottom: 8px;
}
.contact__details dd { margin: 0; font-size: var(--fs-body-sm); letter-spacing: var(--track-ui); line-height: 1.7; }
.contact__details a { border-bottom: 1px solid var(--edge); transition: border-color .25s; }
.contact__details a:hover { border-color: var(--star); }

.form {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--gap);
}
.field { display: flex; flex-direction: column; gap: 8px; }
.field--full { grid-column: 1 / -1; }
.field label {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase; color: var(--steel);
}
.field input, .field select, .field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: transparent;
  color: var(--star);
  font-family: var(--font);
  font-size: var(--fs-body);
  letter-spacing: var(--track-ui);
  transition: border-color .25s;
  appearance: none;
}
.field select {
  /* chevron drawn inline so no external asset is needed */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23a0a0aa'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 10px;
  padding-right: 36px;
}
.field select option { background: var(--void); color: var(--star); }
.field textarea { resize: vertical; line-height: 1.7; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--star); outline: none; }
.field.is-invalid input, .field.is-invalid textarea { border-color: var(--star); }

/* .field is a column flex container — reset to a row so the button and its
   status note sit side by side and left-aligned, not stacked and centred. */
.form__actions {
  display: flex; flex-direction: row;
  align-items: center; justify-content: flex-start;
  gap: var(--gap); flex-wrap: wrap;
}
/* Honeypot — off-screen rather than display:none, which some bots skip. */
.hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

.form__note {
  font-size: var(--fs-caption); letter-spacing: var(--track-ui);
  text-transform: uppercase; color: var(--steel);
}

/* ── FOOTER ────────────────────────────────────────────── */
.footer { border-top: 1px solid var(--edge); padding: var(--section) var(--gutter) 34px; }
.footer__top {
  display: flex; flex-wrap: wrap; gap: var(--section);
  align-items: flex-start; justify-content: space-between;
  padding-bottom: var(--section);
}
.footer__mark { height: 90px; width: auto; opacity: .9; }

.footer__orgs-label {
  font-size: var(--fs-caption); font-weight: 700;
  letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--steel); margin-bottom: 20px;
}
.footer__orgs-row { display: flex; align-items: center; gap: clamp(22px, 4vw, 50px); flex-wrap: wrap; }
.footer__orgs-row img { height: auto; opacity: .78; transition: opacity .3s; }
.footer__orgs-row img:hover { opacity: 1; }
.footer__orgs-row img[alt="Infinity 6 Ltd"]         { width: 158px; }
.footer__orgs-row img[alt="WireNexus"]              { width: 138px; }
.footer__orgs-row img[alt="Infinite Precision Ltd"] { width: 88px;  }

/* Sits above the copyright line rather than inside it — a statement about the
   whole site, not a legal afterthought bolted onto the credits. */
.footer__disclosure {
  padding-top: 26px;
  border-top: 1px solid var(--edge);
}
/* The rule runs the full width of the footer; the measure is held on the text
   itself, so a short paragraph does not leave a short hairline behind it. */
.footer__disclosure p {
  max-width: 74ch;
  font-size: var(--fs-body-sm);
  line-height: 1.7;
  letter-spacing: var(--track-ui);
  color: var(--steel);
}

.footer__bottom {
  display: flex; flex-wrap: wrap; gap: var(--gap);
  align-items: center; justify-content: space-between;
  padding-top: 26px;
  font-size: var(--fs-caption); letter-spacing: var(--track-ui);
  text-transform: uppercase; color: var(--steel);
}
.footer__links { display: flex; gap: 24px; }
.footer__links a { transition: color .25s; }
.footer__links a:hover { color: var(--star); }

/* ── reveal-on-scroll ──────────────────────────────────── */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .7s cubic-bezier(.22,.61,.36,1), transform .7s cubic-bezier(.22,.61,.36,1);
}
[data-reveal].is-in { opacity: 1; transform: none; }

/* stagger children within a group — .caps__list is gone; the capability index
   stages its own items off .cappanel.is-live instead */
.stack [data-reveal]:nth-child(2),
.team__grid [data-reveal]:nth-child(2) { transition-delay: .07s; }
.stack [data-reveal]:nth-child(3),
.team__grid [data-reveal]:nth-child(3) { transition-delay: .14s; }
.stack [data-reveal]:nth-child(4) { transition-delay: .21s; }
.stack [data-reveal]:nth-child(5) { transition-delay: .28s; }
.stack [data-reveal]:nth-child(6) { transition-delay: .35s; }

/* ═══════════════════ RESPONSIVE ════════════════════════ */
@media (max-width: 1080px) {
  /* No pinned stages at this size, so content travels under the nav. It keeps
     its naked look at the top of the page and gains a ground once scrolled.
     That solid fill supersedes the scrim, which would only add a gradient
     tail hanging below it. */
  .nav.is-scrolled { background: var(--void); }
  .nav::before { display: none; }

  .nav__links { display: none; }
  .nav__cta   { display: none; }
  .nav__toggle { display: flex; }
  .nav { gap: 16px; justify-content: space-between; }
}

@media (max-width: 760px) {
  :root { --nav-h: 60px; }

  .form { grid-template-columns: 1fr; }

  /* Seeking video on scroll is expensive on mobile — sections loop instead.
     Shorter scrollers keep the page from feeling endless. */
  .domain__scroller { height: var(--scroll-span-sm, 175vh); }
  #land, #air, #naval, #space { --scroll-span-sm: 130vh; }
  .domain__body { top: auto; bottom: 96px; transform: none; }
  .domain__hud { top: calc(var(--nav-h) + 16px); }

  .hero__stage { padding-bottom: 172px; }
  .hero__scroller { height: 190vh; }
  .hero__meta { bottom: 78px; }
  .scroll-cue { bottom: 34px; right: auto; left: var(--gutter); }

  .footer__mark { height: 66px; }
  .footer__top { gap: 40px; }
}

@media (max-width: 420px) {
  .spec li { grid-template-columns: 1fr; gap: 4px; }
}

/* VIPA diagram: below this the vehicle cannot sit between two columns, so the
   core moves to the top and every callout lines up left. */
@media (max-width: 1040px) {
  .vipa__diagram { grid-template-columns: 1fr; gap: clamp(28px, 5vw, 44px); }
  .vipa__core {
    order: -1;
    width: min(320px, 68vw);
    margin: 0 auto calc(var(--section) - 16px);
  }
  .vipa__col--left  .vnode,
  .vipa__col--right .vnode { text-align: left; padding: 0 0 0 26px; }
  .vipa__col--left  .vnode::before,
  .vipa__col--right .vnode::before { left: 0; right: auto; }
  .vipa__col--left  .vnode::after,
  .vipa__col--right .vnode::after  { left: -2px; right: auto; }

  /* index and mark move above the copy rather than squeezing three columns */
  .layer { grid-template-columns: 1fr auto; gap: 6px 20px; }
  .layer__idx { grid-column: 1; }
  .layer__logo { grid-column: 2; grid-row: 1; align-self: start; width: 130px; height: 38px; }
  .layer__main { grid-column: 1 / -1; margin-top: 10px; }
}

@media (max-width: 640px) {
  /* the 120px floor overlaps three-across on a 390px screen */
  .summation__orgs img { width: clamp(64px, 24vw, 110px); }
  .summation__orgs img[alt="Infinite Precision Ltd"] { width: clamp(40px, 15vw, 68px); }
  .summation__converge { height: 62px; }
  .summation__tick { height: 20px; }
  .summation__rule { top: 20px; }
  .summation__drop { top: 20px; }
  .summation__tick::before { width: 8px; height: 8px; top: -3px; left: -3px; }
  .summation__drop::before { width: 8px; height: 8px; bottom: -3px; left: -3px; }

  .gauge__foot { flex-direction: column; align-items: flex-start; gap: 22px; }
  .gauge__note { padding-left: 0; border-left: 0; }
  /* "Week 1/2/3" will not fit under a 340px track — the end points carry it */
  .gauge__marks span:not(:first-child):not(:last-child) { display: none; }
}

/* ── reduced motion ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .domain__scroller, .hero__scroller { height: 100vh; }
  .domain__stage, .hero__stage { position: relative; }
  .domain__body, .hero__body, .hero__meta, .scroll-cue { opacity: 1 !important; }
  .domain__body { transform: translateY(-50%); }
}

/* ── print ─────────────────────────────────────────────── */
@media print {
  .nav, .nav-mobile, .scroll-cue, .domain__progress, video { display: none !important; }
  body { background: #fff; color: #000; }
  /* the ramp is tuned for black — re-point it at white paper */
  :root {
    --star: #000000; --steel: #4a4a52; --slate: #5e5e66;
    --edge: #9a9aa2; --gunmetal: #c4c4c9;
  }
  .domain__scroller, .hero__scroller { height: auto; }
  .domain__stage, .hero__stage { position: static; height: auto; padding: 40px 0; }
  .domain__body { position: static; transform: none; width: auto; }
}
