/* ============================================================
   NFL Stadium Quiz — own stylesheet, phase 1.
   Palette copied from shared/venue.css (navy #141B43, blue #0089F7,
   sky #5AC8FA) but NOT imported: that sheet models a 100dvh hero over a
   scrolling guide, and this page is a no-scroll app shell. shared/ is
   not touched by the quiz, by design.

   TWO HARD RULES BAKED IN HERE:
   1. The viewer is CENTRED and symmetric. .pano-wrap has equal gutters on
      both sides at every breakpoint and .pano is `inset: 0` inside it.
      A one-sided inset is never an option, not even as a patch.
   2. Nothing ever overlaps the panorama except our own loading state and
      the "drag to look around" tip, both of which are ours and both of
      which get out of the way. Ads (phase 2) go BETWEEN rounds and on the
      score screen — never around the panorama.
   ============================================================ */
:root {
  --accent: #0089F7;
  --sky: #5AC8FA;
  --bg: #0D1230;
  --panel: #10173A;
  --card: #161D45;
  --line: #262F62;
  --line-soft: #1B2148;
  --ink: #F2F4FB;
  --bright: #FFFFFF;
  --muted: #A8B0D4;
  --dim: #707894;
  --good: #34D399;
  --warn: #FBBF24;
  --bad: #F87171;
  --radius: 16px;
  --shell: 1180px;
  --font-display: "Barlow Condensed", "Arial Narrow", sans-serif;
  --font-ui: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; background: var(--bg); color: var(--ink); }
body {
  font-family: var(--font-ui);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;                 /* app shell: the page itself never scrolls */
  overscroll-behavior: none;        /* no pull-to-refresh while dragging the map */
}
a { color: var(--sky); }
:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
.hidden { display: none !important; }

/* El shell CEDE la banda que ocupen los anchors de Auto ads en vez de dejar
   que pinten encima. --anchor-top-h / --anchor-bot-h las publica quiz.js
   midiendo los overlays que Google llegue a mostrar, y valen 0px cuando no hay
   ninguno, asi que esto es un no-op en una pagina sin anuncios. Es la misma
   idea que en shared/venue.css, y aqui es MAS necesaria: la pagina no
   scrollea, o sea que lo que tape un anchor no se puede recuperar bajando —
   y lo primero que tapa el de abajo es el boton Guess. */
.app {
  height: calc(100dvh - var(--anchor-top-h, 0px) - var(--anchor-bot-h, 0px));
  margin-top: var(--anchor-top-h, 0px);
  display: flex;
  flex-direction: column;
  padding-bottom: env(safe-area-inset-bottom);
  transition: height 0.3s, margin-top 0.3s;
}

