/* ═══════════════════════════════════════════════════════════
   SPRK NETWORK — STYLES
   VSL-first conversion layout: running ticker, video as the hero
   in a device bezel, glow CTA, proof marquee, ghost-numeral steps,
   sticky bar. Dark navy paper, muted-gold accent.

   Colour comes only from tokens.css.
   ═══════════════════════════════════════════════════════════ */

/* ── 01 · reset & root ───────────────────────────────────── */

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

html, body { margin: 0; padding: 0; overflow-x: clip; }

html {
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 16px;
  scroll-behavior: smooth;

  /* The nav is sticky and the CTA bar is fixed, so an un-padded anchor
     jump lands its target underneath one of them. */
  scroll-padding-top: 5rem;
  scroll-padding-bottom: 7rem;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
}

body {
  position: relative;
  /* Required. `html` carries its own background, so body's opaque
     background paints as an ordinary element AFTER the negative-z
     layer. Without a stacking context here, .ambient (z-index -2) and
     .step__ghost (-1) escape to the root and are painted over by it —
     the blooms, grid, grain and ghost numerals rendered and were then
     hidden. isolation:isolate scopes them to body so they show. */
  isolation: isolate;
  min-height: 100dvh;
  font-family: var(--font-body);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  color: var(--color-ink);
  background: var(--color-paper);
  font-feature-settings: "ss01", "cv11";
}

img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; padding: 0; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4, p { margin: 0; }

::selection { background: var(--color-accent); color: var(--color-accent-ink); }

a, button, summary, .dot {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.tnum { font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }

.skip {
  position: absolute;
  top: -40px;
  left: var(--space-md);
  padding: var(--space-xs) var(--space-md);
  background: var(--color-ink);
  color: var(--color-paper);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  z-index: var(--z-skip);
}
.skip:focus { top: var(--space-md); }

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

.icon-stroke {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: 0 0 auto;
}


/* ── 02 · ambient ────────────────────────────────────────── */

.ambient {
  position: fixed;
  inset: 0;
  z-index: var(--z-ambient);
  pointer-events: none;
  overflow: hidden;
}

.bloom { position: absolute; border-radius: 50%; filter: blur(80px); opacity: 0.5; }

.bloom--1 {
  top: -14vmax; left: -10vmax;
  width: 58vmax; height: 58vmax;
  background: radial-gradient(closest-side,
    color-mix(in oklch, var(--color-bloom-1) 22%, transparent), transparent 70%);
}

.bloom--2 {
  bottom: -22vmax; right: -16vmax;
  width: 55vmax; height: 55vmax;
  background: radial-gradient(closest-side,
    color-mix(in oklch, var(--color-bloom-2) 40%, transparent), transparent 70%);
}

/* Faint blueprint grid — gives the dark field structure without
   drawing attention to itself. */
.grid-lines {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right,  color-mix(in oklch, var(--color-rule) 55%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklch, var(--color-rule) 55%, transparent) 1px, transparent 1px);
  background-size: 88px 88px;
  opacity: 0.5;
  -webkit-mask-image: radial-gradient(ellipse 90% 60% at 50% 0%, #000, transparent 75%);
  mask-image: radial-gradient(ellipse 90% 60% at 50% 0%, #000, transparent 75%);
}

.grain {
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.95  0 0 0 0 0.94  0 0 0 0 0.92  0 0 0 0.06 0'/></filter><rect width='200' height='200' filter='url(%23n)' opacity='0.6'/></svg>");
  background-size: 200px 200px;
  opacity: 0.4;
  mix-blend-mode: overlay;
}


/* ── 03 · ticker ─────────────────────────────────────────── */

.ticker {
  position: relative;
  z-index: 2;
  overflow: hidden;
  border-bottom: var(--rule-hair) solid var(--color-rule);
  background: color-mix(in oklch, var(--color-paper-2) 60%, transparent);
  padding-block: var(--space-xs);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.ticker__track {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  width: max-content;
  animation: ticker 34s linear infinite;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-ink-3);
  white-space: nowrap;
}

.ticker__sep { color: var(--color-accent); }

@keyframes ticker {
  /* -50% resolves against the border box: for n items there are n-1 gaps,
     so the true repeat period is half a gap longer than half the width.
     Without the correction the strip jumps 8px forward once per cycle. */
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - var(--space-md) / 2)); }
}


/* ── 04 · nav · floating pill ────────────────────────────── */

.nav {
  position: sticky;
  top: var(--space-md);
  z-index: var(--z-nav);
  padding: var(--space-md) var(--page-gutter) 0;
  pointer-events: none;
  transition: top var(--dur-slow) var(--ease-out);
}

.nav[data-state="scrolled"] { top: var(--space-sm); }

.nav__inner {
  pointer-events: auto;
  max-width: var(--max-width);
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-xs) var(--space-xs) var(--space-xs) var(--space-md);
  background: color-mix(in oklch, var(--color-paper) 76%, transparent);
  backdrop-filter: blur(18px) saturate(1.4);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  border: var(--rule-hair) solid var(--color-rule-strong);
  border-radius: var(--radius-pill);
  transition:
    max-width var(--dur-slow) var(--ease-out),
    padding var(--dur-base) var(--ease-out),
    background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-slow) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.nav[data-state="scrolled"] .nav__inner {
  max-width: 56rem;
  padding: var(--space-2xs) var(--space-2xs) var(--space-2xs) var(--space-md);
  background: color-mix(in oklch, var(--color-paper) 94%, transparent);
  border-color: color-mix(in oklch, var(--color-accent) 32%, var(--color-rule-strong));
  box-shadow: var(--sh-nav), 0 0 60px -8px color-mix(in oklch, var(--color-accent) 22%, transparent);
  transform: scale(0.965);
}

.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-sm);
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.nav__brand-logo { width: 20px; height: 20px; object-fit: contain; flex: 0 0 auto; }
.nav__brand-text span { color: var(--color-accent); }

.nav__links {
  display: flex;
  justify-content: center;
  gap: var(--space-md);
  font-size: var(--text-sm);
  color: var(--color-ink-2);
  transition: gap var(--dur-base) var(--ease-out), font-size var(--dur-base) var(--ease-out);
}
.nav[data-state="scrolled"] .nav__links { gap: var(--space-sm); font-size: var(--text-xs); }

