/* ============================================================
   JOHN R CLARK JR. — DESIGN SYSTEM
   Deep navy-black canvas, cream + restrained teal accents.
   ============================================================ */

/* ---------- Fonts ---------- */
@font-face {
  font-family: "Anton";
  src: url("/assets/fonts/anton-latin.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("/assets/fonts/inter-var-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: "Great Vibes"; /* reserved EXCLUSIVELY for the name mark */
  src: url("/assets/fonts/greatvibes-latin.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --navy: #0B1628;
  --navy-2: #15243B;
  --navy-3: #1d3050;
  --cream: #F4F0E8;
  --cream-dim: rgba(244, 240, 232, 0.62);
  --teal: #1BA5C4;
  /* teal darkened for text on cream — the bright teal only hits ~2.5:1
     on #F4F0E8 and fails AA; this holds the brand hue at ~5.2:1 */
  --teal-deep: #0E6E85;
  --teal-glow: rgba(27, 165, 196, 0.45);
  --display: "Anton", "Arial Narrow", sans-serif;
  --body: "Inter", -apple-system, "Helvetica Neue", sans-serif;
  --script: "Great Vibes", cursive;
  --gutter: clamp(20px, 5vw, 96px);
  --nav-h: 76px;
  /* Stage unit. Type inside the pinned stages was sized off viewport WIDTH
     while the blocks were positioned off viewport HEIGHT, so a wide-but-
     short screen (13" laptop with a bookmarks bar) kept the big type and
     lost the gap — measured -148px of overlap at 1440x780.
     1vw === 1.6vh at the 16:10 design ratio, so --u is EXACTLY 1vw at the
     size the design was approved at and only shrinks on shorter screens.
     Defaults to plain 1vw so nothing outside a stage changes. */
  --u: 1vw;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);   /* "rise"  */
  --ease-glide: cubic-bezier(0.30, 0.86, 0.24, 1);
  --ease-settle: cubic-bezier(0.77, 0, 0.18, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: auto; }
html, body { overflow-x: clip; }
body {
  background: var(--navy);
  color: var(--cream);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video, canvas { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

::selection { background: var(--teal); color: var(--navy); }

.skip-link {
  position: fixed; top: -60px; left: 16px; z-index: 300;
  background: var(--cream); color: var(--navy);
  padding: 10px 18px; border-radius: 4px; font-weight: 600;
  transition: top 0.2s var(--ease-glide);
}
.skip-link:focus { top: 12px; }

/* Focus visibility */
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--cream);
  outline-offset: 3px;
  border-radius: 2px;
}

.kicker {
  font-size: 12px; letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--teal); font-weight: 600; margin-bottom: 18px;
}
.section-title {
  font-family: var(--display);
  font-size: clamp(34px, calc(5.4 * var(--u)), 78px);
  line-height: 1.04;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  font-weight: 400;
}

/* ============================================================
   LOADER
   ============================================================ */
.loader {
  position: fixed; inset: 0; z-index: 200;
  background: var(--navy);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 28px;
  transition: opacity 0.7s var(--ease-out), visibility 0.7s;
}
.loader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
.loader__sig { width: min(66vw, 460px); }
.loader__sig svg { width: 100%; height: auto; overflow: visible; }
.loader__sig .sig-glyph {
  opacity: 0;
  transform: translateY(6px);
}
.loader.is-writing .sig-glyph {
  animation: sigWrite 0.45s var(--ease-out) forwards;
  animation-delay: calc(var(--d, 0) * 0.12s);
}
@keyframes sigWrite {
  to { opacity: 1; transform: translateY(0); }
}
.loader__bar {
  width: min(46vw, 300px); height: 1px;
  background: rgba(244, 240, 232, 0.15);
  overflow: hidden;
}
.loader__bar span {
  display: block; height: 100%; width: 0%;
  background: var(--teal);
  transition: width 0.25s var(--ease-glide);
}
.loader__pct {
  font-size: 11px; letter-spacing: 0.4em; color: var(--cream-dim);
}

/* ============================================================
   CURSOR + GRAIN
   ============================================================ */
.cursor {
  position: fixed; top: 0; left: 0; z-index: 250;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--cream);
  pointer-events: none;
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  transition: width 0.25s var(--ease-out), height 0.25s var(--ease-out), opacity 0.3s var(--ease-glide);
  opacity: 0;
}
.cursor.is-active { opacity: 1; }
.cursor.is-hover { width: 46px; height: 46px; }
@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

.grain {
  position: fixed; inset: -100px; z-index: 90;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainShift 0.9s steps(4) infinite;
}
@keyframes grainShift {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-32px, 18px); }
  50% { transform: translate(22px, -26px); }
  75% { transform: translate(-14px, -12px); }
  100% { transform: translate(0, 0); }
}

/* ============================================================
   NAV
   ============================================================ */
/* A faint always-on scrim. .is-scrolled only lands past 60px, so in the
   hero the nav text used to sit bare over a canvas whose luminance changes
   every frame. This floors the contrast without reading as a bar. */
.nav {
  background: linear-gradient(rgba(11, 22, 40, 0.55), transparent);
  position: fixed; top: 0; left: 0; right: 0; z-index: 120;
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--gutter);
  transition: background 0.4s var(--ease-glide), backdrop-filter 0.4s var(--ease-glide), box-shadow 0.4s var(--ease-glide);
}
.nav.is-scrolled {
  background: rgba(11, 22, 40, 0.72);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 rgba(244, 240, 232, 0.07);
}
/* explicit breathing room to the link group. Without it the gap is just
   whatever justify-content:space-between leaves over — a residual, not a
   designed value, and the client read it as cramped. */
.nav__logo { width: 178px; flex: 0 0 auto; margin-right: clamp(24px, 4vw, 64px); }
.nav__logo svg { width: 100%; height: auto; }
.nav__logo .sig-glyph { opacity: 1; }
.nav__links { display: flex; gap: clamp(18px, 3vw, 44px); }
.nav__links a {
  /* 0.22em matches .btn — the site's convention for uppercase microcopy.
     Colour is set LOCALLY, not via --cream-dim: that token is shared with
     .hero__sub, .takeaway__support and others. At 62% alpha over the
     animating orbit canvas these were genuinely hard to read. */
  font-size: 13px; letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(244, 240, 232, 0.86);
  transition: color 0.25s var(--ease-glide);
  position: relative;
}
.nav__links a::after {
  content: ""; position: absolute; left: 0; bottom: -6px;
  width: 100%; height: 1px; background: var(--teal);
  transform: scaleX(0); transform-origin: right;
  transition: transform 0.35s var(--ease-out);
}
.nav__links a:hover { color: var(--cream); }
.nav__links a:hover::after { transform: scaleX(1); transform-origin: left; }

