/* The golden ticket's first screen, the lit stage it opens onto, and the tickets further down the page. */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.hero {
  position: relative; z-index: 1; isolation: isolate; overflow: clip;
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); align-items: center;
  gap: 16px clamp(28px, 4vw, 64px);
  --below-frame: 70px; /* room under the bulb frame for the replay link */
  padding: clamp(40px, 6svh, 72px) max(calc(var(--gutter) + 18px), calc((100% - 76rem) / 2)) calc(var(--below-frame) + 40px);
  /* A soft follow spot tracks the mouse; on touch screens it drifts on its own. */
  background: radial-gradient(circle 26rem at var(--spot-x) var(--spot-y), rgb(255 226 150 / 0.11), transparent 70%), radial-gradient(ellipse at 29% 36%, #233f95, var(--stage) 66%, #0d1c47);
}
@property --spot-x { syntax: "<percentage>"; inherits: false; initial-value: 30%; }
@property --spot-y { syntax: "<percentage>"; inherits: false; initial-value: 35%; }
@media (hover: none) { .hero { animation: spot-drift 16s ease-in-out infinite alternate; } }
@keyframes spot-drift { 0% { --spot-x: 18%; --spot-y: 30%; } 50% { --spot-x: 70%; --spot-y: 55%; } 100% { --spot-x: 40%; --spot-y: 25%; } }

.hero-marquee { display: grid; gap: clamp(18px, 3vw, 32px); min-width: 0; text-align: left; }
.ticket-rest { display: grid; grid-template-columns: minmax(0, 1fr) 24%; gap: 8px; height: clamp(110px, 21vw, 300px); }
.ticket-rest[hidden] { display: none; }
.rest-main, .rest-stub { min-width: 0; min-height: 0; }
.ticket-rest canvas { display: block; width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(var(--lift)); }
.rest-stub canvas { rotate: 8deg; }
[data-resting] .ticket-rest canvas { visibility: hidden; }
.lede { font: 800 clamp(1.4rem, 2.4vw, 2.4rem)/1.15 var(--body); letter-spacing: -0.01em; text-wrap: pretty; }
.lede span { display: block; }
/* The plain one-line explanation under the slogan, so the page says what it is before the forms. Not on the intro screen. */
.lede-more { display: block; max-width: 34ch; margin-top: 12px; font: 700 clamp(1rem, 1.3vw, 1.2rem)/1.4 var(--body); color: var(--muted); }
[data-hero="intro"] .lede-more { display: none; }

/* Wide screens: the torn stub hangs over the main piece's lower right corner, and the form card stacks its fields. */
@media (width > 54rem) {
  .ticket-rest { position: relative; display: block; height: auto; }
  .rest-main { aspect-ratio: 4.95 / 2.7; }
  .rest-stub { position: absolute; z-index: 1; right: 3%; top: 64%; width: 22%; aspect-ratio: 1.45 / 2.7; }
  .hero-marquee .lede { max-width: 70%; }
  .hero .fields { grid-template-columns: minmax(0, 1fr); }
  .hero .ticket-main { gap: 16px; padding: clamp(22px, 2.6vw, 34px); }
  .hero .ticket-main h2 { font-size: clamp(1.5rem, 2.3vw, 2rem); text-align: center; }
  .hero .ticket-main .btn { width: 100%; }
}