.nav__links a {
  padding: var(--space-2xs) var(--space-xs);
  border-radius: var(--radius-sm);
  transition: color var(--dur-fast) var(--ease-out);
  white-space: nowrap;
}
.nav__links a:hover { color: var(--color-ink); }

.nav__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-md);
  background: var(--color-accent);
  color: var(--color-accent-ink);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 600;
  white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.nav__cta:hover {
  transform: translateY(-1px);
  background: color-mix(in oklch, var(--color-accent) 88%, var(--color-ink));
}
.nav__cta:active { transform: translateY(0); }

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.6; transform: scale(0.85); }
}


/* ── 05 · stage · the VSL is the hero ────────────────────── */

.stage {
  position: relative;
  isolation: isolate;
  max-width: 68rem;
  margin: 0 auto;
  padding: var(--space-2xl) var(--page-gutter) var(--space-3xl);
  display: grid;
  justify-items: center;
  gap: var(--space-lg);
  text-align: center;
}

.stage__spotlight {
  position: absolute;
  inset: -10% 0 40%;
  z-index: -1;
  background: radial-gradient(60% 50% at 50% 30%,
    color-mix(in oklch, var(--color-accent) 12%, transparent), transparent 70%);
  pointer-events: none;
}

.stage__mark { width: 46px; height: 46px; object-fit: contain; }

.stage__h {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.1rem, 5.4vw, 4rem);
  line-height: 1.04;
  letter-spacing: -0.035em;
  max-width: 18ch;
  text-wrap: balance;
}

/* The italic-serif gold accent. Its declaration block was deleted along
   with .footer__statement in 1e39e33, which left this selector list
   dangling on a trailing comma so it merged into .stage__sub — every
   accent word inherited 17px muted grey inside a 38px display heading. */
.stage__h em,
.statement__h em,
.section-h em,
.close__h em,
.welcome__h em,
.apply__h em {
  font-family: var(--font-accent);
  font-style: italic;
  font-weight: 400;
  font-size: 1.12em;
  letter-spacing: -0.02em;
  color: var(--color-accent);
  font-feature-settings: normal;
}

.stage__sub {
  /* balance, not pretty: at this length `pretty` leaves a short widow line and
     the Discord line underneath then reads as its ragged continuation. */
  max-width: 48ch;
  color: var(--color-ink-2);
  font-size: var(--text-md);
  text-wrap: balance;
}

/* ── .lp-hero · the current landing-page hero treatment ───────
   Carried by BOTH / and /test. It started life scoped to .testpage while the
   sweepstakes headline was being tried out; once that shipped to the homepage
   the scope was renamed, so the two pages cannot drift apart by accident.

   /test additionally carries .testpage, which now has no rules of its own —
   that is deliberate. It is the hook for the NEXT experiment, so a variant can
   be styled on /test without touching the page ads point at. Anything proven
   there gets promoted into .lp-hero the same way this was.
   ────────────────────────────────────────────────────────────── */

/* Sized for the headline it currently holds — retune both numbers whenever
   its length changes materially. At ~47 characters it takes three lines and
   can afford to be bigger than /'s display headline; the previous ~100
   character version could not, and stacked to seven lines on a phone.
   Tracking goes tighter as the size goes up: letterforms that look spaced
   at 2rem look loose at 5rem. */
.lp-hero .stage__h {
  max-width: 18ch;
  /* Fluid all the way down instead of a flat 2rem floor. A flat 32px broke to
     FOUR lines on a 320px iPhone SE, and on 375/390 it stranded "underground"
     alone in the middle of the headline — 26 characters needed ~361px and a
     390pt phone only offers 358. Scaling with the viewport holds it to two
     lines on every iPhone width from 320 up. */
  font-size: clamp(1.625rem, 8.5vw - 0.1rem, 4rem);
  line-height: 1.0;
  letter-spacing: -0.04em;
}

/* The accent keeps the serif italic and the gold but loses the 12% size bump
   the shared rule gives it. That bump is what pushed "underground" past the
   line and orphaned it, and because the serif has different vertical metrics
   the oversized word also sat off the sans baseline — which is what read as
   the headline breaking apart rather than simply wrapping. */
.lp-hero .stage__h em { font-size: 1em; }

/* ── Vidalytics unmute prompt ──────────────────────────────────
   iOS Safari refuses unmuted autoplay, so the player falls back to muted and
   raises this prompt. Shipped, it is a saturated blue slab across the middle
   of the frame covering ~29% of the video — including the speaker's face —
   for as long as it is up.

   It is NOT hidden, deliberately. Muted autoplay with no prompt is a silent
   VSL: the visitor never learns there is audio, and a silent VSL converts at
   roughly nothing. The prompt is load-bearing. So it is moved off the centre
   and restyled to the page instead — the message and the tap target survive,
   the creative is visible behind them. Coverage 29% -> 14%, at the bottom
   edge, and the hit area stays 50px tall (iOS wants 44 minimum).

   !important throughout because the player writes size, position and colour
   as inline styles from its own theme config. Class names are Vidalytics'
   internals, so a player update could rename them — the failure mode is
   simply the original slab returning, which is where we started.

   The durable fix is in the Vidalytics dashboard, not here.
   ────────────────────────────────────────────────────────────── */
.lp-hero .AutoPlayBox__box {
  top: auto !important;
  bottom: 5% !important;
  left: 50% !important;
  /* a real width, not auto: the label keeps the player's pre-wrap and its own
     newline, and an auto-width box collapses narrow enough to break it into
     four ragged lines instead of the two it is written as */
  width: min(88%, 300px) !important;
  height: auto !important;
  transform: translateX(-50%) !important;
  padding: 9px 16px !important;
  border-width: 1px !important;
  border-radius: var(--radius-pill) !important;
  background-color: color-mix(in oklch, var(--color-paper) 86%, transparent) !important;
  border-color: color-mix(in oklch, var(--color-accent) 55%, transparent) !important;
  box-shadow: var(--sh-card) !important;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  /* the player pulses the box in its own blue; keep the cue, drop the clash */
  --pulse-color: color-mix(in oklch, var(--color-accent) 40%, transparent);
}
.lp-hero .AutoPlayBox__content {
  flex-direction: row !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 9px !important;
  min-height: 0 !important;
}
.lp-hero .AutoPlayBox__icon {
  width: 18px !important;
  height: 18px !important;
  flex: 0 0 auto !important;
}
/* the icon's own wave paths animate opacity, which is left alone — only the
   fill is retargeted off the player's blue */