.nav__burger {
  display: none;
  width: 44px; height: 44px;
  flex-direction: column; align-items: center; justify-content: center; gap: 7px;
}
.nav__burger span {
  display: block; width: 24px; height: 2px; background: var(--cream);
  transition: transform 0.35s var(--ease-out);
}
.nav__burger[aria-expanded="true"] span:first-child { transform: translateY(4.5px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child { transform: translateY(-4.5px) rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: 0; z-index: 110;
  background: rgba(11, 22, 40, 0.96);
  backdrop-filter: blur(18px);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity 0.4s var(--ease-glide), visibility 0.4s var(--ease-glide);
}
.mobile-menu.is-open { opacity: 1; visibility: visible; }
.mobile-menu nav { display: flex; flex-direction: column; align-items: center; gap: 34px; }
.mobile-menu nav a:not(.btn) {
  font-family: var(--display);
  font-size: 34px; text-transform: uppercase; letter-spacing: 0.04em;
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 16px 34px;
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase;
  border-radius: 999px;
  position: relative;
  transition: transform 0.3s var(--ease-out), background 0.3s var(--ease-glide), color 0.3s var(--ease-glide), border-color 0.3s var(--ease-glide), box-shadow 0.3s var(--ease-glide);
  will-change: transform;
  white-space: nowrap;
}
.btn--primary {
  background: var(--cream); color: var(--navy);
}
.btn--primary:hover {
  box-shadow: 0 0 0 1px var(--cream), 0 8px 40px rgba(244, 240, 232, 0.25);
}
.btn--ghost {
  border: 1px solid rgba(244, 240, 232, 0.35); color: var(--cream);
}
.btn--ghost:hover { border-color: var(--teal); color: var(--cream); box-shadow: 0 0 24px rgba(27, 165, 196, 0.2); }
.btn--small { padding: 12px 24px; font-size: 11px; }
.btn--large { padding: 20px 44px; font-size: 14px; }

/* ============================================================
   HERO
   ============================================================ */
.hero { position: relative; }
.hero__pin {
  position: relative;
  --u: min(1vw, 1.6vh);
  height: 100vh; height: 100svh;
  overflow: clip;
}
.hero__canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 1;
  /* Under --hero-zoom < 1 the frame stops covering the canvas. The orbit
     frames' own surround measures RGB(0,5,14) and is near-uniform
     (stddev < 5), so painting the same colour behind makes the join
     invisible rather than a visible letterbox. */
  background: #000509;
}
.hero__cutout {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 3;
  pointer-events: none;
  /* MUST match HERO_ZOOM in main.js. The cutout and the canvas are
     cross-faded into each other; if they scale differently you see two
     Johns at different sizes. Both scale about their shared centre, and
     both sources carry the same 1.777 aspect, so the geometry stays
     registered. */
  transform: scale(var(--hero-zoom, 1));
  transform-origin: 50% 50%;
}
/* Blue scrim / haze over the WHOLE hero stage.

   Sits ABOVE the cutout (canvas 1 -> title 2 -> cutout 3 -> scrim 4 ->
   copy/cue 5), so it veils both John layers identically and leaves the
   positioning line and CTAs untouched. Underneath it the two John layers
   also get a slight desaturate, which is what makes it read as haze
   rather than as a flat sheet of colour laid on top.

   Three stacked layers, top to bottom in paint order:
     1. teal bloom through the upper-middle — the haze itself
     2. an even blue veil across the full frame
     3. a deeper foot so the copy has something to sit on            */
.hero__scrim {
  position: absolute; inset: 0;
  z-index: 4;
  pointer-events: none;
  background:
    radial-gradient(ellipse 92% 78% at 50% 40%,
      rgba(27, 165, 196, 0.26) 0%,
      rgba(27, 165, 196, 0.13) 42%,
      rgba(27, 165, 196, 0.03) 72%,
      transparent 88%),
    linear-gradient(rgba(21, 36, 59, 0.34), rgba(21, 36, 59, 0.34)),
    linear-gradient(to top,
      rgba(11, 22, 40, 0.94) 0%,
      rgba(11, 22, 40, 0.78) 18%,
      rgba(11, 22, 40, 0.42) 38%,
      transparent 64%);
}
/* the haze reads on John, not just over him */
.hero__canvas, .hero__cutout { filter: saturate(0.88) contrast(0.97); }
.hero__title-wrap {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  z-index: 2; /* between canvas and cutout: text passes BEHIND John */
  pointer-events: none;
  /* Clearance for the copy block below. The clamp alone was not enough on a
     short screen: it shrinks with the viewport while the copy block's own
     height (positioning line + subhead + CTAs) stays fixed, so the two close
     on each other. Measured at 1440 wide, the gap ran 137px at 1080 tall,
     56px at 900, 11px at 800 and -25px at 720 — the name and the copy
     overlapping from about 780px down.
     --hero-name-clear is measured in main.js from the copy block's real
     height and offset, and only wins when it is genuinely bigger, so the
     approved composition on a tall screen is untouched. */
  padding-bottom: max(clamp(90px, 16vh, 200px), var(--hero-name-clear, 0px));
}
.hero__title {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  text-align: center;
  line-height: 0.92;
  font-size: clamp(64px, 13.5vw, 220px);
  letter-spacing: 0.02em;
  color: var(--cream);
}
.hero__line { display: block; white-space: nowrap; }
.hero__line .char { display: inline-block; will-change: transform, opacity; }
/* At rest the whole title sits BEHIND John (cutout above). Once the
   orbit takes over the cutout dissolves and the same letters ride in
   FRONT of him — depth in both directions with one text layer. */

.hero__copy {
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(84px, 13vh, 140px);
  z-index: 5;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  padding: 0 var(--gutter);
}
/* The copy sits over the display title and over John, both of which are
   busy. The scrim foot above does most of the separation; these add the
   last bit of lift without changing the type design. */
.hero__positioning {
  font-size: clamp(15px, 1.6vw, 19px);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 18px rgba(11, 22, 40, 0.9), 0 0 3px rgba(11, 22, 40, 0.7);
}
.hero__sub {
  margin-top: 8px;
  font-size: clamp(13px, 1.3vw, 16px);
  /* was --cream-dim (62%) — too quiet against the hero at this size */
  color: rgba(244, 240, 232, 0.82);
  max-width: 560px;
  text-shadow: 0 1px 16px rgba(11, 22, 40, 0.85);
}
/* the outline CTA loses its edge over a busy frame — give it a floor */
.hero__ctas .btn--ghost {
  border-color: rgba(244, 240, 232, 0.55);
  background: rgba(11, 22, 40, 0.30);
  backdrop-filter: blur(2px);
}
.hero__ctas .btn--ghost:hover { background: rgba(11, 22, 40, 0.45); }
.hero__ctas { display: flex; gap: 16px; margin-top: 26px; flex-wrap: wrap; justify-content: center; }

.hero__scrollcue {
  position: absolute; bottom: 22px; left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  font-size: 10px; letter-spacing: 0.42em; text-transform: uppercase;
  color: var(--cream-dim);
}
.hero__scrollcue-line {
  width: 1px; height: 44px;
  background: linear-gradient(to bottom, var(--teal), transparent);
  animation: cueDrop 1.8s var(--ease-out) infinite;
  transform-origin: top;
}
@keyframes cueDrop {
  0% { transform: scaleY(0); opacity: 0; }
  35% { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1) translateY(10px); opacity: 0; }
}

/* ============================================================
   STATS
   ============================================================ */
/* The stats are the proof beat — they need to read as their own chapter,
   not a continuation of the hero. Two separator treatments; pick with
   <html data-sep="ledger|seam">. */
