/* ============================================================
   V4 — cinematic scroll-story
   Full-bleed scenes. The annealing metaphor unfolds through
   scroll: iron → heat → cool → anneal. Then product pitch.
   Massive Inter Tight for impact, Fraunces italic only at the
   brand-reveal moment. Heavy use of color washes per scene.
   ============================================================ */

:root {
  /* Cinema-grade neutrals, deeper than v1. */
  --bg: #050507;
  --bg-2: #0a0a0d;
  --surface: #111114;
  --line: #1d1d22;
  --hairline: rgba(255, 230, 200, 0.06);

  --text: #f0ece4;
  --text-dim: #a7a39a;
  --text-faint: #6b6862;

  /* Heat palette — the molten line of the cycle. */
  --cold: #5b8fce;
  --cold-soft: rgba(91, 143, 206, 0.18);
  --ember: #ff7a3d;
  --ember-deep: #d6451c;
  --ember-glow: #ffb673;
  --ember-soft: rgba(255, 122, 61, 0.20);
  --gold: #f4c468;

  --radius-sm: 4px;
  --radius-md: 10px;
  --radius-lg: 18px;

  --max: 1180px;
  --gutter: clamp(20px, 4.5vw, 56px);

  --ease: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-cinema: cubic-bezier(0.16, 1, 0.3, 1);

  --display: 'Inter Tight', 'Inter', sans-serif;
  --sans: 'Inter', sans-serif;
  --serif-italic: 'Fraunces', Georgia, serif;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 0;
  background: var(--bg);
}

/* Smooth-scroll only on hover-capable devices. On touch, it fights
   momentum scrolling: a flick-and-release causes the browser to keep
   re-snapping the scroll position toward the deceleration target while
   the native momentum is still active, producing a fast up/down jitter. */
@media (hover: hover) and (pointer: fine) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  position: relative;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'ss01', 'cv11', 'kern';
  overflow-x: hidden;
  /* Stop scroll-chaining and rubber-band bounce from interfering when a
     mid-momentum touch reverses direction. Without this, the browser
     fights the incoming touch with its own scroll deceleration logic. */
  overscroll-behavior-y: contain;
}

img { max-width: 100%; display: block; }

a {
  color: var(--text);
  text-decoration: none;
  transition: color 140ms var(--ease);
}

a:hover { color: var(--ember-glow); }

/* ---------- reveal ---------- */
.reveal { opacity: 0; transition: opacity 900ms var(--ease-cinema); transition-delay: calc(var(--reveal-i, 0) * 90ms); }
.reveal.reveal-up { transform: translate3d(0, 28px, 0); transition-property: opacity, transform; }
.reveal.reveal-right { transform: translate3d(28px, 8px, 0); transition-property: opacity, transform; }
.reveal.is-in { opacity: 1; transform: none; }
html:not(.has-js) .reveal, html.reveal-safety .reveal { opacity: 1; transform: none; transition: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ---------- type ---------- */
h1, h2, h3, h4 {
  margin: 0 0 0.5em;
  line-height: 1.05;
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--text);
}

p { margin: 0 0 1em; max-width: 60ch; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

.skip-link { position: absolute; left: -9999px; top: 0; padding: 8px 16px; background: var(--ember); color: var(--bg); z-index: 100; }
.skip-link:focus { left: 0; }

/* ---------- header ---------- */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px var(--gutter);
  max-width: var(--max);
  margin: 0 auto;
  background: transparent;
  /* mix-blend-mode lives behind a hover-capable media query below.
     On mobile it forces a full-frame composite against scrolling
     content every frame, which compounds with momentum scroll and
     causes visible jitter. White-on-dark contrast is enough without it. */
  /* Force the header onto its own GPU layer so it doesn't repaint
     against scrolling content during direction reversals. */
  transform: translateZ(0);
}

@media (hover: hover) and (pointer: fine) {
  .site-header {
    mix-blend-mode: difference;
  }
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.brand-mark { color: var(--ember); display: inline-flex; }

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.6vw, 28px);
  font-size: 0.94rem;
}

.site-nav a {
  color: var(--text);
  font-weight: 500;
  font-family: var(--display);
  letter-spacing: 0.01em;
}

.site-nav a:hover { color: var(--ember-glow); }

.nav-cta {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  background: var(--text);
  color: var(--bg) !important;
  border-radius: 999px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 140ms var(--ease), transform 140ms var(--ease);
  mix-blend-mode: normal;
}