.lp-hero .AutoPlayBox__icon path { fill: var(--color-accent) !important; }
.lp-hero .AutoPlayBox__heading {
  margin: 0 !important;
  padding: 0 !important;
  width: auto !important;
}
.lp-hero .AutoPlayBox__scalableText {
  font-size: 13px !important;
  line-height: 1.15 !important;
  font-weight: 600 !important;
  color: var(--color-ink) !important;
}

/* One idea per line. The supporting line carries the offer and the figure,
   so it sits a step up from the muted body grey rather than whispering. */
.lp-hero .stage__sub {
  max-width: 42ch;
  color: var(--color-ink-2);
  font-size: clamp(1.0625rem, 2.4vw, 1.25rem);
}

/* device bezel around the video */
.frame {
  width: 100%;
  max-width: 62rem;
  margin-top: var(--space-sm);
  padding: var(--space-sm);
  border: var(--rule-hair) solid var(--color-rule-strong);
  border-radius: calc(var(--radius-lg) + 6px);
  background: color-mix(in oklch, var(--color-paper-2) 70%, transparent);
  box-shadow: var(--sh-media);
}

.frame__inner {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #000;
  line-height: 0;
}

.stage__actions {
  display: grid;
  justify-items: center;
  gap: var(--space-md);
  margin-top: var(--space-xs);
}

.stage__trust,
.close__trust {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-ink-3);
  letter-spacing: 0.02em;
}
.stage__trust span,
.close__trust span { display: inline-flex; align-items: center; gap: var(--space-2xs); white-space: nowrap; }

.badge-dot {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--color-success);
  flex: 0 0 auto;
}
.badge-sep { width: 1px; height: 10px; background: var(--color-rule-strong); }

/* outlined capability chips */
.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-sm);
  margin-top: var(--space-xs);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-md);
  border: var(--rule-hair) solid var(--color-rule-strong);
  border-radius: var(--radius-pill);
  background: color-mix(in oklch, var(--color-paper-2) 55%, transparent);
  font-size: var(--text-sm);
  color: var(--color-ink-2);
  white-space: nowrap;
}
.chip .icon-stroke { color: var(--color-accent); }


/* ── 06 · CTA ────────────────────────────────────────────── */

.cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  padding: var(--space-md) var(--space-xl);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-md);
  white-space: nowrap;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out);
}

.cta--lg { padding: var(--space-md) calc(var(--space-xl) * 1.2); font-size: var(--text-lg); }

/* Outlined pill with a light that travels around the border. The ring
   is a spinning conic gradient clipped by the ::after inner fill, so
   only a 1px rim of it is ever visible. */
.cta--glow {
  isolation: isolate;
  overflow: hidden;
  color: var(--color-ink);
  background: transparent;
  border: none;
}

.cta--glow::before {
  content: '';
  position: absolute;
  inset: -160%;
  z-index: -2;
  background: conic-gradient(
    from 0deg,
    transparent 0 62%,
    color-mix(in oklch, var(--color-accent) 55%, transparent) 78%,
    var(--color-accent) 88%,
    transparent 100%
  );
  animation: spin 4s linear infinite;
}

.cta--glow::after {
  content: '';
  position: absolute;
  inset: 1px;
  z-index: -1;
  border-radius: inherit;
  background: color-mix(in oklch, var(--color-paper-2) 92%, var(--color-paper));
  transition: background var(--dur-fast) var(--ease-out);
}

.cta--glow:hover { transform: translateY(-1px); }
.cta--glow:hover::after { background: var(--color-paper-3); }
.cta--glow:active { transform: translateY(0); }

@keyframes spin {
  to { transform: rotate(1turn); }
}

.cta__arrow, .nav__cta-arrow { transition: transform var(--dur-fast) var(--ease-out); }
.cta:hover .cta__arrow, .nav__cta:hover .nav__cta-arrow { transform: translateX(3px); }

/* A line of the description, not a button. It sits close under .stage__sub —
   the negative top margin cancels most of .stage's grid gap — so it reads as
   the last line of the copy rather than as a competing CTA above the VSL.
   Blurple is hard-coded on purpose: it is the mark doing the recognition
   work, and it is the only non-token colour on the site. Do not "fix" it. */
.discord-inline {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: calc(var(--space-md) - var(--space-lg));
  max-width: 100%;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  letter-spacing: -0.01em;
  color: var(--color-ink-2);
  text-align: center;
  text-wrap: balance;
  transition: color var(--dur-fast) var(--ease-out);
}
.discord-inline svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: #5865F2;
  transition: color var(--dur-fast) var(--ease-out);
}
.discord-inline strong { color: #5865F2; font-weight: 700; }
.discord-inline:hover { color: var(--color-ink); }
.discord-inline:hover strong,
.discord-inline:hover svg { color: #7983F5; }


/* ── 07 · shared section heads ───────────────────────────── */

.section-head {
  max-width: var(--max-width);
  margin: 0 auto var(--space-2xl);
  display: grid;
  gap: var(--space-xs);
  text-align: center;
  justify-items: center;
}

.section-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-2xs) var(--space-md);
  border: var(--rule-hair) solid color-mix(in oklch, var(--color-accent) 28%, transparent);
  border-radius: var(--radius-pill);
}

.section-h {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.08;
  letter-spacing: -0.03em;
  max-width: 22ch;
  text-wrap: balance;
}

.section-note {
  color: var(--color-ink-3);
  font-size: var(--text-sm);
  max-width: var(--measure);
}


/* ── 08 · proof · wins marquee ───────────────────────────── */

.proof {
  padding: var(--space-3xl) 0;
  overflow: hidden;
}
.proof .section-head { padding-inline: var(--page-gutter); }

.wins__marquee {
  position: relative;
  width: 100%;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.wins__track {
  display: flex;
  gap: var(--space-md);
  width: max-content;
  padding-block: var(--space-md);
  animation: marquee var(--marquee) linear infinite;
}
.wins__marquee:hover .wins__track { animation-play-state: paused; }

/* The source screenshots are portrait phone captures (roughly 1:2.2).
   Left at natural ratio each card renders ~600px tall and the marquee
   eats the whole viewport, so the band is height-capped and the image
   is cropped from the top — which is where the message content sits. */
.win-card {
  flex: 0 0 auto;
  width: clamp(190px, 21vw, 250px);
  height: clamp(320px, 34vw, 420px);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-paper-2);
  box-shadow: var(--sh-card);
  transition:
    transform var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}