.stats {
  position: relative;
  padding: clamp(80px, 12vh, 150px) var(--gutter);
  isolation: isolate;
}
.stats__inner {
  position: relative; z-index: 2;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(28px, 4vw, 60px);
  max-width: 1400px; margin: 0 auto;
}
.stat { text-align: left; position: relative; padding-left: 22px; }
.stat::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 1px;
}
.stat__value {
  font-family: var(--display);
  font-size: clamp(44px, 5.6vw, 92px);
  line-height: 1;
  letter-spacing: 0.01em;
}
/* "Update so that it all stays with similar spacing (1 line heading, 2 line
   subheading)" — the four sublabels run 26 to 64 characters, so left to
   themselves they wrap to one, two and three lines and the cards no longer
   line up. Both fields now RESERVE their line count regardless of length. */
.stat__label {
  margin-top: 10px;
  font-size: 13px; font-weight: 600; letter-spacing: 0.24em;
  line-height: 1.35;
  min-height: 1.35em;          /* exactly one line */
}
.stat__sublabel {
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.5;
  max-width: 240px;
  min-height: 3em;             /* exactly two lines at 1.5 */
}

/* wave belongs to the seam variant only */
.stats__wave { display: none; }

/* ---------- VARIANT: LEDGER (default) ----------------------------
   A cream proof band between two dark cinematic sections. The numbers
   read like a printed fact sheet, and the return to navy for THE STORY
   feels like the film resuming. Edges fade into the navy on both sides
   so the band sits in the film rather than being pasted onto it. */
[data-sep="ledger"] .stats { background: var(--cream); }
[data-sep="ledger"] .stats::before,
[data-sep="ledger"] .stats::after {
  content: ""; position: absolute; z-index: 1;
  left: 0; right: 0; height: clamp(70px, 9vh, 130px);
  pointer-events: none;
}
[data-sep="ledger"] .stats::before {
  top: 0;
  background: linear-gradient(to bottom, var(--navy), rgba(11, 22, 40, 0));
}
[data-sep="ledger"] .stats::after {
  bottom: 0;
  background: linear-gradient(to top, var(--navy), rgba(11, 22, 40, 0));
}
/* inverted type: #15243B per the design system's light-section rule */
[data-sep="ledger"] .stat__value { color: var(--navy-2); }
[data-sep="ledger"] .stat__label { color: var(--teal-deep); }
[data-sep="ledger"] .stat__sublabel { color: rgba(21, 36, 59, 0.72); }
[data-sep="ledger"] .stat::before {
  background: linear-gradient(to bottom, var(--teal-deep), rgba(14, 110, 133, 0));
}

/* LEDGER also carries the drawn wave, sitting in the lower fade where
   the cream band resolves into the navy. It reads as the divider between
   the proof band and THE STORY, and draws left->right on scroll. */
[data-sep="ledger"] .stats__wave {
  display: block;
  position: absolute; z-index: 2;      /* above the ::after fade */
  left: 0; right: 0;
  bottom: clamp(6px, 1.6vh, 26px);     /* sits in the darker half of the fade */
  height: clamp(46px, 6vw, 70px);
  pointer-events: none;
}
[data-sep="ledger"] .stats__wave svg { width: 100%; height: 100%; overflow: visible; }
/* the SVG's own gradient fades to cream at both ends — right for a dark
   panel, invisible on this light band. Override with solid teal. */
[data-sep="ledger"] #seamPath {
  stroke: var(--teal);
  stroke-width: 2.5;
  filter: drop-shadow(0 0 8px rgba(27, 165, 196, 0.7));
}
[data-sep="ledger"] #seamNode { filter: drop-shadow(0 0 9px rgba(27, 165, 196, 0.95)); }

/* ---------- VARIANT: SEAM ----------------------------------------
   Stays in the dark. The band lifts onto its own surface and a hairline
   wave draws left→right across the boundary as you scroll. */
[data-sep="seam"] .stats {
  background: var(--navy-2);
  border-top: 1px solid rgba(244, 240, 232, 0.07);
  padding-bottom: clamp(110px, 15vh, 190px);
}
[data-sep="seam"] .stat__value { color: var(--cream); }
[data-sep="seam"] .stat__label { color: var(--teal); }
[data-sep="seam"] .stat__sublabel { color: var(--cream-dim); }
[data-sep="seam"] .stat::before {
  background: linear-gradient(to bottom, var(--teal), transparent);
}
[data-sep="seam"] .stats__wave {
  display: block;
  position: absolute; z-index: 3;
  left: 0; right: 0; bottom: -1px;
  height: clamp(56px, 7vw, 80px);
  pointer-events: none;
  /* the surface change resolves into the void beneath the wave */
  background: linear-gradient(to bottom, rgba(21, 36, 59, 0), var(--navy) 78%);
}
[data-sep="seam"] .stats__wave svg { width: 100%; height: 100%; overflow: visible; }
[data-sep="seam"] #seamPath { filter: drop-shadow(0 0 6px rgba(27, 165, 196, 0.45)); }
[data-sep="seam"] #seamNode { filter: drop-shadow(0 0 8px rgba(27, 165, 196, 0.9)); }

/* ============================================================
   PILLARS
   ============================================================ */
.pillars { position: relative; }
/* THE STAGE GRID.
   Three rows: intro / elastic slack / pillar slot. Grid rows cannot
   overlap, so the intro and the pillar copy are structurally incapable of
   colliding however short the viewport gets — the middle row absorbs the
   slack instead. Replaces `top: 20vh` + `bottom: 14vh`, which had no idea
   how tall their own contents were. */
.pillars__pin {
  position: relative;
  --u: min(1vw, 1.6vh);
  height: 100vh; height: 100svh;
  overflow: clip;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto minmax(0, 1fr) auto;
  row-gap: clamp(16px, 3vh, 44px);
  padding: clamp(96px, 14vh, 170px) var(--gutter) clamp(72px, 12vh, 130px);
}
.pillars__media { position: absolute; inset: 0; background: var(--navy); }
.city-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}
.city2d {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}
.city2d__d rect { vector-effect: non-scaling-stroke; }
/* the city is already dark — only ground the copy zone */
.pillars__scrim--city {
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to right, rgba(11, 22, 40, 0.72) 0%, rgba(11, 22, 40, 0.28) 44%, transparent 72%),
    linear-gradient(to top, rgba(11, 22, 40, 0.82), transparent 38%);
}
.pillars__intro {
  grid-row: 1; grid-column: 1;
  justify-self: start;
  z-index: 2;
  /* was 760px, which was NARROWER than "Built from the ground up." set in
     Anton at 78px — so each of the two <br> lines wrapped again and the
     headline silently rendered as FOUR lines, 324px tall. Widening to the
     line's natural width is what the <br> always intended. */
  max-width: min(100%, 980px);
}
/* All five pillars share ONE grid cell, so the row is as tall as the
   tallest of them and they cross-fade in place exactly as before. */