/* ---------- top bar ---------- */
.bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--panel);
}
.bar-right { margin-left: auto; display: flex; gap: 6px; align-items: center; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 7px 11px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(13, 18, 48, 0.72);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.chip-link:hover { border-color: var(--sky); color: var(--bright); }
.brand-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(0, 137, 247, 0.22);
}
.bar-stat {
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.bar-stat b { color: var(--bright); font-size: 1.1rem; }
@media (max-width: 420px) { .chip-suffix { display: none; } }

/* ---------- screens ---------- */
.screen { flex: 1; min-height: 0; display: none; }
.screen.is-on { display: flex; }
#screen-start.is-on, #screen-results.is-on { overflow-y: auto; }

/* ---------- start + results (shared "pitch" column) ---------- */
.pitch {
  width: 100%;
  max-width: 640px;
  margin: auto;
  padding: 24px 20px 32px;
  text-align: center;
}
.kicker {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--sky); margin-bottom: 10px;
}
.pitch h1 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 8vw, 3.2rem);
  font-weight: 900;
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin-bottom: 14px;
}
.accent { color: var(--sky); }
.lede { color: var(--muted); font-size: 0.94rem; margin-bottom: 18px; }
.how {
  list-style: none;
  text-align: left;
  display: grid;
  gap: 10px;
  margin: 0 auto 22px;
  max-width: 460px;
}
.how li {
  position: relative;
  padding: 11px 14px 11px 44px;
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  background: var(--card);
  font-size: 0.86rem;
  color: var(--muted);
  counter-increment: how;
}
.how { counter-reset: how; }
.how li::before {
  content: counter(how);
  position: absolute; left: 12px; top: 11px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #fff;
  font-family: var(--font-display); font-weight: 800; font-size: 0.85rem;
  display: grid; place-items: center;
}
.how b { color: var(--ink); }
.fineprint { margin-top: 16px; font-size: 0.74rem; color: var(--dim); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 12px 22px;
  border: 0;
  border-radius: 12px;
  font-family: var(--font-ui);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, transform 0.08s, opacity 0.15s;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: #0a97ff; }
.btn-primary:disabled { background: #1B2148; color: var(--dim); cursor: default; }
.btn-ghost {
  background: transparent;
  color: var(--sky);
  border: 1px solid var(--line);
}
.btn-ghost:hover { border-color: var(--sky); }
.btn-xl { min-height: 56px; padding: 14px 40px; font-size: 1rem; width: 100%; max-width: 320px; }

/* ============================================================
   PLAY SCREEN
   Column on every breakpoint: panorama on top, map under it. Both are
   centred in the same shell, which is what keeps rule 1 true without a
   special case per viewport — and it is also the layout that records
   cleanly for video, which is the point of the run format.
   ============================================================ */
#screen-play { flex-direction: column; position: relative; }

.pano-wrap {
  flex: none;
  height: 40dvh;
  min-height: 200px;
  padding: 8px;                     /* equal gutters: the symmetry rule */
  display: flex;
  transition: height 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
/* On reveal the view yields height to the map. The reveal is the map's
   moment — the answer marker and the miss line have to be visible, and on a
   phone the sheet plus a 40dvh panorama left a 67px strip for them (measured
   at 500x723 in the first playable build, where the marker landed behind the
   card). The view stays on screen as a strip, still centred and symmetric. */
#screen-play.is-reveal .pano-wrap { height: 22dvh; min-height: 120px; }
@media (prefers-reduced-motion: reduce) { .pano-wrap { transition: none; } }
.pano {
  position: relative;
  flex: 1;
  min-width: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: #05070f;
  border: 1px solid var(--line-soft);
}
.pano-canvas { position: absolute; inset: 0; }
.pano-canvas canvas { display: block; width: 100% !important; height: 100% !important; }

/* our own loading state — DVM's is turned off in JS (show_loading_screen) */
.pano-loader {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: radial-gradient(120% 120% at 50% 40%, #131A44 0%, #070A1C 100%);
  transition: opacity 0.26s;
  z-index: 3;
}
.pano-loader.is-off { opacity: 0; pointer-events: none; }
.loader-card { text-align: center; padding: 0 22px; max-width: 340px; }
.loader-chip {
  display: inline-block;
  font-size: 0.64rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--sky);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 12px; margin-bottom: 12px;
}
.loader-bar {
  height: 4px; border-radius: 4px; background: var(--line-soft);
  overflow: hidden; margin-bottom: 10px;
}
.loader-bar i {
  display: block; height: 100%; width: 40%; border-radius: 4px;
  background: linear-gradient(90deg, var(--accent), var(--sky));
  animation: slide 1.15s ease-in-out infinite;
}
@keyframes slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(250%); } }
.loader-label { font-size: 0.8rem; color: var(--muted); }
@media (prefers-reduced-motion: reduce) { .loader-bar i { animation: none; width: 100%; } }

.pano-tip {
  position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%);
  z-index: 2;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
  background: rgba(7, 10, 28, 0.74);
  border: 1px solid var(--line-soft);
  padding: 6px 12px; border-radius: 999px;
  pointer-events: none;
  transition: opacity 0.4s;
  white-space: nowrap;
}
.pano-tip.is-off { opacity: 0; }

