/* ============================================================================
   The landing's own sections — the lake under the first screens, the manifesto,
   the flight, the two routes, the plans, the finale and the game. Only
   index.html loads this sheet; blurt.css stays the whole site's.
   ========================================================================== */

/* ------------------------------------------------------------- the lake ---- */
/* One canvas under the hero, the manifesto and the flight: a sticky layer the
   height of the screen that takes no room (its negative margin), so the sections
   scroll over it while lake.js moves the camera. Its own background is the
   stand-in water; the hero keeps its own stand-in sky above it. */
/* clip, not hidden: the layer's negative margin lets it stick until the zone's
   very end, and only a clip (which, unlike hidden, is no scroll container and so
   keeps it sticky) stops the water at the zone's bottom edge */
.lake { position: relative; isolation: isolate; overflow: clip; }
.lake-sky {
  position: sticky; top: 0; z-index: 0;
  height: 100vh; height: 100svh; margin-bottom: -100vh; margin-bottom: -100svh;
  background: linear-gradient(180deg, var(--lake) 0%, var(--lake-deep) 100%);
  pointer-events: none;
}
.lake-sky canvas { display: block; width: 100%; height: 100%; opacity: 0; transition: opacity .9s ease; }
.lake-sky.is-on canvas { opacity: 1; }
/* once the lake draws, the hero's stand-in steps aside for it */
.lake .hero .scene { transition: opacity .9s ease; }
.lake-sky.is-on ~ .hero .scene { opacity: 0; }
/* the lake runs into the page's paper below it, as a mist would */
.lake::after {
  content: ""; position: absolute; z-index: 1; left: 0; right: 0; bottom: 0;
  height: clamp(60px, 16svh, 180px); pointer-events: none;
  background: linear-gradient(transparent, var(--paper));
}

@media (prefers-reduced-motion: reduce) {
  .lake-sky canvas, .lake .hero .scene { transition: none; }
}

/* ⌥ inside a line: the app's keycap, small */
.inline-key {
  display: inline-flex; align-items: center; justify-content: center;
  width: .86em; height: .86em; border-radius: .19em; margin-right: .2em;
  vertical-align: middle; position: relative; top: -.07em;   /* centred on the capitals */
  background: linear-gradient(135deg, var(--keycap-top), var(--keycap-bottom));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .16), 0 .05em .12em rgb(0 0 0 / .55);
}
.inline-key b { font: 300 .5em/1 -apple-system, BlinkMacSystemFont, var(--mono); color: var(--paper-ink); }

/* Blurt's mark inside a line: the slab and its four bars [5, 9, 13, 7] */
.inline-mark {
  --h: .62em;
  display: inline-flex; align-items: center; justify-content: center;
  gap: calc(var(--h) * 2.5 / 22); height: var(--h); aspect-ratio: 42 / 22;
  border-radius: calc(var(--h) * 6 / 22); margin-right: .2em;
  vertical-align: middle; position: relative; top: -.07em;   /* centred on the capitals */
  background: linear-gradient(var(--stage-3), var(--stage));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .08), 0 .04em .14em rgb(0 0 0 / .4);
}
.inline-mark i {
  display: block; width: calc(var(--h) * 2.5 / 22); height: calc(var(--h) * 9 / 22);
  border-radius: 99px; background: var(--accent-bright); transform-origin: center;
}
.inline-mark i:nth-child(1) { height: calc(var(--h) * 5 / 22); }
.inline-mark i:nth-child(3) { height: calc(var(--h) * 13 / 22); }
.inline-mark i:nth-child(4) { height: calc(var(--h) * 7 / 22); }

/* In view, the mark in a pill speaks (the pill itself draws in: blurt.css). */
[data-pills].is-in .inline-mark i { animation: speak 1.3s ease-in-out infinite alternate; }
[data-pills].is-in .inline-mark i:nth-child(2) { animation-delay: -.4s; animation-duration: 1.1s; }
[data-pills].is-in .inline-mark i:nth-child(3) { animation-delay: -.9s; animation-duration: 1.5s; }
[data-pills].is-in .inline-mark i:nth-child(4) { animation-delay: -.2s; animation-duration: 1.2s; }
@keyframes speak { 0% { transform: scaleY(.55); } 45% { transform: scaleY(1.15); } 100% { transform: scaleY(.8); } }

/* ------------------------------------------------------------ manifesto ---- */
/* It stands on the water the camera has tilted down to. Its words take the
   palettes' strongest ink by the light of the visitor's hour (sky.js waterSky,
   set by lake.js): Paper Studio's by day, Midnight's from dusk to dawn, with a
   thin veil of the same light behind them for what the water mirrors. */