.nav-cta:hover { background: var(--ember-glow); color: var(--bg) !important; }
.nav-cta:active { transform: scale(0.97); }

@media (max-width: 600px) {
  .site-nav a:not(.nav-cta) { display: none; }
}

/* ============================================================
   ░ scenes — full-viewport cinematic stages
   Each scene paints its own color wash. The four scenes together
   walk through the metallurgy metaphor: iron → heat → cool → anneal.
   ============================================================ */

/* ============================================================
   ░ timeline — scroll-driven cinematic stage
   The four scenes are stacked inside a sticky stage. The outer
   .timeline section is 400vh tall, giving JS a runway to convert
   scroll position into a 0..1 progress value. Scene opacities
   are driven from that progress so the user is literally
   scrolling the annealing process forward in time.
   ============================================================ */

.timeline {
  position: relative;
  /* 4 scenes × 150vh-equivalent of scroll per scene. Longer runway =
     more rAF frames per transition = smoother subjective animation.
     Lock to svh so iOS Safari's URL bar appearing/hiding doesn't
     resize the runway mid-scroll. */
  height: calc(100svh * 6);
}

.timeline-stage {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

.timeline-scene {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 18vh var(--gutter) 14vh;
  overflow: hidden;
  /* Two independent opacity drivers written by main.js each frame:
     --bg-op for the atmospheric glow (smooth cosine crossfade),
     --frame-op for the text content (stepped, no overlap). */
  --bg-op: 0;
  --frame-op: 0;
}

.timeline-scene.scene-anneal {
  justify-content: center;
  text-align: center;
}

/* First-paint default: scene i visible before JS runs. */
.timeline-scene.scene-iron {
  --bg-op: 1;
  --frame-op: 1;
}

html:not(.has-js) .timeline-scene.scene-iron {
  --bg-op: 1;
  --frame-op: 1;
}

/* Background atmosphere lives on a ::before pseudo, controlled by --bg-op
   so it can fade independently of the text content above it. The per-scene
   class (.scene-iron, .scene-heat, .scene-cool, .scene-anneal) supplies
   the gradient in its ::before declaration below.

   The ::before also carries a slow ambient drift animation so the colors
   feel alive rather than static — the gradient anchor points subtly
   scale and translate over long cycles. Pure transform = GPU-accelerated
   and cheap on mobile. */
.timeline-scene::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: var(--bg-op);
  pointer-events: none;
  transform-origin: center;
  /* Single inhale-hold-exhale arc using a cubic-bezier tuned for
     breathing feel: slow leaving rest, quicker through middle, slow
     entering peak, then mirrored on the way back. Hold at peak comes
     from the 45-55% keyframe twin in the @keyframes blocks below. */
  animation: atmosphere-breathe 24s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Per-scene timing variations — each scene gets its own breathing
   rhythm so the four feel like distinct moments. */
.scene-iron::before { animation-duration: 24s; } /* slow ambient breath */
.scene-cool::before { animation-duration: 26s; } /* slowest — settling */
.scene-heat::before {
  /* Heat is agitated — shorter breath, deeper amplitude. */
  animation: heat-breathe 14s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.scene-anneal::before {
  /* Anneal is the peak forge — deep, deliberate breath. */
  animation: ember-breathe 9s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* The inner forge glow has a much faster pulse — like a heart inside
   the slow outer breath of scene iv. */
.scene-forge {
  animation: forge-pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  transform-origin: center;
}

/* Each keyframe block uses the 45%/55% trick to give the breath a
   brief hold at peak. The 0%/100% pair are the natural rest pose.

   No translate or rotate — those made the off-center gradient anchors
   visibly drift sideways, which reads as "splotches moving around"
   rather than "glow blooming from center." Pure radial scale lets each
   gradient grow outward from the box center, paired with a brightness
   + saturate pulse so the colors visibly intensify at peak. The result
   reads as the atmosphere breathing in (bright + saturated + larger)
   and breathing out (dim + muted + smaller) without any drift. */

@keyframes atmosphere-breathe {
  0%, 100% {
    transform: scale(1);
    filter: brightness(0.88) saturate(0.92);
  }
  45%, 55% {
    transform: scale(1.07);
    filter: brightness(1.18) saturate(1.10);
  }
}

@keyframes heat-breathe {
  0%, 100% {
    transform: scale(1);
    filter: brightness(0.85) saturate(0.92);
  }
  45%, 55% {
    transform: scale(1.09);
    filter: brightness(1.22) saturate(1.12);
  }
}

@keyframes ember-breathe {
  0%, 100% {
    transform: scale(1);
    filter: brightness(0.86) saturate(0.92);
  }
  45%, 55% {
    transform: scale(1.12);
    filter: brightness(1.28) saturate(1.14);
  }
}

@keyframes forge-pulse {
  /* The inner forge glow is a single centered radial — large radial
     scale is safe here because there are no off-center anchors to
     translate. The bigger contrast (0.80 -> 1.30) reads as the core
     of the fire pulsing inside the slower outer breath. */
  0%, 100% {
    transform: scale(0.80);
    filter: brightness(0.75);
  }
  45%, 55% {
    transform: scale(1.28);
    filter: brightness(1.35);
  }
}

@media (prefers-reduced-motion: reduce) {
  .timeline-scene::before,
  .scene-forge {
    animation: none;
  }
}

/* Vignette and forge fade with the atmosphere — they're part of the
   visual glow, not the text. */
.timeline-scene .scene-vignette,
.timeline-scene .scene-forge {
  opacity: var(--bg-op);
}

/* Frame (chapter card + word + caption) and scene-temp (vertical
   "COLD" / "RISING" labels) fade with the stepped pattern, so text
   never overlaps between scenes. */
.timeline-scene .scene-frame,
.timeline-scene .scene-temp {
  opacity: var(--frame-op);
}

.scene-frame {
  position: relative;
  z-index: 3;
  max-width: 960px;
}

/* Cinematic vignette per scene — soft radial darkening at the corners.
   Adds weight to the frame without UI chrome. */
.scene-vignette {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    radial-gradient(ellipse 90% 70% at 50% 50%, transparent 45%, rgba(0, 0, 0, 0.32) 88%, rgba(0, 0, 0, 0.55) 100%);
}

/* Chapter card — italic Roman numeral + hairline + small-caps caption.
   Reads like a film chapter marker. */
.scene-chapter {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0 0 28px;
}

.scene-anneal .scene-chapter {
  justify-content: center;
}

.ch-numeral {
  font-family: var(--serif-italic);
  font-variation-settings: 'opsz' 14, 'SOFT' 100;
  font-style: italic;
  font-size: 1.6rem;
  font-weight: 500;
  color: var(--ember-glow);
  line-height: 1;
  letter-spacing: 0;
  flex-shrink: 0;
}

.ch-rule {
  display: inline-block;
  flex: 0 0 32px;
  height: 1px;
  background: var(--ember-soft);
}

.ch-cap {
  font-family: var(--display);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--text-faint);
  flex-shrink: 0;
}

.scene-word {
  font-family: var(--display);
  /* Min reduced so multi-word phrases ("Let it cool.") wrap cleanly at
     375px without overflowing. text-wrap: balance handles the break. */
  font-size: clamp(4rem, 17vw, 16rem);
  font-weight: 500;
  line-height: 0.9;
  margin: 0 0 32px;
  letter-spacing: -0.045em;
  text-wrap: balance;
  color: var(--text);
  /* Subtle weight in space — keeps hero words from feeling flat-printed. */
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.4),
    0 0 90px rgba(0, 0, 0, 0.5);
}

/* Cinematic staircase: chapter card → word → caption arrive in sequence
   per scene. Overrides the global reveal stagger with a slower beat that
   feels like a cinematic count rather than a list. */
.scene-frame > .reveal {
  transition-delay: calc(var(--reveal-i, 0) * 260ms);
}

.scene-caption {
  font-family: var(--sans);
  font-size: clamp(1.06rem, 1.5vw, 1.28rem);
  line-height: 1.55;
  color: var(--text-dim);
  max-width: 38ch;
  margin: 0;
}

.scene-temp {
  position: absolute;
  top: 50%;
  right: var(--gutter);
  transform: translateY(-50%);
  pointer-events: none;
  z-index: 1;
}

.scene-temp-label {
  font-family: var(--display);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--text-faint);
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
}

