/* Foundry Revenue Partners — page styles.
   Built to the style reference: editorial broadsheet, monochrome
   canvas, one saturated accent used like a highlighter. Every
   value resolves to a token. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--surface-canvas);
  color: var(--color-typesetter-ink);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  line-height: var(--leading-prose);
  font-weight: var(--font-weight-regular);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
a:hover { color: var(--color-accent-edge); }
:focus-visible { outline: 3px solid var(--color-highlighter-green); outline-offset: 4px; }
::selection { background: var(--color-highlighter-green); color: var(--color-typesetter-ink); }

.wrap { max-width: var(--page-max-width); margin-inline: auto; padding-inline: var(--gutter); }

/* The skip link is FIXED, not absolute: the scroll wrapper is
   transformed, so an absolute link would land off-screen. */
.skip {
  position: fixed; left: -9999px; z-index: 120;
  background: var(--color-press-black); color: var(--color-bone-white);
  padding: var(--spacing-10) var(--spacing-20);
}
.skip:focus { left: var(--spacing-20); top: var(--spacing-20); }

/* ---------- micro-typography: the chrome of the whole design ---------- */
.micro {
  font-family: var(--font-ui);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
  text-transform: uppercase;
  font-weight: var(--font-weight-w550);
}

/* ---------- background: fine contour lines ---------- */
.bg-lines {
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  z-index: -1; pointer-events: none;
  background-color: var(--color-shadow-moss);
  opacity: 0.24;
  -webkit-mask-image: url('/bg-lines.svg'); mask-image: url('/bg-lines.svg');
  -webkit-mask-size: cover; mask-size: cover;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}

/* ---------- preloader ---------- */
.loader {
  position: fixed; inset: 0; z-index: 100;
  background: var(--surface-dark-section);
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: var(--spacing-40); padding: var(--gutter);
  will-change: transform;
}
.loader-row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--spacing-20); flex-wrap: wrap;
}
/* The loader carries the lockup reversed out, sized against the counter beside
   it so the two read as one line rather than one shouting over the other.
   The tag's width/height are the display size, not the artwork's native
   515x148 — the loader is the first thing anyone sees, and it must not appear
   at native size for the moment before the stylesheet lands. */
.loader-mark { line-height: 0; }
.loader-mark img {
  display: block;
  height: clamp(34px, 5.4vw, 62px);
  width: auto;
}
.loader-count {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 5vw, 3.25rem);
  line-height: var(--leading-flat);
  letter-spacing: var(--tracking-display);
  color: var(--color-newsprint-gray);
  font-variant-numeric: tabular-nums;
}
.loader-track { height: 1px; width: 100%; background: var(--color-slate-verdant); overflow: hidden; }
.loader-bar { height: 1px; width: 0%; background: var(--color-highlighter-green); }
.loader.is-lifting { transition: transform 1s cubic-bezier(0.76, 0, 0.24, 1); transform: translateY(-100%); }
.loader.is-done { display: none; }

/* ---------- the page wrapper ----------
   An ordinary container: the browser does the scrolling. */
.scroll-wrap { position: relative; z-index: 1; }

/* ---------- scroll reveals ---------- */
.reveal { opacity: 0; transform: translateY(20px); }
.js-reveals .reveal {
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.is-in { opacity: 1; transform: none; }

/* ---------- nav ---------- */
.nav {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--spacing-20); padding-block: var(--spacing-30); position: relative;
}
/* The wordmark is the logo lockup now, not set type.

   The width/height ON THE TAG are the DISPLAY size, not the artwork's native
   515x148. They do two jobs: reserve the right space so the nav does not jump
   as the file arrives, and — the reason they were changed — give a sane result
   if this stylesheet has not loaded. With the native numbers there, a stale or
   missing site.css renders the lockup 515px wide across the top of the page. */
/* The wordmark's height, shared with the floating menu button, which is
   pinned level with it. */
:root { --wordmark-h: clamp(26px, 3vw, 34px); }
.wordmark { display: block; align-self: center; line-height: 0; }
.wordmark img {
  display: block;
  /* Sized by what the SMALLER line of the lockup needs to stay readable, not
     by what looks tidy in the corner. At 22px the words inside it were less
     legible than the set type they replaced, which is a strange trade for a
     logo. The floor holds on a phone, where 3vw would be far too small. */
  height: var(--wordmark-h);
  width: auto;
}
.nav .micro { border-bottom: 1px solid currentColor; padding-bottom: 3px; }

/* ---------- display type ---------- */
h1, h2 {
  font-family: var(--font-display);
  font-weight: var(--font-weight-regular);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  margin: 0;
}

/* Hero. "Revenue Systems" carries no photo, so it is the widest
   line and defines the measure: the h1 sizes to max-content and
   the lines that do have photos flex to match it. */
h1 {
  width: max-content; max-width: 90vw; margin-inline: auto;
  font-family: var(--font-ui); font-weight: var(--font-weight-w550);
  font-size: var(--text-hero); line-height: 1.08;
  letter-spacing: var(--tracking-display);
}
h1 .ln { display: flex; align-items: center; gap: 0.12em; height: 1.08em; }
h1 .w { white-space: nowrap; flex: 0 0 auto; }

/* Two-layer crossfade. Layer b sits on top and its opacity is what
   animates, so the dissolve goes photo-to-photo, never through the
   background. */
.tile {
  position: relative; flex: 1 1 auto; min-width: 0; height: 0.94em;
  border-radius: var(--radius-images); overflow: hidden;
  background-color: var(--color-slate-verdant);
}
.tile-layer { position: absolute; inset: 0; background-size: cover; background-position: center; }
.tile-layer.b { opacity: 0; transition: opacity 1600ms cubic-bezier(0.4, 0, 0.2, 1); }
.tile-layer.b.is-top { opacity: 1; }

/* Split-flap board. The tile is cut into horizontal slats; each slat is a
   card that flips around its own centre line, staggered top to bottom, so
   the photograph changes the way a JFK departures board changes. */
.tile.is-board { perspective: 900px; }
.tile .flap {
  position: absolute; left: 0; right: 0;
  transform-style: preserve-3d;
  transition: transform 380ms cubic-bezier(0.45, 0.05, 0.3, 1);
  will-change: transform;
}
.tile .flap.is-flipped { transform: rotateX(-180deg); }
.tile .flap-face {
  position: absolute; inset: 0;
  backface-visibility: hidden;
  background-repeat: no-repeat;
  box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.34), inset 0 -1px 0 rgba(255, 255, 255, 0.05);
}
.tile .flap-face.back { transform: rotateX(180deg); }