.pillar {
  grid-row: 3; grid-column: 1;
  justify-self: start;
  align-self: end;
  z-index: 2;
  max-width: 560px;
  opacity: 0;
  visibility: hidden;
}
.pillar__num {
  font-family: var(--display);
  font-size: clamp(60px, calc(8 * var(--u)), 120px);
  /* block, not inline: as an inline span its box was driven by Anton's
     ascent/descent and measured 174px for a 115px glyph — 48% of the
     whole pillar block for a decorative numeral. Digits have no
     descenders, so 0.86 clears the caps with nothing cut off. */
  display: block;
  line-height: 0.86;
  color: transparent;
  -webkit-text-stroke: 1px rgba(244, 240, 232, 0.35);
}
.pillar__title {
  font-family: var(--display);
  font-size: clamp(34px, calc(4.4 * var(--u)), 64px);
  /* was inheriting the body's 1.6 — 101px of line box for a 63px word. */
  line-height: 1.02;
  text-transform: uppercase;
  margin-top: 10px;
  letter-spacing: 0.02em;
}
.pillar__title::after {
  content: ""; display: block;
  width: 74px; height: 3px; margin-top: 12px;
  background: var(--teal);
  box-shadow: 0 0 18px var(--teal-glow);
}
.pillar__text { margin-top: 16px; color: var(--cream-dim); font-size: clamp(14px, calc(1.35 * var(--u)), 17px); max-width: 470px; }

/* ============================================================
   WORK
   ============================================================ */
.work { position: relative; padding: clamp(90px, 14vh, 170px) 0; }
.work__media { position: absolute; inset: 0; }
.work__video { width: 100%; height: 100%; object-fit: cover; }
.work__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(rgba(11, 22, 40, 0.93), rgba(11, 22, 40, 0.88) 30%, rgba(11, 22, 40, 0.95));
}
.work__inner { position: relative; z-index: 2; padding: 0 var(--gutter); max-width: 1440px; margin: 0 auto; }
/* Two proofs, each its own scroll beat. No cards, no boxes, no grid of
   tiles — the visual sits opposite the story and the three ideas reveal
   in sequence. Sides alternate for rhythm. */
.proof {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  align-items: center;
  gap: clamp(28px, 5vw, 90px);
  margin-top: clamp(56px, 10vh, 130px);
  perspective: 1400px;
}
.proof--flip .proof__visual { order: 2; }

.proof__visual {
  display: flex; align-items: center; justify-content: center;
  min-height: clamp(240px, 32vw, 400px);
  /* the glow that used to sit inside the card, now unboxed */
  background: radial-gradient(ellipse at 50% 60%, rgba(27, 165, 196, 0.10), transparent 70%);
  transform-style: preserve-3d;
  will-change: transform;
}
.proof__visual svg { width: min(92%, 560px); height: auto; max-height: 100%; overflow: visible; }

.proof__title {
  font-family: var(--display);
  font-size: clamp(30px, 4vw, 58px);
  text-transform: uppercase;
  letter-spacing: 0.015em;
  line-height: 1.05;
  margin-bottom: clamp(20px, 3vh, 34px);
}
.proof__beat {
  padding-left: 20px;
  position: relative;
  margin-bottom: clamp(16px, 2.4vh, 26px);
}
.proof__beat::before {           /* a hairline that steps down the three beats */
  content: ""; position: absolute; left: 0; top: 4px; bottom: 4px;
  width: 1px; background: linear-gradient(to bottom, var(--teal), rgba(27, 165, 196, 0));
}
.proof__label {
  display: block;
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.32em; text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 6px;
}
.proof__line {
  font-size: clamp(15px, 1.5vw, 18px);
  line-height: 1.5;
  color: var(--cream);
  max-width: 46ch;
}
.proof__cta {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: clamp(14px, 2.4vh, 28px);
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--cream);
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(244, 240, 232, 0.25);
  transition: color 0.3s var(--ease-glide), border-color 0.3s var(--ease-glide);
}
.proof__arrow { transition: transform 0.35s var(--ease-out); }
.proof__cta:hover { color: var(--teal); border-color: var(--teal); }
.proof__cta:hover .proof__arrow { transform: translateX(6px); }

@media (max-width: 900px) {
  /* stack: visual above story, pure scroll sequence, no hover needed */
  .proof { grid-template-columns: 1fr; gap: clamp(20px, 4vh, 34px); }
  .proof--flip .proof__visual { order: 0; }
  .proof__visual { min-height: clamp(200px, 52vw, 300px); }
}



.card__map-nodes circle { fill: var(--navy); stroke: var(--cream); stroke-width: 1.4; }
.card__map-center { fill: var(--teal); }
.card__map-pulse {
  fill: none; stroke: var(--teal); stroke-width: 2;
  transform-origin: 280px 180px;
  animation: mapPulse 3s var(--ease-glide) infinite;
}
@keyframes mapPulse {
  0% { transform: scale(1); opacity: 0.8; }
  100% { transform: scale(2.6); opacity: 0; }
}
.card__map-labels text { font-family: var(--body); font-size: 11px; letter-spacing: 0.14em; opacity: 0.75; }
.card__map-labels .card__map-center-label {
  font-family: var(--display); font-size: 15px; opacity: 1; fill: var(--navy);
}
.card__pipe-flow { stroke-dasharray: 8 10; animation: pipeFlow 1.2s linear infinite; }
@keyframes pipeFlow { to { stroke-dashoffset: -18; } }
.card__pipe-person { fill: var(--cream); }
.card__pipe-person-label { font-size: 20px; }
.card__pipe-labels text { font-family: var(--body); font-size: 11px; letter-spacing: 0.14em; opacity: 0.75; }
.card__title {
  font-family: var(--display);
  font-size: clamp(24px, 2.6vw, 38px);
  text-transform: uppercase;
  margin-top: 10px;
  line-height: 1.1;
  letter-spacing: 0.015em;
}
.card__text { margin-top: 14px; color: var(--cream-dim); font-size: 15px; }

/* ============================================================
   TIMELINE
   ============================================================ */
.timeline { position: relative; background: var(--navy); }
/* A real grid row inside the pin, not an absolute overlay. As an overlay
   it had no idea how tall the track below it was and the two collided by
   7-9px at 1440x780 and 1280x720 — the client's "need a little space
   between timeline and title". */
.timeline__head {
  grid-row: 1; grid-column: 1;
  justify-self: start;
  padding: 0 var(--gutter);
  z-index: 3;
  max-width: 900px;
}
/* smaller than a standalone .section-title — it shares the stage with the
   track instead of owning its own screen */
