/*
  turingos-launch.css — the launch countdown at the top of the Turing AI OS page.

  A night sky above the white page. A very large clock runs across it, and
  down the gap in its middle — between the hours and the minutes — a bomb with
  the Turing mark on it falls for nine days, towards the ground it reaches at
  zero.

  Everything that places the bomb is CSS driven by one number, --fall (0 at
  release, 1 at the ground), which the template sets from the server's clock
  and js/turingos-launch.js keeps moving. So the scene is right before the
  script runs, and right without it.

  The script draws the sky, the Earth and the bomb with WebGL and says so with
  .tl-gl on the section. Without that class the drawn bomb and the ground in
  this file are what is seen.

  Its own class names (tl-*), and its own colours rather than the page's: the
  page's tokens are the light scheme, and this is the one dark thing on it.
*/

.tl {
  --tl-night: #03050b;
  --tl-text: #f3f6fd;
  --tl-dim: rgba(238, 242, 251, 0.62);
  --tl-faint: rgba(238, 242, 251, 0.36);
  --tl-line: rgba(238, 242, 251, 0.14);
  --tl-amber: #ffb23e;
  --tl-red: #ff4b3a;
  --tl-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --tl-ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* The geometry of the fall. --tl-x is where it comes down, across the
     section; the rest are heights. The nose is at --tl-nose. */
  --tl-x: 50%;
  --tl-top: 4%;
  --tl-bomb-h: clamp(200px, 35vh, 330px);
  --tl-ground-h: clamp(84px, 15vh, 136px);
  --tl-channel: clamp(150px, 16vw, 230px);
  --tl-travel: calc(100% - var(--tl-top) - var(--tl-bomb-h) - var(--tl-ground-h));
  --tl-nose: calc(var(--tl-top) + var(--tl-bomb-h) + var(--fall, 0) * var(--tl-travel));

  position: relative;
  min-height: max(640px, calc(100vh - 60px));
  min-height: max(640px, calc(100svh - 60px));
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(60% 50% at var(--tl-x) 100%, rgba(31, 107, 255, 0.20), transparent 70%),
    radial-gradient(45% 40% at 12% 0%, rgba(124, 70, 239, 0.14), transparent 70%),
    var(--tl-night);
  color: var(--tl-text);
  font-family: var(--t-font, 'Inter', sans-serif);
}