h2 { font-size: var(--text-heading); max-width: 15ch; margin-bottom: var(--spacing-40); }
h2.wide { max-width: 22ch; }
h2 .alt {
  font-family: var(--font-ui); font-weight: var(--font-weight-w550);
  font-size: var(--text-heading-sm); letter-spacing: var(--tracking-display);
}
h3 {
  font-family: var(--font-ui); font-size: var(--text-body);
  font-weight: var(--font-weight-w550); letter-spacing: var(--tracking-mid);
  margin: 0 0 var(--spacing-8);
}

p { max-width: 58ch; margin: 0 0 var(--spacing-25); }
.note {
  max-width: 52ch; margin: 0; font-family: var(--font-display);
  font-size: var(--text-note); line-height: 1.2; letter-spacing: var(--tracking-mid);
}

/* ---------- sections ---------- */
section { padding-block: var(--section-gap); }
.hero { padding-block: var(--spacing-40) var(--spacing-120); }
.eyebrow { color: var(--color-newsprint-gray); margin: 0 0 var(--spacing-30); display: block; }
.rule { border-top: 1px solid var(--color-highlighter-green); }

/* ---------- buttons ---------- */
.actions {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--spacing-30); max-width: none; margin-top: var(--spacing-45);
}
.btn {
  display: inline-block;
  background: var(--color-highlighter-green);
  color: var(--color-typesetter-ink);
  padding: var(--spacing-20) var(--spacing-30);
  border-radius: var(--radius-buttons);
  box-shadow: var(--shadow-lg);
}
.btn:hover { background: var(--color-accent-press); color: var(--color-typesetter-ink); }
.btn-ghost {
  display: inline-block; background: transparent;
  color: var(--color-bone-white);
  border: 1px solid var(--color-bone-white);
  border-radius: var(--radius-pills);
  padding: var(--spacing-25) var(--spacing-20);
}
.btn-ghost:hover { background: var(--color-bone-white); color: var(--color-press-black); }
.link-t {
  font-family: var(--font-times); font-size: var(--text-body-sm);
  text-decoration: underline; text-underline-offset: 3px;
}

/* ---------- the wavy boundary at each end of the dark section ---------- */
.curve { position: relative; line-height: 0; }
.curve.top { height: clamp(90px, 13vw, 190px); margin-bottom: -1px; }
.curve.bottom { height: clamp(70px, 9vw, 130px); margin-top: -1px; }
.curve svg { display: block; width: 100%; height: 100%; overflow: visible; }
.curve-fill { fill: var(--surface-dark-section); }
.curve-line { fill: none; stroke: var(--color-shadow-moss); }

/* ---------- the pinned problem section ---------- */
.dark { background: var(--surface-dark-section); color: var(--color-bone-white); }
.dark h2 { color: var(--color-bone-white); }
.dark .eyebrow { color: var(--color-muted-sage); }
.dark p { font-weight: var(--font-weight-light); }
.dark .link-t { color: var(--color-muted-sage); }