.manifesto {
  --water: var(--water-dark, var(--is-dark));
  --water-ink: color-mix(in srgb, #F2F5F7 calc(100% * var(--water)), #16120C);
  --water-veil: color-mix(in srgb, rgb(6 9 18) calc(100% * var(--water)), var(--haze, rgb(241 231 216)));
  --water-veil-a: var(--water-veil-alpha, 30%);
  padding-block: clamp(110px, 20svh, 240px) clamp(130px, 26svh, 300px);
  color: var(--water-ink);
}
.manifesto .wrap { position: relative; }
.manifesto .wrap::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: -12% -8% -14%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--water-veil) var(--water-veil-a), transparent) 62%, transparent);
}
.manifest {
  font-family: var(--sans); font-weight: 800;
  font-size: clamp(36px, 5.2vw, 96px); line-height: 1.24; letter-spacing: -.035em;
  color: var(--water-ink); max-width: 15.5em; text-wrap: balance;
  transition: color 1.2s ease;
}
.manifest-notes {
  display: grid; grid-template-columns: repeat(2, minmax(0, 30ch)); gap: clamp(24px, 4vw, 72px);
  margin-top: clamp(40px, 6vw, 84px); margin-left: clamp(0px, 10vw, 180px);
  font-size: 17px; line-height: 1.6; color: var(--water-ink);
}
.manifest-notes strong { font-weight: 700; }
.manifesto :focus-visible { outline-color: var(--water-ink); }

@media (max-width: 760px) {
  .manifest-notes { grid-template-columns: minmax(0, 1fr); margin-left: 0; }
}
@media (max-width: 560px) {
  .manifest { font-size: clamp(28px, 8.2vw, 40px); }
}
@media (prefers-reduced-motion: reduce) {
  [data-pills].is-in .inline-mark i { animation: none; }
  .manifest { transition: none; }
}

/* ----------------------------------------------------------------- mist ---- */
/* Between the manifesto and the flight: a pass through the sky's own haze, then
   the name. The track (.lake-mist) is only scroll; the veil is fixed over the
   screen (there only while it shows) and flight.js thickens and clears it with the scroll — so the screen
   stands in solid fog for a moment only: the moment the camera turns to the far
   shore (lake.js: the middle of .mist-core passes the middle of the screen).
   Puffs come first and go last (::after), the solid haze between (::before, the
   square of --fog-a), each drifting at its own depth (--mist-x). "Introducing…"
   comes with the fog; as it clears the name stands in the open sky, and leaves
   as the shore rises with the flight. Only with the flight armed (landing.js
   .is-flying); with Reduce Motion, none of it. */
.lake-mist { display: none; }
.lake.is-flying .lake-mist { display: block; position: relative; height: 120vh; height: 120svh; pointer-events: none; }
.mist-core { position: absolute; left: 0; right: 0; top: 0; height: 60%; }
.mist-veil {
  /* the haze, cooled by the sky it hangs in; lit in patches from above */
  --fog: color-mix(in srgb, var(--haze, rgb(241 231 216)) 68%, var(--sky-mid, rgb(170 200 215)));
  --fog-lit: color-mix(in srgb, var(--fog) 72%, color-mix(in srgb, white calc(100% - 70% * var(--sky-dark, 0)), var(--fog)));
  --name-h: clamp(52px, 8vw, 128px);          /* the lockup's mark */
  position: fixed; inset: 0; z-index: 5; overflow: clip; display: none;
}
/* Each part on its own layer: the scroll only moves and fades them — nothing is
   painted again (a veil repainted every frame cost 30 ms a frame at 2x). */