.tl-sky {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ── The ground, where there is no WebGL to draw it ────── */

.tl-earth {
  position: absolute;
  z-index: 1;
  left: var(--tl-x);
  top: calc(100% - var(--tl-ground-h) - 22px);
  width: max(300vw, 2600px);
  aspect-ratio: 1;
  border-radius: 50%;
  transform: translateX(-50%);
  background: radial-gradient(circle at 50% 0%, #14285a 0%, #0a1430 5%, #050913 16%, #03050b 40%);
  box-shadow:
    0 -1px 0 rgba(150, 196, 255, 0.70),
    0 -10px 34px rgba(60, 130, 255, 0.45),
    0 -50px 140px rgba(61, 224, 176, 0.14),
    inset 0 26px 60px rgba(70, 150, 255, 0.16);
  transition: box-shadow 1.6s ease, background 1.6s ease;
}

.tl.is-live .tl-earth {
  background: radial-gradient(circle at 50% 0%, #6b2c12 0%, #2a1110 4%, #0a0810 14%, #03050b 40%);
  box-shadow:
    0 -1px 0 rgba(255, 214, 150, 0.85),
    0 -12px 40px rgba(255, 140, 50, 0.55),
    0 -60px 170px rgba(255, 90, 40, 0.25),
    inset 0 26px 70px rgba(255, 150, 60, 0.28);
}

.tl-gl .tl-earth { display: none; }

/* ── The fall ──────────────────────────────────────────── */

.tl-stage {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

/* Where it will land: rings lying flat on the ground, seen from the side. */
.tl-target {
  position: absolute;
  left: var(--tl-x);
  bottom: var(--tl-ground-h);
  width: clamp(220px, 27vw, 400px);
  aspect-ratio: 6.5 / 1;
  transform: translate(-50%, 50%);
}

.tl-target i {
  position: absolute;
  inset: 0;
  border: 1px solid var(--tl-amber);
  border-radius: 50%;
  opacity: 0;
  animation: tl-ring 3.6s cubic-bezier(0.2, 0.6, 0.3, 1) infinite;
}
.tl-target i:nth-child(2) { animation-delay: 1.2s; }
.tl-target i:nth-child(3) { animation-delay: 2.4s; }

.tl-target::before,
.tl-target::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.tl-target::before {
  width: 30%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--tl-amber) 30%, var(--tl-amber) 70%, transparent);
}
.tl-target::after {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--tl-red);
  box-shadow: 0 0 16px 5px rgba(255, 75, 58, 0.7);
}

@keyframes tl-ring {
  0% { transform: scale(0.06); opacity: 0.9; }
  100% { transform: scale(1); opacity: 0; }
}

/* The line it is falling down. */
.tl-guide {
  position: absolute;
  left: var(--tl-x);
  top: calc(var(--tl-nose) + 14px);
  bottom: var(--tl-ground-h);
  border-left: 1px dashed rgba(255, 178, 62, 0.40);
}

/* The height, in days: a mark on the line for each, the nose at the day that
   is left. The script fades the ones it has passed. The slow part of the
   fall ends at the last mark (0.88 of the way down); what is below it is the
   last ten seconds. */
.tl-ruler {
  position: absolute;
  left: var(--tl-x);
  top: calc(var(--tl-top) + var(--tl-bomb-h));
  height: calc(var(--tl-travel) * 0.88);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tl-ruler li {
  position: relative;
  height: 0;
  font: 500 0.6rem/1 var(--tl-mono);
  color: var(--tl-faint);
  transition: opacity 0.6s ease;
}
.tl-ruler li::before {
  content: '';
  position: absolute;
  left: -5px;
  top: 0;
  width: 11px;
  border-top: 1px solid rgba(255, 178, 62, 0.55);
}
.tl-ruler li span { position: absolute; left: 13px; top: -0.3rem; }
.tl-ruler li.is-past { opacity: 0; }
.tl-ruler li:last-child { color: var(--tl-amber); }

.tl-fall {
  position: absolute;
  left: var(--tl-x);
  top: calc(var(--tl-nose) - var(--tl-bomb-h));
  height: var(--tl-bomb-h);
  transform: translateX(-50%);
}

/* The bomb as WebGL draws it: a canvas larger than the bomb, with room
   above for the air it has come through and below for the heat ahead of its
   nose. The script's proportions (1.7 wide, 2.6 tall, the nose a quarter of
   a bomb above the bottom) are these. */
.tl-bomb-gl {
  position: absolute;
  left: 50%;
  bottom: calc(var(--tl-bomb-h) * -0.25);
  width: calc(var(--tl-bomb-h) * 1.7);
  height: calc(var(--tl-bomb-h) * 2.6);
  transform: translateX(-50%);
  display: none;
}

.tl-gl .tl-bomb-gl { display: block; }

/* The part of that canvas that is the bomb, for a hand to take hold of.
   Up and down is still the page's to scroll. */
.tl-grab {
  position: absolute;
  left: 50%;
  top: 0;
  width: calc(var(--tl-bomb-h) * 0.46);
  height: 100%;
  transform: translateX(-50%);
  border-radius: 45%;
  pointer-events: auto;
  touch-action: pan-y;
  cursor: grab;
  display: none;
}
.tl-gl .tl-grab { display: block; }
.tl-grab.is-held { cursor: grabbing; }

/* Says so, until somebody has. */
.tl-hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--tl-ground-h) * 0.26);
  display: none;
  margin: 0;
  text-align: center;
  font: 500 0.66rem/1 var(--tl-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--tl-dim);
  transition: opacity 0.6s ease;
  animation: tl-rise 1s 1.6s var(--tl-ease) both;
}
.tl-gl .tl-hint { display: block; }
.tl.is-played .tl-hint,
.tl.is-final .tl-hint { opacity: 0; }
.tl-gl .tl-bomb { visibility: hidden; }

/* The bomb as a drawing, where there is no WebGL. It hangs from its tail and
   swings a little, as a thing falling through air does. */
.tl-bomb {
  position: relative;
  height: 100%;
  transform-origin: 50% 0;
  animation: tl-sway 5.2s ease-in-out infinite alternate;
}