/* — Scene 01 — Iron (cold) —
   Background lives on ::before so --bg-op can fade it smoothly while
   the text on this scene fades stepped. Alphas tuned for crossfade
   stacking (where each scene contributes at fractional opacity). */
.scene-iron {
  color: var(--text);
}
.scene-iron::before {
  background:
    radial-gradient(1400px 900px at 80% 30%, rgba(91, 143, 206, 0.45), transparent 65%),
    radial-gradient(1100px 700px at 0% 80%, rgba(91, 143, 206, 0.26), transparent 60%),
    radial-gradient(900px 700px at 50% 100%, rgba(60, 110, 180, 0.18), transparent 60%),
    linear-gradient(180deg, #050507 0%, #06080d 100%);
}
.scene-iron .scene-word {
  color: #e9ecf2;
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.4),
    0 0 100px rgba(91, 143, 206, 0.18);
}
.scene-iron .ch-numeral { color: var(--cold); }
.scene-iron .ch-rule { background: rgba(91, 143, 206, 0.28); }
.scene-iron .scene-temp-label { color: rgba(91, 143, 206, 0.5); }

/* — Scene 02 — Heat (warming) — alphas boosted for crossfade pop. */
.scene-heat::before {
  background:
    radial-gradient(1400px 900px at 80% 40%, rgba(214, 69, 28, 0.48), transparent 65%),
    radial-gradient(1100px 700px at 20% 90%, rgba(255, 122, 61, 0.42), transparent 60%),
    radial-gradient(900px 700px at 60% 0%, rgba(255, 90, 40, 0.22), transparent 60%),
    linear-gradient(180deg, #060507 0%, #1a0907 100%);
}
.scene-heat .scene-word {
  color: var(--text);
  /* Heat halo — radiant warmth around the word. Static; no animation
     needed because the gradient backdrop already breathes. */
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.4),
    0 0 60px rgba(255, 140, 80, 0.28),
    0 0 140px rgba(220, 90, 40, 0.18),
    0 0 240px rgba(214, 69, 28, 0.12);
}
.scene-heat .ch-numeral { color: var(--ember-glow); }
.scene-heat .scene-temp-label { color: rgba(255, 122, 61, 0.55); }