.mist-veil::before, .mist-veil::after, .mist-intro, .mist-name { will-change: transform, translate, scale, opacity; }
.mist-veil::before, .mist-veil::after { content: ""; position: absolute; left: -8%; right: -8%; }
.mist-veil::before {
  top: -10%; bottom: -10%;
  opacity: calc(var(--fog-a, 0) * var(--fog-a, 0));
  translate: 0 calc(var(--mist-x, 0) * 24vh);
  background:
    radial-gradient(var(--lit-w, 40%) 14% at 24% 36%, var(--fog-lit), transparent 70%),
    radial-gradient(calc(var(--lit-w, 40%) * .86) 12% at 74% 48%, var(--fog-lit), transparent 70%),
    radial-gradient(calc(var(--lit-w, 40%) * 1.14) 15% at 46% 64%, var(--fog-lit), transparent 70%),
    var(--fog);
}
.mist-veil::after {
  top: -25%; bottom: -25%;
  opacity: min(1, calc(var(--fog-a, 0) * 1.8));
  translate: 0 calc(var(--mist-x, 0) * 60vh);
  background:
    radial-gradient(30% 14% at 10% 30%, var(--fog), transparent 72%),
    radial-gradient(26% 12% at 38% 22%, var(--fog-lit), transparent 72%),
    radial-gradient(34% 15% at 66% 34%, var(--fog), transparent 72%),
    radial-gradient(24% 11% at 90% 26%, var(--fog-lit), transparent 72%),
    radial-gradient(32% 14% at 18% 72%, var(--fog-lit), transparent 72%),
    radial-gradient(28% 13% at 52% 80%, var(--fog), transparent 72%),
    radial-gradient(34% 15% at 84% 70%, var(--fog), transparent 72%);
  animation: mist-drift 46s ease-in-out infinite alternate;
}
.mist-intro, .mist-name { position: absolute; left: 0; right: 0; top: 50%; z-index: 1; margin: 0; }
.mist-intro {
  opacity: var(--intro-a, 0);
  /* in the middle of the fog; above the name once it comes */
  translate: 0 calc(-50% - var(--intro-up, 0) * (var(--name-h) * .5 + .9em) + var(--lift, 0) * 1vh);
  text-align: center; color: var(--sky-ink);
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(28px, 3.6vw, 54px); letter-spacing: -.01em;
}
.mist-name {
  display: flex; justify-content: center;
  opacity: var(--name-a, 0);
  translate: 0 calc(-50% + (1 - var(--come, 0)) * 3vh + var(--lift, 0) * 1vh);
  scale: calc(.94 + .06 * var(--come, 0));
}
.mist-name .brand { position: relative; color: var(--sky-ink); }
.mist-name .lockup { --lk-h: var(--name-h); }
/* a breath of the sky's own veil behind it, for its ink on the brightest sky */
.mist-name .brand::before {
  content: ""; position: absolute; z-index: -1; inset: -150% -45%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--sky-veil) var(--sky-veil-a), transparent) 22%,
    color-mix(in srgb, var(--sky-veil) calc(var(--sky-veil-a) * .55), transparent) 55%,
    transparent);
}
/* on a narrow screen the lit patches stay wide banks, not round glows */
@media (max-width: 700px) { .mist-veil { --lit-w: 110%; } }
@keyframes mist-drift { from { transform: translateX(-5%); } to { transform: translateX(5%); } }

/* --------------------------------------------------------------- flight ---- */
/* Four stations on the lake's far shore. Without the script (or with Reduce
   Motion) a plain list: each window beside its card. Armed (landing.js), the
   section is eight screens tall and its stage stays pinned while the lake's
   camera travels along the shore (it came in out of the mist above); flight.js stands each window on the shore and
   floats the island on the water, and the player under them (player.js) shows
   what the scroll is doing and plays it all by itself. */
.flight {
  position: relative; z-index: 2;
  --inset: max(var(--pad), calc((100% - var(--maxw)) / 2 + var(--pad)));
  --dock: clamp(20px, 5svh, 56px);
}
.flight-stage { position: relative; }
.flight > .anchor { position: absolute; top: 0; left: 0; width: 1px; height: 1px; }
.flight-head { position: relative; z-index: 3; padding-top: clamp(96px, 14svh, 150px); }
.flight-h {
  display: flex; flex-direction: column; align-items: flex-start; gap: .12em;
  font: 800 clamp(32px, 4.4vw, 78px)/1.1 var(--sans); letter-spacing: -.035em;
}

/* the plain list */
.stations {
  list-style: none; margin: 0 auto; max-width: var(--maxw);
  padding: clamp(40px, 6vw, 80px) var(--pad) clamp(140px, 18vw, 220px);
  display: grid; gap: clamp(48px, 7vw, 96px);
}
.station { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: clamp(24px, 4vw, 64px); align-items: center; }
.flight-island, .flight-player { display: none; }

/* a window on the shore: its chrome is the first screen's (blurt.css) */
.station-win { color: var(--ink); }
.win-body { position: relative; padding: 16px 20px 40px; min-height: 118px; }
.win-text { margin: 0; font-size: 18px; line-height: 1.5; color: var(--ink); white-space: pre-line; }
.win-text .sel { border-radius: .08em; transition: background-color .35s ease; }
.station-win.is-selected .win-text .sel { background: color-mix(in srgb, var(--coral) 26%, transparent); transition: none; }
.station-win .caret { display: inline-block; width: 2px; height: 1.05em; margin-left: 1px; vertical-align: -.16em; background: var(--accent); animation: blink 1s steps(1) infinite; }
.station-win.is-selected .caret { visibility: hidden; }
/* before the take lands the field is empty — the caret waits at its start */
.station-win:is([data-text="none"], [data-text="morph"]) .win-text .sel { display: none; }

/* The clean-up, shown while the island says "Cleaning up": the words it heard,
   the fillers struck and closing up, the spoken command folding away. --m is the
   step's progress (flight.js), so it runs with the scroll. */
.win-raw {
  display: none; margin: 0 0 4px; font-size: 18px; line-height: 1.5; color: var(--ink-2);
  --k: clamp(0, (var(--m, 0) - .3) / .55, 1);   /* how far the going words have closed up */
}
.station-win[data-text="morph"] .win-raw { display: block; }
.station-win[data-text="morph"] .win-text { display: none; }
.win-raw .w.is-filler, .win-raw .w.is-command {
  display: inline-block; overflow: hidden; white-space: nowrap; vertical-align: bottom;
  max-width: calc((1 - var(--k)) * 7em);
  margin-right: calc((1 - var(--k)) * .27em);   /* its space, closing with it */
  opacity: calc(1.15 - var(--m, 0) * 1.25);
}
.win-raw .w.is-filler { color: var(--coral-ink); text-decoration: line-through; text-decoration-thickness: 2px; }
.win-raw .w.is-command { color: var(--link); background: color-mix(in srgb, var(--accent) 14%, transparent); border-radius: 4px; padding-inline: .15em; }