.timeline__head .section-title { font-size: clamp(30px, calc(4.4 * var(--u)), 64px); }
.timeline__note { margin-top: 16px; color: var(--cream-dim); }
.timeline__pin {
  position: relative;
  --u: min(1vw, 1.6vh);
  height: 100vh; height: 100svh;
  overflow: clip;
  /* Two rows: head / track, both content-sized, and the PAIR is centred in
     the stage — "can we make the timeline in the middle of the screen".
     minmax(0,1fr) on the track row would have pinned the block to the top
     and pushed the track low: measured 138px below the screen centre.
     Symmetric padding keeps the centred block honest while still clearing
     the fixed nav at the top. */
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto;
  align-content: center;
  row-gap: clamp(20px, 4vh, 56px);
  padding: clamp(76px, 10vh, 120px) 0;
}
.timeline__track {
  position: relative;
  /* the track is far wider than the viewport — it must NOT be stretched
     to the grid column, or the chapters would be squeezed */
  grid-row: 2; grid-column: 1;
  justify-self: start;
  align-self: center;
  width: max-content;
  display: flex;
  /* tightened from clamp(60px, 7vw, 120px) to shorten the whole section */
  gap: clamp(40px, 5vw, 80px);
  padding: 0 8vw 0 var(--gutter);
  will-change: transform;
}
.timeline__track::before {
  content: "";
  position: absolute;
  left: 0; right: -60vw; top: 0;
  height: 1px;
  background: rgba(244, 240, 232, 0.12);
}
.chapter {
  position: relative;
  flex: 0 0 auto;
  /* narrowed from clamp(240px, 24vw, 330px) — with the tighter track gap
     this is what actually shortens the horizontal distance, and the pin
     length follows it automatically via getDistance(). */
  width: clamp(220px, 20vw, 280px);
  padding-top: 54px;
}
.chapter__node {
  position: absolute;
  top: -7px; left: 0;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--navy);
  border: 2px solid var(--cream);
  z-index: 2;
}
.chapter--ongoing .chapter__node { border-color: var(--teal); box-shadow: 0 0 16px var(--teal-glow); }
.chapter__seg {
  position: absolute;
  top: 0; left: 0; height: 1px;
  background: var(--cream);
  width: 0;
}
.chapter--ongoing .chapter__seg {
  background: linear-gradient(to right, var(--teal), rgba(27, 165, 196, 0.35));
  box-shadow: 0 0 12px var(--teal-glow);
}
.chapter--ongoing .chapter__seg::after {
  content: "";
  position: absolute; right: -3px; top: -2.5px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 14px var(--teal);
  animation: ongoingPulse 2s var(--ease-settle) infinite;
}
@keyframes ongoingPulse {
  0%, 100% { opacity: 0.6; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.5); }
}
.chapter__index {
  font-family: var(--display);
  font-size: 15px;
  color: transparent;
  -webkit-text-stroke: 1px rgba(244, 240, 232, 0.4);
  letter-spacing: 0.06em;
}
.chapter--ongoing .chapter__index { -webkit-text-stroke: 1px var(--teal); }
.chapter__title {
  font-family: var(--display);
  font-size: clamp(20px, 1.9vw, 27px);
  text-transform: uppercase;
  line-height: 1.12;
  margin-top: 8px;
  letter-spacing: 0.02em;
}
.chapter__company { margin-top: 8px; font-size: 13px; color: var(--cream); font-weight: 600; }
.chapter__dates {
  margin-top: 4px; font-size: 12px; letter-spacing: 0.18em;
  color: var(--teal); font-weight: 600;
}
.chapter--done .chapter__dates { color: var(--cream-dim); }
.chapter__detail { margin-top: 10px; font-size: 13.5px; color: var(--cream-dim); }
.chapter--ongoing .chapter__title { text-shadow: 0 0 30px rgba(27, 165, 196, 0.35); }

/* ---- the reward: five lines converge into John past TODAY ---- */
.chapter-reward {
  position: relative;
  flex: 0 0 auto;
  /* "John's body and rays smaller so that John and rays can also be in the
     middle section". At 1040x500 the panel towered over 280px-wide chapters
     whose content is ~300px tall, so John dominated the band instead of
     sitting in it. Same 2.08 aspect, so the rays keep their shape.
     The subtraction is the stage's own furniture (padding + head + row
     gap) — it keeps the panel inside the centred block on short screens,
     where overflow would be clipped rather than absorbed. */
  width: min(58vw, 750px);
  height: min(360px, calc(100svh - 350px));
  align-self: center;
  margin-left: clamp(40px, 6vw, 110px);
}
.chapter-reward__lines {
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
}
.chapter-reward__john {
  position: absolute;
  right: 0; bottom: 0;
  height: 96%;
  width: auto; max-width: none;
  object-fit: contain;
  object-position: bottom right;
  filter: drop-shadow(0 0 60px rgba(27, 165, 196, 0.18));
  pointer-events: none;
}
.chapter-reward__copy {
  position: absolute;
  left: 0; bottom: 14%;
  max-width: 46%;
}
.chapter-reward__title {
  font-family: var(--display);
  font-size: clamp(30px, 3.6vw, 58px);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: 0.015em;
}
.chapter-reward__title span { display: block; }
.chapter-reward__title span:last-child { color: var(--teal); text-shadow: 0 0 34px rgba(27, 165, 196, 0.4); }
.chapter-reward__sub {
  margin-top: 12px;
  color: var(--cream-dim);
  font-size: clamp(14px, 1.3vw, 17px);
  letter-spacing: 0.04em;
}

.timeline__present {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: clamp(70px, 8vw, 130px);
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(to right, transparent, rgba(27, 165, 196, 0.1));
  border-left: 1px dashed rgba(27, 165, 196, 0.4);
  z-index: 3;
}
.timeline__present span {
  font-size: 11px; letter-spacing: 0.4em; font-weight: 600;
  color: var(--teal);
  writing-mode: vertical-rl;
  text-orientation: mixed;
}

/* ============================================================
   IN HIS OWN WORDS  —  the cinematic pause
   Quieter than everything above it. Almost nothing on screen to
   begin with; the video frame earns prominence as you scroll.
   ============================================================ */
.words { position: relative; background: var(--navy); }
.words__pin {
  position: relative;
  --u: min(1vw, 1.6vh);
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: clamp(80px, 12vh, 150px) var(--gutter) clamp(110px, 16vh, 200px);
  overflow: clip;
}
.words__kicker { text-align: center; }

.words__statement {
  font-family: var(--display);
  font-size: clamp(30px, 5vw, 76px);
  line-height: 1.06;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  text-align: center;
  max-width: 18ch;
  color: var(--cream);
  /* both statements occupy the SAME optical slot so one gives way to
     the other rather than the page growing a second headline */
  grid-area: 1 / 1;
  z-index: 2;
  pointer-events: none;
}
.words__statement[data-words-line="2"] { color: var(--cream); }

/* the two statements share one centred cell above the frame */
.words__pin { }
/* Centring is applied in main.js as xPercent/yPercent, NOT here. GSAP
   animates y on these statements, and GSAP owns the whole transform: it
   snapshots any CSS transform into pixels on first touch, then an explicit
   `y` overwrites the vertical half outright. That is measurable — the
   statements were sitting 76px BELOW centre. Percent units in GSAP resolve
   against the element's live size on every render, so they survive both the
   animation and any later resize. */
.words__statement { position: absolute; left: 50%; top: 50%; }

.words__frame {
  position: relative;
  z-index: 1;
  margin: 0;
  /* A 1100px-wide 16:9 frame is 619px tall, which with this pin's own
     padding overflowed every viewport shorter than ~970px and pushed the
     frame under the centred statement. Cap the WIDTH by the available
     height (not max-height, which would break the 16:9 and letterbox the
     video). 280px is the pin's own padding; at 900 tall this still
     resolves above 1100, so the approved size is unchanged. */
  width: min(100%, 1100px, calc((100svh - 280px) * 16 / 9));
  aspect-ratio: 16 / 9;
  border: 1px solid rgba(244, 240, 232, 0.16);
  background:
    radial-gradient(ellipse at 50% 50%, rgba(27, 165, 196, 0.07), transparent 70%),
    var(--navy-2);
  display: flex; align-items: center; justify-content: center;
  will-change: transform, opacity;
}
/* thin inner rule — a frame awaiting footage, not a fake player */
.words__frame::after {
  content: ""; position: absolute; inset: 10px;
  border: 1px solid rgba(244, 240, 232, 0.06);
  pointer-events: none;
}
.words__placeholder { text-align: center; padding: var(--gutter); }