.win-card:hover {
  transform: translateY(-6px);
  border-color: color-mix(in oklch, var(--color-accent) 35%, var(--color-rule));
  box-shadow: var(--sh-lift);
}
.win-card img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }

@keyframes marquee {
  /* same half-gap correction as @keyframes ticker */
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - var(--space-md) / 2)); }
}


/* ── 09 · statement · the turn ───────────────────────────── */

.statement {
  padding: var(--space-3xl) var(--page-gutter);
  border-block: var(--rule-hair) solid var(--color-rule);
  background: color-mix(in oklch, var(--color-paper-2) 45%, transparent);
}

.statement__inner {
  max-width: 46rem;
  margin: 0 auto;
  display: grid;
  justify-items: center;
  gap: var(--space-md);
  text-align: center;
}

.statement__h {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.9rem, 4.4vw, 3.2rem);
  line-height: 1.06;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.statement__sub {
  font-family: var(--font-accent);
  font-style: italic;
  font-size: clamp(1.3rem, 2.4vw, 1.9rem);
  color: var(--color-accent);
  letter-spacing: -0.01em;
}

.statement .cta { margin-top: var(--space-sm); }


/* ── 10 · steps · ghost numerals ─────────────────────────── */

.steps {
  padding: var(--space-4xl) var(--page-gutter);
  max-width: calc(var(--max-width) + var(--page-gutter) * 2);
  margin: 0 auto;
}

.steps__list {
  max-width: 60rem;
  margin: 0 auto;
  display: grid;
  gap: var(--space-3xl);
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-lg);
  align-items: start;
  padding-block: var(--space-md);
}

/* the oversized translucent numeral sitting behind each step */
.step__ghost {
  position: absolute;
  top: 50%;
  right: -0.1em;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(7rem, 17vw, 13rem);
  line-height: 0.8;
  color: var(--color-ink);
  opacity: 0.035;
  pointer-events: none;
  user-select: none;
  z-index: -1;
}

.step--flip { direction: rtl; text-align: right; }
.step--flip > * { direction: ltr; }
.step--flip .step__ghost { right: auto; left: -0.1em; }
.step--flip .step__body { text-align: right; }

.step__icon {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  background: color-mix(in oklch, var(--color-accent) 10%, transparent);
  border: var(--rule-hair) solid color-mix(in oklch, var(--color-accent) 22%, transparent);
  color: var(--color-accent);
  flex: 0 0 auto;
}
.step__icon .icon-stroke { width: 20px; height: 20px; }

.step__body { display: grid; gap: var(--space-xs); min-width: 0; }

.step__num {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.step__h {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.step__p {
  color: var(--color-ink-2);
  font-size: var(--text-md);
  max-width: 52ch;
  line-height: var(--leading-body);
}
.step--flip .step__p { margin-left: auto; }


/* ── 11 · stats ──────────────────────────────────────────── */

.stats {
  padding: var(--space-2xl) var(--page-gutter) var(--space-3xl);
}

.stats__inner {
  max-width: 60rem;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: var(--space-lg);
  padding-block: var(--space-xl);
  border-block: var(--rule-hair) solid var(--color-rule);
  text-align: center;
}

.stat { display: grid; gap: var(--space-2xs); justify-items: center; }

.stat__value {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 4.4vw, 3rem);
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--color-accent);
}

.stat__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-ink-3);
}


/* ── 12 · VIP ────────────────────────────────────────────── */

.vip {
  padding: var(--space-3xl) var(--page-gutter);
  max-width: calc(var(--max-width) + var(--page-gutter) * 2);
  margin: 0 auto;
}

.vip__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: var(--space-md);
  max-width: var(--max-width);
  margin: 0 auto;
}

/* One border, one soft shadow. No ::before ghost border, no looping
   glow — a card should sit on the page, not inside a lit box. */
.vip-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-lg);
  min-height: 15rem;
  border-radius: var(--radius-md);
  border: var(--rule-hair) solid color-mix(in oklch, var(--color-accent) 20%, var(--color-rule));
  background: linear-gradient(180deg,
    color-mix(in oklch, var(--color-accent) 7%, var(--color-paper-2)) 0%,
    var(--color-paper-2) 90%);
  box-shadow: var(--sh-card);
  transition:
    transform var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}
.vip-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in oklch, var(--color-accent) 45%, var(--color-rule));
  box-shadow: var(--sh-lift);
}

.vip-card__badge {
  position: absolute;
  top: var(--space-md);
  right: var(--space-md);
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 8px;
  background: var(--color-accent);
  color: var(--color-accent-ink);
  border-radius: var(--radius-xs);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
}
.vip-card__badge svg { width: 9px; height: 9px; fill: currentColor; }

.vip-card__icon {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: color-mix(in oklch, var(--color-accent) 10%, transparent);
  border: var(--rule-hair) solid color-mix(in oklch, var(--color-accent) 20%, transparent);
  color: var(--color-accent);
}

.vip-card__h {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-lg);
  line-height: 1.2;
  letter-spacing: -0.015em;
  margin-top: var(--space-2xs);
}

.vip-card__p {
  color: var(--color-ink-2);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  flex: 1;
}


/* ── 13 · rails · mobile scroll-snap ─────────────────────── */

/* No overflow:hidden — clipping is what sliced the card shadows
   into a hard vertical line at the rail edge. On mobile the track
   itself becomes the scroller (see the 60rem block). */
.rail { position: relative; }

.dots { display: none; justify-content: center; gap: 2px; margin-top: var(--space-md); }

/* The dot reads as 8px but the tappable box is 44x44 — Apple's and
   Google's minimum target size. Padding does the work so the visual
   dot never grows. */