/* each station's own window */
.win-fields { display: grid; gap: 6px; padding: 12px 20px 10px; border-bottom: 1px solid var(--line-08); font-size: 13px; color: var(--mute); }
.win-fields b { font-weight: 600; color: var(--ink-3); margin-right: .3em; }
.win-style {
  display: inline-block; margin-bottom: 10px; padding: 4px 9px; border-radius: 7px;
  font: 500 12px/1.2 var(--mono); letter-spacing: .02em;
  color: var(--link); background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.win-send { position: absolute; right: 14px; bottom: 12px; width: 26px; height: 26px; border-radius: 50%; background: var(--accent); }
.win-send::after { content: ""; position: absolute; inset: 8px 9px 7px; border: solid var(--on-accent); border-width: 2px 2px 0 0; transform: rotate(-45deg); }
.win-assistant .win-body { min-height: 150px; }
.win-assistant .win-text { font-size: 15px; line-height: 1.45; }
/* A prompt runs long: the field shows its first lines and fades, as a text field
   does with more than it can show — the text itself is the take, whole. */
.station-win.win-assistant .win-text {
  max-height: calc(8 * 1.45em); overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent);
}

/* the second station: one window, five apps' skins, the same text in each */
.win-apps .win-body { transition: background-color .3s ease; }
.win-apps[data-app="slack"] .win-body { padding-left: 64px; }
.win-apps[data-app="slack"] .win-body::before {
  content: ""; position: absolute; left: 20px; top: 18px; width: 32px; height: 32px; border-radius: 8px;
  background: linear-gradient(135deg, var(--accent-bright), var(--accent-deep));
}
.win-apps[data-app="mail"] .win-body::before {
  content: "To: Team"; display: block; margin: -4px -20px 12px; padding: 0 20px 10px;
  border-bottom: 1px solid var(--line-08); font-size: 13px; color: var(--mute);
}
.win-apps[data-app="notes"] .win-body {
  background: repeating-linear-gradient(transparent 0 26px, color-mix(in srgb, #D9A441 22%, transparent) 26px 27px),
    color-mix(in srgb, #FFE39A calc(22% - 14% * var(--is-dark)), transparent);
  background-position: 0 14px;
}
.win-apps[data-app="code"] .win-body { background: var(--stage2); padding-left: 52px; }
.win-apps[data-app="code"] .win-text { font: 15px/1.6 var(--mono); color: var(--paper-ink); }
.win-apps[data-app="code"] .win-body::before {
  content: "1"; position: absolute; left: 20px; top: 16px; font: 15px/1.6 var(--mono); color: var(--paper-ink3);
}
.win-apps[data-app="safari"] .win-text {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding: 8px 14px; border-radius: 10px; background: var(--line-05); box-shadow: inset 0 0 0 1px var(--line-10);
  font-size: 16px;
}

/* the warning a stand-in wears, or a recorded take's stamp */
.take-mark, .take-stamp {
  position: absolute; left: 14px; bottom: 9px; z-index: 1;
  padding: 4px 8px; border-radius: 6px;
  font: 500 10.5px/1.2 var(--mono); letter-spacing: .04em; white-space: nowrap;
}
.take-mark { color: var(--coral-ink); background: color-mix(in srgb, var(--coral) 13%, var(--card-top)); }
/* the assistant's send button sits in the stamp's corner: the stamp stops short of it */
.win-assistant :is(.take-mark, .take-stamp) { max-width: calc(100% - 64px); overflow: hidden; text-overflow: ellipsis; }
.take-stamp { color: var(--mute); background: var(--line-05); }

/* the card */
.station-card {
  position: relative; border-radius: 22px; padding: 26px 28px 28px;
  background: linear-gradient(180deg, var(--card-top), var(--card-bottom));
  box-shadow: 0 0 0 1px var(--line-08), 0 24px 60px -22px rgb(0 0 0 / .4);
  color: var(--ink-2);
}
.station-card h3 { margin: 0 0 10px; font: 700 clamp(22px, 1.8vw, 28px)/1.2 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.station-card p { font-size: 16px; line-height: 1.55; color: var(--ink-2); }
.gesture { display: flex; align-items: center; gap: 12px; margin-top: 16px; font-weight: 600; color: var(--ink); }
.app-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 16px; }
.app-chips button {
  padding: 7px 12px; border-radius: 8px; font: 600 13px/1.2 var(--sans);
  color: var(--ink-2); background: var(--line-05); box-shadow: inset 0 0 0 1px var(--line-10);
}
.app-chips button[aria-pressed="true"] { color: var(--on-accent); background: var(--accent); box-shadow: none; }

/* ⌥ in the card, pressed the way the station's take is: held, or tapped twice and held */
.mini-key {
  position: relative; flex: none; width: 34px; height: 34px; border-radius: 9px;
  display: inline-grid; place-items: center;
  background: linear-gradient(135deg, var(--keycap-top), var(--keycap-bottom));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .14), 0 3px 0 var(--capsule-bottom), 0 5px 10px rgb(0 0 0 / .35);
  font: 300 16px/1 -apple-system, BlinkMacSystemFont, var(--mono); color: var(--paper-ink);
  animation: key-hold 2.8s ease-in-out infinite;
}
.mini-key::after {
  content: ""; position: absolute; right: 5px; top: 5px; width: 3px; height: 3px; border-radius: 50%;
  background: var(--keycap-top); animation: led-hold 2.8s ease-in-out infinite;
}
.mini-key[data-press="double"]::after { animation-name: led-double; }
.mini-key[data-press="double"] { animation-name: key-double; }
@keyframes key-hold {
  0%, 14%, 78%, 100% { transform: none; box-shadow: inset 0 1px 0 rgb(255 255 255 / .14), 0 3px 0 var(--capsule-bottom), 0 5px 10px rgb(0 0 0 / .35); }
  20%, 72% { transform: translateY(2px); box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), 0 1px 0 var(--capsule-bottom), 0 2px 4px rgb(0 0 0 / .35); }
}
@keyframes led-hold { 0%, 18%, 76%, 100% { background: var(--keycap-top); } 22%, 72% { background: var(--accent-bright); box-shadow: 0 0 4px var(--accent-bright); } }
@keyframes key-double {
  0%, 10%, 16%, 22%, 82%, 100% { transform: none; }
  12%, 14%, 26%, 76% { transform: translateY(2px); }
}
@keyframes led-double { 0%, 23%, 80%, 100% { background: var(--keycap-top); } 26%, 76% { background: var(--accent-bright); box-shadow: 0 0 4px var(--accent-bright); } }

/* The player: Play, and the four chapters. Each track fills faintly to where the
   page's scroll stands (--to) and solidly to where the picture has got (--at):
   the picture follows the scroll at its own pace (lake.js). */
.fp-play {
  flex: none; display: inline-flex; align-items: center; gap: 9px;
  height: 40px; padding: 0 17px 0 14px; border-radius: 11px;
  font: 700 14px/1 var(--sans); color: var(--on-accent); background: var(--accent);
  transition: background-color .2s ease;
}
.fp-play:hover { background: color-mix(in srgb, var(--accent) 86%, var(--ink)); }
.fp-icon { flex: none; width: 11px; height: 12px; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }
.fp-play[data-state="pause"] .fp-icon { clip-path: none; background: linear-gradient(90deg, currentColor 0 36%, transparent 36% 64%, currentColor 64%); }
.fp-chapters { flex: 1; min-width: 0; display: flex; gap: 12px; margin: 0; padding: 0; list-style: none; }
.fp-chapters li { flex: 1; min-width: 0; }
.fp-chapters button {
  width: 100%; display: flex; flex-direction: column; gap: 8px; padding: 6px 0;
  font: 600 13px/1.2 var(--sans); color: var(--mute); text-align: left; white-space: nowrap;
  transition: color .25s ease;
}
.fp-chapters button:hover, .fp-chapters button[aria-current] { color: var(--ink); }
.fp-name { overflow: hidden; text-overflow: ellipsis; }
.fp-track { position: relative; display: block; height: 4px; border-radius: 2px; overflow: hidden; background: var(--line-16); }
.fp-track::before, .fp-track::after { content: ""; position: absolute; inset: 0; transform-origin: left; }
.fp-track::before { background: color-mix(in srgb, var(--accent) 36%, transparent); transform: scaleX(var(--to, 0)); }
.fp-track::after { background: var(--accent); transform: scaleX(var(--at, 0)); }
.fp-hint {
  flex: none; display: flex; align-items: center; gap: 9px; margin: 0;
  font: 500 11.5px/1.2 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--mute);
}
.fp-mouse { position: relative; flex: none; width: 14px; height: 21px; border: 1.5px solid currentColor; border-radius: 8px; }
.fp-mouse::after {
  content: ""; position: absolute; left: 50%; top: 4px; width: 2px; height: 4px; margin-left: -1px;
  border-radius: 1px; background: currentColor; animation: fp-wheel 1.8s ease-in-out infinite;
}
@keyframes fp-wheel { 0%, 20% { transform: none; opacity: 1; } 75%, 100% { transform: translateY(6px); opacity: 0; } }
.flight-player.is-playing .fp-mouse::after { animation: none; }
@media (hover: none) { .fp-mouse { display: none; } }