/* — Scene 03 — Cool (settling) —
   Reads as a kiln cooling: dominant indigo-blue atmosphere with a
   residual ember afterglow only at the bottom-right corner. The heat
   is leaving, not absent. Alphas boosted for crossfade pop. */
.scene-cool::before {
  background:
    radial-gradient(1600px 1000px at 35% 30%, rgba(91, 143, 206, 0.48), transparent 65%),
    radial-gradient(1100px 700px at 75% 60%, rgba(60, 110, 180, 0.32), transparent 62%),
    radial-gradient(900px 600px at 10% 100%, rgba(70, 130, 200, 0.22), transparent 60%),
    radial-gradient(560px 420px at 95% 100%, rgba(214, 69, 28, 0.22), transparent 60%),
    linear-gradient(180deg, #060709 0%, #080b12 100%);
}
.scene-cool .scene-word {
  color: #e9ecf2;
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.4),
    0 0 100px rgba(91, 143, 206, 0.20);
}
.scene-cool .ch-numeral { color: var(--cold); }
.scene-cool .ch-rule { background: rgba(91, 143, 206, 0.28); }
.scene-cool .scene-temp-label { color: rgba(91, 143, 206, 0.5); }

/* ============================================================
   — Scene 04 — Anneal (brand reveal, peak ember)
   The page's climax. Forge-grade lighting: multiple concentric
   ember radials, deeper edges, warm scatter. The "Anneal." word
   reveals letter by letter once the scene enters view.
   ============================================================ */