.problem { position: relative; isolation: isolate; overflow: hidden; padding-block: 0; }
.problem-flow-clip { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.problem-flow {
  position: absolute; left: 0; top: 0; width: 100%; height: 300vh;
  background-color: var(--color-shadow-moss); opacity: 0.15;
  -webkit-mask-image: url('/bg-lines.svg'); mask-image: url('/bg-lines.svg');
  -webkit-mask-size: 100% 100vh; mask-size: 100% 100vh;
  -webkit-mask-repeat: repeat-y; mask-repeat: repeat-y;
  will-change: transform;
}
.problem-body { position: relative; z-index: 1; }

/* The section scrolls like any other: the statements advance on Next,
   not on scroll, so nothing here is pinned. */
.pin-track { position: relative; }
.pin-panel { min-height: 100vh; display: flex; align-items: center; position: relative; }
.pin-panel.is-loose { min-height: 0; padding-block: clamp(60px, 9vh, 110px); }
.pin-grid {
  max-width: var(--page-max-width); margin-inline: auto; padding-inline: var(--gutter);
  width: 100%; display: grid; gap: clamp(28px, 4vw, 72px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  align-items: center;
}
.panel-mark {
  position: absolute; left: 52px; top: 53px;
  font-family: var(--font-ui); font-size: var(--text-panel-mark);
  font-weight: var(--font-weight-w550); line-height: var(--leading-flat);
  letter-spacing: var(--tracking-display); color: var(--color-highlighter-green);
}

.pin-figure { position: relative; }
.pin-photo {
  position: relative; aspect-ratio: 4 / 3;
  border-radius: var(--radius-images); overflow: hidden;
  background-color: var(--color-slate-verdant);
}
.pin-layer { position: absolute; inset: 0; background-size: cover; background-position: center; }
.pin-layer.b { opacity: 0; transition: opacity 700ms cubic-bezier(0.4, 0, 0.2, 1); }

.pin-head { display: flex; align-items: center; gap: var(--spacing-20); margin-bottom: clamp(24px, 4vh, 44px); }
.pin-count { color: var(--color-highlighter-green); font-variant-numeric: tabular-nums; }
.pin-progress { flex: 1 1 auto; height: 1px; background: var(--color-slate-verdant); position: relative; overflow: hidden; }
.pin-bar { position: absolute; left: 0; top: 0; height: 1px; width: 0%; background: var(--color-highlighter-green); }

.quotes { position: relative; min-height: 1px; opacity: 0; transition: opacity 400ms ease; }
.quote {
  margin: 0; max-width: 24ch;
  font-family: var(--font-display); font-size: var(--text-quote);
  line-height: 1.1; letter-spacing: var(--tracking-tight);
  color: var(--color-bone-white);
  padding-left: var(--spacing-25);
  border-left: 2px solid var(--color-highlighter-green);
}
.js-pin .quote { position: absolute; left: 0; top: 0; width: 100%; opacity: 0; transition: opacity 400ms ease; }
.js-pin .quote.is-live { opacity: 1; }
.quotes.is-loose { height: auto !important; opacity: 1; }
.quotes.is-loose .quote { position: static; width: auto; opacity: 1; margin-bottom: var(--spacing-30); }

/* Next sits in space reserved under the statement, so nothing moves when
   it appears. Hidden, and out of the tab order, until a statement has
   finished typing. */
.pin-next-row {
  position: relative; margin-top: clamp(24px, 4vh, 44px);
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--spacing-15) var(--spacing-30);
}
/* A quiet way through to Products & Services, beside Next: text only, on
   the same cadence — it appears when a statement has finished typing and
   stands aside while the next one types. */
/* Next is at least as wide as the "Scroll down" cue that takes its place
   after the last statement, so the link beside them never shifts or crowds. */
.pin-next { min-width: 10em; }
/* The quiet link: text and a small arrow, no box, sitting beside a main
   button as the lower-key way through to Products & Services. Muted until
   hovered, when it darkens and the arrow nudges on. Colours default for the
   light page; the dark sections override them. */
.quiet-link {
  display: inline-flex; align-items: center; gap: var(--spacing-8);
  color: var(--color-newsprint-gray); transition: color 200ms ease;
}
.quiet-link path { stroke: var(--color-accent-edge); transition: transform 200ms ease; }
.quiet-link:hover, .quiet-link:focus-visible { color: var(--color-typesetter-ink); }
.quiet-link:hover path, .quiet-link:focus-visible path { transform: translateX(3px); }
/* In Current Problem (dark): paler, and it pops in on Next's cadence. */
.pin-link { color: color-mix(in srgb, var(--color-muted-sage) 75%, transparent); }
.pin-link path { stroke: var(--color-highlighter-green); }
.pin-link:hover, .pin-link:focus-visible { color: var(--color-bone-white); }
.pin-link {
  opacity: 0; visibility: hidden; transform: translate3d(0, 8px, 0);
  transition: opacity 300ms ease 80ms, transform 300ms ease 80ms, visibility 0s linear 380ms, color 200ms ease;
}
.pin-link.is-on {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity 300ms ease 80ms, transform 300ms ease 80ms, visibility 0s, color 200ms ease;
}
.pin-next {
  appearance: none; cursor: pointer;
  background: transparent; color: var(--color-bone-white);
  border: 1px solid var(--color-highlighter-green);
  border-radius: var(--radius-buttons);
  padding: var(--spacing-15) var(--spacing-30);
  opacity: 0; visibility: hidden; transform: translate3d(0, 8px, 0);
  transition: opacity 300ms ease, transform 300ms ease, visibility 0s linear 300ms,
              background-color 200ms ease, color 200ms ease;
}
.pin-next.is-on {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity 300ms ease, transform 300ms ease, visibility 0s,
              background-color 200ms ease, color 200ms ease;
}
.pin-next:hover, .pin-next:focus-visible { background: var(--color-highlighter-green); color: var(--color-typesetter-ink); }
.pin-next[hidden] { display: none; }

/* The cue to keep going down the page, shown after the last statement
   here and after the last phase of the rail. Each context places it; this
   is how it looks. The arrow bobs on a CSS loop, so it costs the main
   thread nothing. Clicking it glides to the next section. */
.more-cue {
  display: inline-flex; align-items: center; gap: var(--spacing-15);
  appearance: none; cursor: pointer; padding: 0;
  background: transparent; border: 0; color: var(--color-bone-white);
  opacity: 0; visibility: hidden; transform: translate3d(0, calc(-50% + 8px), 0);
  transition: opacity 300ms ease, transform 300ms ease, visibility 0s linear 300ms;
}
.more-cue.is-on {
  opacity: 1; visibility: visible; transform: translate3d(0, -50%, 0);
  transition: opacity 300ms ease, transform 300ms ease, visibility 0s;
}
.more-cue-arrow path { stroke: var(--color-highlighter-green); }
.more-cue.is-on .more-cue-arrow { animation: more-cue-bob 1.6s ease-in-out infinite; }
.more-cue:hover, .more-cue:focus-visible { color: var(--color-highlighter-green); }
.more-cue[hidden] { display: none; }
@keyframes more-cue-bob {
  0%, 100% { transform: translateY(-3px); }
  50%      { transform: translateY(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .more-cue.is-on .more-cue-arrow { animation: none; }
}
/* In Current Problem: the spot Next occupied. */
.pin-more { position: absolute; left: 0; top: 50%; }

/* Character spans: hidden characters keep their width, so the line
   never reflows as it types. */
.ch { opacity: 0; }
.ch.is-on { opacity: 1; }
.ch.has-caret { box-shadow: 2px 0 0 0 var(--color-highlighter-green); }
.word { display: inline-block; white-space: pre; }

/* ---------- research metrics ---------- */
.metric {
  border-top: 1px solid var(--color-typesetter-ink);
  padding-top: var(--spacing-30);
  display: grid; gap: clamp(28px, 4vw, 64px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  align-items: center;
}
.metric.a, .metric.b { margin-bottom: clamp(56px, 9vh, 110px); }
.metric.b { align-items: start; }
.metric.c { margin-bottom: clamp(40px, 6vh, 72px); }
.metric-num {
  font-family: var(--font-display); font-size: var(--text-metric);
  line-height: var(--leading-flat); letter-spacing: var(--tracking-display);
  margin: 0 0 var(--spacing-30);
}
/* The highlighter sweep. background-size is animated by site.js. */
.mark {
  white-space: nowrap; padding: 0 0.08em;
  background: linear-gradient(var(--color-highlighter-green), var(--color-highlighter-green)) no-repeat;
  background-size: 0% 0.9em; background-position: 0 0.1em;
}
.metric p { max-width: 52ch; }
.metric p + p { margin-bottom: 0; }
.fig-cap {
  font-family: var(--font-ui); font-size: var(--text-caption);
  line-height: var(--leading-caption); letter-spacing: var(--tracking-caption);
  text-transform: uppercase; font-weight: var(--font-weight-w550);
  color: var(--color-newsprint-gray); text-align: center; margin: var(--spacing-15) 0 0;
}
.fig-cap.phrase { font-size: var(--text-figure-cap); line-height: 1.15; letter-spacing: var(--tracking-wide); margin-top: 18px; }
.fig-cap.lead { font-size: var(--text-figure-lab); line-height: 1.15; letter-spacing: var(--tracking-wide); margin: 0 0 6px; }
.fig-total {
  font-family: var(--font-display); font-size: var(--text-figure);
  line-height: var(--leading-flat); letter-spacing: var(--tracking-figure);
  text-align: center; font-variant-numeric: tabular-nums;
}
.fig-total.above { margin: 0 0 var(--spacing-4); }
.fig-total.below { margin: var(--spacing-10) 0 0; }
.fig-total.is-full { color: var(--color-highlighter-green); }
.figure { display: block; width: 100%; height: auto; margin-inline: auto; }
.figure.pyramid { max-width: 380px; }
.figure.door, .figure.mountain { max-width: 420px; }

/* ---------- figure 01: the pyramid of dollar bills ---------- */
.pyr-bill { fill: none; stroke: var(--color-typesetter-ink); stroke-opacity: 0.18; }
.pyr-bill.is-filled { fill: var(--color-highlighter-green); stroke: var(--color-accent-edge); stroke-opacity: 0.5; }
.pyr-glyph { fill: var(--color-typesetter-ink); opacity: 0.18; }
.pyr-glyph.is-filled { fill: var(--color-accent-ink); opacity: 1; }
.pyr-label { fill: var(--color-newsprint-gray); opacity: 0.5; }
.pyr-label.is-filled { fill: var(--color-press-black); opacity: 1; }

/* ---------- figure 02: the lead who walks straight back out ---------- */
.door-line { stroke: var(--color-typesetter-ink); }
.door-ground { stroke-opacity: 0.22; stroke-width: 1; }
.door-frame { stroke-opacity: 0.55; stroke-width: 1.5; }
.door-rule { stroke-opacity: 0.25; stroke-width: 1; }
.door-sill { stroke: var(--color-highlighter-green); stroke-width: 2.5; }
.door-sign {
  fill: var(--color-typesetter-ink); fill-opacity: 0.6;
  font-family: var(--font-ui); font-size: 12px;
  font-weight: var(--font-weight-w550); letter-spacing: 1.2px;
}
.fig-limb { stroke: var(--color-typesetter-ink); stroke-width: 2; stroke-linecap: round; }
.fig-head { fill: none; stroke: var(--color-typesetter-ink); stroke-width: 2; }
.bill-note { fill: var(--color-bone-white); stroke: var(--color-typesetter-ink); stroke-width: 1.5; }
.bill-glyph {
  fill: var(--color-typesetter-ink); font-family: var(--font-ui);
  font-size: 9px; font-weight: var(--font-weight-w550);
}

/* ---------- figure 03: the eroding ridge ---------- */
.mtn-ground { stroke: var(--color-typesetter-ink); stroke-opacity: 0.22; stroke-width: 1; }
.mtn-datum { stroke: var(--color-typesetter-ink); stroke-opacity: 0.18; stroke-width: 1; }
.mtn-ghost {
  fill: var(--color-highlighter-green); fill-opacity: 0.16;
  stroke: var(--color-highlighter-green); stroke-opacity: 0.75;
  stroke-width: 1.25; stroke-linejoin: round;
}
.mtn-solid {
  fill: var(--color-bone-white); stroke: var(--color-typesetter-ink);
  stroke-opacity: 0.7; stroke-width: 1.5; stroke-linejoin: round;
}

/* ---------- footer ---------- */
.footer {
  background: var(--surface-dark-section); color: var(--color-bone-white);
  padding-block: var(--spacing-60); position: relative; isolation: isolate;
}
.footer-grid { display: grid; gap: var(--spacing-40); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.footer p { font-weight: var(--font-weight-light); margin-bottom: var(--spacing-10); }
.footer .micro { color: var(--color-bone-white); display: block; margin-bottom: var(--spacing-20); }
.footer .link-t { align-self: flex-start; }

/* ---------- full-bleed accent band: the closing signature ---------- */
/* The band closes the page with the full lockup rather than a single letter.
   It is decorative — the name is already in the footer above it — so the img
   carries an empty alt and the container stays aria-hidden. */
.accent-band {
  background: var(--surface-accent-band);
  min-height: clamp(14rem, 45vw, 40rem);
  padding: var(--spacing-50);
  position: relative; isolation: isolate;
  display: flex;
  align-items: center;
}
.accent-band img {
  display: block;
  width: min(100%, clamp(18rem, 55vw, 46rem));
  height: auto;
}

main, .footer, .accent-band, .nav { position: relative; }
.dark, .footer, .accent-band { isolation: isolate; }


/* ---------- where do you stand: the car coming together ----------
   A 3D scene (home-3d.js) on a stage, with HTML tags pinned to points on
   the car. The tags are positioned by script every frame; each is a label
   on a hairline leader ending in a dot at its point. */
.stand { position: relative; }
.stand-grid {
  display: grid; gap: clamp(40px, 6vw, 90px); align-items: center;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
}
/* 4:3 — an F1 car is long and low, and a taller stage is mostly sky. */
.e3 { position: relative; width: 100%; aspect-ratio: 4 / 3; max-height: 72vh; }
.e3-stage { position: absolute; inset: 0; }
.e3-stage canvas { display: block; width: 100% !important; height: 100% !important; }
.e3.is-fallback .e3-stage {
  background: url('/img/phase-04-growth.webp') center / cover no-repeat;
  border-radius: var(--radius-images);
}
.e3.is-fallback .e3-tag { display: none; }

.e3-tag { position: absolute; left: 0; top: 0; opacity: 0; pointer-events: none; z-index: 2; will-change: transform, opacity; }
.e3-tag-in {
  position: absolute; left: 0; bottom: 0; transform: translate(-50%, 5px);
  display: flex; flex-direction: column; align-items: center;
}
/* Each tag arrives in order: the dot lands on its part, the leader draws
   up from it, then the label rises in with a small overshoot. */
.e3-tag-text {
  display: inline-flex; align-items: center; gap: var(--spacing-8);
  white-space: nowrap; color: var(--color-bone-white);
  background: var(--color-press-black);
  border-radius: var(--radius-pills); padding: var(--spacing-8) var(--spacing-15);
  box-shadow: var(--shadow-lg);
  font-family: var(--font-ui); font-weight: var(--font-weight-w550);
  font-size: clamp(0.82rem, 1.3vw, 1.05rem); letter-spacing: 0.04em; text-transform: uppercase;
  opacity: 0; transform: translateY(10px) scale(0.92);
  transition: opacity 0.3s ease 0.2s, transform 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.3) 0.2s;
}
.e3-tag-num { color: var(--color-highlighter-green); font-weight: var(--font-weight-bold); }
.e3-tag-line {
  width: 2px; height: var(--e3-lead, 44px); background: var(--color-highlighter-green);
  transform: scaleY(0); transform-origin: 50% 100%;
  transition: transform 0.3s cubic-bezier(0.3, 0, 0.2, 1);
}
.e3-tag-dot {
  position: relative; width: 10px; height: 10px; border-radius: var(--radius-round);
  background: var(--color-highlighter-green);
}
.e3-tag-dot::after {
  content: ''; position: absolute; inset: -1px; border-radius: var(--radius-round);
  border: 2px solid var(--color-highlighter-green); opacity: 0;
}
.e3-tag.is-on .e3-tag-text { opacity: 1; transform: none; }
.e3-tag.is-on .e3-tag-line { transform: scaleY(1); }
.e3-tag.is-on .e3-tag-dot::after { animation: e3-ping 1.4s cubic-bezier(0.2, 0, 0.3, 1) infinite; }
@keyframes e3-ping {
  0%   { transform: scale(1); opacity: 0.9; }
  100% { transform: scale(3.2); opacity: 0; }
}
/* Flying into the title, the tags travel as labels alone. */
.e3-tag.is-merging .e3-tag-line, .e3-tag.is-merging .e3-tag-dot { opacity: 0; transition: opacity 0.15s; }
/* Staggered leaders, so a tag never sits on top of its part's neighbour. */
.e3-tag[data-tag="blueprint"] { --e3-lead: 58px; }
.e3-tag[data-tag="build"] { --e3-lead: 46px; }
.e3-tag[data-tag="ai"] { --e3-lead: 34px; }

/* The finale: the title rises in letter by letter (site.js splits it into
   .e3-ch spans, staggered by --i), "Engine" in the accent, and a green
   rule sweeps in underneath. */
.e3-final {
  position: absolute; left: 0; right: 0; bottom: 6%; z-index: 3;
  display: flex; flex-direction: column; align-items: center; gap: var(--spacing-10);
  pointer-events: none;
}
.e3-final-title {
  font-family: var(--font-ui); font-weight: var(--font-weight-bold);
  font-size: clamp(1.7rem, 3.6vw, 3rem); line-height: 1; letter-spacing: -0.03em;
  color: var(--color-typesetter-ink); text-align: center;
}
.e3-word { display: inline-block; white-space: nowrap; }
.e3-word:last-child { color: var(--color-accent-ink); }
.e3-ch {
  display: inline-block; opacity: 0; transform: translateY(0.7em) rotate(8deg);
  transition: opacity 0.3s ease, transform 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.25);
  transition-delay: calc(var(--i, 0) * 38ms);
}
.e3-final-rule {
  width: min(62%, 340px); height: 4px; border-radius: var(--radius-round);
  background: var(--color-highlighter-green);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 0.8s cubic-bezier(0.65, 0, 0.2, 1) 0.6s;
}
.e3-final.is-on .e3-ch { opacity: 1; transform: none; }
.e3-final.is-on .e3-final-rule { transform: scaleX(1); }
.e3.is-fallback .e3-final { opacity: 1 !important; }
.e3.is-fallback .e3-final .e3-ch { opacity: 1; transform: none; color: var(--color-bone-white); }
.e3.is-fallback .e3-final-rule { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .e3-ch, .e3-final-rule, .e3-tag-text, .e3-tag-line { transition: none; }
  .e3-tag.is-on .e3-tag-dot::after { animation: none; }
}
.stand-copy h2 { max-width: 18ch; }
.stand-copy p { max-width: 46ch; }

@media (max-width: 860px) {
  .stand { padding-top: clamp(14px, 2.5vh, 28px); padding-bottom: clamp(80px, 12vh, 150px); }
  .stand-grid { grid-template-columns: minmax(0, 1fr); }
  .e3 { max-width: 560px; margin-inline: auto; }
  /* Copy leads, the car coming together reads as the payoff below it. */
  .e3 { order: 2; }
  .stand-copy { order: 1; }
}

/* ---------- AI on the foundation ----------
   One contained panel, a soft green tint set in from the page edges, so the
   section reads as its own beat after the car and never runs into the dark
   footer. Inside, top to bottom: the claim, three steps on a line, then the
   proof and the two ways on. */
.lift { padding-block: var(--spacing-40) clamp(90px, 12vh, 150px); }
.lift-panel {
  background: color-mix(in srgb, var(--color-echo-green) 38%, var(--color-bone-white));
  border: 1px solid color-mix(in srgb, var(--color-shadow-moss) 45%, transparent);
  border-radius: var(--radius-images);
  padding: clamp(28px, 5vw, 64px);
}
.lift-top {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(24px, 5vw, 70px); align-items: end;
}
.lift-top h2 {
  margin: 0; max-width: 16ch; font-size: clamp(2.25rem, 4.6vw, 4.25rem);
  line-height: 1.05; letter-spacing: var(--tracking-mid); text-wrap: balance;
}
.lift-top p { margin: 0; max-width: 42ch; }

/* Three steps on one line. The line and the dots draw in order when reached. */
.lift-steps {
  list-style: none; margin: clamp(40px, 6vw, 70px) 0 0; padding: 0; position: relative;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(20px, 3vw, 40px);
}
.lift-steps::before,
.lift-steps::after {
  content: ''; position: absolute; left: 7px; right: 0; top: 7px; height: 2px;
}
.lift-steps::before { background: color-mix(in srgb, var(--color-shadow-moss) 50%, transparent); }
.lift-steps::after { background: var(--color-accent-edge); transform-origin: left center; }
.lift-steps li { position: relative; padding-top: var(--spacing-35); }
.lift-dot {
  position: absolute; left: 0; top: 0; z-index: 1; width: 16px; height: 16px;
  border-radius: var(--radius-round); background: var(--color-accent-edge);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-echo-green) 38%, var(--color-bone-white));
}
.lift-steps li:last-child .lift-dot { background: var(--color-highlighter-green); }
.lift-step-n {
  display: block; font-size: var(--text-caption); letter-spacing: 0.14em;
  font-weight: var(--font-weight-w550); color: var(--color-accent-edge); margin-bottom: var(--spacing-8);
}
.lift-steps h3 {
  margin: 0 0 var(--spacing-8); font-family: var(--font-display); font-weight: var(--font-weight-regular);
  font-size: clamp(1.6rem, 2.4vw, 2.1rem); line-height: 1.05; letter-spacing: var(--tracking-mid);
}
.lift-steps p { margin: 0; max-width: 28ch; font-size: var(--text-body-sm); line-height: 1.5; color: var(--color-newsprint-gray); }

.lift-steps.is-armed::after { transform: scaleX(0); }
.lift-steps.is-armed .lift-dot { transform: scale(0.4); opacity: 0; }
.lift-steps.is-armed li > :not(.lift-dot) { opacity: 0; transform: translateY(8px); }
.lift-steps.is-on::after { transform: scaleX(1); transition: transform 1.6s cubic-bezier(0.65, 0, 0.35, 1); }
.lift-steps.is-on .lift-dot {
  transform: none; opacity: 1;
  transition: transform 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.4) calc(var(--i) * 0.6s), opacity 0.2s ease calc(var(--i) * 0.6s);
}
.lift-steps.is-on li > :not(.lift-dot) {
  opacity: 1; transform: none;
  transition: opacity 0.5s ease calc(var(--i) * 0.6s + 0.15s), transform 0.5s ease calc(var(--i) * 0.6s + 0.15s);
}