.tl-bomb svg {
  position: relative;
  display: block;
  height: 100%;
  width: auto;
  overflow: visible;
  filter: drop-shadow(0 18px 34px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 22px rgba(90, 150, 255, 0.22));
}

@keyframes tl-sway {
  from { transform: translateX(-5px) rotate(-1.7deg); }
  to { transform: translateX(5px) rotate(1.7deg); }
}

.tl-trail {
  position: absolute;
  left: 50%;
  bottom: 88%;
  width: 34%;
  height: 60vh;
  transform: translateX(-50%);
  background: linear-gradient(to top, rgba(200, 220, 255, 0.34), rgba(160, 190, 255, 0.10) 35%, transparent);
  filter: blur(9px);
  border-radius: 50% 50% 0 0;
}

.tl-heat {
  position: absolute;
  left: 50%;
  bottom: -11%;
  width: 150%;
  aspect-ratio: 1.5;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 42%, rgba(255, 214, 140, 0.95), rgba(255, 138, 42, 0.5) 34%, transparent 70%);
  opacity: calc(0.22 + var(--fall, 0) * 0.7);
  mix-blend-mode: screen;
  animation: tl-flicker 0.42s ease-in-out infinite alternate;
}

@keyframes tl-flicker {
  from { transform: translateX(-50%) scale(0.92); }
  to { transform: translateX(-50%) scale(1.08); }
}

/* ── The other scene: the rocket and the meteor ────────── */

/* The same clock and the same channel. At the foot of it a rocket stands on
   its pad on the horizon; at the head of it a meteor comes down, larger as
   --fall goes from 0 to 1. The script draws both, and the ground and sky
   behind them. */
.tl-scene-rocket {
  --tl-ship-h: clamp(210px, 38vh, 350px);
  --tl-rock: calc(var(--tl-ship-h) * (0.40 + 0.34 * var(--fall, 0)));
  background:
    radial-gradient(70% 45% at 50% 100%, rgba(31, 107, 255, 0.22), transparent 70%),
    radial-gradient(40% 30% at 50% 0%, rgba(255, 110, 40, 0.16), transparent 70%),
    var(--tl-night);
}

.tl-pad {
  position: absolute;
  left: var(--tl-x);
  bottom: var(--tl-ground-h);
  width: 2px;
  height: 2px;
  margin: 0 0 -1px -1px;
}

/* The course the rocket will fly: from its nose to the meteor. */
.tl-scene-rocket .tl-guide {
  top: calc(var(--tl-top) + var(--tl-rock) + 18px);
  bottom: calc(var(--tl-ground-h) + var(--tl-ship-h) + 14px);
  border-left-color: rgba(120, 180, 255, 0.34);
}

/* It stands on its foot: when the script tips it, that is what it turns about. */
.tl-ship {
  position: absolute;
  left: var(--tl-x);
  bottom: var(--tl-ground-h);
  height: var(--tl-ship-h);
  width: calc(var(--tl-ship-h) * 0.3);
  margin-left: calc(var(--tl-ship-h) * -0.15);
  transform-origin: 50% 100%;
}

/* A canvas larger than the rocket, with room below for its flame: 1.5
   rockets wide and 2.7 tall, the rocket's middle 0.65 down it. */
.tl-ship-gl {
  position: absolute;
  left: 50%;
  top: calc(var(--tl-ship-h) * -0.15);
  width: calc(var(--tl-ship-h) * 1.5);
  height: calc(var(--tl-ship-h) * 2.7);
  transform: translateX(-50%);
  display: none;
}

.tl-ship-art {
  display: block;
  height: 100%;
  width: 100%;
  filter: drop-shadow(0 0 24px rgba(150, 190, 255, 0.35));
}

.tl-meteor {
  position: absolute;
  left: var(--tl-x);
  top: var(--tl-top);
  width: var(--tl-rock);
  height: var(--tl-rock);
  margin-left: calc(var(--tl-rock) * -0.5);
}

/* The meteor's canvas: 2.8 of it wide and 3 tall, its middle 0.62 down, so
   that there is room above for what it trails. */
.tl-meteor-gl {
  position: absolute;
  left: 50%;
  top: calc(var(--tl-rock) * -1.36);
  width: calc(var(--tl-rock) * 2.8);
  height: calc(var(--tl-rock) * 3);
  transform: translateX(-50%);
  display: none;
}