.dot {
  width: 44px; height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  -webkit-appearance: none;
  appearance: none;
}
.dot::before {
  content: '';
  width: 8px; height: 8px;
  border-radius: 50%;
  background: color-mix(in oklch, var(--color-accent) 55%, transparent);
  transition: background var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.dot.is-active::before { background: var(--color-accent); transform: scale(1.3); }
.dot:active::before { transform: scale(0.9); }


/* ── 14 · faq ────────────────────────────────────────────── */

.faq {
  padding: var(--space-3xl) var(--page-gutter);
  border-top: var(--rule-hair) solid var(--color-rule);
}

.faq__list { max-width: 52rem; margin: 0 auto; display: flex; flex-direction: column; }

.faq__item { border-top: var(--rule-hair) solid var(--color-rule); }
.faq__item:last-child { border-bottom: var(--rule-hair) solid var(--color-rule); }

.faq__item summary {
  list-style: none;
  cursor: pointer;
  padding: var(--space-lg) 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.015em;
  transition: color var(--dur-fast) var(--ease-out);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary > span:first-child { flex: 1; min-width: 0; }
.faq__item summary:hover { color: var(--color-accent); }

.faq__chev {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  color: var(--color-ink-3);
  transition: transform var(--dur-base) var(--ease-out);
  flex: 0 0 auto;
  line-height: 1;
}
.faq__item[open] .faq__chev { transform: rotate(45deg); color: var(--color-accent); }

.faq__a {
  padding: 0 0 var(--space-lg);
  max-width: var(--measure);
  color: var(--color-ink-2);
  font-size: var(--text-md);
  line-height: var(--leading-body);
}
.faq__a a { color: var(--color-accent); border-bottom: 1px dotted currentColor; }


/* ── 15 · closing CTA ────────────────────────────────────── */

.close {
  /* extra bottom room so the fixed CTA bar never sits over this section;
     this used to live in the mobile block, leaving desktop uncovered */
  padding: var(--space-3xl) var(--page-gutter) calc(var(--space-4xl) + 4rem);
  background: linear-gradient(180deg, transparent 0%,
    color-mix(in oklch, var(--color-paper-2) 65%, transparent) 100%);
}

.close__inner {
  max-width: 46rem;
  margin: 0 auto;
  display: grid;
  justify-items: center;
  gap: var(--space-md);
  text-align: center;
}

.close__h {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 4.6vw, 3.2rem);
  line-height: 1.06;
  letter-spacing: -0.035em;
}

.close__sub { color: var(--color-ink-2); max-width: var(--measure); }
.close .cta { margin-top: var(--space-sm); }


/* ── 16 · footer ─────────────────────────────────────────── */

.footer {
  /* was space-3xl on top to clear the statement block; now a single meta row */
  padding: var(--space-xl) var(--page-gutter) var(--space-xl);
  border-top: var(--rule-hair) solid var(--color-rule);
}

.footer__inner { max-width: var(--max-width); margin: 0 auto; }

/* Earnings disclaimer. Sized to be read, not to be technically present:
   --text-sm on --color-ink-3 is the same treatment as the footer links,
   not a smaller or fainter step. A disclaimer that has to be squinted at
   fails the only job it has. */
.footer__disclaimer {
  max-width: 68ch;
  padding-bottom: var(--space-lg);
  color: var(--color-ink-3);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
}
.footer__disclaimer p { margin: 0; }
.footer__disclaimer-h {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-ink-3);
}

/* No dividing rule, and no space-between — that pushed the brand,
   copyright and links to opposite ends of a full-width row, which read
   as three unrelated islands. They sit together now and wrap as one
   group. */
.footer__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  align-items: baseline;
  justify-content: flex-start;
  padding-top: var(--space-md);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-ink-3);
  letter-spacing: 0.03em;
}

.footer__brand { display: inline-flex; align-items: center; gap: var(--space-xs); color: var(--color-ink-2); }
.footer__brand img { width: 18px; height: 18px; object-fit: contain; }

.footer__links { display: flex; flex-wrap: wrap; gap: var(--space-xs); }

/* A thin middot carries the separation the old 24px gap was doing, in a
   fraction of the width. Rendered from CSS so the markup stays a clean
   list — and skipped on the last item. */
.footer__links li { display: inline-flex; align-items: baseline; }
.footer__links li:not(:last-child)::after {
  content: '·';
  margin-left: var(--space-xs);
  color: color-mix(in oklch, var(--color-ink-3) 50%, transparent);
}

.footer__links a { color: var(--color-ink-3); transition: color var(--dur-fast) var(--ease-out); white-space: nowrap; }
.footer__links a:hover { color: var(--color-ink); }


/* ── 17 · sticky CTA bar ─────────────────────────────────── */

.stickybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  display: flex;
  justify-content: center;
  padding: var(--space-sm) var(--page-gutter);
  padding-bottom: max(var(--space-sm), env(safe-area-inset-bottom));
  background: color-mix(in oklch, var(--color-paper) 82%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-top: var(--rule-hair) solid var(--color-rule);
  transform: translateY(110%);
  transition: transform var(--dur-slow) var(--ease-out);
  pointer-events: none;
}

.stickybar[data-state="shown"] { transform: none; pointer-events: auto; }
.stickybar .cta { width: 100%; max-width: 26rem; }


/* ── 18 · entrance motion ────────────────────────────────── */

/* Hero elements rise on load.

   The hidden state lives in the keyframes, NOT on the element, and the
   fill is `backwards` rather than `forwards`. So the element's resting
   style is fully visible: if animations never run — throttled tab,
   prerender, an engine that blocks them — the hero still renders. */