/* The proof and the two ways on, under a hairline. */
.lift-foot {
  margin-top: clamp(40px, 6vw, 70px); padding-top: clamp(24px, 3vw, 36px);
  border-top: 1px solid color-mix(in srgb, var(--color-shadow-moss) 45%, transparent);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--spacing-30);
}
.lift-stat { display: flex; align-items: flex-start; gap: var(--spacing-20); max-width: 40rem; flex: 1 1 26rem; }
.lift-stat-n {
  flex: 0 0 auto; font-family: var(--font-display); font-size: clamp(2.75rem, 4.5vw, 3.75rem);
  line-height: 0.9; letter-spacing: var(--tracking-tight); color: var(--color-accent-edge);
}
.lift-stat .lift-stat-line { margin: 0 0 var(--spacing-4); font-weight: var(--font-weight-regular); }
.lift-stat .lift-stat-src { margin: 0; font-size: var(--text-caption); line-height: 1.5; letter-spacing: var(--tracking-caption); color: var(--color-newsprint-gray); }
.lift-stat .lift-stat-src .link-t { font-size: inherit; }
.lift-actions { display: flex; flex-wrap: wrap; gap: var(--spacing-15); margin: 0; }

/* An outlined button for light backgrounds, the partner of .btn. */
.btn-line {
  display: inline-block; padding: var(--spacing-20) var(--spacing-30);
  border: 1px solid var(--color-typesetter-ink); border-radius: var(--radius-buttons);
  color: var(--color-typesetter-ink); text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.btn-line:hover { background: var(--color-typesetter-ink); color: var(--color-bone-white); }
.btn-line:focus-visible { outline: 2px solid var(--color-accent-edge); outline-offset: 3px; }

@media (max-width: 860px) {
  .lift-top { grid-template-columns: minmax(0, 1fr); gap: var(--spacing-20); }
  /* The steps stack, and the line runs down between the dots instead of
     across: one segment per gap, so it stops at the last dot. */
  .lift-steps { grid-template-columns: minmax(0, 1fr); gap: var(--spacing-30); }
  .lift-steps::before, .lift-steps::after { display: none; }
  .lift-steps li:not(:last-child)::before,
  .lift-steps li:not(:last-child)::after {
    content: ''; position: absolute; left: 7px; top: 16px; width: 2px;
    bottom: calc(-1 * var(--spacing-30));
  }
  .lift-steps li:not(:last-child)::before { background: color-mix(in srgb, var(--color-shadow-moss) 50%, transparent); }
  .lift-steps li:not(:last-child)::after { background: var(--color-accent-edge); transform-origin: center top; }
  .lift-steps.is-armed li::after { transform: scaleY(0); }
  .lift-steps.is-on li::after { transform: scaleY(1); transition: transform 0.6s ease calc(var(--i) * 0.6s + 0.2s); }
  .lift-steps li { padding-top: 0; padding-left: var(--spacing-40); }
  .lift-steps p { max-width: none; }
}
@media (max-width: 560px) {
  .lift-stat { flex-direction: column; gap: var(--spacing-10); }
  .lift-actions { width: 100%; }
  .lift-actions a { flex: 1 1 auto; text-align: center; }
}
@media (prefers-reduced-motion: reduce) {
  .lift-steps::after, .lift-steps li::after, .lift-steps .lift-dot, .lift-steps li > * { transition: none !important; }
}

/* ---------- the approach artwork: a rail of four phases ----------
   The section scrolls like any other. The rail moves on the arrow, not on
   scroll, so nothing here is pinned. */

.approach { position: relative; isolation: isolate; overflow: hidden; padding-block: 0; }
.rail-track { position: relative; }
/* Never shorter than the longest phase needs to clear the button beneath
   it; on a short laptop screen the section simply runs a little past the
   bottom edge, which is fine now that it scrolls. */
.rail-panel { height: max(100vh, 820px); position: relative; overflow: hidden; }

.approach-title {
  position: absolute; left: var(--gutter); top: clamp(30px, 6vh, 64px);
  z-index: 9; pointer-events: none; isolation: isolate;
}
.approach-title-halo {
  position: absolute; left: -6%; top: -40%; width: 118%; height: 190%;
  background: radial-gradient(65% 65% at 26% 50%,
    color-mix(in srgb, var(--surface-dark-section) 70%, transparent) 0%,
    color-mix(in srgb, var(--surface-dark-section) 35%, transparent) 60%,
    transparent 100%);
  filter: blur(18px);
}
.approach-title-text {
  position: relative; display: block; max-width: 16ch;
  font-family: var(--font-ui); font-size: var(--text-approach);
  font-weight: var(--font-weight-w550); line-height: var(--leading-flat);
  letter-spacing: var(--tracking-display); color: var(--color-highlighter-green);
  text-shadow: 0 10px 34px rgba(0, 0, 0, 0.65),
               0 0 42px color-mix(in srgb, var(--color-highlighter-green) 22%, transparent);
}

.rail-head {
  position: absolute; right: var(--gutter); top: clamp(30px, 6vh, 64px);
  z-index: 4; display: flex; align-items: center; gap: var(--spacing-15);
}
.rail-head .pin-progress { flex: 0 0 auto; width: clamp(80px, 11vw, 170px); }
.rail-head .pin-count { color: var(--color-muted-sage); }

.rail-line {
  position: absolute; left: 0; right: 0; top: 54%; height: 1px; z-index: 2;
  background: color-mix(in srgb, var(--color-shadow-moss) 32%, transparent);
}
.rail-marker { position: absolute; left: 34%; top: 54%; transform: translate(-50%, -50%); z-index: 5; width: 13px; height: 13px; }
.rail-dot {
  position: absolute; inset: 0; border-radius: var(--radius-round);
  background: var(--color-highlighter-green);
  box-shadow: 0 0 22px color-mix(in srgb, var(--color-highlighter-green) 55%, transparent);
}
.rail-pulse {
  position: absolute; left: 50%; top: 50%; width: 13px; height: 13px;
  transform: translate(-50%, -50%) scale(1); opacity: 0;
  border: 1px solid var(--color-highlighter-green); border-radius: var(--radius-round);
}

.rail { position: absolute; left: 0; top: 0; height: 100%; display: flex; align-items: stretch; z-index: 3; will-change: transform; }

/* The arrow sits on the rail line at the right edge, pointing the way the
   rail travels. Hidden, and out of the tab order, until the phase on the
   marker has finished typing. */
.rail-next {
  position: absolute; right: var(--gutter); top: 54%; z-index: 8;
  width: 56px; height: 56px; padding: 0; cursor: pointer; appearance: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-dark-section);
  border: 1px solid var(--color-highlighter-green); border-radius: var(--radius-round);
  opacity: 0; visibility: hidden; transform: translate3d(-8px, -50%, 0);
  transition: opacity 300ms ease, transform 300ms ease, visibility 0s linear 300ms, background-color 200ms ease;
}
.rail-next path { stroke: var(--color-highlighter-green); transition: stroke 200ms ease; }
.rail-next.is-on {
  opacity: 1; visibility: visible; transform: translate3d(0, -50%, 0);
  transition: opacity 300ms ease, transform 300ms ease, visibility 0s, background-color 200ms ease;
}
.rail-next:hover, .rail-next:focus-visible { background: var(--color-highlighter-green); }
.rail-next:hover path, .rail-next:focus-visible path { stroke: var(--color-typesetter-ink); }
.rail-next[hidden] { display: none; }
/* Its mirror at the left end of the line, from phase 02 on. */
.rail-prev { right: auto; left: var(--gutter); transform: translate3d(8px, -50%, 0); }
/* After the last phase: the forward arrow's spot, on the line. The dark
   backing keeps the line from running through the words. */