/* The meteor as a drawing, where there is no WebGL. */
.tl-rock {
  position: absolute;
  inset: 0;
  border-radius: 46% 54% 50% 50% / 52% 48% 54% 46%;
  background: radial-gradient(circle at 50% 78%, #ffd9a0 0%, #ff8a2a 22%, #6b2a14 48%, #1a1210 78%);
  box-shadow: 0 0 60px 18px rgba(255, 120, 40, 0.45);
}

.tl-gl .tl-ship-gl,
.tl-gl .tl-meteor-gl { display: block; }
.tl-gl .tl-ship-art,
.tl-gl .tl-rock { visibility: hidden; }

.tl-scene-rocket .tl-grab {
  width: 100%;
  border-radius: 50%;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.tl-ship .tl-grab { border-radius: 40% 40% 12% 12%; }

/* The console: a row of keys under the pad. Each says what it changes and,
   beneath that, what it is set to. */
.tl-console {
  position: absolute;
  z-index: 4;
  left: 50%;
  bottom: calc(var(--tl-ground-h) * 0.13);
  display: none;
  gap: 2px;
  padding: 5px;
  transform: translateX(-50%);
  border: 1px solid var(--tl-line);
  border-radius: 999px;
  background: rgba(6, 9, 18, 0.55);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transition: opacity 0.4s ease;
}
.tl-gl .tl-console { display: flex; }
.tl.is-zero .tl-console,
.tl.is-live .tl-console { opacity: 0; pointer-events: none; }

.tl-key {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.28rem;
  min-width: 6.6rem;
  padding: 0.5rem 1.05rem 0.55rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--tl-text);
  text-align: left;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
  transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.12s ease;
}
.tl-key span {
  font: 500 0.56rem/1 var(--tl-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--tl-faint);
}
.tl-key b {
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.tl-key:hover { background: rgba(255, 255, 255, 0.08); }
.tl-key:active { transform: scale(0.97); }
.tl-key:focus-visible { outline: 2px solid #6aa5ff; outline-offset: 2px; }

.tl-key-fire span { color: var(--tl-amber); }
.tl-key-fire.is-on {
  background: rgba(255, 140, 50, 0.22);
  box-shadow: 0 0 34px 2px rgba(255, 130, 40, 0.55), inset 0 0 0 1px rgba(255, 178, 62, 0.6);
}

/* Narrower than this the console would run into the date; it moves to the
   right, where the link down the page gives way to it. */
@media (min-width: 901px) and (max-width: 1180px) {
  .tl-scene-rocket .tl-console { left: auto; right: 24px; transform: none; }
  .tl-scene-rocket .tl-more { display: none; }
}

/* Between zero and the meteor. */
.tl-shout {
  position: absolute;
  left: 0;
  right: 0;
  top: calc((100% - var(--tl-ground-h)) / 2);
  z-index: 2;
  display: none;
  margin: 0;
  transform: translateY(-50%);
  text-align: center;
  font: 600 clamp(1.4rem, 4.6vw, 4rem)/1 var(--tl-mono);
  letter-spacing: 0.5em;
  text-indent: 0.5em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 0 60px rgba(255, 150, 60, 0.8);
  animation: tl-rise 0.7s var(--tl-ease) both;
}
.tl.is-zero:not(.is-live) .tl-shout { display: block; }
.tl.is-zero:not(.is-live) .tl-count { opacity: 0; transition: opacity 0.4s ease; }
.tl.is-zero .tl-guide,
.tl.is-zero .tl-hint { opacity: 0; transition: opacity 0.4s ease; }

/* ── The words ─────────────────────────────────────────── */

.tl-copy {
  position: absolute;
  inset: 0;
  z-index: 2;
  max-width: 1240px;
  margin: 0 auto;
}

.tl-count {
  position: absolute;
  inset: 0 24px;
}

.tl-head {
  position: absolute;
  left: 0;
  top: clamp(1.6rem, 5.5vh, 3.2rem);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 1.8vw, 1.6rem);
}

/* The Turing mark, as tall as the two lines beside it. */
.tl-logo {
  flex: none;
  height: clamp(5.6rem, 9.4vw, 8rem);
  width: auto;
  fill: #fff;
  filter: drop-shadow(0 0 26px rgba(120, 165, 255, 0.45));
  animation: tl-rise 1s 0.05s var(--tl-ease) both;
}

.tl-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1rem;
  padding: 0.4rem 0.9rem 0.4rem 0.75rem;
  border: 1px solid rgba(255, 178, 62, 0.34);
  border-radius: 999px;
  background: rgba(255, 178, 62, 0.07);
  font: 600 0.72rem/1 var(--tl-mono);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--tl-amber);
}