.scene-anneal {
  text-align: center;
  justify-content: center;
}
.scene-anneal::before {
  background:
    radial-gradient(800px 800px at 50% 50%, rgba(255, 200, 130, 0.42), transparent 60%),
    radial-gradient(1400px 1000px at 50% 55%, rgba(255, 122, 61, 0.55), transparent 62%),
    radial-gradient(2000px 1200px at 50% 60%, rgba(214, 69, 28, 0.55), transparent 65%),
    radial-gradient(1200px 800px at 20% 105%, rgba(214, 69, 28, 0.62), transparent 65%),
    radial-gradient(1200px 800px at 80% -5%, rgba(255, 100, 50, 0.36), transparent 65%),
    linear-gradient(180deg, #06060a 0%, #1a0907 50%, #0a0606 100%);
}

/* Inner forge radial — sits behind the wordmark, slowly visible.
   Pure CSS, no animation, so screenshot capture stays stable. */
.scene-forge {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(420px 420px at 50% 50%, rgba(255, 200, 140, 0.18), transparent 65%);
}

.scene-anneal .scene-vignette {
  background:
    radial-gradient(ellipse 90% 70% at 50% 50%, transparent 38%, rgba(0, 0, 0, 0.40) 88%, rgba(0, 0, 0, 0.65) 100%);
}

.scene-anneal .scene-frame {
  text-align: center;
  margin: 0 auto;
}

.scene-anneal .ch-numeral { color: var(--ember-glow); }
/* "Four of four" picks up the ember glow so it reads as part of the
   chapter card rather than washing out against the bright atmosphere. */
.scene-anneal .ch-cap {
  color: var(--ember-glow);
  text-shadow: 0 0 18px rgba(255, 170, 110, 0.45);
}
.scene-anneal .scene-caption {
  margin: 0 auto;
  color: rgba(240, 236, 228, 0.86);
}

.brand-reveal {
  font-family: var(--serif-italic);
  font-variation-settings: 'opsz' 144, 'SOFT' 100, 'WONK' 1;
  font-style: italic;
  font-weight: 500;
  color: var(--ember-glow);
  letter-spacing: -0.04em;
  line-height: 0.92;
  margin: 0 0 36px;
  text-shadow:
    0 0 60px rgba(255, 170, 110, 0.50),
    0 0 140px rgba(255, 122, 61, 0.40),
    0 0 220px rgba(214, 69, 28, 0.32);
}

.brand-anneal {
  display: inline-block;
  font-style: italic;
  /* Keep every letter on one line even on narrow mobile viewports.
     Without this, the per-letter inline-block boxes can break between
     "A" and "nneal" mid-cascade because some browsers re-measure
     inline-block dimensions during a transform animation. */
  white-space: nowrap;
}

.brand-reveal {
  white-space: nowrap;
}

/* Letter cascade. Each letter waits hidden until the parent enters view,
   then rises + scales-up in sequence. Total reveal ~1.1s for six letters.
   Pure transform + opacity (no filter: blur) — keeps the renderer happy
   for headless screenshots and stays GPU-cheap on slower devices. */
.brand-anneal .ltr {
  display: inline-block;
  opacity: 0;
  transform: translateY(40px) scale(0.88);
  /* No will-change — the animation fires once and forwards-locks. Leaving
     it set would keep six promoted layers alive forever, adding GPU memory
     pressure during fast scrolling on mobile. */
}

.brand-reveal.is-in .brand-anneal .ltr {
  animation: anneal-letter 1000ms var(--ease-cinema) forwards;
}

.brand-reveal.is-in .brand-anneal .ltr:nth-child(1) { animation-delay: 80ms; }
.brand-reveal.is-in .brand-anneal .ltr:nth-child(2) { animation-delay: 180ms; }
.brand-reveal.is-in .brand-anneal .ltr:nth-child(3) { animation-delay: 280ms; }
.brand-reveal.is-in .brand-anneal .ltr:nth-child(4) { animation-delay: 400ms; }
.brand-reveal.is-in .brand-anneal .ltr:nth-child(5) { animation-delay: 540ms; }
.brand-reveal.is-in .brand-anneal .ltr:nth-child(6) { animation-delay: 700ms; }

@keyframes anneal-letter {
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* The period: a separate object that lands after the letters settle, with
   its own ember glow. Like a final ember spark from the forge.
   No will-change — one-shot animation, forwards-locked. */
.brand-period {
  display: inline-block;
  color: var(--gold);
  opacity: 0;
  transform: scale(0.7);
  text-shadow:
    0 0 30px rgba(255, 200, 110, 0.8),
    0 0 60px rgba(255, 170, 80, 0.5);
}

.brand-reveal.is-in .brand-period {
  animation: anneal-period 700ms var(--ease-cinema) 980ms forwards;
}

@keyframes anneal-period {
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .brand-anneal .ltr,
  .brand-period {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
  }
}

/* ============================================================
   ░ pitch — first paragraph of product copy after the metaphor
   ============================================================ */

.pitch {
  padding: clamp(80px, 14vw, 180px) var(--gutter);
  max-width: var(--max);
  margin: 0 auto;
  border-top: 1px solid var(--hairline);
}

.pitch-inner {
  max-width: 880px;
}

.pitch-meta {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ember-glow);
  margin: 0 0 36px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.pitch-meta::before {
  content: '';
  width: 56px;
  height: 1px;
  background: var(--ember-soft);
}

.pitch-h {
  font-family: var(--display);
  font-size: clamp(2.4rem, 5.4vw, 4.4rem);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: var(--text);
  margin: 0 0 32px;
  text-wrap: balance;
}

.pitch-h em {
  /* Matches the WONK axis from the scene iv brand reveal so the pitch
     reads as Chapter V of the same film, not a register switch. */
  font-family: var(--serif-italic);
  font-variation-settings: 'opsz' 144, 'SOFT' 100, 'WONK' 1;
  font-style: italic;
  font-weight: 500;
  color: var(--ember-glow);
}

.pitch-sub {
  font-family: var(--sans);
  font-size: clamp(1.04rem, 1.3vw, 1.16rem);
  line-height: 1.6;
  color: var(--text-dim);
  max-width: 60ch;
  margin: 0 0 40px;
}

/* ---------- waitlist form ---------- */
.waitlist {
  display: flex;
  gap: 8px;
  max-width: 480px;
  flex-wrap: wrap;
}

.waitlist input {
  flex: 1 1 220px;
  min-width: 0;
  padding: 15px 20px;
  font: inherit;
  font-size: 1rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  outline: none;
  transition: border-color 140ms var(--ease), background 140ms var(--ease),
    box-shadow 140ms var(--ease);
}

.waitlist input::placeholder { color: var(--text-faint); }

.waitlist input:focus {
  border-color: var(--ember);
  background: var(--bg-2);
  box-shadow: 0 0 0 3px var(--ember-soft);
}

.waitlist button {
  padding: 15px 26px;
  font: inherit;
  font-weight: 500;
  font-size: 1rem;
  color: var(--bg);
  background: var(--text);
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  transition: background 140ms var(--ease), transform 140ms var(--ease),
    box-shadow 140ms var(--ease);
}

.waitlist button:hover {
  background: var(--ember-glow);
  box-shadow: 0 8px 32px rgba(255, 122, 61, 0.25);
}

.waitlist button:active { transform: scale(0.97); }

/* ---------- waitlist: training-type radio group ---------- */
/* Sits on its own full-width row between the email field and the
   submit button. Overrides the generic ".waitlist input" pill styles
   that would otherwise bleed onto the radios. */
.waitlist-lifter-type {
  flex: 1 1 100%;
  min-width: 0;
  margin: 4px 0 0;
  padding: 0;
  border: 0;
}

.waitlist-lifter-type legend {
  width: 100%;
  padding: 0;
  margin-bottom: 10px;
  color: var(--text-dim);
  font-size: 0.92rem;
  line-height: 1.4;
}

.waitlist-lifter-type label {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  color: var(--text-dim);
  font-size: 0.96rem;
  line-height: 1.3;
  cursor: pointer;
  transition: background 140ms var(--ease), color 140ms var(--ease);
}

.waitlist-lifter-type label + label { margin-top: 2px; }

.waitlist-lifter-type label:hover { background: var(--surface); color: var(--text); }

.waitlist-lifter-type label:has(input:checked) { background: var(--surface); color: var(--text); }

.waitlist-lifter-type label span { flex: 1; }

/* custom radio control - neutralizes the inherited text-input styling */
.waitlist-lifter-type input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 0;
  padding: 0;
  display: grid;
  place-content: center;
  background: var(--bg-2);
  border: 1.5px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
  transition: border-color 140ms var(--ease), box-shadow 140ms var(--ease);
}

.waitlist-lifter-type input[type="radio"]::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ember);
  transform: scale(0);
  transition: transform 140ms var(--ease);
}