.rise { animation: rise var(--dur-slow) var(--ease-out) backwards; }
.d1 { animation-delay: 80ms; }
.d2 { animation-delay: 160ms; }
.d3 { animation-delay: 240ms; }
.d4 { animation-delay: 320ms; }
.d5 { animation-delay: 400ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Everything below the fold fades in when scrolled to — JS adds .is-in.

   Scoped to .js (set by an inline script in <head>) on purpose. If the
   script never runs, the IntersectionObserver never fires, or the tab is
   throttled, the content must still be READABLE — never trapped at
   opacity 0. No-JS is the safe state here, not the broken one. */
.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.js .reveal.is-in { opacity: 1; transform: none; }


/* ── 19 · touch devices & safe areas ─────────────────────── */

@supports (padding: max(0px)) {
  /* viewport-fit=cover means landscape notches eat into the gutter on
     EVERY section, not just these two. Folding the inset into the token
     covers .stage/.steps/.faq/.vip and the bleeding .vip__grid too. */
  :root {
    --page-gutter: max(clamp(1rem, 4vw, 3rem),
                       env(safe-area-inset-left), env(safe-area-inset-right));
  }

  .nav {
    padding-left: max(var(--page-gutter), env(safe-area-inset-left));
    padding-right: max(var(--page-gutter), env(safe-area-inset-right));
  }
  .footer {
    padding-left: max(var(--page-gutter), env(safe-area-inset-left));
    padding-right: max(var(--page-gutter), env(safe-area-inset-right));
    padding-bottom: max(var(--space-2xl), env(safe-area-inset-bottom));
  }
}

/* On a touchscreen there is no pointer to leave, so a :hover state
   latches on after a tap and stays lit. Neutralise the hover styling
   and give real press feedback instead. */
@media (hover: none) {
  .vip-card:hover,
  .win-card:hover {
    transform: none;
    box-shadow: var(--sh-card);
    border-color: var(--color-rule);
  }
  .nav__cta:hover { background: var(--color-accent); }
  .cta--glow:hover::after { background: color-mix(in oklch, var(--color-paper-2) 92%, var(--color-paper)); }
  .cta--glow:hover, .nav__cta:hover { transform: none; }
  .cta:hover .cta__arrow, .nav__cta:hover .nav__cta-arrow { transform: none; }
  .cta--glow:active, .nav__cta:active { transform: scale(0.97); }

  .faq__item summary:hover { color: var(--color-ink); }
  .faq__item summary:active { color: var(--color-accent); }

  .wins__marquee:hover .wins__track { animation-play-state: running; }
}


/* ── 20 · responsive ─────────────────────────────────────── */

@media (max-width: 60rem) {
  /* Hiding .nav__links removes it as a GRID ITEM, not just visually — so
     the CTA auto-placed into the middle 1fr track and stretched to ~67%
     of the pill. Two explicit tracks give the CTA its own width back. */
  .nav__inner { grid-template-columns: 1fr auto; }
  .nav__links { display: none; }
  .nav__cta {
    justify-self: end;
    font-size: var(--text-xs);
    /* 4px block padding gave a 26.6px tall target — well under the 44px
       minimum, on the page's most persistent conversion control. */
    padding: var(--space-sm) var(--space-md);
    min-height: 44px;
    justify-content: center;
    gap: var(--space-2xs);
  }

  /* ── VSL first. The video is the whole point of this page, so pull it
     as close to the top as the copy allows. The logo mark is redundant
     with the nav pill sitting two rows above it. ─────────────────── */
  .stage {
    padding-top: var(--space-md);
    padding-bottom: var(--space-lg);
    gap: var(--space-sm);
  }
  .stage__mark { display: none; }
  .stage__h { font-size: clamp(1.75rem, 8vw, 2.4rem); }
  .stage__sub { font-size: var(--text-sm); max-width: 36ch; }

  /* thinner bezel = more video on a narrow screen */
  .frame { padding: 5px; margin-top: var(--space-2xs); border-radius: calc(var(--radius-md) + 5px); }
  .frame__inner { border-radius: var(--radius-md); }

  .stage__actions { gap: var(--space-sm); margin-top: 0; }
  .stage .cta { width: 100%; max-width: 22rem; }
  .chips { margin-top: 0; }

  /* The pipes made the trust line wrap onto two rows with a separator
     dangling at the end of the first. Dots alone carry the rhythm.
     Needs the parent in the selector: `.stage__trust span` is (0,1,1)
     and would otherwise outrank a bare `.badge-sep` (0,1,0). */
  .stage__trust .badge-sep,
  .close__trust .badge-sep { display: none; }
  .stage__trust,
  .close__trust { gap: var(--space-xs) var(--space-md); }

  /* ── Vertical rhythm. Every section carried desktop padding top AND
     bottom, stacking into ~192px of dead space between blocks. ───── */
  .section-head { margin-bottom: var(--space-xl); }
  .proof,
  .statement,
  .steps,
  .vip,
  .faq       { padding-block: var(--space-2xl); }
  .stats     { padding-block: var(--space-lg) var(--space-2xl); }
  .stats__inner { padding-block: var(--space-lg); gap: var(--space-md); }

  .steps__list { gap: var(--space-2xl); }
  .step { grid-template-columns: 1fr; gap: var(--space-md); }
  /* the alternating flip is a desktop conceit — stack everything left */
  .step--flip { direction: ltr; text-align: left; }
  .step--flip .step__body { text-align: left; }
  .step--flip .step__p { margin-left: 0; }
  .step__ghost { font-size: 7rem; opacity: 0.04; right: 0; }
  .step--flip .step__ghost { left: auto; right: 0; }

  .faq__item summary { font-size: var(--text-md); padding: var(--space-md) 0; }
  .footer__meta { flex-direction: column; align-items: flex-start; gap: var(--space-sm); }

  /* ── VIP grid becomes a native scroll-snap rail.
     Native scrolling (not a transform carousel) gives iOS and Android
     real momentum, rubber-banding and fling velocity for free, and it
     stays usable if JS never runs. ─────────────────────────────── */
  .dots { display: flex; }

  .vip__grid {
    position: relative;
    display: flex;
    gap: var(--space-md);
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;

    /* Bleed to the screen edges so a card can sit flush while
       scrolling, then pad it back — this is also what gives the drop
       shadows room instead of guillotining them at the edge. */
    margin-inline: calc(var(--page-gutter) * -1);
    padding-inline: var(--page-gutter);
    padding-block: var(--space-sm);
    scroll-padding-inline: var(--page-gutter);
    scrollbar-width: none;
  }
  .vip__grid::-webkit-scrollbar { display: none; }

  .vip__grid > * {
    flex: 0 0 min(84vw, 380px);
    min-width: 0;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    overflow-wrap: break-word;
  }

  /* keep the sticky bar from covering the final CTA */
  .close { padding-bottom: calc(var(--space-4xl) + 4rem); }
}

@media (max-width: 26rem) {
  .win-card { width: 62vw; height: 300px; }
  .chips { gap: var(--space-xs); }
  .chip { font-size: var(--text-xs); padding: var(--space-2xs) var(--space-sm); }
}

/* "Network" only drops on genuinely tiny screens now. It used to go at
   26rem, which truncated the brand to "SPRK" on every normal phone —
   space the shrunken nav CTA no longer needs. */
@media (max-width: 21rem) {
  .nav__brand-text span { display: none; }
}


/* ── 21 · reduced motion ─────────────────────────────────── */

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

  .rise { opacity: 1; transform: none; animation: none; }
  .js .reveal { opacity: 1; transform: none; }
  .bloom { opacity: 0.4; }

  /* the infinite loops are the things that must actually stop */
  .wins__track { animation: none; transform: none; }
  .wins__marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .ticker__track { animation: none; }
  .cta--glow::before { animation: none; background: var(--color-rule-strong); }
}