/* ---------- map ---------- */
.map-wrap {
  flex: 1;
  min-height: 0;
  position: relative;
  padding: 0 8px 4px;
  display: flex;
}
.map {
  flex: 1;
  min-width: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;               /* we own pan and pinch */
  cursor: crosshair;
  -webkit-tap-highlight-color: transparent;
}
.map-outline { fill: #1A2250; stroke: #3A468F; stroke-width: 1.2; stroke-opacity: 0.55; }
/* El trazo interior del mapa: fronteras de estado en la NFL, rios en Gran
   Bretana. Un solo <path> para las dos cosas, porque hacen el mismo trabajo —
   darle estructura a una silueta que si no es una mancha. */
.map-borders { fill: none; stroke: #2E3873; stroke-width: 0.8; }

/* ---------- insets ----------
   A magnified window onto a patch of the plane that the map cannot resolve at
   its own scale. It is NOT decoration and NOT a reveal-only courtesy: the pin
   can be dropped inside it. Six Premier League grounds live inside 25km of
   Trafalgar Square and two of them are 1.7 real pixels apart on the main map;
   at the inset's scale the same pair is 12px. A league with nothing to
   magnify declares no insets and nothing here is ever rendered.

   It hangs OUTSIDE #map-g on purpose, so it neither pans nor zooms: a
   magnifier that moves with the thing it magnifies is just the map again. */
.inset-bg    { fill: #10173A; }
.inset-land  { fill: #1A2250; stroke: #3A468F; stroke-width: 0.18; stroke-opacity: 0.55; }
/* Mas visible que en el mapa grande, y a proposito: dentro del inset el trazo
   NO es contexto, es la unica referencia que hay. El meandro de Chelsea-Fulham
   del Tamesis es lo que separa Stamford Bridge y Craven Cottage de los del
   norte, y sin el la ventana magnificada es un rectangulo liso. */
.inset-lines { fill: none; stroke: #5566A8; stroke-width: 0.24; }
.inset-frame { fill: none; stroke: #3A468F; stroke-width: 1.4; stroke-opacity: 0.9; }
.inset-label {
  fill: var(--muted); font-family: var(--font-display); font-weight: 800;
  font-size: 15px; letter-spacing: 0.04em; text-transform: uppercase;
}
.inset-zoom { fill: var(--sky); font-family: var(--font-display); font-weight: 800; font-size: 15px; }
/* the footprint of the window, drawn on the map itself so the panel is
   anchored to a real place instead of floating next to one */
.inset-locator {
  fill: none; stroke: var(--sky); stroke-width: 1.4; stroke-opacity: 0.85;
  vector-effect: non-scaling-stroke;
}

.pin-guess {
  fill: none; stroke: var(--warn); stroke-width: 2.4;
  vector-effect: non-scaling-stroke;
}
.pin-guess-dot { fill: var(--warn); }
.pin-real { fill: var(--good); stroke: #04120C; stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.pin-real-halo { fill: none; stroke: var(--good); stroke-width: 2; stroke-opacity: 0.45; vector-effect: non-scaling-stroke; }
.miss-line {
  stroke: var(--bad); stroke-width: 2; stroke-dasharray: 6 5;
  vector-effect: non-scaling-stroke; stroke-linecap: round;
}
.pin-label {
  fill: var(--bright);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 15px;
  paint-order: stroke;
  stroke: #05070f;
  stroke-width: 4px;
  stroke-linejoin: round;
}

.map-hint {
  position: absolute; left: 50%; top: 6px; transform: translateX(-50%);
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
  background: rgba(7, 10, 28, 0.7);
  border: 1px solid var(--line-soft);
  padding: 5px 12px; border-radius: 999px;
  pointer-events: none; transition: opacity 0.3s;
  white-space: nowrap;
}
.map-hint.is-off { opacity: 0; }
.map-reset {
  position: absolute; right: 12px; top: 6px;
  min-height: 32px; padding: 5px 12px;
  font-size: 0.64rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted); background: rgba(7, 10, 28, 0.8);
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
}
.map-reset:hover { color: var(--bright); border-color: var(--sky); }

/* ---------- action bar ---------- */
.actions {
  flex: none;
  padding: 8px 12px 12px;
  display: flex;
  justify-content: center;
}
.actions .btn { width: 100%; max-width: 420px; }

/* ============================================================
   REVEAL SHEET
   A bottom sheet over the MAP half only, never over the panorama: the
   answer is about the map, and the view stays open behind it so the
   player can go back and see what gave it away.
   ============================================================ */
.sheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 20;
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
  transform: translateY(110%);
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
}
.sheet.is-on { transform: translateY(0); pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { .sheet { transition: none; } }
.sheet-card {
  max-width: 520px;
  margin: 0 auto;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 -18px 50px rgba(0, 0, 0, 0.5);
  padding: 14px 16px 16px;
  text-align: center;
}
.rv-verdict { font-size: 0.8rem; color: var(--muted); }
.rv-verdict b { color: var(--bad); font-size: 1.05rem; }
.rv-verdict.is-close b { color: var(--good); }
.rv-stadium {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 6vw, 2rem);
  font-weight: 900;
  line-height: 1.05;
  text-transform: uppercase;
  margin: 2px 0 2px;
}
.rv-meta { font-size: 0.8rem; color: var(--muted); }
.rv-points {
  font-family: var(--font-display);
  margin: 8px 0 12px;
  letter-spacing: 0.04em;
}
.rv-points b { font-size: 1.9rem; font-weight: 900; color: var(--sky); }
.rv-points span { font-size: 0.72rem; text-transform: uppercase; color: var(--muted); letter-spacing: 0.1em; }
.rv-cta { width: 100%; margin-bottom: 8px; font-size: 0.8rem; }
#next-btn { width: 100%; }

/* ---------- scorecard (results) ---------- */
.total { font-family: var(--font-display); line-height: 1; margin-bottom: 6px; }
.total b { font-size: clamp(3.4rem, 16vw, 5.5rem); font-weight: 900; color: var(--sky); }
.total span { font-size: 1.1rem; color: var(--muted); margin-left: 6px; }
.total-line { color: var(--muted); font-size: 0.92rem; margin-bottom: 18px; }
.scorecard { list-style: none; display: grid; gap: 6px; margin-bottom: 22px; text-align: left; }
.scorecard li {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  gap: 10px;
  align-items: baseline;
  padding: 9px 12px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--card);
  font-size: 0.84rem;
}
.sc-n { font-family: var(--font-display); font-weight: 800; color: var(--dim); }
.sc-name { color: var(--ink); font-weight: 600; }
.sc-name small { display: block; font-weight: 400; color: var(--dim); font-size: 0.74rem; }
.sc-pts { font-family: var(--font-display); font-weight: 800; font-size: 1.05rem; color: var(--sky); }

/* ============================================================
   ANUNCIOS
   Dos colocaciones, las dos etiquetadas y las dos FUERA del camino:
   ninguna toca la panoramica, el mapa ni la tarjeta del reveal.
   ============================================================ */
.ad-label {
  display: block;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 6px;
}

/* Unidad del marcador final, en flujo y por debajo de "Play again". Sin alto
   reservado: si no se rellena, colapsa y la pantalla queda como si no
   existiera. */
.quiz-ad {
  margin: 18px auto 0;
  width: 336px;
  max-width: 100%;
  min-height: 0;              /* sin relleno, colapsa: nada de huecos */
}
.quiz-ad:empty { display: none; }

/* ---------- intersticial entre rondas ----------
   Cubre la ventana entera mientras la siguiente panoramica carga. Se retira
   sola cuando la vista esta en pantalla; el boton de salida esta SIEMPRE
   disponible y lejos del anuncio, para que un toque impaciente no caiga en la
   creatividad. */
.ad-gate {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(5, 7, 15, 0.94);
  animation: gate-in 0.18s ease-out;
}
.ad-gate[hidden] { display: none; }
@keyframes gate-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ad-gate { animation: none; } }

.ad-gate-card {
  width: 100%;
  max-width: 360px;
  text-align: center;
}
.ad-gate-chip {
  display: inline-block;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sky);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 12px;
  margin-bottom: 16px;
}
.ad-gate-unit {
  min-height: 280px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 10px;
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  background: var(--card);
}
/* 28px de aire entre la creatividad y el boton de salir. Un intersticial con
   el "skip" pegado al anuncio es un generador de clics accidentales, y un clic
   accidental no vale nada y sí cuesta. */
.ad-gate-skip {
  margin-top: 28px;
  width: 100%;
  max-width: 200px;
}

/* ---------- modal (load error) ---------- */
.modal {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  background: rgba(5, 7, 15, 0.74);
  padding: 20px;
}
.modal[hidden] { display: none; }
.modal-card {
  max-width: 400px; text-align: center;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px;
}
.modal-card h3 {
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 900;
  text-transform: uppercase; margin-bottom: 8px;
}
.modal-card p { color: var(--muted); font-size: 0.86rem; margin-bottom: 16px; }

/* ============================================================
   Wider viewports. The shell is centred with a max width, so the gutters
   grow evenly on both sides and the panorama stays symmetric. The
   panorama gets more height because on a landscape screen the map needs
   less: at 960x600 it letterboxes inside a wide box anyway.
   ============================================================ */
@media (min-width: 760px) {
  #screen-play { max-width: var(--shell); width: 100%; margin: 0 auto; }
  .pano-wrap { height: 52dvh; padding: 10px 10px 6px; }
  #screen-play.is-reveal .pano-wrap { height: 34dvh; }
  .map-wrap { padding: 0 10px 4px; }
  .actions { padding: 6px 10px 12px; }
  .sheet { padding: 10px 10px 14px; }
  .pitch { max-width: 680px; }
}
/* Short landscape (phone turned sideways, and the case that matters for
   recording): the map cannot afford 60% of a 380px-tall viewport, so the
   two halves go side by side — each with its own equal gutters. */
@media (max-height: 560px) and (min-width: 700px) {
  /* `.is-on` NO es decoracion: sin el, este selector de ID (1-0-0) le gana a
     `.screen { display:none }` (0-1-0) y la pantalla de juego se pinta SIEMPRE,
     tambien debajo de la portada, empujando la explicacion de como se juega
     (medido en produccion el 30 ago: 435px de alto sin `is-on`). Con `is-on`
     el selector es 1-1-0 y sigue ganando a `.screen.is-on` (0-2-0), asi que
     la rejilla de dos columnas se conserva al jugar. */
  #screen-play.is-on {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr auto;
    column-gap: 0;
  }
  .pano-wrap { height: auto; grid-row: 1 / 3; padding: 8px 4px 8px 8px; }
  #screen-play.is-reveal .pano-wrap { height: auto; }
  .map-wrap { grid-row: 1; padding: 8px 8px 0 4px; }
  .actions { grid-column: 2; grid-row: 2; padding: 6px 8px 10px 4px; }
  .sheet { left: 50%; }
}

/* ============================================================
   ESCRITORIO: LA PANO A LA IZQUIERDA, EL MAPA A LA DERECHA
   ------------------------------------------------------------
   Por que cambia (medido el 2026-08-28 a 1600x823, no a ojo):

   La columna apilada le daba al mapa una caja de 1160x275, pero el mapa es
   un viewBox de 960x600 con preserveAspectRatio="meet": dentro de esa caja
   se dibuja a 440x275 y deja 360px de vacio a CADA lado. El 62 % del ancho
   que se le reservaba no lo usaba nadie, y el boton Guess quedaba aplastado
   contra el borde inferior. El mapa es el control de la partida y era lo mas
   pequeno de la pantalla.

   El split lo arregla porque las dos piezas dejan de competir por el ALTO y
   pasan a repartirse el ANCHO, que es lo que sobra en un escritorio:

       apilado   pano 1160x412 (478.000 px2)   mapa 440x275 (121.000 px2)
       split     pano  818x521 (426.000 px2)   mapa 718x449 (322.000 px2)

   El mapa se hace 2,7 veces mas grande. La pano pierde un 11 % de area y
   gana proporcion: de 2,8:1 (una rendija) a 1,6:1, que es donde caben el
   techo y el campo en el mismo encuadre. Para adivinar un estadio eso vale
   mas que los pixeles.

   LAS DOS COLUMNAS SON IGUALES, y el reparto NO es libre de consecuencias.
   El mapa clava su proporcion con `aspect-ratio`, asi que con cualquier
   reparto la celda que recibe es exactamente la que dibuja: letterbox cero
   siempre. Lo que decide el reparto es OTRA cosa — cuanto mapa hay y que
   forma tiene la pano, que es un intercambio directo:

       columnas    mapa a 1856px      pano
       1,15 : 1    804x503 (404 kpx)  925x561, 1,65:1
       1    : 1    865x540 (467 kpx)  865x598, 1,45:1   <- este

   Se eligio el 1:1 porque la queja era el TAMANO DEL MAPA: da un 15 % mas de
   mapa y la pano sigue siendo apaisada de sobra (1,45:1 frente al 2,8:1 de
   la columna apilada). Dos paneles iguales, ademas, se leen como una sola
   pieza en vez de como un principal y un accesorio.

   La rejilla se centra en vertical y el ancho lo limita el ALTO disponible
   (--play-h), no al reves: en una ventana baja el bloque encoge entero en
   vez de recortar el mapa por abajo. Es la misma idea que --anchor-*-h, que
   sigue entrando en la cuenta.

   MOVIL NO SE TOCA: `.play-grid` es `display: contents` por debajo de este
   breakpoint, o sea que no genera caja y el DOM se comporta exactamente
   igual que antes de existir. Vertical, la pano arriba y el mapa debajo.
   ============================================================ */
.play-grid { display: contents; }

@media (min-width: 1024px) and (min-height: 561px) {
  /* `.is-on` por lo mismo que arriba: este `display: flex` de ID se comia el
     `display: none` de `.screen` y la pantalla de juego salia en la portada. */
  #screen-play.is-on {
    max-width: none;
    width: 100%;
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .play-grid {
    /* El reparto ES DE LA LIGA, no del motor: --cols, --split, --wcap y
       --map-ar los publica quiz.js desde `layout` del banco (ver applyLayout).
       Los valores por defecto de abajo son los de la NFL, asi que un banco que
       no declare `layout` se comporta exactamente como antes de compartir el
       motor. Y NO son transferibles: con un mapa vertical (Gran Bretana) el
       1:1 de la NFL da una pano VERTICAL, que es peor que la columna apilada
       que el split vino a sustituir. */
    --col-gap: 16px;
    --row-gap: 10px;
    /* alto libre = ventana - anchors de Google - barra (50) - fila de accion
       y su hueco (72). De ahi sale el tope de ancho: con columnas iguales el
       alto del bloque es 0,3125 x (ancho - hueco), o sea 1 / 0,3125 = 3,2. */
    --play-h: calc(100dvh - var(--anchor-top-h, 0px) - var(--anchor-bot-h, 0px) - 122px);

    position: relative;
    display: grid;
    /* recorta el sheet contra el borde del bloque: sin esto, `translateY(110%)`
       lo esconde por debajo de la REJILLA pero no de la VENTANA, y asomaban
       111px de la tarjeta en el aire de abajo (medido a 1856x873). Ahora el
       sheet entra y sale del panel, que ademas es de donde tiene que salir. */
    overflow: hidden;
    width: min(1840px, 94vw, calc(var(--col-gap) + var(--play-h) * var(--wcap, 3.2)));
    grid-template-columns: var(--cols, 1fr 1fr);
    grid-template-rows: auto auto;
    column-gap: var(--col-gap);
    row-gap: var(--row-gap);
  }

  /* La pano ocupa las dos filas: su borde inferior cuadra con el del boton,
     no con el del mapa. Sin `height` fija — la rejilla la estira. */
  .pano-wrap,
  #screen-play.is-reveal .pano-wrap {
    grid-column: 1;
    grid-row: 1 / 3;
    height: auto;
    min-height: 0;
    padding: 0;
  }

  /* El mapa CLAVA su proporcion: asi la caja que recibe es la que dibuja, y
     no queda ni un pixel de letterbox dentro de la celda. */
  .map-wrap {
    grid-column: 2;
    grid-row: 1;
    padding: 0;
    aspect-ratio: var(--map-ar, 960 / 600);
    /* panel propio: al lado de una pano con marco, un mapa suelto sobre el
       fondo se lee como un hueco, no como el otro medio de la partida. */
    background: rgba(16, 23, 58, 0.55);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    overflow: hidden;
  }

  .actions { grid-column: 2; grid-row: 2; padding: 0; }
  .actions .btn { max-width: none; }

  /* El sheet cubre la COLUMNA DEL MAPA, nunca la pano: la respuesta es del
     mapa y la vista se queda abierta detras para poder volver a mirarla. */
  .sheet {
    left: auto;
    right: 0;
    bottom: 0;
    width: calc((100% - var(--col-gap)) / var(--split, 2));
    padding: 0 10px 10px;
  }

  /* El aire de la barra superior tambien se reparte: sin esto la rejilla se
     centra contra un alto que ya incluye la barra y queda alta. */
  .pitch { max-width: 720px; }
}