.tl-eyebrow i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--tl-red);
  box-shadow: 0 0 10px 2px rgba(255, 75, 58, 0.8);
  animation: tl-blink 1s steps(2, jump-none) infinite;
}

@keyframes tl-blink {
  from { opacity: 1; }
  to { opacity: 0.2; }
}

.tl-title {
  margin: 0;
  font-size: clamp(1.7rem, 3.1vw, 2.7rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.04em;
  color: #fff;
}

/* Each word comes into focus on its own. */
.tl-w {
  display: inline-block;
  animation: tl-word 0.95s var(--tl-ease) both;
  animation-delay: calc(var(--i, 0) * 90ms + 120ms);
}

@keyframes tl-word {
  from { opacity: 0; transform: translateY(0.4em); filter: blur(12px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}

.tl-telemetry {
  position: absolute;
  right: 0;
  top: clamp(1.8rem, 6vh, 3.5rem);
  display: grid;
  grid-template-columns: auto auto;
  gap: 0.95rem 2.2rem;
  margin: 0;
  font-family: var(--tl-mono);
  animation: tl-rise 1s 0.5s var(--tl-ease) both;
}

.tl-telemetry dt {
  margin: 0 0 0.35rem;
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--tl-faint);
}

.tl-telemetry dd {
  margin: 0;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  color: var(--tl-text);
  white-space: nowrap;
}

.tl-telemetry .tl-armed { color: var(--tl-red); animation: tl-blink 1s steps(2, jump-none) infinite; }

/* ── The clock ─────────────────────────────────────────── */

/* Four pairs of very large numbers, with the bomb's channel down the middle
   of them. Its centre is the centre of the sky above the ground. */
.tl-clock {
  position: absolute;
  left: 0;
  right: 0;
  top: calc((100% - var(--tl-ground-h)) / 2 + 2vh);
  display: grid;
  grid-template-columns: 1fr 1fr var(--tl-channel) 1fr 1fr;
  transform: translateY(-50%);
  transition: opacity 0.5s ease, transform 0.5s var(--tl-ease), filter 0.5s ease;
}

.tl-pair {
  display: flex;
  flex-direction: column;
  align-items: center;
  animation: tl-rise 1.1s var(--tl-ease) both;
  animation-delay: calc(var(--i, 0) * 110ms + 350ms);
}
.tl-pair:nth-child(3) { grid-column: 4; }

.tl-pair b {
  display: block;
  font-size: min(12vw, 172px);
  font-weight: 200;
  line-height: 0.92;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'zero' 0;
  color: var(--tl-text);
  text-shadow: 0 0 60px rgba(120, 165, 255, 0.38);
  white-space: nowrap;
}

/* One digit. When it changes the script slides the old one out above it. */
.tl-d {
  position: relative;
  display: inline-block;
  font-style: normal;
}
.tl-d-out {
  position: absolute;
  left: 0;
  top: 0;
}

.tl-pair > span {
  margin-top: 1.1rem;
  font: 500 0.68rem/1 var(--tl-mono);
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-transform: uppercase;
  color: var(--tl-dim);
}

.tl-pair-s > span { color: var(--tl-amber); }

@keyframes tl-rise {
  from { opacity: 0; transform: translateY(26px); filter: blur(14px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}

.tl-when {
  position: absolute;
  left: 0;
  bottom: calc(var(--tl-ground-h) * 0.26);
  margin: 0;
  font-size: 0.92rem;
  color: var(--tl-dim);
  animation: tl-rise 1s 0.8s var(--tl-ease) both;
}

.tl-more {
  position: absolute;
  z-index: 4;
  right: max(24px, calc(50% - 596px));
  bottom: calc(var(--tl-ground-h) * 0.26);
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--tl-dim) !important;
  text-decoration: none !important;
}
.tl-more:hover { color: var(--tl-text) !important; }
.tl-more span { display: inline-block; margin-left: 0.25rem; animation: tl-nudge 1.8s ease-in-out infinite; }

@keyframes tl-nudge {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(4px); }
}

/* ── The story ─────────────────────────────────────────── */

/* Told when the page is opened: the line being spoken, and under it the key
   that starts and stops the telling. It stands below the left of the clock,
   clear of the pad, and stays through the launch and after it. */
.tl-story {
  position: absolute;
  z-index: 4;
  left: max(24px, calc(50% - 596px));
  bottom: calc(var(--tl-ground-h) + 2.4rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
  width: min(25rem, 31vw);
}
.tl-story[hidden] { display: none; }

.tl-story-line {
  margin: 0;
  font-size: clamp(1rem, 1.25vw, 1.2rem);
  font-weight: 500;
  line-height: 1.42;
  letter-spacing: -0.01em;
  text-wrap: balance;
  color: var(--tl-text);
  text-shadow: 0 1px 18px rgba(3, 5, 11, 0.9), 0 0 2px rgba(3, 5, 11, 0.9);
  transition: opacity 0.4s ease;
}
.tl-story[data-state='paused'] .tl-story-line,
.tl-story[data-state='held'] .tl-story-line { opacity: 0.45; }

.tl-story-key {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.55rem 1.15rem 0.6rem 0.95rem;
  overflow: hidden;
  border: 1px solid var(--tl-line);
  border-radius: 999px;
  background: rgba(6, 9, 18, 0.55);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  color: var(--tl-text);
  text-align: left;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.12s ease;
}
.tl-story-key:hover { background: rgba(255, 255, 255, 0.1); }
.tl-story-key:active { transform: scale(0.97); }
.tl-story-key:focus-visible { outline: 2px solid #6aa5ff; outline-offset: 2px; }

/* How much of it has been told, along the foot of the key. */
.tl-story-key::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--tl-amber);
  transform: scaleX(var(--told, 0));
  transform-origin: left;
  opacity: 0.85;
}
.tl-story[data-state='waiting'] .tl-story-key::after,
.tl-story[data-state='told'] .tl-story-key::after { opacity: 0; }

.tl-story-words {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.tl-story-words span {
  font: 500 0.56rem/1 var(--tl-mono);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--tl-faint);
}
.tl-story-words b {
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* A voice, drawn: four bars, still until it speaks. */
.tl-story-bars {
  display: flex;
  align-items: center;
  gap: 3px;
  height: 1.3rem;
}
.tl-story-bars i {
  width: 3px;
  height: 100%;
  border-radius: 2px;
  background: var(--tl-amber);
  transform: scaleY(0.28);
}
.tl-story-bars i:nth-child(2) { transform: scaleY(0.6); }
.tl-story-bars i:nth-child(3) { transform: scaleY(0.42); }
.tl-story[data-state='telling'] .tl-story-bars i { animation: tl-speak 0.9s ease-in-out infinite; }
.tl-story[data-state='telling'] .tl-story-bars i:nth-child(2) { animation-delay: -0.35s; animation-duration: 0.7s; }
.tl-story[data-state='telling'] .tl-story-bars i:nth-child(3) { animation-delay: -0.6s; animation-duration: 1.1s; }
.tl-story[data-state='telling'] .tl-story-bars i:nth-child(4) { animation-delay: -0.2s; animation-duration: 0.8s; }

@keyframes tl-speak {
  0%, 100% { transform: scaleY(0.25); }
  50% { transform: scaleY(1); }
}

/* The browser would not let the page speak unasked: the key says it is there. */
.tl-story.is-asking .tl-story-key {
  border-color: rgba(255, 178, 62, 0.6);
  animation: tl-ask 2.2s ease-out infinite;
}

@keyframes tl-ask {
  0% { box-shadow: 0 0 0 0 rgba(255, 178, 62, 0.5), 0 18px 50px -18px rgba(0, 0, 0, 0.9); }
  70%, 100% { box-shadow: 0 0 0 16px rgba(255, 178, 62, 0), 0 18px 50px -18px rgba(0, 0, 0, 0.9); }
}

/* ── The last ten seconds ──────────────────────────────── */

/* The clock steps back and one number takes the sky. */
.tl-final {
  position: absolute;
  left: 0;
  right: 0;
  top: calc((100% - var(--tl-ground-h)) / 2);
  display: none;
  margin: 0;
  transform: translateY(-50%);
  text-align: center;
  font-size: min(62vh, 44vw);
  font-weight: 200;
  line-height: 0.8;
  letter-spacing: -0.06em;
  font-variant-numeric: tabular-nums;
  color: #fff1ec;
  text-shadow: 0 0 90px rgba(255, 75, 58, 0.75), 0 0 200px rgba(255, 110, 40, 0.5);
}

.tl.is-final .tl-final { display: block; }
.tl.is-final .tl-clock { opacity: 0; transform: translateY(-50%) scale(0.94); filter: blur(10px); }
.tl.is-final .tl-head,
.tl.is-final .tl-telemetry,
.tl.is-final .tl-when { opacity: 0.35; transition: opacity 0.5s ease; }

/* A red breath at the edges on every one of them. */
.tl::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  box-shadow: inset 0 0 180px 30px rgba(255, 60, 40, 0.55);
}
.tl.is-final::after { animation: tl-alarm 1s ease-out infinite; }

@keyframes tl-alarm {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* ── Zero ──────────────────────────────────────────────── */

.tl-flash {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(90% 90% at var(--tl-x) calc(100% - var(--tl-ground-h)),
    #fff 0%, #fff6dc 30%, rgba(255, 200, 130, 0.9) 60%, rgba(255, 130, 60, 0.5) 100%);
}

.tl.is-impact .tl-flash { animation: tl-flash 1.9s ease-out both; }

@keyframes tl-flash {
  0%, 7% { opacity: 1; }
  100% { opacity: 0; }
}

/* The ground moves. Scaled up a little so that no edge shows while it does. */
.tl.is-impact .tl-sky { animation: tl-quake 1.4s cubic-bezier(0.3, 0.1, 0.3, 1) both; }

@keyframes tl-quake {
  0% { transform: scale(1.04) translate(0, 0); }
  8% { transform: scale(1.04) translate(-10px, 8px); }
  20% { transform: scale(1.04) translate(9px, -7px); }
  34% { transform: scale(1.035) translate(-7px, -4px); }
  50% { transform: scale(1.03) translate(5px, 4px); }
  70% { transform: scale(1.015) translate(-3px, 2px); }
  100% { transform: scale(1) translate(0, 0); }
}

/* Launched: the bomb and its instruments are gone, and the clock gives way
   to the announcement. The stage keeps its place in the layout, hidden, so
   the script can still find the ground. */
.tl.is-live .tl-stage { visibility: hidden; }
.tl.is-live .tl-count { display: none; }

.tl-live {
  position: absolute;
  left: 24px;
  right: 24px;
  top: clamp(2.5rem, 11vh, 6.5rem);
  display: none;
  text-align: center;
}
.tl.is-live .tl-live { display: block; }

.tl-live .tl-logo {
  height: clamp(3rem, 5vw, 4.2rem);
  margin-bottom: 1.3rem;
}
.tl-live .tl-logo,
.tl-live .tl-eyebrow { display: flex; width: max-content; margin-left: auto; margin-right: auto; }

.tl-live .tl-title {
  font-size: clamp(2.8rem, 7.6vw, 6.8rem);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.055em;
}

.tl-live-lead {
  margin: 1.4rem 0 0;
  font-size: clamp(1.02rem, 1.6vw, 1.3rem);
  color: rgba(238, 242, 251, 0.82);
  text-shadow: 0 1px 18px rgba(3, 5, 11, 0.9);
  animation: tl-rise 1s 0.55s var(--tl-ease) both;
}

.tl-btn {
  margin-top: 1.8rem;
  background: #fff;
  color: #0b0e14 !important;
  box-shadow: 0 16px 50px -12px rgba(255, 178, 62, 0.75);
  animation: tl-rise 1s 0.7s var(--tl-ease) both;
}
.tl-btn:hover { background: #fff3d6; }

/* After the detonation the announcement waits for the light to pass. */
.tl.is-impact .tl-live .tl-logo { animation-delay: 1.05s; }
.tl.is-impact .tl-live .tl-eyebrow { animation: tl-rise 1s 1.2s var(--tl-ease) both; }
.tl.is-impact .tl-live .tl-w { animation-delay: calc(var(--i, 0) * 120ms + 1.4s); }
.tl.is-impact .tl-live-lead { animation-delay: 2.2s; }
.tl.is-impact .tl-btn { animation-delay: 2.5s; }

/* Leaving: as the page scrolls on, the words let go of the sky first. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .tl-copy {
      animation: tl-leave linear both;
      animation-timeline: view();
      animation-range: exit 5% exit 85%;
    }
  }
}

@keyframes tl-leave {
  to { opacity: 0; transform: translateY(-7vh) scale(0.97); }
}

/* ── Narrow screens: the clock, and the fall beneath it ── */

@media (max-width: 900px) {
  .tl {
    --tl-top: 14%;
    --tl-bomb-h: 200px;
    --tl-ground-h: 88px;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .tl-copy {
    position: relative;
    inset: auto;
    order: 1;
    margin: 0;
  }

  .tl-count {
    position: relative;
    inset: auto;
    padding: 2.2rem 16px 0;
    text-align: center;
  }

  .tl-head,
  .tl-clock,
  .tl-when { position: static; }

  .tl-head { flex-direction: column; gap: 1rem; }
  .tl-logo { height: 3.4rem; }
  .tl-hint { bottom: 2.6rem; }

  .tl-telemetry { display: none; }

  .tl-title { font-size: clamp(1.7rem, 7vw, 2.4rem); }

  .tl-clock {
    grid-template-columns: repeat(4, 1fr);
    gap: 0 4px;
    margin-top: 1.6rem;
    transform: none;
  }
  .tl-pair:nth-child(3) { grid-column: auto; }
  .tl-pair b { font-size: min(18vw, 120px); }
  .tl-pair > span { margin-top: 0.7rem; font-size: 0.58rem; letter-spacing: 0.18em; text-indent: 0.18em; }

  .tl.is-final .tl-clock { transform: scale(0.94); }
  /* The number stands where the words were, so they step right back. */
  .tl.is-final .tl-head,
  .tl.is-final .tl-when { opacity: 0.08; }

  .tl-final {
    top: 56%;
    font-size: min(60vw, 300px);
  }

  .tl-when { margin-top: 1.4rem; }

  .tl-stage {
    position: relative;
    inset: auto;
    order: 2;
    height: 540px;
  }

  .tl-trail { height: 120px; }

  .tl-scene-rocket { --tl-top: 9%; --tl-ship-h: 210px; }

  /* The console comes after the fall, as a block of its own, two keys to a row. */
  .tl-console {
    position: relative;
    order: 3;
    left: auto;
    bottom: auto;
    margin: 0 16px 3.2rem;
    transform: none;
    border-radius: 22px;
  }
  .tl-gl .tl-console { display: grid; grid-template-columns: 1fr 1fr; }
  .tl-key { min-width: 0; border-radius: 16px; }
  .tl-shout { top: auto; bottom: 46%; }

  .tl-live {
    position: relative;
    left: auto;
    right: auto;
    top: auto;
    padding: 2.6rem 16px 0;
  }

  .tl-more { left: 16px; right: auto; bottom: 0.9rem; }
}

@media (prefers-reduced-motion: reduce) {
  .tl-bomb,
  .tl-heat,
  .tl-target i,
  .tl-logo,
  .tl-hint,
  .tl-eyebrow i,
  .tl-more span,
  .tl-w,
  .tl-pair,
  .tl-when,
  .tl-telemetry,
  .tl-live-lead,
  .tl-btn,
  .tl-telemetry .tl-armed,
  .tl.is-final::after { animation: none !important; }
  .tl-target i:first-child { opacity: 0.7; }
  /* Playing with it is motion; with motion turned down it is left alone. */
  .tl-gl .tl-grab,
  .tl-gl .tl-hint,
  .tl-gl .tl-console { display: none; }
}

/* The story, on a narrow screen: under the clock and above the sky, in the
   middle, with room kept for its longest line so nothing below it moves. */
@media (max-width: 900px) {
  .tl-story {
    position: relative;
    order: 1;
    left: auto;
    bottom: auto;
    align-items: center;
    width: auto;
    margin: 1.6rem 16px 0;
    text-align: center;
  }
  .tl-story-line { order: 2; min-height: 4.3em; font-size: 1.02rem; }
}

@media (prefers-reduced-motion: reduce) {
  .tl-story-key,
  .tl-story-bars i { animation: none !important; }
}