/* ── 22 · /form · application page ───────────────────────────
   Standalone page at /form. Deliberately has no nav, ticker or
   sticky bar: once someone has committed to applying, every other
   link is a way to leave.

   The colours INSIDE the Typeform are set in Typeform's own
   designer — it is a cross-origin iframe and cannot be restyled
   from here. Everything around it is ours, and the widget is
   mounted with opacity:0 so this page's navy shows through
   instead of Typeform's default white.
   ─────────────────────────────────────────────────────────── */

.formpage { min-height: 100dvh; }

.apply {
  position: relative;
  z-index: 1;
  max-width: 52rem;
  margin: 0 auto;
  padding: clamp(2rem, 6vw, 4.5rem) var(--page-gutter) var(--space-3xl);
  display: grid;
  justify-items: center;
  gap: var(--space-lg);
  text-align: center;
}

.apply__head { display: grid; justify-items: center; gap: var(--space-sm); }

.apply__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-lg);
  letter-spacing: -0.02em;
  color: var(--color-ink);
  transition: opacity var(--dur-fast) var(--ease-out);
}
.apply__brand:hover { opacity: 0.82; }
.apply__logo { width: 34px; height: 34px; object-fit: contain; }
.apply__wordmark span { color: var(--color-accent); }

.apply__h {
  margin: var(--space-sm) 0 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.65rem, 4.2vw, 2.6rem);
  line-height: 1.08;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

/* Sits under the form, not above it. Once the application is in it has
   nothing left to say, so it goes. */
.apply__lede {
  margin: var(--space-xs) 0 0;
  max-width: 52ch;
  color: var(--color-ink-3);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  text-wrap: balance;
}
.apply[data-state="submitted"] .apply__lede { display: none; }

.apply__gate { display: grid; justify-items: center; gap: var(--space-xs); }
.apply__gate[hidden] { display: none; }

/* Ghost pill, not a glow CTA. Above the form it must read as context,
   not as a competing way out of the page. */
.apply__discord {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  border: var(--rule-hair) solid color-mix(in oklch, var(--color-accent) 26%, var(--color-rule));
  background: color-mix(in oklch, var(--color-paper-2) 70%, transparent);
  color: var(--color-ink-2);
  font-weight: 600;
  font-size: var(--text-sm);
  letter-spacing: -0.01em;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.apply__discord:hover {
  color: var(--color-ink);
  border-color: var(--color-accent);
  transform: translateY(-1px);
}
.apply__discord-mark { width: 18px; height: 18px; color: var(--color-accent); }

/* Locked: dimmed, with a padlock, so the state is legible before the click
   rather than only after it. Still focusable and still clickable — the click
   is what surfaces the reason. */
.apply__discord[data-locked="true"] {
  color: var(--color-ink-3);
  border-color: var(--color-rule);
  background: color-mix(in oklch, var(--color-paper-2) 45%, transparent);
}
.apply__discord[data-locked="true"] .apply__discord-mark { color: var(--color-ink-3); }
.apply__discord[data-locked="true"]:hover {
  color: var(--color-ink-2);
  border-color: var(--color-rule-strong);
}
.apply__discord-lock {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.75;
}
/* Unlocked — the padlock is the only thing that has to change. */
.apply__discord:not([data-locked]) .apply__discord-lock { display: none; }

.apply__lock {
  margin: 0;
  max-width: 34ch;
  color: var(--color-accent);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  text-wrap: balance;
}
.apply__lock[hidden] { display: none; }

/* the branded shell the form sits inside */
.apply__frame {
  position: relative;
  width: 100%;
  margin-top: var(--space-sm);
  padding: var(--space-sm);
  border: var(--rule-hair) solid color-mix(in oklch, var(--color-accent) 24%, var(--color-rule));
  border-radius: calc(var(--radius-lg) + 6px);
  background: color-mix(in oklch, var(--color-paper-2) 78%, transparent);
  box-shadow: var(--sh-media);
}

.apply__embed {
  width: 100%;
  height: clamp(30rem, 68vh, 44rem);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.apply__embed iframe { border: 0; }

/* Skeleton shown until onReady. Sits over the slot so the visitor
   never looks at an empty white rectangle while the iframe boots. */
.apply__skeleton {
  position: absolute;
  inset: var(--space-sm);
  z-index: 2;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-sm);
  border-radius: var(--radius-lg);
  background: var(--color-paper-2);
  color: var(--color-ink-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: opacity var(--dur-slow) var(--ease-out), visibility var(--dur-slow);
}
/* Ready: the form is behind this, so get out of the way entirely. */
.apply__skeleton[data-state="ready"] { opacity: 0; visibility: hidden; }

/* Failed: stay put and become the recovery. Hiding it would leave a tall
   empty box with the only way forward below the fold. */
.apply__skeleton[data-state="failed"] .apply__spinner,
.apply__skeleton[data-state="failed"] .apply__loading { display: none; }

.apply__failed { display: none; }
.apply__skeleton[data-state="failed"] .apply__failed {
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  padding: var(--space-lg);
  text-align: center;
}

.apply__failed-h {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-lg);
  letter-spacing: -0.02em;
  color: var(--color-ink);
  text-transform: none;
}
.apply__failed-p {
  color: var(--color-ink-2);
  font-size: var(--text-sm);
  max-width: 34ch;
  text-transform: none;
  letter-spacing: 0;
}
.apply__failed .cta { margin-top: var(--space-2xs); }

/* A 416px slot sized for a form is dead space once there is no form in it. */
.apply__frame[data-state="failed"] .apply__embed { height: auto; min-height: 12rem; }

/* Submitted: the form has done its job. Remove the iframe from the flow
   entirely rather than overlaying it — an overlay leaves Typeform's own
   ending screen live underneath, scrollable and competing. */
.apply__done { display: none; }
.apply__frame[data-state="submitted"] .apply__embed,
.apply__frame[data-state="submitted"] .apply__skeleton { display: none; }
.apply__frame[data-state="submitted"] .apply__done {
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  padding: clamp(var(--space-xl), 7vw, var(--space-3xl)) var(--space-lg);
  text-align: center;
}
.apply__done-h {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.4rem, 3.4vw, 2rem);
  letter-spacing: -0.03em;
  line-height: 1.12;
  color: var(--color-ink);
  text-wrap: balance;
}
.apply__done-p {
  max-width: 42ch;
  color: var(--color-ink-2);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  text-wrap: balance;
}
.apply__done-invite { color: var(--color-accent-soft); }
.apply__done-invite[hidden] { display: none; }
.apply__done .cta { margin-top: var(--space-xs); }
.apply__done .cta[hidden] { display: none; }