.rail-more {
  position: absolute; right: var(--gutter); top: 54%; z-index: 8;
  padding: var(--spacing-8) 0 var(--spacing-8) var(--spacing-15);
  background: var(--surface-dark-section);
}

/* On screen the whole time, bottom left, its left edge on the left edge of
   the phase text. site.js writes --phase-left from the rail's geometry. */
.rail-details {
  position: absolute; left: var(--phase-left, var(--gutter)); bottom: clamp(30px, 6vh, 64px); z-index: 8;
  padding: var(--spacing-15) var(--spacing-25);
}
.phase { position: relative; flex: 0 0 auto; width: clamp(300px, 38vw, 540px); margin-right: clamp(170px, 20vw, 320px); }
.phase-tick {
  position: absolute; left: 50%; top: 54%; width: 1px; height: 30px;
  transform: translate(-50%, -50%);
  background: color-mix(in srgb, var(--color-shadow-moss) 50%, transparent);
}
.phase-photo {
  position: absolute; left: 0; right: 0; bottom: 46%; margin-bottom: 26px;
  height: clamp(210px, 36vh, 400px);
  border-radius: var(--radius-images); overflow: hidden;
  background-color: var(--color-slate-verdant);
  background-size: cover; background-position: center;
  filter: grayscale(1) contrast(1.06) brightness(0.66);
  opacity: 0.26;
}
.phase-photo-tint { position: absolute; inset: 0; background: var(--color-highlighter-green); opacity: 0.1; }
/* Not fully black and white: a trace of the original colour survives. */
.phase-photo.tinted { filter: grayscale(0.82) saturate(1.15) contrast(1.04) brightness(0.7); }
.phase-photo.tinted .phase-photo-tint { opacity: 0.05; }
.phase-photo-frame { position: absolute; inset: 12px; border: 1px solid color-mix(in srgb, var(--color-bone-white) 28%, transparent); }
.phase-text { position: absolute; left: 0; right: 0; top: 54%; margin-top: 38px; }
.phase-kicker { color: var(--color-highlighter-green); letter-spacing: 0.16em; margin-bottom: var(--spacing-10); }
.phase-name {
  font-family: var(--font-display); font-size: var(--text-phase);
  line-height: var(--leading-flat); letter-spacing: var(--tracking-tight);
  opacity: 0.32;
}
.phase-desc {
  max-width: 40ch; margin: 26px 0 0;   /* wide enough that the longest phase stays clear of the button below */
  font-weight: var(--font-weight-light); font-size: var(--text-phase-desc);
  line-height: 1.35; opacity: 0;
}