/* ── armed: pinned, the camera travels ─────────────────────────────────── */
.flight.is-armed { height: 800vh; height: 800svh; }
.flight.is-armed .flight-stage { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: clip; }
.flight.is-armed .stations { position: absolute; inset: 0; margin: 0; padding: 0; max-width: none; display: block; }
.flight.is-armed .station { position: absolute; inset: 0; display: block; pointer-events: none; }
.flight.is-armed .station-win {
  position: absolute; left: 0; top: 0; width: clamp(340px, 34vw, 640px);
  visibility: hidden; will-change: transform;
}
.flight.is-live .station-win.is-near { visibility: visible; }
.flight.is-armed .station-card {
  position: absolute; left: var(--inset); bottom: var(--dock);
  width: min(410px, calc(100% - 2 * var(--pad)));
  opacity: 0; transform: translateY(16px);
  transition: opacity .45s ease, transform .5s var(--ease-quick);
}
.flight.is-armed .station.is-current .station-card { opacity: 1; transform: none; pointer-events: auto; }
.flight.is-armed .flight-island {
  display: block; position: absolute; left: 0; top: 0; margin: 0; cursor: default; pointer-events: none;
  will-change: transform;
}
/* the player: beside the card, on its baseline */
.flight.is-live .flight-player {
  display: flex; align-items: center; gap: 16px;
  position: absolute; z-index: 2; bottom: var(--dock); right: var(--inset);
  left: calc(var(--inset) + min(410px, 100% - 2 * var(--pad)) + clamp(20px, 2.4vw, 36px));
  max-width: 760px; margin-left: auto;
  padding: 9px 18px 9px 9px; border-radius: 16px;
  background: linear-gradient(180deg, var(--card-top), var(--card-bottom));
  box-shadow: 0 0 0 1px var(--line-08), 0 18px 44px -22px rgb(0 0 0 / .45);
}