/* ---- the real video: a facade until it is clicked ---------------- */
/* Nothing of YouTube's is loaded until the button is pressed, so what sits
   in the layout is our poster and our play control. The iframe replaces
   them on the click. */
.words__play {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; cursor: pointer;
  background: transparent;
}
.words__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* matches the hero's grade so the still sits in the same world */
  filter: saturate(0.88) contrast(0.97);
}
.words__play-ring {
  position: relative; z-index: 1;
  width: clamp(56px, 7vw, 92px); aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid rgba(244, 240, 232, 0.72);
  background: rgba(11, 22, 40, 0.42);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.3s var(--ease-glide), border-color 0.3s var(--ease-glide), transform 0.4s var(--ease-out);
}
.words__play:hover .words__play-ring,
.words__play:focus-visible .words__play-ring {
  background: rgba(27, 165, 196, 0.34);
  border-color: var(--cream);
  transform: scale(1.06);
}
/* the triangle, drawn rather than shipped as an asset */
.words__play-tri {
  width: 0; height: 0;
  margin-left: 14%;                       /* optical centring, not geometric */
  border-top: 0.44em solid transparent;
  border-bottom: 0.44em solid transparent;
  border-left: 0.74em solid var(--cream);
  font-size: clamp(18px, 2.2vw, 30px);    /* the em units above scale off this */
}
.words__iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}
.words__frame.is-playing { background: #000; }
.words__name {
  font-family: var(--display);
  font-size: clamp(22px, 2.6vw, 40px);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--cream);
}
.words__desc {
  margin-top: 12px;
  font-size: clamp(12px, 1.2vw, 15px);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--teal);
  max-width: 34ch; margin-left: auto; margin-right: auto;
}
.words__note {
  margin-top: 22px;
  font-size: 13px;
  color: var(--cream-dim);
  letter-spacing: 0.04em;
}

@media (max-width: 767.98px) {
  /* mobile: no pin, no overlap — a plain sequence so the video is easy
     to reach and watch */
  /* The client asked for the DESKTOP choreography here, so mobile keeps the
     pinned centre stage rather than collapsing to a flow block. The two
     statements must therefore stay in one absolute slot — a flow layout
     cannot cross-fade them without the page growing a second headline.
     Symmetric padding also answers "too much spacing underneath video
     before next section": the frame is centred in the stage instead of
     sitting on a 140px floor. */
  .words__pin { padding: clamp(56px, 9vh, 92px) var(--gutter); }
  .words__statement { font-size: clamp(27px, 7.6vw, 40px); max-width: 15ch; }
  .words__frame { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .words__pin { min-height: 0; display: block; }
  .words__statement { position: static; transform: none; text-align: left; margin: 18px 0 0; max-width: none; }
  .words__kicker { text-align: left; }
  .words__frame { margin-top: 40px; opacity: 1 !important; }
}

/* ============================================================
   THE OTHER SIDE OF THE TABLE  —  the level meeting

   The plainest block on the page, on purpose. The words section
   above is a large bordered frame; this one is empty space, so the
   contrast in density is what separates them — not a divider.

   BASE styles below are the no-JS / mobile / reduced-motion state:
   a plain stacked block, everything visible, nothing overlapping.
   The pinned centre-stage layout only switches on when JS adds
   .beside--staged, so a script failure degrades to readable copy
   rather than to a pile of absolutely-positioned text.
   ============================================================ */
.beside { position: relative; background: var(--navy); }
.beside__pin {
  position: relative;
  --u: min(1vw, 1.6vh);
  padding: clamp(90px, 14vh, 170px) var(--gutter);
}
.beside__kicker { text-align: center; }

/* auto margins so the BASE (no-JS / reduced-motion) state is a tidy
   centred column too — staged mode centres with flex, but the static
   fallback has no flex parent and would otherwise sit left-anchored. */
.beside__lockup {
  position: relative;
  width: min(100%, 980px);
  margin-left: auto; margin-right: auto;
}

/* the table edge — the entire visual metaphor, one shared line */
.beside__rule {
  display: block;
  height: 1px;
  width: 100%;
  transform-origin: 50% 50%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(244, 240, 232, 0.34) 12%,
    rgba(244, 240, 232, 0.34) 88%,
    transparent
  );
}

/* two halves of ONE statement, meeting at the centre gutter.
   Same size, same weight, same baseline — equal, never stacked. */
.beside__statement {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: clamp(18px, 3.4vw, 56px);
  margin-top: clamp(22px, 3.4vh, 40px);
  font-family: var(--display);
  font-size: clamp(28px, 4.4vw, 64px);
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  font-weight: 400;
}
.beside__half { display: block; }
.beside__half--a { text-align: right; color: var(--cream); }
.beside__half--b { text-align: left;  color: var(--teal); }

.beside__support {
  margin: clamp(34px, 5vh, 58px) auto 0;
  max-width: 58ch;
  text-align: center;
  color: var(--cream-dim);
  font-size: clamp(15px, 1.5vw, 18px);
  line-height: 1.68;
}

.beside__closing { margin-top: clamp(40px, 7vh, 70px); }
/* Was the ONLY element on the site set in the body face (Inter) at headline
   scale, weight 500, mixed case, negative tracking — which is why it read as
   "a different font / something wrong". Now matches .beside__statement. */
.beside__close {
  max-width: 26ch;
  margin-left: auto; margin-right: auto;
  text-align: center;
  color: var(--cream);
  font-family: var(--display);
  font-size: clamp(21px, 2.7vw, 38px);
  line-height: 1.24;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.015em;
}

/* ---- staged: the pinned, centre-stage version (desktop + motion) ---- */
.beside--staged .beside__pin {
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  overflow: clip;
}
/* The closing line is centred by FLEX, not by a transform — GSAP owns
   the transform on .beside__close and would clobber a translate here. */
.beside--staged .beside__closing {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  margin-top: 0;
  padding: 0 var(--gutter);
  z-index: 3;
  pointer-events: none;
}

@media (max-width: 767.98px) {
  /* "Would like Beside You to be NEXT TO Not Above You like it is on
     desktop. Adds the play on words." It was stacking to one column and
     left-aligning, which loses the metaphor entirely — the two halves have
     to meet either side of the shared rule. Kept at two columns; at 390px
     each column is ~165px so each half wraps to two lines
     ("NOT ABOVE / YOU."), which still reads as one statement across the
     rule. Centre alignment restored to match desktop. */
  .beside__pin { padding: clamp(56px, 9vh, 92px) var(--gutter); }
  .beside__statement {
    gap: clamp(10px, 3vw, 18px);
    font-size: clamp(22px, 7vw, 34px);
  }
  .beside__support { font-size: 15px; }
  .beside__close { font-size: clamp(19px, 5.6vw, 28px); }
}

/* ============================================================
   TAKEAWAY  —  the empty-handed payoff

   Built on the PILLARS composition, not on a centred content block:
   a pinned full-viewport stage, copy anchored to the left gutter,
   one dominant thought at a time in the lower slot. Type scales,
   the accent bar, the scrim and the beat rhythm are all borrowed
   from .pillars so the two read as the same system.

   BASE styles are the no-JS / mobile / reduced-motion state: a plain
   stacked block in document flow. The pinned stage only switches on
   when JS adds .takeaway--staged.
   ============================================================ */