/* Static fallback for print and reduced motion: a two-up grid. */
.rail-track.is-loose { height: auto; }
.rail-panel.is-loose { height: auto; transform: none; overflow: visible; padding-block: clamp(90px, 14vh, 150px); }
.rail.is-loose {
  position: relative; transform: none; flex-wrap: wrap; height: auto;
  gap: var(--spacing-40); padding-inline: var(--gutter);
}
.rail.is-loose .phase { height: 540px; width: calc(50% - 20px); margin-right: 0; }
.rail.is-loose .phase-photo { opacity: 1; }
.rail.is-loose .phase-name, .rail.is-loose .phase-desc { opacity: 1; }
.rail-panel.is-loose .rail-details { position: relative; left: auto; bottom: auto; margin: var(--spacing-40) var(--gutter) 0; }


/* ---------- mobile ----------
   Same sections and the same scroll-driven behaviour, sized for a hand:
   panels measure in svh so browser chrome cannot clip them, the pinned
   tracks are shorter, and the horizontal rail runs at phone scale. */
@media (max-width: 860px) {
  /* The hero fills the top block and lines up with every other section's
     gutter rather than sitting in a narrower centred column. */
  h1 {
    width: 100%; max-width: 100%; margin-inline: 0;
    font-size: clamp(1.6rem, 11.8vw, 3.9rem);
    letter-spacing: -0.075em;
  }
  /* Narrower photo strips, pushed to the outer edge of their line, so all
     four lines start and end on the same two margins — a clean rectangle. */
  h1 .ln { gap: 0.1em; justify-content: space-between; }
  /* Metric 02 reads text-first when the two columns stack. */
  .metric.b > *:first-child { order: 2; }
  .metric.b > *:last-child { order: 1; }
  .tile { flex: 1 1 auto; min-width: 0; height: 1.02em; }
  /* The first screen is the headline alone, centred in what is left of the
     viewport under the nav; it holds there while the black block climbs in. */
  /* The hold is the viewport minus the nav bar above it, so the headline's
     own midline lands on the middle of the screen. */
  .hero-track { position: relative; height: 128svh; }
  /* Sticky, not a scroll-driven transform: the compositor holds the
     headline, so it cannot shake against the page as it scrolls. */
  .hero-hold { position: sticky; top: 0; height: calc(100svh - 76px); }
  .hero {
    min-height: 100%;
    display: flex; align-items: center;
    padding-block: 0;
    padding-inline: calc(var(--gutter) + 22px);
  }

  .pin-panel { min-height: 0; align-items: flex-start; padding-block: clamp(84px, 14svh, 132px) clamp(34px, 6svh, 60px); }
  .pin-grid { gap: var(--spacing-30); }
  .pin-photo { aspect-ratio: 3 / 2; }
  .panel-mark {
    left: var(--gutter); top: clamp(18px, 4vh, 34px);
    font-size: clamp(1.5rem, 8vw, 2.25rem);
  }
  .quote { max-width: none; padding-left: var(--spacing-20); }

  /* The rail is the one thing still moving in here; keep it on its own
     compositor layer so its travel does not repaint the block. */
  .rail { will-change: transform; backface-visibility: hidden; }
  /* The rail cuts between phases, so the arriving card takes focus with a
     short fade rather than snapping to full contrast. */
  .phase-photo, .phase-name, .phase-desc { transition: opacity 240ms linear; }
  /* One vertical rhythm, top to bottom: the same space above the title as
     below the button, and the panel exactly as tall as its content. The
     title, the tallest phase text and the button are measured by site.js
     (--title-h, --text-h, --btn-h); the fallbacks are typical values. */
  .rail-panel {
    transform: none !important;
    --edge: 40px;                                         /* above title, below button */
    --photo-top: calc(var(--edge) + var(--title-h, 56px) + 28px);
    --photo-h: clamp(170px, 26svh, 230px);
    --rail-y: calc(var(--photo-top) + var(--photo-h) + 20px);
    height: calc(var(--rail-y) + 20px + var(--text-h, 200px) + 40px + var(--btn-h, 42px) + var(--edge));
  }
  .approach-title { top: var(--edge); }
  .approach-title-text { max-width: 15ch; font-size: clamp(1.3rem, 6.2vw, 1.75rem); }
  /* The button and the counter share the bottom edge, centred on each other. */
  .rail-details { bottom: var(--edge); }
  .rail-head { top: auto; bottom: calc(var(--edge) + var(--btn-h, 42px) / 2); transform: translateY(50%); }
  /* The photo ends 20px above the line and the text starts 20px below it,
     so the arrows are sized to that band and touch neither. */
  .rail-next { top: var(--rail-y); width: 40px; height: 40px; }
  .rail-more { top: var(--rail-y); }
  /* The button takes the bottom-left, so the counter stands alone. */
  .rail-head .pin-progress { display: none; }
  /* The timeline sits just under the photo and the card rides it. */
  .rail-line, .phase-tick { top: var(--rail-y); }
  .rail-marker { top: var(--rail-y); left: 50%; }
  .phase { width: min(80vw, 330px); margin-right: clamp(70px, 18vw, 110px); }
  .phase-tick { height: 22px; }
  .phase-photo { top: var(--photo-top); bottom: auto; margin-bottom: 0; height: var(--photo-h); }
  .phase-photo-frame { inset: 8px; }
  .phase-text { top: calc(var(--rail-y) + 20px); margin-top: 0; }
  .phase-desc { max-width: none; margin-top: 16px; }

  .accent-band { min-height: clamp(11rem, 52vw, 20rem); padding: var(--spacing-30); }

}