/* Stage lights frame the art and the form with one continuous footlight strip. */
.hero::before { content: ""; position: absolute; z-index: -1; inset: -24% -30% 0; background: repeating-conic-gradient(from 150deg at 36% 0, rgb(255 226 141 / 0.09) 0deg 6deg, transparent 6deg 23deg); mask-image: linear-gradient(#000, #0000 86%); }
/* Marquee bulbs run around the whole stage: two interleaved sets blink in turn, so the light seems to chase. */
/* Every edge fits a whole number of bulbs (round), and the side columns start below the corner bulbs, so corners never double up or cut a bulb in half.
   Each tile holds one bulb of each set: the first set at its first quarter, the second at its third, so the two blink in turn. */
.hero-lights { --step: 38px; --stops: #fff8d8 0 3px, #ffc72c 4.5px, rgb(255 199 44 / 0.35) 6px, transparent 8px; --row: radial-gradient(circle at 25% 50%, var(--stops)); --col: radial-gradient(circle at 50% 25%, var(--stops)); }
.hero-lights { position: absolute; inset: 6px 6px calc(var(--below-frame) + 6px); pointer-events: none; }
.hero-lights::before, .hero-lights::after {
  content: ""; position: absolute; inset: 0; padding-block: 16px;
  background: var(--row) 0 0 / var(--step) 16px round no-repeat border-box, var(--row) 0 100% / var(--step) 16px round no-repeat border-box, var(--col) 0 0 / 16px var(--step) no-repeat round content-box, var(--col) 100% 0 / 16px var(--step) no-repeat round content-box;
  filter: drop-shadow(0 0 5px rgb(255 199 44 / 0.7));
  animation: bulbs-chase 900ms steps(1) infinite;
}
.hero-lights::after { --row: radial-gradient(circle at 75% 50%, var(--stops)); --col: radial-gradient(circle at 50% 75%, var(--stops)); animation-delay: -450ms; }
@keyframes bulbs-chase { 0% { opacity: 1; } 50% { opacity: 0.22; } }
[data-hero="intro"] .hero-lights { display: none; }
/* When the stage opens, the bulbs switch on one after another around the frame before they start to chase. */
@property --lit { syntax: "<angle>"; inherits: false; initial-value: 360deg; }
.hero-lights { mask-image: conic-gradient(from -90deg, #000 var(--lit), #0000 0); animation: lights-on 1400ms cubic-bezier(0.45, 0, 0.55, 1) both; }
@keyframes lights-on { from { --lit: 0deg; } }
@media (prefers-reduced-motion: reduce) { .hero, .hero-lights, .hero-lights::before, .hero-lights::after { animation: none; } }

/* Gold foil: a band of light sweeps across a gold prop on hover, and once as it first comes into view. */
.ticket-main, .how li { position: relative; }
.ticket-main, .how li, .game-front { overflow: hidden; } /* the waiting band stays off the edges */
.ticket-main::after, .how li::after, .game-front::after { content: ""; position: absolute; z-index: 1; inset: 0; border-radius: inherit; pointer-events: none; background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.5) 47%, rgb(255 240 190 / 0.25) 53%, transparent 65%); translate: -130% 0; }
.ticket-main:hover::after, .how li:hover::after, .game-card:hover .game-front::after, .shown .ticket-main::after, .shown .how li::after { animation: foil-sweep 1100ms cubic-bezier(0.45, 0, 0.55, 1); }
.shown .how li:nth-child(2)::after { animation-delay: 160ms; }
.shown .how li:nth-child(3)::after { animation-delay: 320ms; }
@keyframes foil-sweep { to { translate: 130% 0; } }
@media (prefers-reduced-motion: reduce) { .ticket-main::after, .how li::after, .game-front::after { display: none; } }

.tear-again { position: absolute; left: 50%; bottom: 16px; translate: -50% 0; min-height: 44px; padding: 8px 16px; border: 0; background: transparent; color: var(--gold); font: 800 0.9375rem/1.2 var(--body); text-decoration: underline; text-underline-offset: 0.2em; cursor: pointer; }
.tear-again:hover { color: var(--text); }

@media (max-width: 54rem) {
  .hero { grid-template-columns: minmax(0, 1fr); justify-items: center; row-gap: 12px; padding-top: 40px; }
  .hero-marquee, .ticket-stage { width: min(100%, 34rem); }
  .hero-marquee { gap: 14px; justify-items: center; text-align: center; }
  .ticket-rest { width: 100%; height: clamp(104px, 35vw, 222px); }
}

/* The intro: a still ticket on the dark stage until the 3D one arrives. */
html:not([data-hero="intro"]) .intro-only, .ticket-canvas { display: none; }
[data-hero="intro"] .hero { display: block; height: 100svh; min-height: 30rem; padding: 0; background: radial-gradient(ellipse 60% 55% at 50% 50%, #173080, #050a21 78%); }
[data-hero="intro"] .hero::before, [data-hero="intro"] .ticket-stage, [data-hero="intro"] .ticket-rest, [data-hero="intro"] .tear-again { display: none; }
[data-hero="intro"] .ticket-canvas, [data-resting] .ticket-canvas { display: block; position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 100svh; touch-action: pan-y; opacity: 0; }
[data-scene="ready"] .ticket-canvas { opacity: 1; }
[data-resting] .ticket-canvas { z-index: 2; pointer-events: none; }
[data-scene="ready"] .still { display: none; }
[data-hero="intro"] .lede { position: absolute; z-index: 2; top: clamp(16px, 6vh, 56px); left: 0; right: 0; padding-inline: 92px; pointer-events: none; font: 800 clamp(1.125rem, 2.1vw, 1.75rem)/1.45 var(--body); letter-spacing: normal; max-width: none; text-align: center; text-wrap: balance; }

[data-hero="intro"] .lede span { display: inline; }
[data-burst] .lede { opacity: 0; transition: opacity 300ms; }

.still { position: absolute; z-index: 0; top: 50%; left: 50%; display: flex; width: min(84vw, 62rem); aspect-ratio: 6.4 / 2.7; transform: translate(-50%, -50%); background: var(--gold); border-radius: 14px; filter: drop-shadow(var(--lift)); }
.still span { flex: 1; display: grid; place-items: center; margin: 3.4%; background: var(--panel); border-radius: 8px; }
.still img { width: 84%; }
.still i { flex: none; width: 22.7%; border-left: 3px dashed rgb(42 28 0 / 0.55); }

.ticket-grab { position: absolute; z-index: 3; padding: 0; border: 0; border-radius: 12px; background: transparent; cursor: grab; touch-action: none; }
.ticket-grab:active { cursor: grabbing; }
.ticket-grab:focus-visible { outline-offset: 2px; }
/* A pulsing marker on the stub's top-right corner shows new visitors where to pull. It shows with the hint and goes once they grab. */
.ticket-grab::before, .ticket-grab::after { position: absolute; pointer-events: none; opacity: 0; transition: opacity 300ms; }
.ticket-grab::before { content: ""; top: -11px; right: -11px; width: 26px; height: 26px; border-radius: 50%; background: var(--gold); border: 4px solid #0a1740; outline: 3px solid var(--gold); animation: pull-ripple 1.4s ease-out infinite; }
.ticket-grab::after { content: "¡Jala aquí!"; top: -54px; right: 0; padding: 7px 14px; white-space: nowrap; border-radius: 999px; background: #0a1740; color: var(--gold); border: 2px solid var(--gold); font: 400 1.05rem/1 var(--display); box-shadow: var(--lift); }
.hero:has(.ticket-hint.on) .ticket-grab::before, .hero:has(.ticket-hint.on) .ticket-grab::after { opacity: 1; }
@keyframes pull-ripple { from { outline-offset: 0; outline-color: var(--gold); } to { outline-offset: 16px; outline-color: rgb(255 199 44 / 0); } }

.ticket-hint { position: absolute; z-index: 2; left: 16px; right: 16px; bottom: clamp(56px, 9vh, 84px); font: 400 clamp(1.25rem, 3.2vw, 2.1rem)/1.1 var(--display); color: var(--gold); pointer-events: none; text-shadow: 0 3px 0 #0a1740; opacity: 0; transform: translateY(10px); transition: opacity 400ms, transform 400ms cubic-bezier(0.16, 1, 0.3, 1); }
.ticket-hint.on { opacity: 1; transform: none; }
.ticket-hint small { display: block; margin-top: 6px; font: 700 clamp(0.875rem, 1.6vw, 1rem)/1.2 var(--body); color: var(--text); text-shadow: none; }
.ticket-skip { position: absolute; z-index: 3; left: 50%; bottom: max(8px, env(safe-area-inset-bottom)); transform: translateX(-50%); display: grid; place-items: center; min-height: 44px; padding-inline: 18px; color: var(--text); }
.ticket-skip:hover { color: var(--gold); }
.ticket-skip.gone { visibility: hidden; }

/* Stays on screen as long as the music can play. */
.ticket-sound { position: fixed; z-index: 20; bottom: max(12px, env(safe-area-inset-bottom)); left: 12px; min-height: 44px; padding: 8px 14px; border: 2px solid var(--gold); border-radius: 999px; background: #0a1740; color: var(--gold); font: 800 0.9375rem/1 var(--body); cursor: pointer; }
.ticket-sound:hover { background: var(--panel); }
.ticket-sound[hidden], .ticket-grab[hidden] { display: none; }

/* The forms land where the 3D pieces are heading. */
[data-landing] .ticket-shadow { animation: forms-land 800ms cubic-bezier(0.16, 1, 0.3, 1) both; }
[data-landing] .heads img { animation: heads-hop 800ms cubic-bezier(0.16, 1, 0.3, 1) both; }
[data-landing] .lede { animation: forms-land 800ms cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes forms-land { from { opacity: 0; } to { opacity: 1; } }
@keyframes heads-hop { from { translate: 0 100%; } to { translate: 0 0; } }

/* The little game: a solid TV on its stand and a real phone floating in front, leaning toward the mouse. */
/* The TV and phone each tilt in their own 3D space (no preserve-3d here), so stacking order alone keeps the phone on top. */
.demo { --tilt-x: 0; --tilt-y: 0; padding-bottom: clamp(72px, 12vw, 150px); perspective: 1500px; }
.demo::before { content: ""; position: absolute; left: 8%; right: 18%; bottom: clamp(14px, 2vw, 28px); height: clamp(18px, 3vw, 40px); border-radius: 50%; background: radial-gradient(closest-side, rgb(3 8 30 / 0.7), transparent); }
.depth { position: absolute; inset: 0; border-radius: inherit; background: var(--edge); transform: translateZ(calc(var(--back) * -1)); pointer-events: none; }

.tv { --edge: #1b2650; position: relative; padding-bottom: 5cqw; background: linear-gradient(#0b1436, #050b24 30%); box-shadow: inset 0 0 0 1px #2a3768; transform-style: preserve-3d; transform: rotateX(calc(3deg + var(--tilt-y) * -5deg)) rotateY(calc(-11deg + var(--tilt-x) * 9deg)); transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1); }
.tv::before { content: "Cabezones"; position: absolute; left: 0; right: 0; bottom: 1.5cqw; text-align: center; font: 400 max(0.6875rem, 1.4cqw)/1 var(--display); color: #8fa0d8; transform: translateZ(1px); }
.tv::after { content: ""; position: absolute; right: 3cqw; bottom: 2cqw; width: 0.8cqw; height: 0.8cqw; min-width: 5px; min-height: 5px; border-radius: 50%; background: #ff5a4a; box-shadow: 0 0 6px 1px rgb(255 90 74 / 0.8); transform: translateZ(1px); }
.tv-screen { position: relative; overflow: hidden; transform: translateZ(1px); box-shadow: inset 0 0 2cqw rgb(3 8 30 / 0.7); }
.tv-screen::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(115deg, rgb(255 255 255 / 0.07) 0 22%, transparent 22.5%), radial-gradient(circle at calc(50% + var(--tilt-x) * 45%) calc(50% + var(--tilt-y) * 45%), rgb(255 255 255 / 0.1), transparent 58%); }
.tv-neck { position: absolute; left: 44%; right: 44%; top: 100%; height: 5cqw; background: linear-gradient(90deg, #0b1436, #2a3768 45%, #0b1436); transform: translateZ(-20px); }
.tv-foot { position: absolute; left: 28%; right: 28%; top: calc(100% + 4.6cqw); height: 1.3cqw; min-height: 7px; border-radius: 3px 3px 8px 8px; background: linear-gradient(#34427a, #0b1436); box-shadow: 0 3px 8px rgb(3 8 30 / 0.7); transform: translateZ(-20px); }

.phone { --edge: #1b2650; z-index: 5; aspect-ratio: 9 / 16; width: clamp(118px, 15.5cqw, 140px); align-content: start; padding: 24px 9px 14px; gap: 5px; border-color: #050b24; background: linear-gradient(160deg, #24418f, var(--panel) 45%, #15276a); transform-style: preserve-3d; transform: translateZ(calc(30px + var(--tilt-y) * 8px)) rotateX(calc(var(--tilt-y) * -9deg)) rotateY(calc(-20deg + var(--tilt-x) * 14deg)) rotateZ(3deg); transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1); }
.phone .depth { inset: -5px; }
.phone::before { content: ""; position: absolute; top: 8px; left: 50%; width: 34%; height: 10px; margin-left: -17%; border-radius: 99px; background: #050b24; transform: translateZ(1px); }
.phone::after { content: ""; position: absolute; left: 34%; right: 34%; bottom: 6px; height: 4px; border-radius: 99px; background: rgb(244 247 255 / 0.65); transform: translateZ(1px); }
.phone > p, .phone > button { transform: translateZ(1px); }
.phone .buzz { min-width: 0; min-height: clamp(66px, 11cqw, 88px); padding-inline: 4px; font-size: clamp(1rem, 2.6cqw, 1.3rem); }
.phone-hint { margin-top: 2px; }

/* The layers inside the TV screen shift at different depths. */
.tv-scores, .race-title, .race-track, .tv-status { transition: translate 500ms cubic-bezier(0.16, 1, 0.3, 1); }
.tilting .tv, .tilting .phone, .tilting .tv-scores, .tilting .race-title, .tilting .race-track, .tilting .tv-status { transition-duration: 140ms; transition-timing-function: ease-out; }
.tv-scores { translate: calc(var(--tilt-x) * 5px) calc(var(--tilt-y) * 4px); }
.race-title { translate: calc(var(--tilt-x) * 8px) calc(var(--tilt-y) * 6px); }
.race-track { translate: calc(var(--tilt-x) * 12px) calc(var(--tilt-y) * 8px); }
.tv-status { translate: calc(var(--tilt-x) * 6px) calc(var(--tilt-y) * 4px); }

/* Too narrow for the phone beside the TV: it lies wide underneath, still a solid object. */
@container (max-width: 34rem) {
  .tv { transform: rotateX(3deg) rotateY(-7deg); }
  .phone { position: relative; aspect-ratio: auto; width: 100%; margin-top: clamp(44px, 14cqw, 64px); padding: 14px; transform: rotateX(8deg); }
  .phone::before { display: none; }
}
@media (max-width: 34rem) {
  .demo { padding: 0; }
  .demo::before { display: none; }
}

/* Así funciona: three tickets, torn stub on the left. */
.how ol { list-style: none; counter-reset: step; display: grid; gap: clamp(18px, 2.4vw, 32px); grid-template-columns: minmax(0, 1fr); }
@media (width > 54rem) { .how ol { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.how li { --notch: 12px; counter-increment: step; display: grid; grid-template-columns: clamp(64px, 6vw, 84px) minmax(0, 1fr); filter: drop-shadow(var(--lift)); }
.how li:nth-child(1) { rotate: -0.8deg; }
.how li:nth-child(3) { rotate: 0.8deg; }
.how li::before { content: counter(step); display: grid; place-items: center; grid-row: span 2; font: 400 clamp(2.25rem, 3.6vw, 3rem)/1 var(--display); color: var(--gold-ink); background: var(--gold); border-radius: 14px 0 0 14px; mask-image: radial-gradient(circle var(--notch) at 100% 0, #0000 98%, #000), radial-gradient(circle var(--notch) at 100% 100%, #0000 98%, #000); mask-composite: intersect; }
.how strong { display: block; margin-bottom: -1px; padding: 18px 20px 4px; font-size: 1.25rem; font-weight: 800; background: var(--panel); border-radius: 0 14px 0 0; border-left: 3px dashed var(--panel-edge); }
.how span { padding: 0 20px 20px; color: var(--muted); background: var(--panel); border-radius: 0 0 14px 0; border-left: 3px dashed var(--panel-edge); }

/* Seis juegos: playing cards with the logo in front and the description on the back. */
.games { padding-top: 0; }
.games ul { position: relative; list-style: none; display: grid; gap: clamp(14px, 2vw, 24px); grid-template-columns: repeat(6, minmax(0, 1fr)); padding-block: 12px 24px; perspective: 1500px; transform-style: preserve-3d; }
.games li { aspect-ratio: 5 / 7; transform-style: preserve-3d; }
.games li:nth-child(1) { transform: rotate(-2.4deg); }
.games li:nth-child(2) { transform: translateY(-6px) rotate(1.2deg); }
.games li:nth-child(3) { transform: rotate(-0.8deg); }
.games li:nth-child(4) { transform: translateY(-6px) rotate(1.6deg); }
.games li:nth-child(5) { transform: rotate(-1.4deg); }
.games li:nth-child(6) { transform: translateY(-4px) rotate(2.2deg); }
.games ul.waiting-to-deal li { visibility: hidden; }
.game-card { position: relative; display: block; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 14px; background: none; color: inherit; font: inherit; cursor: pointer; transform-style: preserve-3d; transition: transform 620ms cubic-bezier(0.16, 1, 0.3, 1); }
.game-card:focus-visible { outline-offset: 5px; }
.game-card.flipped, .game-card.face-down { transform: rotateY(180deg); }
.game-front, .game-back { position: absolute; inset: 0; display: grid; place-items: center; padding: clamp(10px, 1.1vw, 16px); border-radius: 14px; backface-visibility: hidden; box-shadow: var(--lift); }
.game-front { background: #fffaf0; outline: 2px solid var(--gold-deep); outline-offset: -8px; }
.game-front img { width: 100%; height: auto; }
/* The back's three equal-sided rows keep the logo in the exact center, with the description under it. */
.game-back { grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr); gap: clamp(4px, 0.6vw, 8px); padding: clamp(5px, 0.6vw, 9px); transform: rotateY(180deg); color: var(--text); font-weight: 700; line-height: 1.32; text-align: center; background: repeating-linear-gradient(45deg, #1f3f9c 0 6px, var(--stage) 6px 12px); border: clamp(4px, 0.5vw, 7px) solid var(--gold); }
.game-back-logo { grid-row: 2; justify-self: center; width: 90%; height: auto; filter: drop-shadow(0 3px 4px rgb(3 8 30 / 0.7)); }
.game-back > span { grid-row: 3; align-self: start; padding: 3px 4px; border-radius: 6px; background: var(--stage); font-size: clamp(0.75rem, 0.95vw, 0.875rem); }
/* Turned over, a card shows a moment from its game (tools/game-cards.html draws them): the logo moves to the top and the description to the bottom.
   Face down in the deck, every back stays the same pattern. */
.game-card:not(.face-down) .game-back { grid-template-rows: auto minmax(0, 1fr) auto; background: var(--preview) center / cover no-repeat, var(--stage); }
.game-card:not(.face-down) .game-back-logo { grid-row: 1; width: 72%; }
.game-card:not(.face-down) .game-back > span { grid-row: 3; align-self: end; background: rgb(10 23 64 / 0.88); }
.extra-card { position: absolute; top: 0; left: 0; transform-style: preserve-3d; pointer-events: none; }
.games-note { margin-top: clamp(24px, 3vw, 36px); font-weight: 700; }

/* The cast jump in a wave on the footer floor, swapping to their jumping pose in the air. */
.cast-member { --hop: 2.6s; position: relative; z-index: 1; width: clamp(84px, 16vw, 180px); aspect-ratio: 1; margin-bottom: -6px; }
.cast-member:nth-child(1) { --wave: 0; }
.cast-member:nth-child(2) { --wave: 1; }
.cast-member:nth-child(3) { --wave: 2; }
.cast-member:nth-child(4) { --wave: 3; }
.cast-member::after { content: ""; position: absolute; left: 22%; right: 22%; bottom: -4px; height: 10px; border-radius: 50%; background: rgb(3 8 30 / 0.45); animation: cast-shadow var(--hop) ease-in-out infinite; animation-delay: calc(var(--wave) * 0.42s - var(--hop)); }
.cast-member img { position: absolute; z-index: 1; inset: 0; width: 100%; transform-origin: 50% 96%; animation: cast-hop var(--hop) ease-in-out infinite; animation-delay: calc(var(--wave) * 0.42s - var(--hop)); }
.cast-member img:first-child { animation-name: cast-hop, cast-on-ground; animation-timing-function: ease-in-out, linear; }
.cast-member img:last-child { animation-name: cast-hop, cast-in-air; animation-timing-function: ease-in-out, linear; }
@keyframes cast-hop {
  0%, 100% { transform: translateY(0) scale(1); }
  8% { transform: translateY(0) scale(1.08, 0.88); }
  20% { transform: translateY(-36%) scale(0.97, 1.05); }
  32% { transform: translateY(0) scale(1, 1.02); }
  36% { transform: translateY(0) scale(1.1, 0.86); }
  44% { transform: translateY(0) scale(1); }
}
@keyframes cast-on-ground { 0%, 10% { opacity: 1; } 10.1%, 31% { opacity: 0; } 31.1%, 100% { opacity: 1; } }
@keyframes cast-in-air { 0%, 10% { opacity: 0; } 10.1%, 31% { opacity: 1; } 31.1%, 100% { opacity: 0; } }
@keyframes cast-shadow {
  0%, 8%, 32%, 100% { transform: scale(1); opacity: 1; }
  20% { transform: scale(0.55); opacity: 0.45; }
}

@media (max-width: 79.99rem) {
  .games ul { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: 56rem; margin-inline: auto; }
}
@media (max-width: 37.5rem) {
  .games ul { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .games li { aspect-ratio: 5 / 7.8; }
  [data-hero="intro"] .lede { padding-inline: 16px; top: 28px; font-size: 1.0625rem; }
}

@media (max-width: 22rem) {
  html:not([data-hero="intro"]) .hero .lede { font-size: 1.2rem; }
  .games ul { grid-template-columns: minmax(0, 1fr); }
  .games li { aspect-ratio: 5 / 6; }
}
.hint-tall { display: none !important; }
/* A tall phone gets a tall still ticket, like the 3D one, with the stub at the bottom. */
@media (max-aspect-ratio: 4 / 5) {
  .ticket-rest {
    width: min(100%, 16rem);
    grid-template-columns: minmax(0, 1fr) 40%;
    gap: 12px;
  }
  .hint-side { display: none !important; }
  .hint-tall { display: block !important; }
  /* On the upright ticket the label sits beside the marker, on the perforation, so it doesn't cover the ticket's text. */
  .ticket-grab::after { top: -18px; right: 26px; }
  .still { flex-direction: column; width: auto; height: 58svh; aspect-ratio: 2.7 / 6.4; }
  .still img { width: 90%; }
  .still i { width: auto; height: 22.7%; border-left: 0; border-top: 3px dashed rgb(42 28 0 / 0.55); }
}
@media (max-height: 26rem) {
  .ticket-hint small { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .how li { rotate: none; }
  .cast-member::after, .cast-member img { animation: none; }
  .cast-member img:first-child { opacity: 0; }
  .game-card { transition: none; }
}

/* Conoce a los Cabezones: the cast under spotlights, each taking a turn at a game pose. */
.lineup > p, .games-hint { max-width: 46ch; margin-top: calc(clamp(20px, 3vw, 36px) * -0.5); margin-bottom: clamp(20px, 3vw, 36px); font-weight: 700; }
.lineup ul { list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(12px, 2vw, 28px); }
.cabezon { position: relative; display: grid; justify-items: center; gap: 12px; width: 100%; padding: 8px 6px 14px; border: 0; border-radius: 16px; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.cabezon::before { content: ""; position: absolute; z-index: -1; left: 12%; right: 12%; bottom: 46px; height: 18%; border-radius: 50%; background: rgb(255 199 44 / 0.2); box-shadow: 0 0 28px 10px rgb(255 199 44 / 0.14); }
.cabezon img { width: min(100%, 15rem); height: auto; aspect-ratio: 1; object-fit: contain; filter: drop-shadow(0 10px 10px rgb(3 8 30 / 0.45)); transition: scale 300ms cubic-bezier(0.16, 1, 0.3, 1); }
.cabezon:hover img { scale: 1.05; }
.cabezon.hop img { animation: cabezon-hop 520ms cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes cabezon-hop { 40% { translate: 0 -9%; } }
.cabezon-game { display: grid; place-items: center; width: min(100%, 13rem); min-height: calc(2.4em + 16px); padding: 6px 12px; border: 2px solid var(--gold); border-radius: 999px; background: #0a1740; color: var(--gold); font-weight: 800; font-size: 0.9375rem; line-height: 1.2; text-align: center; }
@media (max-width: 40rem) { .lineup ul { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (prefers-reduced-motion: reduce) { .cabezon.hop img { animation: none; } }

/* "3, 2, 1, ¡Ya!" pops in the middle of the race screen. */
.race-count { position: absolute; z-index: 2; left: 50%; top: 56%; translate: -50% -50%; font: 400 clamp(1.75rem, 9cqw, 5rem)/1 var(--display); color: var(--gold); -webkit-text-stroke: 0.5cqw #0a1740; paint-order: stroke; text-shadow: 0 0.6cqw 0 #0a1740; pointer-events: none; }
.race-count.pop { animation: count-pop 600ms cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes count-pop { from { scale: 1.8; opacity: 0; } 30% { opacity: 1; } }

/* A full code gets a "¡Listo!" stamp on the field. It means the code is complete; the server still checks it. */
.ready-stamp { position: absolute; right: 10px; bottom: 9px; padding: 2px 8px; font: 400 0.9375rem/1.3 var(--display); color: var(--stage); border: 3px solid var(--stage); border-radius: 6px; rotate: -10deg; opacity: 0; pointer-events: none; }
.ticket-stage.ready .ready-stamp { animation: stamp-in 380ms cubic-bezier(0.2, 0, 0.2, 1) forwards; }
@keyframes stamp-in { 0% { opacity: 0; scale: 1.9; } 70% { opacity: 1; scale: 0.94; } 100% { opacity: 1; scale: 1; } }
.ticket-stage.ready .code-input { padding-right: 96px; }

/* When Ana wins the demo race, the footer cast celebrates: quick hops, in their jumping pose. */
.floor.cheer .cast-member { --hop: 0.8s; }
.floor.cheer .cast-member img:first-child { animation-name: cast-hop; opacity: 0; }
.floor.cheer .cast-member img:last-child { animation-name: cast-hop; opacity: 1; }

/* Sections step in once as they're reached: the tickets punch in one by one, the cast steps forward. */
.reveal main > section:not(.hero, .games, .shown) > *, .reveal .games:not(.shown) > :not(ul) { opacity: 0; }
.reveal main > section.shown:not(.hero) > *:not(ul), .reveal .how.shown > ol, .reveal .lineup.shown > ul { animation: rise-in 700ms cubic-bezier(0.16, 1, 0.3, 1) backwards; }
.reveal main > section.shown > :nth-child(2) { animation-delay: 120ms; }
.reveal main > section.shown > :nth-child(3) { animation-delay: 240ms; }
@keyframes rise-in { from { opacity: 0; translate: 0 28px; } }
.reveal .how li, .reveal .lineup li { opacity: 0; }
.reveal .how.shown li, .reveal .lineup.shown li { opacity: 1; }
.reveal .how.shown li { animation: ticket-punch 560ms cubic-bezier(0.16, 1, 0.3, 1) both; }
.reveal .lineup.shown li { animation: step-forward 620ms cubic-bezier(0.16, 1, 0.3, 1) both; }
.reveal .how.shown li:nth-child(2), .reveal .lineup.shown li:nth-child(2) { animation-delay: 140ms; }
.reveal .how.shown li:nth-child(3), .reveal .lineup.shown li:nth-child(3) { animation-delay: 280ms; }
.reveal .lineup.shown li:nth-child(4) { animation-delay: 420ms; }
@keyframes ticket-punch { from { opacity: 0; scale: 0.82; translate: 0 18px; } 60% { opacity: 1; } }
@keyframes step-forward { from { opacity: 0; scale: 0.9; translate: 0 36px; } }
@media (prefers-reduced-motion: reduce) { .ticket-stage.ready .ready-stamp { animation: none; opacity: 1; } .race-count.pop { animation: none; } }

/* Muy pronto: a selfie on a phone turns into the guest's own character, shown in three game poses. */
.selfie { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(20px, 4vw, 56px); align-items: center; margin-top: clamp(36px, 5vw, 64px); padding: clamp(20px, 3vw, 36px); border-radius: 18px; background: var(--panel); border: 2px solid var(--panel-edge); box-shadow: var(--lift); }
.selfie h3 { margin: 6px 0 10px; font: 400 clamp(1.6rem, 2.6vw, 2.25rem)/1.1 var(--display); }
.selfie-copy > p:last-of-type { max-width: 34ch; color: var(--muted); font-weight: 700; }
.selfie-copy .btn { margin-top: 18px; }
.btn.gold { background: var(--gold); color: var(--gold-ink); }
.btn.gold:hover { background: #ffd24f; }
.soon { display: inline-block; padding: 4px 12px; border-radius: 999px; background: var(--gold); color: var(--gold-ink); font-weight: 800; font-size: 0.875rem; letter-spacing: 0.04em; text-transform: uppercase; }
.selfie-show { display: grid; grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: clamp(10px, 2vw, 24px); }
.selfie-phone { position: relative; display: grid; gap: 10px; justify-items: center; width: clamp(96px, 11vw, 132px); padding: 18px 10px 12px; border: 5px solid #050b24; border-radius: 22px; background: #0a1740; rotate: -4deg; box-shadow: var(--lift); }
.viewfinder { position: relative; display: block; width: 100%; aspect-ratio: 3 / 4; border-radius: 10px; overflow: hidden; background: radial-gradient(circle at 50% 40%, #3a5cb8, #1a3580); }
.viewfinder::before { content: ""; position: absolute; z-index: 1; inset: 8px; background: linear-gradient(var(--gold), var(--gold)) 0 0 / 14px 3px, linear-gradient(var(--gold), var(--gold)) 0 0 / 3px 14px, linear-gradient(var(--gold), var(--gold)) 100% 0 / 14px 3px, linear-gradient(var(--gold), var(--gold)) 100% 0 / 3px 14px, linear-gradient(var(--gold), var(--gold)) 0 100% / 14px 3px, linear-gradient(var(--gold), var(--gold)) 0 100% / 3px 14px, linear-gradient(var(--gold), var(--gold)) 100% 100% / 14px 3px, linear-gradient(var(--gold), var(--gold)) 100% 100% / 3px 14px; background-repeat: no-repeat; }
.viewfinder img { position: absolute; left: 8%; bottom: -6%; width: 84%; }
.shutter { width: 26px; height: 26px; border-radius: 50%; background: #f4f7ff; box-shadow: 0 0 0 3px #0a1740, 0 0 0 5px #f4f7ff; }
.selfie-arrow { width: clamp(28px, 4vw, 48px); height: 22px; background: var(--gold); clip-path: polygon(0 35%, 60% 35%, 60% 0, 100% 50%, 60% 100%, 60% 65%, 0 65%); }
.selfie-poses { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; }
.selfie-poses img { width: 100%; filter: drop-shadow(0 8px 8px rgb(3 8 30 / 0.45)); }
.selfie-poses img:nth-child(2) { scale: 1.12; }
.shown .selfie-phone { animation: snap 900ms 300ms cubic-bezier(0.16, 1, 0.3, 1) backwards; }
.shown .selfie-poses img { animation: step-forward 620ms cubic-bezier(0.16, 1, 0.3, 1) backwards; }
.shown .selfie-poses img:nth-child(1) { animation-delay: 700ms; }
.shown .selfie-poses img:nth-child(2) { animation-delay: 840ms; }
.shown .selfie-poses img:nth-child(3) { animation-delay: 980ms; }
@keyframes snap { 0% { filter: brightness(1); } 12% { filter: brightness(2.4); } 40% { filter: brightness(1); } }
@media (max-width: 54rem) { .selfie { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 30rem) { .selfie-show { grid-template-columns: minmax(0, 1fr); justify-items: center; } .selfie-poses { width: 100%; } .selfie-arrow { rotate: 90deg; } }
@media (prefers-reduced-motion: reduce) { .shown .selfie-phone, .shown .selfie-poses img { animation: none; } }

/* Dudas: each question is a stub you pull open; the gold plus turns into a minus. */
.faq-list { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
.faq-item { border-radius: 14px; background: var(--panel); border: 2px solid var(--panel-edge); box-shadow: var(--lift); }
.faq-item[open] { border-color: var(--gold); }
.faq-item summary { position: relative; display: block; padding: 18px 56px 18px 20px; font-weight: 800; font-size: 1.125rem; line-height: 1.3; cursor: pointer; list-style: none; border-radius: 12px; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; position: absolute; right: 16px; top: 50%; translate: 0 -50%; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--gold); color: var(--gold-ink); font: 400 1.25rem/1 var(--display); transition: rotate 300ms cubic-bezier(0.16, 1, 0.3, 1); }
.faq-item[open] summary::after { content: "−"; rotate: 180deg; }
.faq-item p { padding: 0 20px 18px; color: var(--muted); line-height: 1.55; }
.faq-item[open] p { animation: rise-in 420ms cubic-bezier(0.16, 1, 0.3, 1); }
@media (max-width: 54rem) { .faq-list { grid-template-columns: minmax(0, 1fr); } }
@media (prefers-reduced-motion: reduce) { .faq-item summary::after { transition: none; } .faq-item[open] p { animation: none; } }

/* The marquee wire: a cable that drops from the hero frame's corner bulb to the code form. Its bulbs stay dark until you
   scroll past them (stage-fx.js sets --wire-lit and the wire's place), and the last one switches on the "¡Tu turno!" sign. */
main { position: relative; }
/* Bulbs sit every --step from one --step below the frame; the top half step is bare cord. The glow is drawn into each
   bulb, since a drop-shadow filter on a page-tall layer is costly. Bulbs switch on as you pass them, with no animation. */
.wire { --step: 44px; --bulb-glow: radial-gradient(circle, #fff8d8 0 3px, #ffc72c 4.5px, rgb(255 199 44 / 0.5) 5.5px, rgb(255 199 44 / 0.18) 7px, transparent 8px); position: absolute; z-index: 2; left: 6px; width: 16px; padding-top: calc(var(--step) / 2); pointer-events: none;
  background: var(--bulb-off) 0 0 / 16px var(--step) repeat-y content-box, linear-gradient(#050b24, #050b24) center / 3px 100% no-repeat border-box; }
.wire::after { content: ""; position: absolute; inset: calc(var(--step) / 2) 0 0; background: var(--bulb-glow) 0 0 / 16px var(--step) repeat-y; mask-image: linear-gradient(#000 calc(var(--wire-lit, 0px) - var(--step) / 2), #0000 0); }
/* Each section's rail switches on once the wire's light reaches it (stage-fx.js adds .rail-on). */
.how, .lineup, .faq { position: relative; }
.how::before, .lineup::before, .faq::before { content: ""; position: absolute; inset: 0 0 auto; height: 16px; pointer-events: none; background: var(--bulb) 0 0 / 38px 16px repeat-x; filter: drop-shadow(0 0 5px rgb(255 199 44 / 0.75)); visibility: hidden; }
.rail-on::before { visibility: visible; }
.ask { position: relative; }
.turn-sign { position: absolute; z-index: 3; top: 0; left: 6px; translate: 0 -50%; margin: 0; padding: 10px 18px; font: 400 clamp(1.05rem, 2vw, 1.4rem)/1 var(--display); letter-spacing: 0.04em; color: rgb(255 199 44 / 0.3); background: #0a1740; border: 4px dotted rgb(255 199 44 / 0.25); border-radius: 12px; box-shadow: var(--lift); rotate: -2deg; }
.turn-sign.on { color: var(--gold); border-color: var(--gold); text-shadow: 0 0 8px rgb(255 199 44 / 0.8), 0 0 22px rgb(255 199 44 / 0.45); box-shadow: var(--lift), 0 0 26px rgb(255 199 44 / 0.35); animation: sign-on 700ms steps(1) both; }
@keyframes sign-on { 0% { opacity: 0.5; } 18% { opacity: 1; } 30% { opacity: 0.55; } 46%, 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .turn-sign.on { animation: none; } }