.takeaway { position: relative; }
.takeaway__pin {
  position: relative;
  padding: clamp(90px, 14vh, 170px) var(--gutter);
}

.takeaway__media { position: absolute; inset: 0; background: var(--navy); }
.takeaway__photo { position: absolute; inset: -6% 0; margin: 0; }
.takeaway__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* navy/cream duotone — unchanged from the original section */
  filter: grayscale(1) contrast(1.04) brightness(0.62) sepia(0.22) hue-rotate(178deg) saturate(0.9);
  will-change: transform;
}
/* left-weighted, exactly like .pillars__scrim--city: grounds the copy
   column without flattening the whole frame */
.takeaway__scrim {
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to right, rgba(11, 22, 40, 0.72) 0%, rgba(11, 22, 40, 0.28) 44%, transparent 72%),
    linear-gradient(to top, rgba(11, 22, 40, 0.82), transparent 38%);
}

.takeaway__intro { position: relative; z-index: 2; max-width: 900px; }
.takeaway__head { max-width: 20ch; }
.takeaway__emphasis {
  font-family: var(--display);
  font-size: clamp(46px, 8.4vw, 138px);
  line-height: 0.96;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  margin-top: clamp(6px, 1.2vh, 16px);
  color: var(--cream);
}
/* the pillars accent bar, same 74x3 and same glow */
.takeaway__emphasis::after {
  content: ""; display: block;
  width: 74px; height: 3px;
  margin-top: clamp(14px, 2.2vh, 24px);
  background: var(--teal);
  box-shadow: 0 0 18px var(--teal-glow);
}

.takeaway__support {
  position: relative; z-index: 2;
  /* tightened per client feedback — was clamp(28px, 4.5vh, 52px) */
  margin-top: clamp(16px, 2.4vh, 28px);
  max-width: 470px;
  color: var(--cream-dim);
  font-size: clamp(14px, 1.35vw, 17px);
  line-height: 1.7;
}

.takeaway__beats { position: relative; z-index: 2; }
.leave { margin-top: clamp(26px, 4vh, 48px); }
.leave__title {
  font-family: var(--display);
  font-size: clamp(42px, 7.6vw, 118px);
  line-height: 0.98;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  font-weight: 400;
  color: var(--cream);
}
/* same accent bar as .pillar__title, on every beat — it anchors the
   lower-left composition so the stage never reads as an empty frame
   with one phrase floating in it */
.leave__title::after {
  content: ""; display: block;
  width: 74px; height: 3px;
  margin-top: clamp(14px, 2.2vh, 24px);
  background: var(--teal);
  box-shadow: 0 0 18px var(--teal-glow);
}
/* the last thought carries the teal through to "POSSIBLE." in the
   finale directly below — recolour both or neither */
.leave[data-leave="3"] .leave__title { color: var(--teal); }

/* ---- staged: the pinned stage (desktop + motion) ---- */
.takeaway--staged .takeaway__pin {
  height: 100vh; height: 100svh;
  padding: 0;
  overflow: clip;
}
.takeaway--staged .takeaway__intro {
  position: absolute;
  left: var(--gutter); right: var(--gutter);
  top: 17vh;
}
/* support and the three beats share ONE slot, the .pillar slot */
.takeaway--staged .takeaway__support,
.takeaway--staged .leave {
  position: absolute;
  left: var(--gutter); right: var(--gutter);
  bottom: 15vh;
  margin-top: 0;
}
.takeaway--staged .takeaway__beats {
  position: absolute; inset: 0;
  pointer-events: none;
}
.takeaway--staged .leave { opacity: 0; visibility: hidden; }

/* ============================================================
   CONNECT
   ============================================================ */
.connect {
  position: relative;
  background:
    radial-gradient(ellipse 70% 55% at 50% 100%, rgba(27, 165, 196, 0.13), transparent),
    var(--navy);
  /* deliberately more air than any other section: with one invitation
     and nothing else on it, the space IS the composition */
  padding: clamp(130px, 21vh, 270px) var(--gutter);
  border-top: 1px solid rgba(244, 240, 232, 0.06);
}
.connect__inner { max-width: 1100px; margin: 0 auto; text-align: center; }
.connect__title {
  font-family: var(--display);
  font-size: clamp(52px, 9.5vw, 160px);
  line-height: 0.98;
  text-transform: uppercase;
  letter-spacing: 0.015em;
}
.connect__line { display: block; overflow: hidden; }
.connect__line em { font-style: normal; color: var(--teal); }
.connect__sub {
  margin: clamp(28px, 4.4vh, 46px) auto 0;
  max-width: 640px;
  color: var(--cream-dim);
  font-size: clamp(15px, 1.5vw, 18px);
}
.connect__ctas {
  display: flex; gap: 18px; justify-content: center;
  margin-top: clamp(52px, 7.5vh, 88px); flex-wrap: wrap;
}

/* .field, .connect__form-actions and .form-status are still in use by the
   BOOKING MODAL — do not remove them with the inline form's styles. */
.field { margin-bottom: 18px; }
.field label {
  display: block;
  font-size: 11px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--cream-dim); font-weight: 600;
  margin-bottom: 8px;
}
.field__optional {
  font-weight: 400; letter-spacing: 0.12em;
  color: rgba(244, 240, 232, 0.4);
}
/* First <select> on the site — it needs every rule the inputs get, plus
   appearance:none and its own chevron, because a native macOS/iOS select
   ignores font:inherit and paints its own control. <option> needs an
   explicit background too: the parent's rgba() does not inherit into the
   native dropdown list on Windows/Linux. */
.field select {
  appearance: none; -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--cream-dim) 50%),
    linear-gradient(135deg, var(--cream-dim) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 2px), calc(100% - 13px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 42px;
  cursor: pointer;
}
.field select option { background: var(--navy-2); color: var(--cream); }
.field select:invalid { color: var(--cream-dim); }