@media (max-width: 1199px) {
  .fp-hint { display: none; }
}
@media (max-width: 920px) {
  .station { grid-template-columns: minmax(0, 1fr); }
  /* the player across the bottom, the card above it */
  .flight.is-live .flight-player { left: var(--inset); max-width: none; }
  .flight.is-armed .station-card { bottom: calc(var(--dock) + 70px); }
}
@media (max-width: 700px) {
  .flight-head { padding-top: 86px; }
  .flight.is-armed .station-win { width: min(380px, calc(100% - 32px)); }
  .flight.is-armed .station-card { left: 16px; right: 16px; width: auto; bottom: 74px; padding: 18px 20px 20px; border-radius: 18px; }
  .flight.is-live .flight-player { left: 16px; right: 16px; bottom: 16px; gap: 12px; padding: 5px 14px 5px 5px; border-radius: 15px; }
  .fp-play { padding: 0 14px 0 12px; }
  /* the chapters' names go (still their buttons' names): the card says where the flight is */
  .fp-name { height: 0; }
  .fp-chapters { gap: 6px; }
  /* the five apps in one row: the card stays short enough for the island above it */
  .app-chips { gap: 5px; margin-top: 12px; }
  .app-chips button { padding: 6px 8px; font-size: 12.5px; }
  .fp-chapters button { gap: 0; padding: 12px 0; }
  .station-card h3 { font-size: 20px; margin-bottom: 6px; }
  .station-card p { font-size: 14.5px; }
  .gesture { margin-top: 10px; font-size: 14.5px; }
  .win-text, .win-raw { font-size: 16px; }
  .win-body { min-height: 96px; }
}
/* a phone has no room for the heading and a window on the shore (the prompt's
   grows tall): the heading steps aside once the first take is under way (flight.js);
   the card names the station */
