/* 2026 NFL Madrid Game · SI Tickets
   Colours and type from the NFL 2026 Madrid Game style guide (July 2026). */

@font-face { font-family: 'Talavera'; src: url('../assets/fonts/talavera.otf') format('opentype'); font-display: swap; }
@font-face { font-family: 'All-Pro Sans'; src: url('../assets/fonts/allpro-sans-regular.otf') format('opentype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'All-Pro Sans'; src: url('../assets/fonts/allpro-sans-bold.otf') format('opentype'); font-weight: 700; font-display: swap; }

:root {
  /* The date pill's type size; the hero's football is sized from it, so the ball's tips clear the pill. */
  --date-fs: clamp(11px, 1.2vw, 14px);
  /* Madrid event palette */
  --red: #DC0032;          /* PMS 199 C · background */
  --red-deep: #9C192F;     /* PMS 7427 C · pattern */
  --gold: #F6BE00;         /* PMS 7408 C · background */
  --gold-deep: #F6A000;    /* PMS 130 C · pattern */
  /* Team accents */
  --falcons: #A71930;
  --bengals: #FB4F14;
  --nfl-blue: #1C3C70;     /* the Madrid shield's MADRID GAME band */
  --silver: #A5ACAF;

  --ink: #1B0A0F;
  --ink-2: #5A4A4E;
  --line: #E4D9DB;
  --paper: #FFFFFF;
  --paper-2: #FBF6F2;
  --danger: #B00020;

  --display: 'Talavera', 'Georgia', serif;
  --sans: 'All-Pro Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --ease: cubic-bezier(.2, .8, .2, 1);
  --radius: 14px;
  --gutter: clamp(16px, 4vw, 48px);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  color: #fff;
  background: var(--red-deep) url('../assets/img/stone-red.jpg') center / cover fixed;
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
button { font: inherit; cursor: pointer; }
a { color: inherit; }
[hidden] { display: none !important; }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

/* ---------- Hero: helmet face-off ---------- */

/* --h is the hero's height on every screen, and the scale the helmets, ball and brand column are
   sized by. Desktop: as tall as the viewport allows (up to 86% of it) while leaving at least
   --gap-min of width per 1.776h, the proportions the face-off was first laid out in. Units are
   the hero's own width (cqw) and the viewport height (svh). */
.hero {
  /* Inherited by the helmets and the brand column; cqw there is the hero's width. */
  --hero-h: clamp(600px, 100svh, 1200px);
  --gap-min: clamp(240px, 22cqw, 340px);
  --h: min(calc(0.86 * var(--hero-h)), calc((100cqw - var(--gap-min)) / 1.776));
  /* Sticky: the hero stays locked at the top while the form panel scrolls up over it. */
  position: sticky; top: 0; z-index: 0;
  overflow: hidden; container-type: inline-size; isolation: isolate;
  background: var(--red);
  height: min(var(--hero-h), calc(var(--h) * 1.0));
}
/* As the panel rises the face-off pushes in and dims, timed to the scroll from the top until the
   hero is covered (--hero-px, its height, set by hero-duel.js). The individual scale property
   leaves the transforms the helmets and brand column already use alone. */
.hero::after { content: ''; position: absolute; inset: 0; z-index: 7; background: #000; opacity: 0; pointer-events: none; }
@supports (animation-timeline: scroll()) {
  .hero > .duel, .hero > .hero__confetti, .hero > .hero__center, .hero > .hero__ball, .hero::after {
    animation-timeline: scroll(root); animation-range: 0 var(--hero-px, 100svh); animation-fill-mode: both; animation-timing-function: linear;
  }
  .hero > .duel, .hero > .hero__confetti, .hero > .hero__center, .hero > .hero__ball { animation-name: hero-push; }
  .hero::after { animation-name: hero-dim; }
}
@keyframes hero-push { to { scale: 1.08; } }
@keyframes hero-dim { to { opacity: .6; } }
@media (prefers-reduced-motion: reduce) {
  .hero > .duel, .hero > .hero__confetti, .hero > .hero__center, .hero > .hero__ball, .hero::after { animation: none; }
}
/* The chulapo pattern drifts left to right behind the helmets. The tile is the pattern cropped
   to exactly two repeats (1710x1080), so it loops without a seam; it is drawn at the hero's
   full height, so there is no vertical seam either. The layer is one tile wider than the hero
   and slides one tile width per loop: a GPU transform, no repaints. --tile-w (the tile's drawn
   width, hero height x 1710/1080) is set exactly by hero-duel.js; the fallback assumes the
   hero is --h tall, as it is on landscape screens. */
.hero__pattern {
  --tile-w: var(--hero-tile-w, calc(var(--h) * 1.5833));
  position: absolute; top: 0; bottom: 0; left: 0;
  width: calc(100% + var(--tile-w)); margin-left: calc(-1 * var(--tile-w));
  background: url('../assets/img/chulapo-loop.jpg') left top / var(--tile-w) 100% repeat-x;
  z-index: -1; /* bottom of the hero's own stack, under the gradient, logo and helmets */
  animation: chulapo-drift 16s linear infinite;
  will-change: transform;
}
@keyframes chulapo-drift { to { transform: translateX(var(--tile-w)); } }
@media (prefers-reduced-motion: reduce) { .hero__pattern { animation: none; } }
.duel { position: absolute; inset: 0; z-index: 1; pointer-events: none; } /* click-through to the shield; the music button opts back in */
/* z 1 above: the scroll push-in scales .duel, which makes it a stacking context of its own, so it
   needs its own layer to keep the helmets over the confetti (z 0) and, on wide screens, the brand
   column (z 0); the phone layout lifts the brand column to z 5, above them. */
/* Black gradient over the bottom half: above the pattern, behind the helmets (z 1). */
.hero::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 50%; z-index: 0;
  background: linear-gradient(to top, #000, transparent);
  pointer-events: none;
}
/* The helmets (square images, the helmet filling their width) face each other across the brand
   column: the Bengals on the left looking right, the Falcons on the right looking left, each with
   its facemask at the column's edge. Like the player clips before them, each fills the hero's full
   height: the helmet itself is 90% of its image's height (5% transparent above and below), so the
   image is --h / 0.9 tall and starts 5% above the top. The backs of the helmets run off the sides
   of the screen on narrower windows. */
.hero {
  --helm-gap: clamp(380px, 40cqw, 700px);
  --helm: calc(var(--h) / 0.9);
}
/* Decorative, and they overlap the shield on wide screens: clicks go through to it. */
.duel__helmet {
  pointer-events: none;
  position: absolute; top: calc(-0.05 * var(--helm)); z-index: 1;
  display: block; width: var(--helm); max-width: none; height: auto;
  filter: drop-shadow(0 24px 36px rgba(0, 0, 0, .55));
}
/* The source images face the other way (Falcons right, Bengals left), so both are mirrored with
   the individual scale property, which leaves the slide-in transforms alone. */
.duel__helmet--bengals { left: calc(50cqw - var(--helm-gap) / 2 - var(--helm)); scale: -1 1; }
.duel__helmet--falcons { left: calc(50cqw + var(--helm-gap) / 2); scale: -1 1; }
/* Black fading up over the lower half of each helmet, so the team lockups in front stand out.
   One strip per side, from the screen edge to just past the facemask, under the lockups (z 4 in
   the hero) and over the helmets. A mask feathers each strip's inner side to nothing over its
   last 45%, so there's no hard edge and the brand column and ball between them stay bright. */
.duel::before, .duel::after {
  content: ''; position: absolute; bottom: 0; z-index: 2; height: 55%;
  width: calc(50cqw - var(--helm-gap) / 2 + 40px);
  background: linear-gradient(to top, rgba(0, 0, 0, .9), rgba(0, 0, 0, .55) 40%, transparent);
  pointer-events: none;
}
.duel::before { left: 0; -webkit-mask-image: linear-gradient(to right, #000 55%, transparent); mask-image: linear-gradient(to right, #000 55%, transparent); }
.duel::after { right: 0; -webkit-mask-image: linear-gradient(to left, #000 55%, transparent); mask-image: linear-gradient(to left, #000 55%, transparent); }
/* Music toggle: just the headphones (from the Club SI F1 site), no box. The 48px hit area
   stays; a soft shadow keeps it legible over the helmets. */
.duel__sound {
  pointer-events: auto;
  /* A white disc in the top-right corner, the icon navy on it. */
  position: absolute; right: max(12px, calc(var(--gutter) - 12px)); top: 12px; z-index: 6; width: 48px; height: 48px;
  display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; color: var(--nfl-blue);
  background: #fff; box-shadow: 0 6px 18px rgba(10, 20, 50, .35);
  transition: background .2s, transform .2s;
}
.duel__sound svg {
  width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.duel__sound:hover { background: #EEF2F8; transform: scale(1.06); }
.duel__sound .slash { transition: opacity .2s; }
.duel__sound[aria-pressed="true"] .slash { opacity: 0; }
.duel__sound .wave { opacity: 0; transition: opacity .2s; }
.duel__sound[aria-pressed="true"] .wave { opacity: 1; }

/* Gold confetti falling behind the helmets: filmed on black and screened, so the black drops out
   and only the glinting gold adds light to the pattern. z 0, after the hero's gradient and before
   the brand column in the markup, so it sits over the gradient, under the logos and the helmets
   (z 1-3). Fades up once it is really playing. */
.hero__confetti {
  position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover;
  mix-blend-mode: screen; pointer-events: none; opacity: 0; transition: opacity 1.5s ease;
}
.hero__confetti.on { opacity: 1; }

/* Brand column, centred between the helmets and drawn behind them (z-index 0 under the
   helmets' 1), so the helmets overlap the logo. */
.hero__center {
  /* Stands on the top of the ball (.hero__ball, its own layer so it can sit behind the helmets
     even where this column is in front of them): the SI Tickets × Madrid Game lockup, partner line
     included (720/1586 as tall as it is wide). As big as the height allows (24px to the top, at
     least 20px over the ball), kept to the space between the facemasks. */
  --logo-w: min(calc(var(--helm-gap) - 10px), calc((var(--h) - 2 * var(--stack-gap) - var(--ball-top) - 44px) / 0.454));
  --stack-gap: clamp(8px, calc(0.025 * var(--h)), 20px);
  /* Lifted clear of the ball by 40% of the room left over (up to 0.14h), less on a short hero so
     the lockup keeps 24px to the top. */
  --lift: max(0px, min(calc(0.4 * (var(--h) - 0.454 * var(--logo-w) - 2 * var(--stack-gap) - var(--ball-top) - 24px)), calc(0.14 * var(--h))));
  position: absolute; left: 50%; bottom: calc(var(--ball-top) + var(--stack-gap)); z-index: 0;
  transform: translateX(-50%);
  width: var(--logo-w);
  display: flex; flex-direction: column; align-items: center; gap: var(--stack-gap); text-align: center;
}
.hero__logo { width: var(--logo-w); filter: drop-shadow(0 20px 40px rgba(0,0,0,.45)); }
/* Soft dark radial shadow behind the lockup, so it lifts off the pattern and helmets (and the red
   SI wordmark off the red). */
.hero__mark {
  position: relative; z-index: 0; display: flex; justify-content: center; margin-bottom: var(--lift);
  padding: 0; border: 0; background: none; color: inherit; cursor: pointer;
}
.hero__mark .hero__logo { transition: transform .3s var(--ease), filter .3s; }
@media (hover: hover) { .hero__mark:hover .hero__logo { transform: scale(1.04); } }
.hero__mark:focus-visible { outline: 3px solid var(--gold); outline-offset: 6px; border-radius: 12px; }
.hero__mark::before {
  content: ''; position: absolute; inset: -22% -40%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(0,0,0,.6), rgba(0,0,0,.3) 55%, transparent);
}
/* The game ball, whole, centred between the helmets and resting just above the date pill (which
   reaches 21px up into the hero). Sized to the helmets: about half the hero's height wide (the
   helmets are 0.9h), but never wider than the gap between the facemasks. --ball-top is where its
   top edge sits (the image is 533/900 as tall as wide, the ball filling it), which the brand
   column stands on. z 0, after the confetti: behind the helmets (z 1-3) at every size. */
.hero {
  --ball-w: min(calc(0.5 * var(--h)), calc(var(--helm-gap) - 40px));
  --ball-b: 30px;
  --ball-top: calc(0.5922 * var(--ball-w) + var(--ball-b));
}
.hero__ball {
  position: absolute; left: 0; right: 0; bottom: var(--ball-b); z-index: 0; margin: 0 auto;
  display: block; width: var(--ball-w); max-width: none; height: auto;
  pointer-events: none; filter: drop-shadow(0 16px 24px rgba(0, 0, 0, .55));
}

/* Team logo and wordmark side by side along the bottom, along the bottom on the dark gradient:
   above the helmets (z 1) so they never cover them, under the dimming layer (z 7). */
.hero__team {
  position: absolute; z-index: 4; bottom: clamp(16px, 5%, 44px);
  display: flex; flex-direction: row; align-items: center; gap: clamp(8px, 1.2cqw, 16px);
  transform: translateX(-50%); pointer-events: none; filter: drop-shadow(0 2px 12px rgba(0, 0, 0, .6));
}
/* Logo beside the wordmark, on the outer side: Bengals logo first, Falcons logo last. */
.hero__team--falcons .hero__team-mark { order: 1; }
.hero__team img { display: block; height: auto; }
.hero__team .hero__wordmark { width: clamp(100px, 15cqw, 210px); }
.hero__team .hero__team-mark { width: auto; height: clamp(36px, 5.2cqw, 72px); }
.hero__team--bengals { left: calc(21cqw - 50px); }
.hero__team--falcons { left: auto; right: 55px; transform: none; } /* its right edge 55px in from the window edge */
html.revealed .hero__team { animation: wordmark-in 1s cubic-bezier(.2, .8, .2, 1) .9s both; }
@keyframes wordmark-in { from { opacity: 0; translate: 0 16px; } to { opacity: 1; translate: 0 0; } }

/* ---------- Signup ---------- */

/* The form panel slides up over the sticky hero, on the gold chulapo pattern (one seamless repeat
   of the style guide's Madrid2026_ChulapoPattern_Gold, rendered at 2x), with a shadow along the
   leading edge. */
.signup { --gold-tile: clamp(110px, 9vw, 160px);
  position: relative; z-index: 1; overflow-x: clip; background: var(--gold); /* clip the drifting pattern sideways only, so the date can sit over the seam */
  box-shadow: 0 -24px 48px rgba(0, 0, 0, .45);
  display: grid; justify-items: center; padding: clamp(48px, 5.5vw, 64px) var(--gutter) clamp(48px, 8vw, 96px); /* room for the date pill's lower half */ scroll-margin-top: 0;
  border-top: 6px solid var(--gold); /* the gold seam the date pill sits on */ }
/* The gold pattern drifts right to left, against the hero's red one, on the same 16 s loop. The
   layer is six tiles wider than the panel and slides exactly six tiles per loop (about the hero's
   pace), so it wraps without a seam; a GPU transform, no repaints. */
.signup::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0; z-index: -1;
  width: calc(100% + 6 * var(--gold-tile));
  background: url('../assets/img/chulapo-gold-tile.png') 0 0 / var(--gold-tile) repeat;
  animation: gold-drift 16s linear infinite; will-change: transform;
}
@keyframes gold-drift { to { transform: translateX(calc(-6 * var(--gold-tile))); } }
@media (prefers-reduced-motion: reduce) { .signup::before { animation: none; } }
.signup .card { width: 100%; max-width: 560px; scroll-margin-top: 24px; }

/* ---------- Team bands · the style guide's vertical team lockups either side of the form ----------
   Bengals left, Falcons right, wherever there's room beside the form (761px up; phones stack). Each is the lockup's vector art
   (logo over the vertical wordmark) on the team's houndstooth from the CIN vs ATL artwork, which
   drifts slowly downwards (one tile per 30 s, seamless). They run the full height of the form card. */
.stage { width: 100%; display: grid; grid-template-columns: minmax(0, 560px); justify-content: center; gap: clamp(20px, 2.4vw, 40px); }
.teamband { display: none; }
@media (min-width: 761px) {
  .stage { grid-template-columns: clamp(96px, 13vw, 200px) minmax(0, 644px) clamp(96px, 13vw, 200px); }
  .signup .card { max-width: 644px; } /* 15% wider beside the bands */
  .teamband {
    --tile: calc(clamp(96px, 13vw, 200px) * 1.1);
    display: block; position: relative; overflow: hidden; isolation: isolate; border-radius: var(--radius);
    box-shadow: 0 30px 80px rgba(40, 0, 10, .4), inset 0 0 0 1px rgba(255, 255, 255, .08);
  }
  .teamband--falcons { background: #2b2b2b; }
  .teamband--bengals { background: #E8501A; }
  .teamband::before {
    content: ''; position: absolute; left: 0; right: 0; top: calc(-1 * var(--tile)); bottom: 0; z-index: -1;
    background: 0 0 / var(--tile) repeat; animation: band-drift 30s linear infinite; will-change: transform;
  }
  .teamband--falcons::before { background-image: url('../assets/img/band-atl.jpg'); }
  .teamband--bengals::before { background-image: url('../assets/img/band-cin.jpg'); }
  .teamband img { display: block; width: 68%; height: auto; margin: 14% auto 0; filter: drop-shadow(0 4px 14px rgba(0, 0, 0, .35)); }
}
@keyframes band-drift { to { transform: translateY(var(--tile)); } }
@media (prefers-reduced-motion: reduce) { .teamband::before { animation: none; } }

/* The game date as a divider: a pill centred on the gold seam between the hero and this panel,
   half over each (the seam is the panel's 6px top border, so its middle is 3px above the
   padding box). */
.countdown__date {
  position: absolute; left: 50%; top: -3px; z-index: 2; transform: translate(-50%, -50%); margin: 0;
  padding: 10px 22px 10px calc(22px + .22em); border: 3px solid var(--gold); border-radius: 999px;
  background: linear-gradient(180deg, #24508F, var(--nfl-blue)); color: #fff; white-space: nowrap;
  font-weight: 700; font-size: var(--date-fs); letter-spacing: .22em; text-transform: uppercase;
  box-shadow: 0 10px 28px rgba(10, 20, 50, .4);
}

/* ---------- Countdown · the NFL London site's split-flap board, in the Madrid style ----------
   Talavera numerals on red flaps and deep-red All-Pro Sans labels, straight on the gold.
   One fluid size, --cd (the numerals' font size), scales the whole board smoothly with the window,
   no breakpoints: 24px + 3vw grows it on wider screens, and (100vw - 40px) / 8.8 keeps it inside
   a small phone (the board is about 8.6 x --cd wide). Spacing and labels are fractions of it. */
.countdown {
  --cd: clamp(28px, min(24px + 3vw, (100vw - 40px) / 8.8), 72px);
  display: flex; align-items: stretch; margin: 0 0 clamp(28px, 5vw, 48px);
}
.countdown .u {
  display: flex; flex-direction: column; align-items: center; gap: calc(var(--cd) * .13);
  padding: 4px calc(var(--cd) * .3); border-left: 1px solid rgba(156, 25, 47, .3);
}
.countdown .u:first-child { border-left: 0; }
/* Each digit is two leaves: the upper one of the old number falls away while the lower one of
   the new number swings up behind it. */
.countdown .v {
  font-family: var(--display); font-weight: 400; font-size: var(--cd);
  line-height: 1; display: flex; gap: .08em;
}
.flap { position: relative; display: block; width: .78em; height: 1.12em; perspective: 200px; color: #fff; filter: drop-shadow(0 6px 12px rgba(60, 0, 12, .45)); }
.flap i { position: absolute; left: 0; right: 0; height: 50%; overflow: hidden; font-style: normal; background: linear-gradient(180deg, #F0123F, var(--red)); backface-visibility: hidden; }
.flap .top, .flap .ft { top: 0; border-radius: 4px 4px 0 0; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09); }
.flap .bot, .flap .fb { bottom: 0; border-radius: 0 0 4px 4px; background: linear-gradient(180deg, #C8002E, #A90027); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .35); }
.flap .top::after, .flap .ft::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: rgba(60, 0, 12, .55); }
.flap b { display: flex; align-items: center; justify-content: center; height: 200%; width: 100%; font: inherit; padding-top: .06em; }
/* The lower leaf shows the bottom half of the glyph. A percentage margin would resolve against
   width, not height; translate resolves against the element's own box. */
.flap .bot b, .flap .fb b { transform: translateY(-50%); }
.flap .ft, .flap .fb { z-index: 2; animation-fill-mode: both; }
.flap .ft { transform-origin: bottom; opacity: 0; }
.flap .fb { transform-origin: top; opacity: 0; }
.flap.go .ft { animation: flapFall .16s ease-in forwards; }
.flap.go .fb { animation: flapRise .19s .16s cubic-bezier(.2, .9, .3, 1.2) forwards; }
@keyframes flapFall { from { opacity: 1; transform: rotateX(0); } 99% { opacity: 1; } to { opacity: 1; transform: rotateX(-90deg); } }
@keyframes flapRise { from { opacity: 1; transform: rotateX(88deg); } to { opacity: 1; transform: rotateX(0); } }
@media (prefers-reduced-motion: reduce) { .flap.go .ft, .flap.go .fb { animation: none; } }
/* The seconds, the column that moves, flip on the shield's navy instead of red. */
#cS .flap { filter: drop-shadow(0 6px 12px rgba(10, 20, 50, .45)); }
#cS .flap i { background: linear-gradient(180deg, #2C5BA0, #24508F); }
#cS .flap .bot, #cS .flap .fb { background: linear-gradient(180deg, #1F4580, var(--nfl-blue)); }
#cS .flap .top::after, #cS .flap .ft::after { background: rgba(8, 18, 45, .55); }
.countdown.live .flap { color: var(--gold); }
.countdown .l {
  font-family: var(--sans); font-weight: 700; font-size: max(10px, calc(var(--cd) * .22));
  letter-spacing: .2em; text-transform: uppercase; color: var(--red-deep); padding-left: .2em;
}

/* ---------- Form card ---------- */

/* The form card: the hero's red chulapo pattern under a dark wash (as the limit popup), the
   copy in white and gold, the inputs white. */
.card {
  --on-card: rgba(255, 255, 255, .88);
  --card-err: #FFB3C1;      /* errors in a light rose, legible on the dark red */
  --card-star: #FF5A78;     /* the required asterisks, a brighter Madrid red */
  position: relative; isolation: isolate;
  background: var(--red-deep) url('../assets/img/chulapo-loop.jpg') center top / auto 520px repeat;
  color: #fff;
  border-radius: var(--radius);
  padding: clamp(24px, 3.4vw, 40px);
  box-shadow: 0 30px 80px rgba(40, 0, 10, .45);
  border-top: 6px solid var(--nfl-blue);
}
.card::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: radial-gradient(120% 60% at 50% 0%, rgba(60, 0, 12, .35), rgba(40, 0, 8, .84) 70%);
}
.card__title {
  margin: 0 0 6px;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(36px, 4.4vw, 52px); line-height: 1; color: #fff; text-shadow: 0 4px 18px rgba(0, 0, 0, .45);
}
.card__eyebrow, .card__title, .card__lede { text-align: center; }
.card__eyebrow { margin: 0 0 8px; font-weight: 700; font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--gold); }
.card__lede { margin: 0 0 20px; color: var(--on-card); }
/* Gold rule between the intro and the fields. */
.card__rule { height: 2px; margin: 0 0 24px; border: 0; background: var(--gold); }

.card__lede p { margin: 0 0 10px; }
.card__lede strong { color: #fff; }
.card__lede .card__terms { margin-top: 14px; font-size: 13px; color: rgba(255, 255, 255, .75); }
/* Entry Period: outside it this notice stands in for the form (main.js), whose fields, button and
   notes are hidden. */
#signup:not([data-entries="open"]) > :is(.row, .field, button[type="submit"], .status, .recaptcha) { display: none; }
.window { margin: 4px 0 6px; padding: 22px 20px; border: 2px solid var(--gold); border-radius: var(--radius); text-align: center; }
.window__title { margin: 0 0 8px; font-family: var(--display); font-weight: 400; font-size: clamp(24px, 3vw, 32px); color: var(--gold); }
.window__body { margin: 0; color: var(--on-card); line-height: 1.5; }

/* ---------- The Madrid film, under the gold rule ----------
   A vertical (9:16) player, centred and capped so it never towers over the card: a gold ring and
   the card's shadow, the controls white on a dark fade along the bottom, gold for progress and
   the "Tap for sound" pill (the site's small button style). */
.film { margin: 0 auto 26px; width: min(100%, 340px); }
.film__frame {
  position: relative; overflow: hidden; isolation: isolate;
  aspect-ratio: 9 / 16; border-radius: var(--radius); background: #000 url('../assets/video/film/si-madrid-poster.jpg') center / cover;
  box-shadow: 0 0 0 2px var(--gold), 0 24px 60px rgba(20, 0, 6, .55);
}
.film__video { display: block; width: 100%; height: 100%; object-fit: cover; background: transparent; }
.film--ready .film__video { cursor: pointer; }
.film button { border: 0; padding: 0; color: inherit; background: none; }
.film svg { display: block; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* Big play button, over the poster until it plays (and whenever it's paused). */
.film__big {
  position: absolute; left: 50%; top: 50%; z-index: 2; translate: -50% -50%;
  display: grid; place-items: center; width: 76px; height: 76px; border-radius: 50%;
  background: var(--gold) !important; color: var(--ink) !important;
  box-shadow: 0 0 0 8px rgba(246, 190, 0, .25), 0 14px 34px rgba(0, 0, 0, .5);
  transition: transform .2s var(--ease), background .2s;
}
.film__big svg { width: 30px; height: 30px; margin-left: 4px; fill: currentColor; stroke: none; }
.film__big:hover { transform: scale(1.06); background: #fff !important; }

/* "Tap for sound": centred along the bottom, just above the control bar, while it plays muted. */
.film__unmute {
  position: absolute; left: 50%; bottom: 60px; z-index: 3; translate: -50% 0; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px 0 11px !important;
  border-radius: 999px; background: var(--gold) !important; color: var(--ink) !important;
  font-weight: 700; font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  box-shadow: 0 8px 22px rgba(0, 0, 0, .4);
  transition: background .2s, transform .2s var(--ease);
  animation: film-nudge 2.4s var(--ease) 1.5s 2;
}
.film__unmute svg { width: 18px; height: 18px; }
.film__unmute svg path:first-child { fill: currentColor; }
.film__unmute:hover { background: #fff !important; transform: translateY(-1px); }
@keyframes film-nudge { 0%, 70%, 100% { transform: none; } 80% { transform: scale(1.08); } 90% { transform: scale(.98); } }

/* Control bar along the bottom on a dark fade. */
.film__bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; align-items: center; gap: 6px; padding: 34px 8px 8px;
  background: linear-gradient(to top, rgba(10, 0, 4, .85), rgba(10, 0, 4, .5) 55%, transparent);
  color: #fff; transition: opacity .3s;
}
/* While it plays, the bar steps back until the pointer or focus comes to the player. */
@media (hover: hover) {
  .film.is-playing .film__bar { opacity: 0; }
  .film.is-playing .film__frame:hover .film__bar, .film.is-playing .film__frame:focus-within .film__bar { opacity: 1; }
}
.film__btn { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 50%; transition: background .2s, color .2s; }
.film__btn:hover { background: rgba(255, 255, 255, .14) !important; color: var(--gold); }
.film__btn svg { width: 20px; height: 20px; }
.film__toggle svg path { fill: currentColor; stroke: none; }
.film__toggle .i-pause, .film.is-playing .film__toggle .i-play { display: none; }
.film.is-playing .film__toggle .i-pause { display: block; }
.film__mute svg path:first-child { fill: currentColor; }
.film__mute .w, .film.is-sound .film__mute .x { display: none; }
.film.is-sound .film__mute .w { display: block; }
.film__time { flex: none; min-width: 34px; font-size: 12px; font-weight: 700; letter-spacing: .04em; font-variant-numeric: tabular-nums; text-align: right; }
.film :focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

/* Seek bar: gold up to the playhead (--k), white at 30% after it. */
.film__seek {
  --k: 0%;
  flex: 1; min-width: 0; height: 20px; margin: 0 4px; background: transparent; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.film__seek::-webkit-slider-runnable-track {
  height: 4px; border-radius: 4px;
  background: linear-gradient(to right, var(--gold) var(--k), rgba(255, 255, 255, .3) var(--k));
}
.film__seek::-moz-range-track { height: 4px; border-radius: 4px; background: rgba(255, 255, 255, .3); }
.film__seek::-moz-range-progress { height: 4px; border-radius: 4px; background: var(--gold); }
.film__seek::-webkit-slider-thumb {
  -webkit-appearance: none; width: 14px; height: 14px; margin-top: -5px; border: 0; border-radius: 50%;
  background: #fff; box-shadow: 0 0 0 3px var(--gold); transition: transform .15s;
}
.film__seek::-moz-range-thumb { width: 14px; height: 14px; border: 0; border-radius: 50%; background: #fff; box-shadow: 0 0 0 3px var(--gold); }
.film__seek:hover::-webkit-slider-thumb { transform: scale(1.2); }
.film__seek:focus-visible { outline-offset: 0; border-radius: 4px; }

/* Buffering: a gold ring spins in the middle. */
.film__spin {
  position: absolute; left: 50%; top: 50%; z-index: 1; width: 44px; height: 44px; margin: -22px 0 0 -22px;
  border: 3px solid rgba(255, 255, 255, .25); border-top-color: var(--gold); border-radius: 50%;
  opacity: 0; pointer-events: none; transition: opacity .2s;
  animation: film-spin .8s linear infinite;
}
.film.is-waiting .film__spin { opacity: 1; transition-delay: .3s; }
@keyframes film-spin { to { transform: rotate(360deg); } }

/* Full screen: the whole frame (so the controls come along), the film letterboxed on black. */
.film__frame:fullscreen { aspect-ratio: auto; border-radius: 0; box-shadow: none; background: #000; }
.film__frame:fullscreen .film__video { object-fit: contain; }
@media (prefers-reduced-motion: reduce) { .film__unmute { animation: none; } }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.field { margin: 0 0 14px; padding: 0; border: 0; min-width: 0; }
.field label, .field legend {
  display: block; margin-bottom: 6px; padding: 0;
  font-weight: 700; font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
}
/* Field titles in gold (not the Terms sentence); the asterisks in red. */
.field:not(.field--check) > label, .field > legend { color: var(--gold); }
/* Every field is required: a red asterisk after each label (not the Terms line). The inputs carry
   `required`, so the asterisk is hidden from screen readers rather than read out as "star". */
.field:not(.field--check) > label::after, .field > legend::after {
  content: '*'; content: '*' / ''; margin-left: .3em; color: var(--card-star);
}
.field input:not([type]), .field input[type="email"], .field select {
  width: 100%; height: 48px; padding: 0 14px;
  font: inherit; color: var(--ink);
  background: var(--paper-2); border: 1.5px solid var(--line); border-radius: 10px;
  transition: border-color .2s, background .2s;
  appearance: none;
}
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath stroke='%231B0A0F' stroke-width='2' d='m1 1 5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; padding-right: 40px;
}
.field input:focus, .field select:focus { outline: none; border-color: var(--red); background: #fff; }
.field.invalid input, .field.invalid select { border-color: var(--card-star); box-shadow: 0 0 0 2px var(--card-star); }
.err { margin: 4px 0 0; min-height: 0; font-size: 13px; color: var(--card-err); }
.err:empty { display: none; }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Team choice: the two Madrid team tiles are the radio buttons. The chosen tile lifts with a ring
   in its team colour and a check badge; once one is chosen, the other fades back. */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; max-width: 380px; padding-top: 4px; }
/* The team question, its tiles and its error are centred in the card. */
.field--team legend { width: 100%; text-align: center; }
.field--team .tiles { margin-inline: auto; }
.field--team .err { text-align: center; }
.tile { --tile-c: var(--ink); position: relative; display: block !important; margin: 0 !important; cursor: pointer; }
.tile--falcons { --tile-c: var(--falcons); }
.tile--bengals { --tile-c: var(--bengals); }
.tile input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.tile img {
  width: 100%; border-radius: 6px;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .25), 0 6px 16px rgba(0, 0, 0, .3);
  transition: transform .25s var(--ease), box-shadow .25s, filter .25s, opacity .25s;
}
.tile:hover img { transform: translateY(-2px); box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .6), 0 10px 22px rgba(0, 0, 0, .35); }
.tile input:focus-visible ~ img { outline: 3px solid var(--gold); outline-offset: 4px; }
.tile input:checked ~ img {
  transform: translateY(-3px) scale(1.03);
  box-shadow: 0 0 0 4px var(--tile-c), 0 0 0 6px #fff, 0 16px 32px rgba(0, 0, 0, .4);
}
.tiles:has(input:checked) .tile input:not(:checked) ~ img { filter: grayscale(.8); opacity: .55; }
.tile::after {
  content: ''; position: absolute; z-index: 2; top: -9px; right: -9px; width: 30px; height: 30px; border-radius: 50%;
  background: var(--tile-c) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 17px no-repeat;
  box-shadow: 0 0 0 3px #fff, 0 3px 10px rgba(0, 0, 0, .3);
  transform: scale(0); transition: transform .3s cubic-bezier(.3, 1.6, .5, 1); pointer-events: none;
}
.tile:has(input:checked)::after { transform: scale(1); }

.field--check { margin: 24px 0 22px; } /* room between the team tiles, the agreement and the button */
.field--check + .field--check { margin-top: -10px; } /* the eligibility line and the rules line sit together */
/* The Terms agreement sits centred under the team tiles, like the question above it. */
.field--check .check { justify-content: center; text-align: center; }
.field--check .err { text-align: center; }
.check {
  display: flex !important; gap: 10px; align-items: flex-start;
  font-weight: 400 !important; font-size: 14px !important; letter-spacing: 0 !important; text-transform: none !important;
  color: var(--on-card); cursor: pointer;
}
.check input { flex: none; width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--red); }
.check a { color: var(--gold); font-weight: 700; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; height: 54px; margin-top: 10px; padding: 0 24px;
  border: 0; border-radius: 999px;
  background: var(--gold); color: var(--ink);
  font-weight: 700; font-size: 15px; letter-spacing: .16em; text-transform: uppercase;
  transition: background .2s, transform .2s var(--ease), box-shadow .2s;
}
.btn:hover { background: var(--gold-deep); transform: translateY(-1px); box-shadow: 0 10px 24px rgba(246, 160, 0, .35); }
/* The form's submit: Madrid red with white text, gold with ink on rollover. */
.btn--red { background: var(--red); color: #fff; }
.btn--red:hover, .btn--red:focus-visible { background: var(--gold); color: var(--ink); box-shadow: 0 10px 24px rgba(246, 160, 0, .35); }
.btn:disabled { opacity: .7; cursor: progress; transform: none; box-shadow: none; }
.btn--ghost { background: transparent; color: inherit; border: 1.5px solid currentColor; }
.btn--ghost:hover { background: rgba(0,0,0,.05); box-shadow: none; }
.btn--sm { width: auto; height: 40px; margin: 0; padding: 0 18px; font-size: 12px; }

.status { margin: 10px 0 0; color: var(--card-err, var(--danger)); font-size: 14px; text-align: center; }
.status:empty { display: none; }

/* reCAPTCHA's floating badge would cover the cookie banner; the line under the form replaces it. */
.grecaptcha-badge { visibility: hidden; }
.recaptcha { margin: 14px 0 0; font-size: 12px; line-height: 1.5; color: rgba(255, 255, 255, .65); text-align: center; }
.recaptcha a { color: inherit; }


.card__partner {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin-top: 24px; padding-top: 20px; border-top: 1px solid rgba(255, 255, 255, .18);
  font-weight: 700; font-size: 12px; line-height: 1.3; letter-spacing: .16em; text-transform: uppercase; color: var(--on-card);
}
.card__partner img { width: 96px; }

/* ---------- Thank-you page ---------- */

/* Same treatment as the hero: the drifting chulapo pattern under a black gradient. */
.thanks {
  position: relative; overflow: hidden; isolation: isolate; background: var(--red);
  min-height: 100svh; display: grid; place-items: center;
  padding: clamp(40px, 8svh, 96px) var(--gutter);
}
.thanks::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 60%; z-index: 0;
  background: linear-gradient(to top, #000, transparent); pointer-events: none;
}
.thanks__inner {
  position: relative; z-index: 1; width: 100%; max-width: 780px;
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
/* A lockup on a red page (thanks, 404): the same dark glow as the splash, so the red SI wordmark
   reads on the red. */
.lockup { position: relative; isolation: isolate; }
.lockup::before {
  content: ''; position: absolute; inset: -18% -14%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(40, 0, 8, .62), rgba(40, 0, 8, .32) 55%, transparent);
}
.thanks__logo { display: block; width: min(calc(100vw - 32px), max(42vw, 360px), 560px, 68svh); filter: drop-shadow(0 20px 40px rgba(0,0,0,.45)); }
.thanks__eyebrow { margin: clamp(16px, 3svh, 32px) 0 10px; color: var(--gold); }
.thanks__title {
  margin: 0; font-family: var(--display); font-weight: 400; line-height: 1;
  font-size: clamp(40px, min(8vw, 11svh), 84px); color: #fff; text-shadow: 0 6px 24px rgba(60, 0, 12, .5); outline: none;
}
.thanks__body { margin: 18px 0 0; max-width: 520px; font-size: clamp(16px, 1.6vw, 19px); line-height: 1.55; text-shadow: 0 2px 12px rgba(0,0,0,.5); }
.thanks__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: clamp(24px, 4svh, 40px); width: 100%; }
.thanks__actions .btn { width: auto; margin: 0; padding: 0 28px; text-decoration: none; }
@media (max-width: 520px) {
  .thanks__actions { flex-direction: column; }
  .thanks__actions .btn { width: 100%; }
}

/* ---------- Footer ---------- */

.foot {
  position: relative; z-index: 1; background: var(--nfl-blue); color: rgba(255, 255, 255, .78);
  padding: clamp(40px, 6vw, 64px) var(--gutter) 28px; font-size: 14px; border-top: 4px solid var(--gold);
}
.foot__inner { max-width: 1160px; margin: 0 auto; }
/* Brand, then three link columns; two columns on tablets, one on phones. */
.foot__grid { display: grid; grid-template-columns: minmax(220px, 1.5fr) repeat(3, minmax(150px, 1fr)); gap: 32px clamp(24px, 4vw, 56px); }
.foot__brand p { margin: 14px 0 0; max-width: 300px; line-height: 1.55; }
.foot__logo { display: inline-block; }
.foot__logo img { width: clamp(130px, 12vw, 160px); height: auto; }
.foot__col h2 {
  margin: 0 0 14px; font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--gold);
}
.foot__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.foot__col li { line-height: 1.45; }
.foot__col a, .foot__col button {
  display: inline-flex; align-items: center; min-height: 32px; padding: 0; border: 0; background: none;
  font: inherit; color: #fff; text-decoration: none; cursor: pointer; transition: color .2s;
}
.foot__col a:hover, .foot__col button:hover { color: var(--gold); }
.foot__bar {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 12px 32px;
  margin-top: clamp(32px, 5vw, 48px); padding-top: 20px; border-top: 1px solid rgba(255, 255, 255, .16);
  font-size: 12px; color: rgba(255, 255, 255, .6);
}
.foot__legal { margin: 0; max-width: 760px; line-height: 1.6; }
.foot__copy { margin: 0; white-space: nowrap; }
@media (max-width: 860px) {
  .foot__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .foot__brand { grid-column: 1 / -1; }
}
@media (max-width: 480px) { .foot__grid { grid-template-columns: 1fr; } }

/* ---------- Cookie banner ---------- */

.cookies {
  position: fixed; z-index: 20; left: 16px; right: 16px; bottom: 16px;
  max-width: 560px; margin: 0 auto;
  display: flex; align-items: center; gap: 16px;
  padding: 16px 18px; border-radius: var(--radius);
  background: var(--ink); color: #fff; box-shadow: 0 20px 50px rgba(0,0,0,.4);
  font-size: 14px;
}
.cookies p { margin: 0; flex: 1; }
.cookies__btns { display: flex; gap: 8px; flex: none; }
.cookies .btn--ghost { color: #fff; }
.cookies .btn--ghost:hover { background: rgba(255,255,255,.1); }

/* ---------- Limit popup · when the entry defences turn someone away ----------
   The hero's red chulapo pattern under a dark wash, a gold frame, the Madrid shield breaking the
   top edge, Talavera headline and the time to the reset on the countdown's navy flaps. */
.limit {
  width: min(440px, calc(100vw - 32px)); max-width: none; max-height: none;
  padding: 0; border: 0; background: none; color: #fff; overflow: visible;
}
.limit::backdrop { background: rgba(10, 20, 50, .72); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.limit[open] { animation: limit-in .55s var(--ease) both; }
.limit[open]::backdrop { animation: limit-fade .3s ease both; }
@keyframes limit-in { from { opacity: 0; transform: translateY(28px) scale(.94); } }
@keyframes limit-fade { from { opacity: 0; } }
.limit__card {
  position: relative; isolation: isolate; margin-top: 70px;
  padding: 84px clamp(22px, 6vw, 40px) 30px; text-align: center;
  border: 3px solid var(--gold); border-radius: 22px;
  background: var(--red-deep) url('../assets/img/chulapo-loop.jpg') center / auto 100% repeat-x;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .55);
}
.limit__card::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: radial-gradient(120% 80% at 50% 0%, rgba(60, 0, 12, .35), rgba(40, 0, 8, .82) 70%);
}
.limit__mark {
  position: absolute; left: 50%; top: -70px; width: 112px; transform: translateX(-50%);
  filter: drop-shadow(0 14px 26px rgba(0, 0, 0, .5));
}
.limit__eyebrow, .limit__label {
  margin: 0; color: var(--gold); font-weight: 700; font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
}
.limit__title {
  margin: 10px 0 0; font-family: var(--display); font-weight: 400; line-height: 1;
  font-size: clamp(42px, 11vw, 60px); text-shadow: 0 4px 18px rgba(0, 0, 0, .45);
}
.limit__body { margin: 14px auto 0; max-width: 340px; font-size: 16px; line-height: 1.5; color: rgba(255, 255, 255, .92); }
.limit__label { margin-top: 24px; font-size: 11px; }
.limit__time {
  display: flex; justify-content: center; align-items: center; gap: 4px; margin-top: 10px;
  font-family: var(--display); font-size: clamp(34px, 9vw, 44px); line-height: 1;
}
/* Each digit on a navy flap, like the countdown's seconds. */
.limit__time b {
  display: grid; place-items: center; width: .8em; height: 1.12em; padding-top: .06em;
  font-weight: 400; border-radius: 5px; color: #fff;
  background: linear-gradient(180deg, #2C5BA0 0 50%, var(--nfl-blue) 50% 100%);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .35), 0 6px 12px rgba(10, 20, 50, .45);
}
.limit__time .limit__colon { width: .35em; font-style: normal; color: var(--gold); text-align: center; }
.limit__ok { margin-top: 26px; background: var(--nfl-blue); color: #fff; }
.limit__ok:hover { background: var(--gold); color: var(--ink); } /* focus keeps navy and white, with the gold ring */
@media (prefers-reduced-motion: reduce) { .limit[open], .limit[open]::backdrop { animation: none; } }

/* ---------- Responsive ---------- */

/* Portrait screens (phones, upright tablets): the hero is --h tall, the helmets either side
   of the centre. The lockup sits on top of the helmets, the highest layer, anchored to the
   bottom centre and sized to the hero's height so it always fits. */
@media (max-aspect-ratio: 1/1), (max-width: 760px) {
  .hero { --h: min(calc(0.9 * 100cqw), 52svh); height: var(--h); }
  /* Full height here too, pushed out so the facemasks stop just clear of the Madrid shield (about
     0.32h wide; the partner line under it runs over the helmets) and the backs of the helmets run well off the screen edges. */
  .hero { --helm-gap: calc(0.48 * var(--h)); }
  /* Half the hero's height wide, as on desktop, but clear of the team lockups in the corners
     (about 120px each side). */
  .hero { --ball-w: min(calc(0.5 * var(--h)), calc(100cqw - 250px)); }
  /* The lockup as big as the height allows (12px to the top), but no wider than 1.1h so the
     helmets still show either side on upright tablets; lifted by 40% of the room left over the
     ball, up to 0.18h. */
  .hero__center {
    z-index: 5; --stack-gap: calc(0.03 * var(--h));
    --logo-w: min(calc(100cqw - 32px), calc(1.1 * var(--h)), calc((var(--h) - 2 * var(--stack-gap) - var(--ball-top) - 24px) / 0.454));
    --lift: max(0px, min(calc(0.4 * (var(--h) - 0.454 * var(--logo-w) - 2 * var(--stack-gap) - var(--ball-top) - 12px)), calc(0.18 * var(--h))));
  }
  /* Tucked into the bottom corners, clear of the centred logos. */
  .hero__team { bottom: 30px; gap: 5px; transform: none; } /* clear of the date pill, which reaches 21px up into the hero */
  .hero__team .hero__wordmark { width: min(20cqw, 80px); }
  .hero__team .hero__team-mark { height: 22px; }
  .hero__team--bengals { left: 12px; }
  .hero__team--falcons { left: auto; right: 12px; }
}
@media (max-width: 520px) {
  .row { grid-template-columns: 1fr; }
  /* Cookie banner: a compact strip, the line of text over two small buttons side by side. */
  .cookies {
    left: 12px; right: 12px; bottom: max(12px, env(safe-area-inset-bottom));
    flex-direction: column; align-items: stretch; gap: 10px;
    padding: 12px 14px; border-radius: 12px; font-size: 13px; line-height: 1.4;
  }
  .cookies__btns > * { flex: 1; height: 34px; font-size: 11px; padding: 0 12px; }
  body { background-attachment: scroll; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}

/* ===========================================================================
   GATE · the splash (app/gate.js)
   The CIN vs ATL chulapo split, its two team patterns drifting against each other. html.gated holds the page behind
   it; data-state runs loading → ready → entering → site. The click sends a striped wipe
   slashing across to the face-off.
=========================================================================== */
.gate { display: none; }
html.gated .gate {
  position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column; isolation: isolate;
  background: #FFBA00; color: var(--ink); overflow: hidden;
  transition: opacity 1.3s ease, visibility 0s 1.3s;
}
/* Nothing scrolls until the click that also unblocks audio. */
html.gated:not([data-state="site"]), html.gated:not([data-state="site"]) body { overflow: hidden; height: 100%; }
html.gated[data-state="site"] .gate { opacity: 0; visibility: hidden; pointer-events: none; }

/* Media: the style guide's Red & Gold chulapo split (Madrid2026_ChulapoPattern_Red_&_Gold), rebuilt
   so it moves. The red pattern fills the screen; the gold sits over it, masked to the artwork's
   stepped diagonal, which stays put. The two drift diagonally in opposite directions, one tile
   (four repeats) per 24 s loop, so they wrap without a seam; GPU transforms only. Everything is
   drawn at the size the 8000x4500 artwork would be at cover: one tile is 1425/8000 of its width. */
.gate__media {
  --pat: calc(max(100vw, 177.78svh) * .178125);
  position: absolute; inset: 0; z-index: -2; overflow: hidden; background: var(--red);
  animation: gate-in 2.8s ease both;
}
@keyframes gate-in { from { opacity: 0; transform: scale(1.08); } to { opacity: 1; transform: none; } }
.gate__pat-gold {
  position: absolute; inset: 0;
  -webkit-mask: url('../assets/gate/pattern-gold-mask.png') 50% 50% / cover no-repeat;
  mask: url('../assets/gate/pattern-gold-mask.png') 50% 50% / cover no-repeat;
}
.gate__pat { position: absolute; inset: calc(-1 * var(--pat)); background: 0 0 / var(--pat) repeat; will-change: transform; }
.gate__pat--red { background-image: url('../assets/gate/pattern-red.jpg'); animation: pat-red 24s linear infinite; }
.gate__pat--gold { background-image: url('../assets/gate/pattern-gold.jpg'); animation: pat-gold 24s linear infinite; }
@keyframes pat-red { to { transform: translate(var(--pat), calc(-1 * var(--pat))); } }
@keyframes pat-gold { to { transform: translate(calc(-1 * var(--pat)), var(--pat)); } }
html[data-state="site"] .gate__pat { animation-play-state: paused; }

/* Shade: black falling in from the left and right edges and a warm deepening all round, so the
   pattern reads as depth behind the centred stack. */
.gate__shade {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, .6), rgba(0, 0, 0, .22) 18%, transparent 36%, transparent 64%, rgba(0, 0, 0, .22) 82%, rgba(0, 0, 0, .6)),
    radial-gradient(ellipse 120% 100% at 50% 40%, transparent 55%, rgba(156, 25, 47, .22) 100%);
  transition: opacity .8s ease;
}
html[data-state="entering"] .gate__shade { opacity: 0; }

/* As the wipe comes in, the pattern punches forward into it. */
.gate__media { transition: scale .6s cubic-bezier(.6, 0, .9, .4); }
html.wipe-in .gate__media { scale: 1.14; }
/* The page switches under the wipe's cover, so the gate goes at once instead of fading. */
html.gated.wipe-in .gate, html.gated.wipe-out .gate { transition: none; }
/* Coming back without a wipe (reduced motion), the gate is visible at once and fades up. */
html.gated:not([data-state="site"]):not(.wipe-in):not(.wipe-out) .gate { transition: opacity .9s ease, visibility 0s; }

/* ---------- THE WIPE · splash to face-off ----------
   Three full-screen panels, skewed into a slash: gold leads, red follows, and the chulapo panel
   with the Madrid shield lands last and covers everything (wipe-in, 0.45 s each, 70 ms apart).
   gate.js swaps the page underneath with a bass hit, holds a beat, then the panels leave to the
   right in reverse order (wipe-out), so the face-off is uncovered gold edge last.
   Each panel is two screens wide and centred on the viewport, so the skew never opens a gap. */
.wipe { display: none; }
html.wipe-in .wipe, html.wipe-out .wipe, html.wipe-cover .wipe {
  display: block; position: fixed; inset: 0; z-index: 60; overflow: hidden; pointer-events: none;
}
.wipe__band {
  position: absolute; top: -10%; bottom: -10%; left: -50vw; width: 200vw;
  transform: skewX(-16deg); translate: -185vw 0;
  display: grid; place-items: center; will-change: translate;
}
.wipe__band--gold { background: var(--gold); --in: 0ms; --out: 140ms; }
.wipe__band--red { background: var(--red); --in: 70ms; --out: 70ms; }
.wipe__band--chulapo {
  --in: 140ms; --out: 0ms;
  background: var(--red-deep) url('../assets/img/chulapo-loop.jpg') center / auto 100% repeat;
  border-inline: 10px solid var(--gold);
  box-shadow: 0 0 80px 20px rgba(246, 190, 0, .45);
}
/* The dark glow from the splash, behind the lockup in the same grid cell, so the red SI wordmark
   reads on the red band. */
.wipe__band--chulapo::before {
  content: ''; grid-area: 1 / 1; width: calc(1.3 * min(calc(100vw - 48px), 760px, 90svh)); aspect-ratio: 2;
  transform: skewX(16deg);
  background: radial-gradient(closest-side, rgba(40, 0, 8, .62), rgba(40, 0, 8, .32) 55%, transparent);
}
.wipe__band img {
  grid-area: 1 / 1; width: min(calc(100vw - 48px), 760px, 90svh); height: auto;
  transform: skewX(16deg); /* stands upright on the slant */
  filter: drop-shadow(0 20px 40px rgba(0, 0, 0, .5));
}
/* A page that opens covered (thanks.html after the form) starts with every panel in place. */
html.wipe-cover .wipe__band { translate: 0 0; }
html.wipe-in .wipe__band { animation: wipe-in .45s cubic-bezier(.75, 0, .25, 1) var(--in) both; }
html.wipe-out .wipe__band { translate: 0 0; animation: wipe-out .55s cubic-bezier(.7, 0, .3, 1) var(--out) both; }
html.wipe-in .wipe__band img { animation: wipe-logo .7s cubic-bezier(.2, .9, .3, 1.3) .3s both; }
html.wipe-out .wipe__band img { animation: wipe-logo-out .4s ease-in both; }
/* The hit: the covered screen jolts as the bass lands. */
html.wipe-hit .wipe { animation: wipe-shake .32s linear both; }
@keyframes wipe-in { from { translate: -185vw 0; } to { translate: 0 0; } }
@keyframes wipe-out { from { translate: 0 0; } to { translate: 185vw 0; } }
@keyframes wipe-logo { from { opacity: 0; scale: 1.6; } to { opacity: 1; scale: 1; } }
@keyframes wipe-logo-out { to { opacity: 0; scale: .85; } }
@keyframes wipe-shake {
  0%, 100% { transform: none; } 20% { transform: translate(-9px, 5px); } 40% { transform: translate(8px, -6px); }
  60% { transform: translate(-6px, -3px); } 80% { transform: translate(4px, 3px); }
}

/* Core: the matchup, the Madrid shield, date and venue, then the loader line that becomes the
   button. Sized by the screen's height so it always fits above the fold. */
.gate__core {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: max(28px, env(safe-area-inset-top)) var(--gutter) 12px;
  transition: opacity .6s ease, transform 1.1s cubic-bezier(.5, 0, .2, 1), filter .9s ease;
}
html[data-state="entering"] .gate__core { opacity: 0; transform: scale(1.35); filter: blur(10px); }
.gate__core > * { animation: gate-rise 1.3s var(--ease) both; }
.gate__when { animation-delay: .25s !important; }
.gate__logo { animation-delay: .45s !important; }
.gate__match { animation-delay: .75s !important; }
.gate__cta { animation-delay: .95s !important; }
@keyframes gate-rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }

/* The matchup sits under the date, above the button. */
.gate__match {
  margin: clamp(14px, 2.6svh, 26px) 0 0; display: flex; align-items: center; justify-content: center;
  gap: clamp(8px, 1.2vw, 16px); font-weight: 700; text-transform: uppercase;
  font-size: clamp(13px, min(1.5vw, 2.1svh), 19px); letter-spacing: .24em;
}
.gate__match img { height: clamp(36px, 6.4svh, 64px); width: auto; filter: drop-shadow(0 2px 8px rgba(60, 0, 12, .45)); }
/* The wordmarks print white, as drawn; a soft shadow keeps them clear of the gold half. */
.gate__match .gate__wordmark { filter: drop-shadow(0 2px 10px rgba(60, 0, 12, .6)); }
/* The team wordmarks (stacked, white) stand as tall as the team marks either side of them. */
.gate__match .gate__wordmark { height: clamp(40px, 7svh, 70px); }
.gate__vs {
  font-family: var(--display); font-weight: 400; text-transform: none; letter-spacing: 0;
  font-size: 1.9em; line-height: 1; color: var(--red); margin: 0 .1em; transform: translateY(-.04em);
}
.gate__logo { margin: 0; display: flex; justify-content: center; }
/* The lockup (SI Tickets × Madrid Game, partner line under), by width: wide, so the screen's width
   and height both cap it (720/1586 as tall as it is wide). */
.gate__logo img {
  width: min(calc(100vw - 32px), max(52vw, 360px), 820px, 80svh); height: auto;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .35)) drop-shadow(0 24px 44px rgba(0, 0, 0, .5));
}
/* A glint crosses the lockup every few seconds. */
.gate__logo { position: relative; cursor: pointer; isolation: isolate; }
/* Soft dark glow behind the lockup, so the red SI wordmark reads on the red half. */
.gate__logo::before {
  content: ''; position: absolute; inset: -18% -14%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(40, 0, 8, .62), rgba(40, 0, 8, .32) 55%, transparent);
}
/* The shield enters too (the whole gate does, see gate.js); it lifts on hover to say so. */
.gate__logo img { transition: transform .35s var(--ease), filter .35s; }
@media (hover: hover) {
  html:is([data-state="ready"], [data-state="loading"]) .gate__logo:hover img { transform: scale(1.05); filter: drop-shadow(0 8px 14px rgba(0, 0, 0, .4)) drop-shadow(0 32px 56px rgba(0, 0, 0, .55)); }
}
.gate__logo::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  -webkit-mask: url('../assets/logos/si-madrid-lockup.png') center / contain no-repeat;
  mask: url('../assets/logos/si-madrid-lockup.png') center / contain no-repeat;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 247, 214, .7) 50%, transparent 62%) -160% 0 / 250% 100% no-repeat;
  mix-blend-mode: overlay; animation: gate-glint 5.5s ease-in-out 2.4s infinite;
}
@keyframes gate-glint { 0% { background-position: -160% 0; } 35%, 100% { background-position: 260% 0; } }
/* The date leads the stack, above the shield. */
.gate__when {
  margin: 0 0 clamp(12px, 2.4svh, 24px); display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 6px 14px; font-weight: 700; font-size: clamp(12px, min(1.3vw, 1.9svh), 16px); letter-spacing: .22em;
  text-transform: uppercase; color: #fff; text-shadow: 0 2px 12px rgba(60, 0, 12, .6);
}

/* The loader line fills, then gives way to the button in the same spot. */
.gate__cta { position: relative; margin-top: clamp(18px, 4svh, 40px); min-height: 60px; display: grid; place-items: center; }
.gate__bar {
  position: absolute; left: 50%; top: 50%; width: 220px; max-width: 60vw; height: 2px; transform: translateX(-50%);
  background: var(--nfl-blue); overflow: hidden; transition: opacity .5s ease, width .7s var(--ease);
}
.gate__bar i { display: block; height: 100%; background: var(--red); transform-origin: left; transform: scaleX(0); transition: transform .4s linear; }
html:not([data-state="loading"]) .gate__bar { opacity: 0; width: 300px; }
.gate__enter {
  position: relative; display: inline-flex; align-items: center; gap: 14px; min-height: 60px; padding: 0 34px 0 38px;
  border: 0; border-radius: 999px; background: var(--nfl-blue); color: #fff;
  font-family: var(--display); font-size: clamp(24px, 3.4svh, 30px); line-height: 1; letter-spacing: .02em;
  box-shadow: 0 14px 40px rgba(10, 20, 50, .4), inset 0 -3px 0 rgba(0, 0, 0, .2);
  opacity: 0; visibility: hidden; transform: translateY(10px) scale(.96);
  transition: opacity .8s ease .15s, transform .9s var(--ease) .15s, visibility 0s .15s, background .2s, box-shadow .2s;
}
html[data-state="ready"] .gate__enter { opacity: 1; visibility: visible; transform: none; }
.gate__enter svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; transition: transform .3s var(--ease); }
.gate__label { padding-top: .08em; }
.gate__enter::before, .gate__enter::after {
  content: ''; position: absolute; inset: -9px; border-radius: inherit; border: 1.5px solid rgba(255, 255, 255, .7);
  opacity: 0; pointer-events: none; animation: gate-ring 2.6s var(--ease) 1.2s infinite;
}
.gate__enter::after { animation-delay: 2.5s; }
@keyframes gate-ring { 0% { transform: scale(.94); opacity: .9; } 75% { transform: scale(1.14, 1.32); opacity: 0; } 100% { opacity: 0; } }
@media (hover: hover) {
  .gate__enter:hover { background: var(--red); box-shadow: 0 18px 50px rgba(156, 25, 47, .45); }
  .gate__enter:hover svg { transform: translateX(4px); }
}
.gate__enter:active { transform: scale(.97); }

/* Phones: a tighter matchup line. */
@media (max-width: 520px) {
  .gate__match { gap: 8px; }
  .gate__match .gate__wordmark { height: 32px; }
  .gate__match img:not(.gate__wordmark) { height: 32px; }
  .gate__when { letter-spacing: .16em; }
}

/* ---------- The face-off arrives: helmets slide in from the wings, the shield drops in ----------
   The helmets are mirrored (scale: -1 1), which flips these translations: duel-in-right brings the
   Bengals in from the left wing, duel-in-left the Falcons from the right. */
html.revealed .duel__helmet--bengals { animation: duel-in-right 1.6s cubic-bezier(.2, .8, .2, 1) both; }
html.revealed .duel__helmet--falcons { animation: duel-in-left 1.6s cubic-bezier(.2, .8, .2, 1) both; }
html.revealed .hero__center > *, html.revealed .hero > .hero__ball { animation: duel-drop 1.2s cubic-bezier(.2, .8, .2, 1) .35s both; }
@keyframes duel-in-left { from { transform: translateX(-60%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes duel-in-right { from { transform: translateX(60%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes duel-drop { from { transform: translateY(-30px) scale(1.15); opacity: 0; } to { transform: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .gate__media, .gate__pat, .gate__core > *, .gate__logo::after,
  .gate__enter::before, .gate__enter::after, html.revealed .duel__helmet, html.revealed .hero__center > *, html.revealed .hero > .hero__ball,
  html.revealed .hero__team { animation: none !important; }
}