.field input, .field textarea, .field select {
  width: 100%;
  background: rgba(11, 22, 40, 0.75);
  border: 1px solid rgba(244, 240, 232, 0.14);
  border-radius: 10px;
  color: var(--cream);
  padding: 14px 16px;
  font: inherit;
  transition: border-color 0.25s var(--ease-glide), box-shadow 0.25s var(--ease-glide);
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px rgba(27, 165, 196, 0.18);
}
.connect__form-actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.form-status { font-size: 13px; color: var(--teal); }
.form-status.is-error { color: #e06c6c; }

/* ============================================================
   MODAL
   ============================================================ */
.modal { position: fixed; inset: 0; z-index: 180; display: flex; align-items: center; justify-content: center; }
.modal[hidden] { display: none; }
.modal__backdrop {
  position: absolute; inset: 0;
  background: rgba(4, 9, 18, 0.8);
  backdrop-filter: blur(8px);
}
.modal__panel {
  position: relative;
  width: min(640px, calc(100vw - 32px));
  max-height: min(86vh, 900px);
  overflow-y: auto;
  background: var(--navy-2);
  border: 1px solid rgba(244, 240, 232, 0.1);
  border-radius: 20px;
  padding: clamp(24px, 4vw, 44px);
  animation: modalIn 0.45s var(--ease-out);
}
@keyframes modalIn {
  from { opacity: 0; transform: translateY(26px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.modal__close {
  position: absolute; top: 14px; right: 18px;
  font-size: 30px; line-height: 1;
  color: var(--cream-dim);
  transition: color 0.2s var(--ease-glide), transform 0.3s var(--ease-out);
  width: 44px; height: 44px;
}
.modal__close:hover { color: var(--cream); transform: rotate(90deg); }
.modal__title { font-family: var(--display); font-size: clamp(24px, 3vw, 34px); text-transform: uppercase; }
.modal__sub { color: var(--cream-dim); margin: 10px 0 24px; }
.modal__calendly { margin-top: 18px; border-radius: 12px; overflow: hidden; background: var(--navy); }
.modal__fallback {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-left: 2px solid var(--teal);
  background: rgba(27, 165, 196, 0.08);
  font-size: 14px;
  line-height: 1.55;
  color: var(--cream);
}
.modal__fallback a { color: var(--teal); text-decoration: underline; }

.modal__calendly iframe { width: 100%; height: min(62vh, 660px); border: 0; }

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  border-top: 1px solid rgba(244, 240, 232, 0.07);
  padding: clamp(60px, 9vh, 110px) var(--gutter) 40px;
  text-align: center;
}
.footer__sig { width: min(300px, 60vw); margin: 0 auto; }
.footer__sig svg { width: 100%; height: auto; }
.footer__sig .sig-glyph { opacity: 1; }
.footer__links {
  display: flex; gap: clamp(16px, 3vw, 38px);
  justify-content: center; flex-wrap: wrap;
  margin-top: 38px;
}
.footer__links a {
  font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--cream-dim);
  transition: color 0.25s var(--ease-glide);
}
.footer__links a:hover { color: var(--teal); }
.footer__statement {
  margin-top: 40px;
  font-size: 15px;
  color: var(--cream);
  letter-spacing: 0.04em;
}
.footer__legal { margin-top: 14px; font-size: 12px; color: rgba(244, 240, 232, 0.4); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 980px) {
  .stats__inner { grid-template-columns: repeat(2, 1fr); }
  .nav__links, .nav__cta { display: none; }
  .nav__burger { display: flex; }
}
/* Timeline goes vertical below 768px — must match the JS isMobile
   breakpoint exactly, since the scroll engine branches on it too. */
@media (max-width: 767.98px) {
  .timeline__pin { height: auto; display: block; overflow: visible; padding-top: 0; }
  /* head returns to normal flow once the pin is unset, or it would sit on
     top of the track */
  .timeline__head {
    position: static;
    max-width: 1100px;
    /* "Add spacing to the left of title element on mobile" — this shorthand
       used to zero the horizontal padding, so the head sat flush at x=0
       while the chapters below it were indented to the gutter at x=20. */
    padding: clamp(70px, 12vh, 130px) var(--gutter) clamp(24px, 4vh, 44px);
  }
  .timeline__head .section-title { font-size: clamp(30px, 7.4vw, 46px); }
  .timeline__track {
    flex-direction: column;
    gap: 46px;
    padding: 0 var(--gutter) 80px;
    /* undo the desktop grid-item sizing — as a column flex container
       max-content would take the widest chapter's unwrapped width */
    width: auto;
  }
  .timeline__track::before {
    left: calc(var(--gutter) + 6px); right: auto; top: 0; bottom: 0;
    width: 1px; height: auto;
  }
  .chapter { width: 100%; padding-top: 0; padding-left: 40px; }
  .chapter__node { top: 6px; left: 0; }
  .chapter__seg { display: none; }
  .chapter-reward {
    width: 100%;
    height: auto;
    min-height: 480px;
    margin: 30px 0 0;
  }
  .chapter-reward__john {
    height: 72%;
    left: 50%; right: auto;
    /* NO transform here. GSAP animates y on this element for the "John
       rises" reveal, and a GSAP transform REPLACES the CSS one — the
       translateX(-50%) that centred him was silently dropped, which pushed
       a 619px-wide image to start at x=195 on a 390px screen. Everything
       on screen was then the image's empty left margin, which is exactly
       the client's "image of John does not show on any mobile device".
       The centring is done with xPercent in main.js instead, so GSAP
       composes it into the same transform it is already writing. */
    object-position: bottom center;
  }
  .chapter-reward__copy {
    max-width: none;
    left: 0; right: 0; bottom: 0;
    text-align: center;
  }
  .timeline__present {
    position: static;
    width: auto; height: 60px;
    border-left: 0; border-top: 1px dashed rgba(27, 165, 196, 0.4);
    background: linear-gradient(to bottom, transparent, rgba(27, 165, 196, 0.08));
    margin: 0 var(--gutter);
  }
  .timeline__present span { writing-mode: horizontal-tb; }

  /* --- HERO on phones ---------------------------------------------
     John cover-fits a portrait viewport at 1.67x and renders WIDER than
     the screen, burying the name mark behind him. Scale him back and set
     the name to nearly the full width, so it reads either side of him the
     way it does on desktop. 0.68 MUST equal HERO_ZOOM in main.js. */
  .hero__pin { --hero-zoom: 0.68; }
  .hero__title { font-size: clamp(62px, 23.5vw, 128px); }
  /* the name is the graphic on a phone — let it sit higher, clear of the
     copy block, now that John no longer fills the frame */
  .hero__title-wrap { padding-bottom: clamp(140px, 26vh, 300px); }
}

@media (max-width: 640px) {
  /* The name mark must be WIDER than John or it cannot read behind him.
     At 0.68 zoom he is ~70% of the screen; 23.6vw puts the name at ~92%,
     leaving it visible either side. This rule sits after the 767.98px
     block and would otherwise override it. */
  .hero__title { font-size: clamp(62px, 23.6vw, 128px); }
  .hero__copy { bottom: clamp(64px, 10vh, 110px); }
  .hero__ctas .btn { padding: 14px 26px; font-size: 12px; }
  .stats__inner { grid-template-columns: 1fr; }
  .pillar { right: var(--gutter); max-width: none; }
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
  .grain { display: none; }
  .hero__scrollcue { display: none; }
  .pillar { opacity: 1 !important; visibility: visible !important; position: relative; left: auto; bottom: auto; margin: 40px var(--gutter); }
  .pillars__pin { height: auto; padding: 80px 0; display: block; }
  .pillars__intro { position: relative; top: auto; margin: 0 var(--gutter) 20px; }
  .pillars__media { position: absolute; }
  .timeline__pin { height: auto; display: block; overflow: visible; padding-top: 0; }
  /* head returns to normal flow once the pin is unset, or it would sit on
     top of the track */
  .timeline__head {
    position: static;
    max-width: 1100px;
    padding: clamp(70px, 12vh, 130px) 0 clamp(24px, 4vh, 44px);
  }
  .timeline__head .section-title { font-size: clamp(30px, 7.4vw, 46px); }
  .timeline__track { flex-wrap: wrap; padding-right: var(--gutter); }
  .timeline__present { display: none; }
  .hero__cutout { display: none; }
}

/* JS-driven helper states */
.no-scroll { overflow: hidden; }