/* ── the submit confirmation beat ──────────────────────────────
   Ring draws, tick draws inside it, then the copy and the CTA rise in
   sequence. The whole thing lands in about a second — long enough to read
   as "that worked", short enough that nobody waits on it to click.
   Every animation is keyed to .apply__done being displayed, which only
   happens on submit, so none of it can fire on a page that is still a form.
   ────────────────────────────────────────────────────────────── */
.apply__done-mark {
  width: clamp(48px, 12vw, 62px);
  height: clamp(48px, 12vw, 62px);
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.apply__done-ring {
  stroke: color-mix(in oklch, var(--color-accent) 55%, transparent);
  stroke-dasharray: 145;
  stroke-dashoffset: 145;
}
.apply__done-tick {
  stroke: var(--color-accent);
  stroke-dasharray: 33;
  stroke-dashoffset: 33;
}

@keyframes done-draw { to { stroke-dashoffset: 0; } }
@keyframes done-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.apply__frame[data-state="submitted"] .apply__done-ring {
  animation: done-draw 620ms var(--ease-out) forwards;
}
.apply__frame[data-state="submitted"] .apply__done-tick {
  animation: done-draw 380ms var(--ease-out) 380ms forwards;
}
.apply__frame[data-state="submitted"] .apply__done-h,
.apply__frame[data-state="submitted"] .apply__done-p,
.apply__frame[data-state="submitted"] .apply__done .cta {
  opacity: 0;
  animation: done-rise 420ms var(--ease-out) forwards;
}
.apply__frame[data-state="submitted"] .apply__done-h        { animation-delay: 560ms; }
.apply__frame[data-state="submitted"] .apply__done-p        { animation-delay: 680ms; }
.apply__frame[data-state="submitted"] .apply__done-invite   { animation-delay: 780ms; }
.apply__frame[data-state="submitted"] .apply__done .cta     { animation-delay: 880ms; }

/* Confirmation must never depend on motion: with reduced motion the mark is
   simply drawn and the copy is simply there. */
@media (prefers-reduced-motion: reduce) {
  .apply__done-ring,
  .apply__done-tick { stroke-dashoffset: 0; }
  .apply__frame[data-state="submitted"] .apply__done-ring,
  .apply__frame[data-state="submitted"] .apply__done-tick,
  .apply__frame[data-state="submitted"] .apply__done-h,
  .apply__frame[data-state="submitted"] .apply__done-p,
  .apply__frame[data-state="submitted"] .apply__done .cta {
    animation: none;
    opacity: 1;
  }
}

/* The header pill deliberately survives the submit: it is a live invite by
   then, and someone who scrolled back up should not have to hunt for it.
   Only the lede goes — see the rule beside .apply__lede. */

.apply__spinner {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid color-mix(in oklch, var(--color-accent) 22%, transparent);
  border-top-color: var(--color-accent);
  animation: apply-spin 0.8s linear infinite;
}
@keyframes apply-spin { to { transform: rotate(1turn); } }

.apply__fallback {
  font-size: var(--text-sm);
  color: var(--color-ink-3);
}
.apply__fallback a {
  color: var(--color-accent);
  border-bottom: 1px dotted currentColor;
}

@media (max-width: 40rem) {
  .apply { gap: var(--space-md); }
  .apply__frame { padding: var(--space-2xs); }
  .apply__skeleton { inset: var(--space-2xs); }
  /* taller slot on phones — Typeform's own chrome eats vertical room */
  .apply__embed { height: clamp(26rem, 74vh, 40rem); }
}

@media (prefers-reduced-motion: reduce) {
  .apply__spinner { animation: none; border-top-color: var(--color-accent); }
}


/* ── 23 · /welcome · booked-call page ────────────────────────
   Reuses .apply (container, head, brand, logo, wordmark, heading)
   and .frame/.frame__inner from the homepage VSL. Only the pieces
   with no existing equivalent are defined here. */

/* The eyebrow reuses .section-eyebrow rather than redeclaring it, so
   retuning the accent pill updates this page too. */

/* Each span is its own line, so the greeting and "to SPRK Network"
   never reflow into one another as the name length changes. */
.welcome__greeting,
.welcome__line2 { display: block; }

/* A long unbroken name (28 chars at the h1's clamp) measured 336px against a
   320px viewport. .apply is a grid, so that token widened the whole column and
   dragged the LEAD COPY AND VIDEO off-screen with it — and overflow-x:clip
   means no scrollbar, so it just vanished. Break the token instead. */
.welcome__greeting { overflow-wrap: anywhere; }

/* Shown only when the embed never mounts. The frame is a black 16:9 box, so
   without this a blocked player is a silent void on a page whose entire
   content is the video. */
/* Fills the frame; the parent sets line-height:0 so there is no gap
   under it the way there would be with an inline element. */
.welcome__video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-lg);
}
#welcome-video[data-state="failed"] > .welcome__video { display: none; }

.welcome__novideo { display: none; }
.welcome__novideo--js,
#welcome-video[data-state="failed"] > .welcome__novideo {
  display: block;
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-ink-2);
  font-size: var(--text-sm);
  line-height: var(--leading-body);   /* parent .frame__inner sets 0 */
}
#welcome-video[data-state="failed"] > div[id^="vidalytics_embed_"] { display: none; }

/* Sits under the video rather than above it, so it needs separation from
   the frame instead of from the heading. */
.welcome__lead--after { margin-top: var(--space-lg); }

.welcome__lead {
  max-width: 54ch;
  color: var(--color-ink-2);
  font-size: var(--text-md);
  line-height: var(--leading-body);
  text-wrap: pretty;
}

/* .frame carries a 62rem cap for the homepage; inside .apply's 52rem
   column it just fills the width. */
.welcome__frame { margin-top: var(--space-xs); }