.waitlist-lifter-type input[type="radio"]:checked {
  border-color: var(--ember);
}

.waitlist-lifter-type input[type="radio"]:checked::before { transform: scale(1); }

.waitlist-lifter-type input[type="radio"]:focus-visible {
  box-shadow: 0 0 0 3px var(--ember-soft);
}

.form-note {
  margin-top: 14px;
  color: var(--text-faint);
  font-size: 0.92rem;
}

.form-note.success { color: var(--ember-glow); }

/* ============================================================
   ░ features — alternating cinematic spreads
   Each spread is generous, paired with a screenshot, and uses
   the heat-cool palette as background washes.
   ============================================================ */

.features {
  border-top: 1px solid var(--hairline);
}

.feature-scene {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 96px);
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(80px, 14vw, 180px) var(--gutter);
  align-items: center;
  border-bottom: 1px solid var(--hairline);
  position: relative;
}

.feature-scene::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(700px 500px at 100% 50%, rgba(255, 122, 61, 0.05), transparent 65%);
}

.feature-scene.flipped .feature-text { order: 2; }
.feature-scene.flipped .feature-art { order: 1; }

.feature-scene.flipped::before {
  background:
    radial-gradient(700px 500px at 0% 50%, rgba(91, 143, 206, 0.06), transparent 65%);
}