/* ============================================================
   The site menu
   ------------------------------------------------------------
   Built by /menu.js, which also owns the list of entries. Three
   bars, and the nav holds nothing else: TeeJay's call on
   22 September, after an earlier version kept "Book a call"
   exposed alongside it. Labels only inside — no descriptions.
   ============================================================ */

/* The menu follows the reader down the page, so the way to every other page
   is always one tap away. It is pinned to the screen at exactly the spot it
   occupies in the header — level with the wordmark, on the content's right
   edge, which stops widening at --page-max-width — so nothing moves on load.
   The wordmark still scrolls away with the page. */
.menu {
  position: fixed; z-index: 70; display: flex; align-items: center;
  top: calc(var(--spacing-30) + var(--wordmark-h) / 2 - 22px);
  right: max(calc(var(--gutter) - 10px), calc((100% - var(--page-max-width)) / 2 + var(--gutter) - 10px));
}

.hamburger {
  display: grid;
  gap: 5px;
  /* The bars are 22px across. The BUTTON is 44, because that is the smallest
     thing a thumb reliably hits — the extra is invisible padding, not a bigger
     icon. Negative margin keeps it optically where the bars sit. */
  min-width: 44px;
  min-height: 44px;
  place-content: center;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  cursor: pointer;
  border-radius: var(--radius-round);
  transition: background-color .2s ease, box-shadow .2s ease, border-color .2s ease;
}
/* Once the page has moved, the button carries its own light backing, so its
   bars read over the dark sections and the footer as well as the light page. */