@media (max-width: 700px) {
  .flight.is-armed .flight-head { transition: opacity .4s ease, transform .5s var(--ease-quick); }
  .flight.is-underway .flight-head { opacity: 0; transform: translateY(-16px); pointer-events: none; }
}
/* a short phone: the card keeps its title and words, not the key's gesture */
@media (max-width: 700px) and (max-height: 760px) {
  .flight.is-armed .station-card .gesture { display: none; }
}
/* the narrowest phones: the card and the prompt's window in a smaller size */
@media (max-width: 360px) {
  .flight.is-armed .station-card { padding: 14px 16px 16px; }
  .flight.is-armed .station-card h3 { font-size: 18px; }
  .flight.is-armed .station-card p { font-size: 13.5px; line-height: 1.45; }
  .flight.is-armed .win-assistant .win-text { font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  .mini-key, .mini-key::after, .station-win .caret { animation: none; }
  .flight.is-armed .station-card { transition: none; }
}

/* ----------------------------------------------------------- two routes ---- */
.routes-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(16px, 2vw, 28px); margin-top: clamp(40px, 5vw, 72px); }
.route { border-radius: 26px; padding: clamp(26px, 3vw, 44px); }
.route--local {
  background: linear-gradient(180deg, var(--card-top), var(--card-bottom));
  box-shadow: 0 0 0 1px var(--line-08), var(--sh-card); color: var(--ink-2);
}
.route--cloud {
  background: linear-gradient(180deg, var(--stage-3), var(--stage));
  box-shadow: var(--sh-stage), inset 0 0 0 1px rgb(255 255 255 / .06); color: var(--paper-ink-2);
}
.route h3 { font: 700 clamp(24px, 2.2vw, 32px)/1.15 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.route--cloud h3 { color: var(--paper-ink); }
.route p { font-size: 16px; line-height: 1.6; max-width: 52ch; }
/* the route itself: four stops on a line, a light travelling along it */
.route-flow {
  list-style: none; margin: 28px 0; padding: 0; position: relative;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
}
.route-flow::before {
  content: ""; position: absolute; left: 12.5%; right: 12.5%; top: 21px; height: 2px;
  background: currentColor; opacity: .18;
}
.route-flow::after {
  content: ""; position: absolute; top: 18px; left: 12.5%; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent-bright); box-shadow: 0 0 10px var(--teal-glow);
  animation: route-travel 3.4s ease-in-out infinite;
}
@keyframes route-travel { 0% { left: 12.5%; opacity: 0; } 12%, 88% { opacity: 1; } 100% { left: calc(87.5% - 8px); opacity: 0; } }
.route-flow li {
  position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 10px;
  text-align: center; font: 600 13px/1.3 var(--sans); color: var(--ink);
}
.route--cloud .route-flow li { color: var(--paper-ink); }
.route-flow .node {
  width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center;
  background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line-12); color: var(--ink);
}
.route--cloud .route-flow .node { background: var(--stage-2); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .1); color: var(--paper-ink); }
.route-flow .node svg { width: 20px; height: 20px; }
.route-flow .node .caret { height: 20px; background: var(--accent); }
.routes-foot { margin-top: 28px; font-size: 15px; color: var(--mute); max-width: 80ch; }
.routes-foot a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }

/* ---------------------------------------------------------------- plans ---- */
.plans { padding-top: 0; padding-bottom: clamp(40px, 5vw, 88px); }
.faq-section { padding-top: clamp(56px, 7vw, 120px); }
.plans-inner { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: clamp(28px, 5vw, 72px); align-items: end; }
.plans-copy p { font-size: 18px; color: var(--ink-2); max-width: 44ch; margin-bottom: 24px; }

/* ------------------------------------------------------------------ faq ---- */
.faq-section .pill-h { margin-bottom: clamp(24px, 4vw, 48px); }

/* --------------------------------------------------------------- finale ---- */
/* The last word, and the mark beside it. The words are sized by their own
   column (cqi), so the two lines — "Stop typing." and "Start blurting." — stand
   whole at any width and never run under the mark. */
.finale { overflow: hidden; padding-block: clamp(96px, 13vw, 200px) clamp(96px, 12vw, 180px); }
.finale-inner { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: clamp(32px, 5vw, 96px); }
.finale-copy { container-type: inline-size; min-width: 0; }
.finale-h { font: 800 clamp(40px, 15.4cqi, 150px)/1.06 var(--sans); letter-spacing: -.045em; color: var(--ink); }
.finale-h .nw-line { white-space: nowrap; }
.finale-cta { margin-top: clamp(28px, 4vw, 52px); display: grid; justify-items: start; gap: 18px; }

/* The mark (BrandMark: slab 42×22, corner 6, bars [5, 9, 13, 7]), a button: the
   game is in it. Its bars breathe; every few seconds it calls (landing.js). */
.big-mark {
  --h: clamp(140px, 14.5vw, 240px);
  position: relative; flex: none; height: var(--h); aspect-ratio: 42 / 22;
  border-radius: calc(var(--h) * 6 / 22); display: grid; place-items: center; cursor: pointer;
  background: linear-gradient(var(--stage-3), var(--stage));
  box-shadow: inset 0 2px 0 rgb(255 255 255 / .07), inset 0 0 0 1px rgb(255 255 255 / calc(.03 + .07 * var(--is-dark))),
    0 calc(var(--h) * .1) calc(var(--h) * .36) -.02em rgb(0 0 0 / .4);
  transition: transform .3s var(--ease-quick);
}
.big-mark:hover { transform: translateY(-4px); }
.big-mark:focus-visible { outline: 3px solid var(--link); outline-offset: 8px; }
.big-mark-bars { display: flex; align-items: center; gap: calc(var(--h) * 2.5 / 22); }
.big-mark-bars i {
  display: block; width: calc(var(--h) * 2.5 / 22); height: calc(var(--h) * 9 / 22); border-radius: 99px;
  background: var(--accent-bright); box-shadow: 0 0 calc(var(--h) * .05) var(--teal-glow);
  animation: speak 1.3s ease-in-out infinite alternate;
}
.big-mark-bars i:nth-child(1) { height: calc(var(--h) * 5 / 22); animation-duration: 1.2s; }
.big-mark-bars i:nth-child(2) { animation-delay: -.5s; animation-duration: 1.05s; }
.big-mark-bars i:nth-child(3) { height: calc(var(--h) * 13 / 22); animation-delay: -.9s; animation-duration: 1.45s; }
.big-mark-bars i:nth-child(4) { height: calc(var(--h) * 7 / 22); animation-delay: -.2s; animation-duration: 1.15s; }
.big-mark-play {
  position: absolute; left: 0; right: 0; bottom: calc(var(--h) * .09);
  font: 700 calc(var(--h) * .085)/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--paper-ink); opacity: 0; transform: translateY(4px);
  transition: opacity .35s ease, transform .35s var(--ease-quick);
}
.big-mark:is(:hover, :focus-visible, .is-calling) .big-mark-play { opacity: .9; transform: none; }
.big-mark.is-calling .big-mark-bars i { animation: call .42s ease-in-out 4 alternate; }
.big-mark.is-calling .big-mark-bars i:nth-child(2) { animation-delay: .07s; }
.big-mark.is-calling .big-mark-bars i:nth-child(3) { animation-delay: .14s; }
.big-mark.is-calling .big-mark-bars i:nth-child(4) { animation-delay: .21s; }
@keyframes call { from { transform: scaleY(.5); } to { transform: scaleY(1.35); } }