@media (max-width: 880px) {
  .feature-scene, .feature-scene.flipped {
    grid-template-columns: 1fr;
    padding: clamp(64px, 12vw, 120px) var(--gutter);
  }
  .feature-scene.flipped .feature-text, .feature-scene.flipped .feature-art { order: initial; }
}

.feature-text { position: relative; z-index: 1; }

.feature-no {
  font-family: var(--serif-italic);
  font-variation-settings: 'opsz' 14, 'SOFT' 100;
  font-style: italic;
  font-size: 1.1rem;
  color: var(--ember-glow);
  margin: 0 0 24px;
  font-weight: 500;
}

.feature-text h2 {
  font-family: var(--display);
  font-size: clamp(2rem, 4.2vw, 3.4rem);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.04;
  margin: 0 0 24px;
  text-wrap: balance;
}

.feature-text p {
  font-family: var(--sans);
  font-size: 1.07rem;
  line-height: 1.62;
  color: var(--text-dim);
  margin: 0;
  max-width: 46ch;
}

.feature-art {
  position: relative;
  z-index: 1;
  margin: 0;
  display: flex;
  justify-content: center;
}

.feature-art img {
  width: 100%;
  max-width: 380px;
  height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  box-shadow:
    0 1px 0 rgba(255, 240, 215, 0.06) inset,
    0 50px 100px -30px rgba(0, 0, 0, 0.7),
    0 0 120px -20px rgba(255, 122, 61, 0.18);
}

/* ============================================================
   ░ faq
   ============================================================ */

.faq {
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(80px, 12vw, 150px) var(--gutter);
  border-top: 1px solid var(--hairline);
}

.faq-head { max-width: 720px; margin: 0 0 56px; }

.folio-quiet {
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ember-glow);
  margin: 0 0 22px;
}

.faq h2 {
  font-family: var(--display);
  font-size: clamp(2rem, 4.2vw, 3.2rem);
  font-weight: 500;
  letter-spacing: -0.025em;
  margin: 0;
  text-wrap: balance;
}

.faq-list {
  display: grid;
  gap: 0;
}

.faq-list details {
  padding: 24px 0;
  border-top: 1px solid var(--hairline);
  transition: background 160ms var(--ease);
}

.faq-list details:last-child { border-bottom: 1px solid var(--hairline); }

.faq-list summary {
  cursor: pointer;
  font-family: var(--display);
  font-size: clamp(1.12rem, 1.7vw, 1.4rem);
  font-weight: 500;
  color: var(--text);
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  letter-spacing: -0.015em;
}

.faq-list summary::-webkit-details-marker { display: none; }

.faq-list summary::after {
  content: '+';
  font-family: var(--display);
  font-size: 1.5rem;
  color: var(--text-faint);
  font-weight: 300;
  flex-shrink: 0;
  transition: transform 240ms var(--ease), color 160ms var(--ease);
}

.faq-list details[open] summary::after {
  content: '−';
  color: var(--ember-glow);
}

.faq-list details p {
  margin: 16px 0 4px;
  font-family: var(--sans);
  font-size: 1.02rem;
  line-height: 1.65;
  color: var(--text-dim);
  max-width: 68ch;
}

/* ============================================================
   ░ closing — final beta CTA
   Hottest moment of the whole page. Ember peak.
   ============================================================ */

.closing {
  position: relative;
  padding: clamp(120px, 18vw, 220px) var(--gutter);
  text-align: center;
  overflow: hidden;
  background:
    radial-gradient(1400px 900px at 50% 50%, rgba(255, 122, 61, 0.24), transparent 65%),
    radial-gradient(1000px 700px at 30% 110%, rgba(214, 69, 28, 0.32), transparent 65%),
    linear-gradient(180deg, var(--bg) 0%, #0d0807 100%);
  border-top: 1px solid var(--hairline);
}

.closing-inner {
  max-width: 800px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}

.closing-folio {
  font-family: var(--display);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--ember-glow);
  margin: 0 0 32px;
}

