/* intro.css — the opening title card.

   Direction: "the mark ignites". The room is black, a seed of amber charges in
   the middle while light streams in from off screen, the words arrive out of
   depth (real perspective, not a fade), and the "?!" lands like a hammer —
   shockwave, shake, flash — before the whole thing burns out into the lobby.

   Everything here is transform/opacity, the canvas carries the particulate, and
   the DOM is built and removed by js/ui/intro.js. Nothing in this file is
   focusable and the overlay never takes pointer events: an intro must never be
   able to trap the remote. */

.intro {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(60% 55% at 50% 48%, #14100e 0%, #06070b 62%, #030407 100%);
  animation: intro-out 560ms var(--ease-out) 2600ms both;
}

.intro__fx {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* ---------- The stage: real depth, the words travel through it ---------- */

.intro__stage {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 0.2rem;
  max-width: 86vw;
  perspective: 1400px;
  perspective-origin: 50% 46%;
  transform-style: preserve-3d;
  animation: intro-shake 340ms cubic-bezier(0.36, 0.07, 0.19, 0.97) 1740ms both;
}

.intro__line {
  display: block;
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 0.92;
  text-transform: uppercase;
  text-wrap: balance;
  text-align: center;
  will-change: transform, opacity;
  backface-visibility: hidden;
}

/* Kicker: the words before the accent one. */
.intro__line--a {
  font-size: min(5rem, 7.4vw);
  letter-spacing: 0.06em;
  color: #fff3e2;
  text-shadow:
    0 0 1.6rem rgb(255 176 102 / 0.55),
    0 0.4rem 2.4rem rgb(0 0 0 / 0.8);
  animation: intro-fly-a 640ms var(--ease-out) 460ms both;
}

.intro__line--a:empty {
  display: none;
}

/* The accent word: the biggest thing the app ever draws. */
.intro__line--b {
  font-size: min(11.5rem, 15.5vw);
  letter-spacing: -0.035em;
  color: #ffd86b;
  text-shadow:
    0 0 2.2rem rgb(255 186 92 / 0.7),
    0 0 6rem rgb(224 112 58 / 0.55),
    0 0.6rem 3rem rgb(0 0 0 / 0.85);
  animation: intro-fly-b 700ms var(--ease-out) 700ms both;
}

/* The punctuation is the punchline: it arrives last, alone, and hits.
   It lives in the lockup's right padding, not on top of the word — that gutter
   is what keeps the whole mark optically centred once the "?!" lands. */
.intro__bang {
  position: absolute;
  right: 0.02em;
  bottom: -0.06em;
  font-family: var(--font-display);
  font-size: 1em;
  font-weight: 800;
  line-height: 0.9;
  color: #ff5f9e;
  text-shadow:
    0 0 2.4rem rgb(255 95 158 / 0.8),
    0 0 7rem rgb(217 74 107 / 0.6);
  transform-origin: 40% 60%;
  animation: intro-slam 320ms var(--ease-slam) 1540ms both;
  will-change: transform, opacity;
}

/* The lockup: accent word + the gutter the "?!" hangs in. The font-size here
   only sizes the bang and its gutter — the word carries its own. */
.intro__mark {
  position: relative;
  display: inline-grid;
  justify-items: center;
  padding-right: 0.86em;
  font-size: min(9rem, 12vw);
  line-height: 0;
}

/* ---------- Impact: two shockwave rings out of the hit point ---------- */

.intro__ring {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 28rem;
  height: 28rem;
  margin: -14rem 0 0 -14rem;
  border: 0.22rem solid rgb(255 216 140 / 0.9);
  border-radius: 50%;
  opacity: 0;
  animation: intro-ring 760ms var(--ease-out) 1740ms both;
}

.intro__ring--2 {
  border-color: rgb(255 95 158 / 0.75);
  animation-delay: 1840ms;
  animation-duration: 900ms;
}

/* ---------- Light: the hit pop, then the burn that hands over ---------- */

.intro__flash,
.intro__burn {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.intro__flash {
  background: radial-gradient(45% 42% at 50% 48%, #fff8e6 0%, rgb(255 176 102 / 0.4) 42%, transparent 72%);
  animation: intro-pop 300ms var(--ease-out) 1730ms both;
}

.intro__burn {
  background: radial-gradient(70% 60% at 50% 50%, #fff6e0 0%, #ffb86a 34%, rgb(224 112 58 / 0.35) 60%, transparent 82%);
  animation: intro-burn 700ms var(--ease-out) 2480ms both;
}

/* ---------- Keyframes ---------- */

@keyframes intro-fly-a {
  from {
    opacity: 0;
    transform: translate3d(0, 2.4rem, -1500px) rotateX(58deg);
    filter: blur(0.9rem);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) rotateX(0deg);
    filter: blur(0);
  }
}

@keyframes intro-fly-b {
  from {
    opacity: 0;
    transform: translate3d(0, -3.4rem, -2400px) rotateX(-52deg);
    filter: blur(1.4rem);
  }
  60% {
    opacity: 1;
    filter: blur(0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) rotateX(0deg);
    filter: blur(0);
  }
}

@keyframes intro-slam {
  from {
    opacity: 0;
    transform: scale(7) rotate(-14deg);
  }
  62% {
    opacity: 1;
    transform: scale(0.86) rotate(3deg);
  }
  to {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }
}

@keyframes intro-ring {
  from {
    opacity: 0.95;
    transform: scale(0.08);
  }
  to {
    opacity: 0;
    transform: scale(2.6);
  }
}

@keyframes intro-shake {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  18% {
    transform: translate3d(-0.9rem, 0.5rem, 0);
  }
  38% {
    transform: translate3d(0.8rem, -0.4rem, 0);
  }
  58% {
    transform: translate3d(-0.45rem, -0.25rem, 0);
  }
  78% {
    transform: translate3d(0.25rem, 0.15rem, 0);
  }
}

@keyframes intro-pop {
  from {
    opacity: 0;
  }
  22% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

@keyframes intro-burn {
  from {
    opacity: 0;
    transform: scale(0.85);
  }
  38% {
    opacity: 1;
    transform: scale(1.04);
  }
  to {
    opacity: 0;
    transform: scale(1.3);
  }
}

@keyframes intro-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* ============================================================================
   Short version — reduced motion and the 1 GB budget.

   Both keep the mark and the hand-over so the opening still reads as an
   opening; what they drop is the depth travel, the shake and the particulate.
   The JS shortens its own clock to match (see SHORT_MS in intro.js).
   ========================================================================== */

.intro--short .intro__stage,
.intro--short .intro__ring,
.intro--short .intro__flash {
  animation: none;
}

.intro--short .intro__ring {
  display: none;
}

.intro--short .intro__line--a {
  animation: intro-appear 260ms linear 60ms both;
}

.intro--short .intro__line--b {
  animation: intro-appear 260ms linear 160ms both;
}

.intro--short .intro__bang {
  animation: intro-appear 200ms linear 320ms both;
}

.intro--short .intro__burn {
  animation: intro-burn 420ms var(--ease-out) 620ms both;
}

.intro--short {
  animation: intro-out 300ms linear 820ms both;
}

@keyframes intro-appear {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Lite keeps the full timeline but drops every blur (a full-screen blurred
   layer is the one thing a 1 GB stick cannot afford at 60fps). */
:root[data-perf="lite"] .intro__line--a,
:root[data-perf="lite"] .intro__line--b {
  filter: none !important;
}

:root[data-perf="lite"] .intro__line--b {
  text-shadow: 0 0 2rem rgb(255 186 92 / 0.6);
}

/* ---------- Modo ligero: la intro no puede animar desenfoques ----------
   Animar `filter: blur()` obliga a recomponer la capa en CADA fotograma; en un
   Fire TV real eso hunde la intro. Aqui se sustituye por opacidad y escala,
   que van por el compositor y cuestan practicamente cero. */

:root[data-perf="lite"] .intro,
:root[data-perf="lite"] .intro * {
  filter: none !important;
  backdrop-filter: none !important;
  box-shadow: none !important;
  text-shadow: none !important;
}

:root[data-perf="lite"] .intro__word,
:root[data-perf="lite"] .intro__line--a,
:root[data-perf="lite"] .intro__line--b,
:root[data-perf="lite"] .intro__flash,
:root[data-perf="lite"] .intro__spark {
  animation-duration: 0.5s !important;
}

:root[data-perf="lite"] .intro__spark,
:root[data-perf="lite"] .intro__ring,
:root[data-perf="lite"] .intro__dust {
  display: none !important;
}