@media (max-width: 920px) {
  .routes-grid, .plans-inner { grid-template-columns: minmax(0, 1fr); }
  .finale-inner { grid-template-columns: minmax(0, 1fr); justify-items: start; }
  .finale-copy { justify-self: stretch; }            /* its width is what sizes the words (cqi) */
  .big-mark { --h: clamp(120px, 34vw, 220px); }
}
@media (max-width: 480px) {
  .route-flow li { font-size: 12px; }
  .route-flow .node { width: 38px; height: 38px; }
  .route-flow::before { top: 18px; } .route-flow::after { top: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .route-flow::after { animation: none; left: 50%; }
  .big-mark-bars i, .big-mark.is-calling .big-mark-bars i { animation: none; }
  .big-mark, .big-mark-play { transition: none; }
}

/* ----------------------------------------------------------------- pong ---- */
/* The mark's slab opened out to the screen: a dark court, the bars in teal. */
.pong {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0; overflow: hidden; background: transparent; color: var(--paper-ink);
  outline: none;
}
.pong::backdrop { background: color-mix(in srgb, var(--paper) 94%, transparent); }
.pong-court {
  position: absolute; inset: clamp(10px, 2vw, 28px);
  border-radius: clamp(22px, 3.4vw, 56px);
  background: linear-gradient(var(--stage-3), var(--stage));
  box-shadow: inset 0 2px 0 rgb(255 255 255 / .06), inset 0 0 0 1px rgb(255 255 255 / .06), 0 30px 80px -30px rgb(0 0 0 / .6);
  overflow: hidden; touch-action: none; cursor: none; transform-origin: 0 0;
}
.pong-paddle, .pong-ball {
  position: absolute; left: 0; top: 0; border-radius: 99px; will-change: transform;
  background: var(--accent-bright); box-shadow: 0 0 22px var(--teal-glow);
}
.pong.is-flying .pong-paddle, .pong.is-flying .pong-ball { visibility: hidden; }
.pong-fly {
  position: fixed; z-index: 2; display: block; border-radius: 99px; pointer-events: none;
  background: var(--accent-bright); box-shadow: 0 0 22px var(--teal-glow);
}
.pong-net {
  position: absolute; left: 50%; top: 9%; bottom: 9%; width: 2px; margin-left: -1px;
  background: repeating-linear-gradient(rgb(255 255 255 / .13) 0 14px, transparent 14px 30px);
}
.pong-score {
  position: absolute; top: 6%; left: 0; right: 0; display: flex; justify-content: center; gap: 14vw;
  font: 500 clamp(30px, 5vw, 68px)/1 var(--mono); color: rgb(255 255 255 / .42);
}
.pong-bar {
  position: absolute; left: 50%; bottom: calc(clamp(10px, 2vw, 28px) + 18px); transform: translateX(-50%);
  display: grid; justify-items: center; gap: 10px; width: max-content; max-width: calc(100% - 40px);
}
.pong-hint { font-size: 13px; color: rgb(255 255 255 / .62); text-align: center; }
.pong-buttons { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.pong-buttons button {
  padding: 10px 16px; border-radius: 12px; font: 600 14px/1.2 var(--sans);
  color: var(--paper-ink); background: rgb(255 255 255 / .08); box-shadow: inset 0 0 0 1px rgb(255 255 255 / .14);
}
.pong-buttons button:hover { background: rgb(255 255 255 / .14); }
.pong-voice[aria-pressed="true"] { color: var(--on-accent); background: var(--accent-bright); box-shadow: none; }
.pong :focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }
.is-playing body { overflow: hidden; }