.closing-h {
  font-family: var(--serif-italic);
  font-variation-settings: 'opsz' 144, 'SOFT' 100, 'WONK' 1;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(3.2rem, 8vw, 6.4rem);
  line-height: 1.0;
  letter-spacing: -0.03em;
  margin: 0 0 36px;
  text-shadow: 0 0 80px rgba(255, 122, 61, 0.30);
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: center;
}

/* Cycle reveal — each temperature word arrives in sequence with its own
   color, mirroring the four-scene metaphor's beat. */
.closing-cycle {
  display: inline-block;
  color: var(--text);
  opacity: 0;
  transform: translateY(28px) scale(0.94);
  /* No will-change — one-shot animation, forwards-locked. See .ltr. */
}

.closing-cycle-1 {
  color: var(--ember);
  text-shadow: 0 0 50px rgba(214, 69, 28, 0.45);
}
.closing-cycle-2 {
  color: var(--cold);
  text-shadow: 0 0 50px rgba(91, 143, 206, 0.40);
}
.closing-cycle-3 {
  color: var(--ember-glow);
  text-shadow: 0 0 60px rgba(255, 170, 110, 0.55), 0 0 120px rgba(214, 69, 28, 0.30);
}

.closing-h.is-in .closing-cycle {
  animation: closing-cycle-in 900ms var(--ease-cinema) forwards;
}

.closing-h.is-in .closing-cycle-1 { animation-delay: 80ms; }
.closing-h.is-in .closing-cycle-2 { animation-delay: 380ms; }
.closing-h.is-in .closing-cycle-3 { animation-delay: 700ms; }

@keyframes closing-cycle-in {
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .closing-cycle {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    animation: none !important;
  }
}

/* Closing coda: a small italic Fraunces line that lands ~300ms after the
   third cycle word finishes staggering in. The exhale after the cycle. */
.closing-coda {
  font-family: var(--serif-italic);
  font-variation-settings: 'opsz' 36, 'SOFT' 100;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.05rem, 1.7vw, 1.4rem);
  line-height: 1.3;
  color: var(--ember-glow);
  letter-spacing: 0;
  margin: 8px 0 36px;
  opacity: 0;
  transform: translateY(14px);
  /* No will-change — one-shot animation, forwards-locked. */
}

/* Trigger the coda's reveal off the closing-h's intersection-observer
   state. By the time .closing-h.is-in fires, the three cycle words begin
   their stagger; the coda then waits out the cycle (final word ends at
   ~1600ms) before landing ~300ms later. */
.closing-h.is-in ~ .closing-coda {
  animation: coda-land 800ms var(--ease-cinema) 1900ms forwards;
}

@keyframes coda-land {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .closing-coda {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}

.closing-sub {
  font-family: var(--sans);
  font-size: 1.08rem;
  color: var(--text-dim);
  margin: 0 auto 36px;
  max-width: 44ch;
  line-height: 1.6;
}

.closing-inner .waitlist {
  margin: 0 auto;
  justify-content: center;
}

.closing-inner .form-note {
  text-align: center;
}

/* ---------- footer ---------- */
.site-footer {
  margin-top: 0;
  border-top: 1px solid var(--hairline);
  background: var(--bg);
}

.footer-inner {
  max-width: var(--max);
  margin: 0 auto;
  padding: 64px var(--gutter) 32px;
  display: grid;
  grid-template-columns: 1.4fr 2fr;
  gap: 48px;
}

@media (max-width: 720px) {
  .footer-inner { grid-template-columns: 1fr; gap: 32px; }
}

.footer-brand .brand-name {
  font-family: var(--display);
  font-size: 1.1rem;
  font-weight: 500;
}

.footer-tag {
  color: var(--text-faint);
  font-size: 0.95rem;
  margin: 16px 0 0;
  max-width: 30ch;
}

.footer-cols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.footer-col h4 {
  font-family: var(--display);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 16px;
}

.footer-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 10px;
}

.footer-col a {
  color: var(--text-dim);
  font-size: 0.95rem;
}

.footer-col a:hover { color: var(--ember-glow); }

.footer-base {
  max-width: var(--max);
  margin: 0 auto;
  padding: 22px var(--gutter) 40px;
  color: var(--text-faint);
  font-size: 0.82rem;
  border-top: 1px solid var(--hairline);
}

/* ---------- motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