.menu.is-floating .hamburger {
  background: var(--color-bone-white);
  border-color: color-mix(in srgb, var(--color-muted-sage) 80%, transparent);
  box-shadow: var(--shadow-lg);
}
.hamburger span {
  display: block;
  width: 22px; height: 2px;
  background: var(--color-press-black);
  border-radius: var(--radius-round);
  transition: background-color .15s ease;
}
.hamburger:hover span { background: var(--color-accent-edge); }
.menu.is-open .hamburger span { background: var(--color-accent-edge); }
.hamburger:focus-visible { outline: 2px solid var(--color-accent-edge); outline-offset: 3px; }

.menu-panel {
  position: absolute;
  top: calc(100% + var(--spacing-10));
  right: 0;
  min-width: 11rem;
  background: var(--color-bone-white);
  border: 1px solid var(--color-muted-sage);
  border-radius: var(--radius-images);
  box-shadow: var(--shadow-lg-2);
  padding: var(--spacing-8);
  z-index: 60;
}
.menu-panel[hidden] { display: none; }
.menu-panel ul { list-style: none; margin: 0; padding: 0; }

.menu-item {
  display: block;
  padding: var(--spacing-10) var(--spacing-15);
  border-radius: var(--radius-buttons);
  text-decoration: none;
  color: var(--color-press-black);
  font-family: var(--font-ui);
  font-size: var(--text-body-sm);
  font-weight: var(--font-weight-w550);
  letter-spacing: var(--tracking-caption);
  white-space: nowrap;
}
.menu-item:hover, .menu-item:focus-visible { background: var(--color-echo-green); outline: none; }
.menu-item:focus-visible { box-shadow: inset 0 0 0 2px var(--color-accent-edge); }

/* The nav is baseline-aligned for type; the button is a square and needs
   centring against it rather than sitting on the same baseline. */
.nav .menu { align-self: center; }
