/* =========================================================================
   TIRO LIBRE — interfaz
   Estética de gráfica de transmisión: tipografía apretada, reglas finas,
   vidrio muy contenido. Nada compite con la cancha.
   ========================================================================= */

/* ======================================================== TIPOGRAFÍA ====

   Un juego de deportes se reconoce por sus NÚMEROS antes que por su motor.
   Durante mucho tiempo este archivo declaraba "gráfica de transmisión" acá
   arriba y después pedía `ui-sans-serif` para todo: la intención estaba
   escrita y no ejecutada.

   POR QUÉ NO HAY UN @font-face CON LA FUENTE ADENTRO
   La idea original era incrustar una condensada pesada como data URI (30-80
   KB sobre los 429 KB del bundle era barato). No se hizo, y por una razón
   concreta: para meter una fuente en el archivo hay que redistribuirla, y
   redistribuir exige una licencia que lo permita —OFL o dominio público—.
   Las condensadas que había a mano en la máquina eran licencias comerciales
   o traían "All rights reserved" en su propia tabla `name`, sin OFL a la
   vista. Bajar una de un CDN quedaba descartado de entrada: rompe el "cero
   dependencias" y, peor, falla en silencio (el juego se abre igual, sólo
   que sin su cara, y nadie se entera hasta que lo ve un tercero).

   LO QUE SÍ SE HIZO
   Armar la cara de display con las condensadas que YA vienen con cada
   sistema, unificadas bajo una sola pila. No hace falta que sean la misma
   fuente: hace falta que compartan la MEDIDA. Por eso los `@font-face` de
   abajo no traen ningún archivo (`src: local(...)` y nada más): existen sólo
   para poder aplicarle `size-adjust` a las caras cuyas mayúsculas son más
   altas que la referencia, y que 40 px sean 40 px de altura de mayúscula en
   todos lados.

   Alturas de mayúscula medidas sobre los archivos reales (fracción de em):
     DIN Condensed Bold  .712   ← referencia (macOS/iOS, la cara de marcador)
     Arial Narrow Bold   .716   → sin corregir, la diferencia no se ve
     Roboto Condensed    .711   → sin corregir
     Impact              .791   → size-adjust 90%
     Haettenschweiler    ~.760  → size-adjust 94% (estimado, no estaba acá)

   Cada cara lleva SU PROPIO nombre de familia (no todas "TL Display"): con
   nombres distintos la caída de una a otra la resuelve la pila de
   `font-family`, que es determinística. Con el mismo nombre repetido en
   varios @font-face queda a criterio del navegador cuál gana, y eso ya se
   probó: en una tanda anterior Chrome elegía la última regla declarada aun
   cuando su `local()` no existía en el sistema.

   Y POR QUÉ HAY DOS PILAS
   `--font-display` es para PALABRAS (¡GOL!, títulos, nombres). `--font-num`
   es para NÚMEROS y excluye a Impact, que no tiene cifras de ancho fijo ni
   `tnum`: sus dígitos miden entre 780 y 1109 unidades y un marcador que
   cuenta 8 → 9 salta de lugar. En el resto de la pila los diez dígitos
   miden exactamente lo mismo.
   ======================================================================== */

@font-face {
  font-family: "TL Haettenschweiler";
  src: local("Haettenschweiler");
  size-adjust: 94%;
  font-display: swap;
}
@font-face {
  font-family: "TL Impact";
  src: local("Impact");
  size-adjust: 90%;
  font-display: swap;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --ink: #f2f6f8;
  --dim: rgba(242, 246, 248, 0.56);
  --faint: rgba(242, 246, 248, 0.24);
  --line: rgba(242, 246, 248, 0.14);
  --panel: rgba(9, 15, 23, 0.72);
  --panel-solid: #0b131d;
  /* fondo de las cajas que scrollean: tiene que ser OPACO para que el
     degradado de "hay más" tenga con qué desvanecer */
  --panel-sunk: #070c13;
  --accent: #35e08a;
  --accent-dim: rgba(53, 224, 138, 0.18);
  --warn: #ff7a6e;
  --gold: #ffd15c;

  --font: ui-sans-serif, -apple-system, "SF Pro Display", "Segoe UI", Inter,
    system-ui, sans-serif;
  --font-display: "DIN Condensed", "Roboto Condensed", "Liberation Sans Narrow",
    "Franklin Gothic Demi Cond", "TL Haettenschweiler", "Arial Narrow",
    "TL Impact", var(--font);
  --font-num: "DIN Condensed", "Roboto Condensed", "Liberation Sans Narrow",
    "Arial Narrow", var(--font);

  /* ---- escala tipográfica
     Nombres por función, no por tamaño: el día que el marcador tenga que
     crecer se toca --t-num y no se sale a cazar 21px por todo el archivo. */
  --t-mark: 9px;      /* etiqueta en versalitas con tracking */
  --t-fine: 10.5px;   /* subtexto, pie de panel */
  --t-small: 11.5px;  /* dato secundario, cuerpo chico */
  --t-base: 13px;     /* cuerpo */
  --t-lead: 15px;     /* entrada destacada */
  --t-title: 19px;    /* título de tarjeta */
  --t-num: 21px;      /* número del HUD */
  --t-head: 27px;     /* título de pantalla */
  --t-big: 38px;      /* número grande, fin de nivel */
  --t-hero: clamp(46px, 8.2vw, 84px);
  /* el tope alto es a propósito: la condensada tiene la mayúscula al 71 %
     del cuerpo, así que 88 px de cuerpo son 62 px de letra en pantalla */
  --t-shout: clamp(42px, 8.6vw, 88px);

  /* ---- tracking
     La cara condensada NO quiere tracking negativo: sus mayúsculas ya vienen
     apretadas y a -0.03em se tocan. El negativo es sólo para la pila del
     sistema, donde el peso 800 abre las letras. Como no se puede detectar
     cuál de las dos cayó, --tr-display queda en cero: es el único valor que
     no arruina ninguna de las dos. */
  --tr-mark: 0.2em;
  --tr-caps: 0.1em;
  --tr-display: 0em;
  --tr-num: -0.01em;

  /* ---- pesos */
  --w-body: 500;
  --w-mid: 600;
  --w-mark: 700;
  --w-strong: 750;
  --w-display: 800;

  /* ---- borde seguro de la pantalla
     env(safe-area-inset-*) sale del notch y del indicador de inicio. Estaba
     usado en dos reglas sueltas del bloque móvil y en ninguna otra parte:
     el marcador quedaba abajo del notch en vertical y los paneles laterales
     abajo del notch en APAISADO, que es como se juega en el teléfono.
     Se centralizan acá y todo el HUD se ancla a estas cuatro variables.
     Bonus: se pueden pisar desde el arnés para probar el layout con insets
     simulados sin un teléfono de verdad. */
  --sa-t: env(safe-area-inset-top, 0px);
  --sa-r: env(safe-area-inset-right, 0px);
  --sa-b: env(safe-area-inset-bottom, 0px);
  --sa-l: env(safe-area-inset-left, 0px);
  --edge: 20px;
  --gx-l: calc(var(--edge) + var(--sa-l));
  --gx-r: calc(var(--edge) + var(--sa-r));
  --gy-t: calc(var(--edge) + var(--sa-t));
  --gy-b: calc(var(--edge) + var(--sa-b));
  /* segunda fila del HUD de arriba: viento y botones comparten altura, así
     no hay forma de que uno se meta abajo del otro */
  --row2: calc(var(--gy-t) + 46px);
}

html, body {
  height: 100%;
  background: #05080d;
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-base);
  font-weight: var(--w-body);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
  /* ANTES ACÁ DECÍA `touch-action: none` Y ROMPÍA TODOS LOS MENÚES EN EL
     TELÉFONO.

     `touch-action` no se resuelve mirando sólo el elemento tocado: el
     navegador intersecta el valor del elemento con el de todos sus
     ancestros. Con `none` en el body, ningún hijo puede volver a habilitar
     el paneo, y eso deja sin scroll táctil a las cuatro cajas que scrollean
     —la grilla de niveles, los grupos del Mundial, los ejercicios y la tabla
     de doce temporadas de la carrera—. Con el dedo no se movían; con rueda o
     trackpad sí, que es por lo que no se veía desde la computadora.

     La defensa que buscaba ese `none` —que un arrastre sobre la cancha no
     mueva la página— la dan los tres elementos que la necesitan, y cada uno
     ya la declara por su cuenta: #game, #contact y #planView. Acá alcanza
     con `manipulation`, que permite scrollear y de paso saca el retardo de
     300 ms del doble toque. Y la página igual no tiene adónde moverse:
     html/body van en overflow:hidden y #wrap es fixed. */
  touch-action: manipulation;
}

#wrap { position: fixed; inset: 0; }

#game {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  cursor: crosshair;
  touch-action: none;
}

#hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
  user-select: none;
  -webkit-user-select: none;
}

#hud button, #hud input, #hud .interactive { pointer-events: auto; }

/* ------------------------------------------------------ roles de texto

   Tres roles y nada más: ETIQUETA (qué es), VALOR (cuánto) y SUBTEXTO (el
   detalle). Se agrupan acá para que la jerarquía se decida una sola vez y
   no se vuelva a inventar en cada panel. */

.corner .lbl,
.wlabel,
#powerLabel,
#practicePanel h3,
.grp h4,
#wcRound,
.wcHead,
.wcVs .v em,
.wcTable .tr.hd,
button.lvl .num,
button.mode .mTag,
#schoolGrid .num,
#dailyBody .mark,
#carBar .cbOvr i,
#carBar .cbTx span,
.carId .fld > span,
#carCardTop .lbl,
#carTimeline .tr.hd,
.offer .oLeague,
.offer .oDiff,
.carSum .lbl,
.fldRow .fldLbl,
#natRow .nrStat i,
.ms .msKick,
.retKick,
.retStats .lbl,
.retBlock .rLbl,
.retHof .hr i {
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  text-transform: uppercase;
  line-height: 1.1;
}

/* La cara de display: sólo mayúsculas, sólo de 13px para arriba y sólo en
   frases cortas. Condensada y sistema difieren mucho de ancho, así que en
   párrafos la línea cambiaría de largo entre plataformas. */
.menuHead h2,
#bannerTitle,
#leTitle,
.wcBig,
.chTitle,
.chTeam,
button.mode .mName,
.wtTx b,
#dailyBody h3,
#schoolGrid .nm,
#carCardTop .who,
#carBar .cbTx b,
.offer .oName,
.carSum .big,
.carRet h3,
.jsyPrev .jName,
#natRow .nrTx b,
.ms .msTx b,
.retName,
.retVerdict b {
  font-family: var(--font-display);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-display);
  text-transform: uppercase;
  font-synthesis-weight: none;
}

/* Números que cambian: ancho fijo o el HUD tiembla. */
.corner .val,
#powerNum,
.wcScore b,
.wcVs .v em.sc,
.wcTable .tr b,
.menuHead .tot b,
#statsBox .srow b,
#windBox .w1,
#windBox .w2,
#effectInfo,
#dailyBody .big-num,
#carBar .cbOvr b,
#carCardTop .num,
#carTimeline .tr b,
.carSum .big,
#natRow .nrStat b,
.retStats .big,
.retHof .hr b {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ------------------------------------------------------------ marcador */

.corner {
  position: absolute;
  top: var(--gy-t);
  padding: 10px 14px 11px;
  background: var(--panel);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line);
  border-radius: 3px;
  line-height: 1.15;
}
#topLeft { left: var(--gx-l); width: 190px; }
#topRight { right: var(--gx-r); text-align: right; min-width: 118px; }

/* La etiqueta lleva un tilde de color: es lo que separa una placa de
   transmisión de una fila de <dl>. Del lado derecho se corre al otro
   extremo para no quedar colgando del aire. */
.corner .lbl {
  position: relative;
  color: var(--dim);
  margin-bottom: 6px;
  padding-left: 8px;
}
.corner .lbl::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1px;
  bottom: 1px;
  width: 2px;
  background: var(--accent);
}
#topRight .lbl { padding-left: 0; padding-right: 8px; }
#topRight .lbl::before { left: auto; right: 0; }

.corner .val {
  font-family: var(--font-num);
  font-size: var(--t-num);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1.02;
  text-transform: uppercase;
  font-synthesis-weight: none;
  overflow-wrap: anywhere;
}
/* La regla fina es la jerarquía: arriba el dato, abajo la letra chica. */
.corner .sub {
  margin-top: 7px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
  font-size: var(--t-fine);
  color: var(--dim);
  font-weight: var(--w-body);
  letter-spacing: 0.01em;
}

/* --------------------------------------------------------------- viento */

#windBox {
  position: absolute;
  top: var(--gy-t);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 15px 9px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
#windBox .arrow {
  display: inline-block;
  font-size: 22px;
  line-height: 1;
  color: var(--accent);
  flex: none;
}
#windBox.moderado { border-color: rgba(255, 209, 92, 0.5); }
#windBox.moderado .arrow { color: var(--gold); }
#windBox.fuerte { border-color: rgba(255, 122, 110, 0.6); }
#windBox.fuerte .arrow { color: var(--warn); }
#windBox.vendaval {
  border-color: rgba(255, 122, 110, 0.9);
  background: rgba(64, 14, 14, 0.72);
}
#windBox.vendaval .arrow { color: var(--warn); }
#windBox.vendaval .w1 { color: var(--warn); }
#windBox .w1 {
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
}
#windBox .w2 {
  font-size: var(--t-fine);
  font-weight: var(--w-mid);
  color: var(--dim);
}

/* ------------------------------------------------------------- botones */

#tools {
  position: absolute;
  top: var(--gy-t);
  /* 134px = ancho mínimo de #topRight (118) + el aire entre paneles */
  right: calc(var(--gx-r) + 134px);
  display: flex;
  gap: 7px;
}
#tools button {
  width: 30px;
  height: 30px;
  border-radius: 3px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
#tools button:hover { background: rgba(30, 46, 62, 0.85); border-color: var(--faint); }
#tools button.off { color: var(--warn); }
/* repetición y código comparten la misma caja que ♪ y ☰, pero se leen como
   acciones sobre el tiro anterior: color de acento apenas insinuado */
#tools #btnReplay, #tools #btnShare { color: var(--accent); }
#tools #btnShare { font-size: var(--t-small); letter-spacing: 0; }
#tools button:disabled { opacity: 0.35; cursor: not-allowed; }

/* ------------------------------------------------- widget de contacto */

#contactWrap {
  position: absolute;
  left: var(--gx-l);
  bottom: var(--gy-b);
  width: 148px;
}
#contact {
  position: relative;
  width: 148px;
  height: 148px;
  border-radius: 50%;
  cursor: pointer;
  pointer-events: auto;
  /* el halo oscuro no es decoración: en el teléfono este widget cae encima
     del pateador y sin un borde propio la pelota chica se confunde con la
     pelota grande que hay atrás */
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5),
              0 0 0 1px rgba(255, 255, 255, 0.16),
              0 0 0 7px rgba(5, 8, 13, 0.45);
  touch-action: none;
}
/* La pelota en sí la dibuja JS en este canvas (patrón real de gajos). */
#contactBall {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  pointer-events: none;
}
#contactCross {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
}
#contactCross::before, #contactCross::after {
  content: "";
  position: absolute;
  background: rgba(15, 22, 28, 0.22);
}
#contactCross::before { left: 50%; top: 10%; bottom: 10%; width: 1px; transform: translateX(-0.5px); }
#contactCross::after  { top: 50%; left: 10%; right: 10%; height: 1px; transform: translateY(-0.5px); }

#contactDot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  background: var(--warn);
  border: 2.5px solid #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.55), 0 0 0 3px rgba(255, 122, 110, 0.25);
  pointer-events: none;
  transition: left 0.05s linear, top 0.05s linear;
}
#contactArrow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 74px;
  height: 3px;
  margin-top: -1.5px;
  transform-origin: 0 50%;
  background: linear-gradient(90deg, rgba(53, 224, 138, 0) 0%, var(--accent) 100%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
}
#contactArrow::after {
  content: "";
  position: absolute;
  right: -1px;
  top: -3px;
  border: 4px solid transparent;
  border-left-color: var(--accent);
}
.wlabel {
  margin-top: 9px;
  color: var(--dim);
  text-align: center;
}
#effectInfo {
  margin-top: 5px;
  padding: 4px 8px;
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: 0.04em;
  text-align: center;
  color: var(--accent);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  transition: color 0.15s;
}
#effectInfo.warn { color: var(--warn); }
#effectInfo.plain { color: var(--dim); }

/* -------------------------------------------------------- potencia */

#power {
  position: absolute;
  right: var(--gx-r);
  bottom: var(--gy-b);
  width: 44px;
  height: 168px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
#powerFill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 60%;
  background: linear-gradient(180deg, var(--gold) 0%, var(--accent) 65%, #1fbf74 100%);
  transition: height 0.03s linear;
}
#power.short #powerFill { background: linear-gradient(180deg, #ff9a4d, var(--warn)); }
#power.charging { border-color: rgba(53, 224, 138, 0.55); }
/* El número vive en una franja oscura y no suelto sobre la barra: la barra
   es un degradado que va de oro a verde según cuánto se cargó, y no hay un
   solo color de tinta que se lea sobre los dos extremos. Antes era tinta
   oscura, que arriba del 50 % quedaba sobre el fondo del panel —oscuro
   también— y desaparecía justo en los tiros fuertes. */
#powerNum {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  padding: 4px 0 5px;
  text-align: center;
  font-family: var(--font-num);
  font-size: var(--t-lead);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  color: var(--ink);
  background: rgba(4, 8, 13, 0.78);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  font-synthesis-weight: none;
}
#power .ticks {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.16) 0 1px,
    transparent 1px 21px
  );
}
/* La palabra no entra en los 44 px de la barra: alineada a la derecha crece
   hacia adentro de la pantalla. Centrada se salía por el borde. */
#powerLabel {
  position: absolute;
  right: var(--gx-r);
  bottom: calc(var(--gy-b) + 174px);
  width: 120px;
  text-align: right;
  color: var(--dim);
}

/* ------------------------------------------------- mapa de la cancha

   El único mapa del HUD, en el lugar de siempre: abajo a la derecha, al
   lado de la barra de potencia. Antes había dos —el plano y un insert 3D
   que aparecía y se iba—; quedó el 3D, fijo y del tamaño del anterior,
   porque además es el control con el que se mueve la pelota.             */

#planWrap {
  position: absolute;
  right: calc(var(--gx-r) + 56px);
  bottom: var(--gy-b);
  padding: 7px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
#planView {
  display: block;
  width: 168px;
  height: 118px;
  border-radius: 2px;
  cursor: crosshair;
  pointer-events: auto;
  touch-action: none;
}
#planWrap .cap {
  margin-top: 6px;
  font-size: var(--t-mark);
  letter-spacing: 0.12em;
  color: var(--dim);
  text-align: center;
  font-weight: var(--w-mark);
  text-transform: uppercase;
}
#planWrap .cap b {
  color: var(--accent);
  font-family: var(--font-num);
  font-weight: var(--w-display);
  font-size: var(--t-fine);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------- panel de práctica */

#practicePanel {
  position: absolute;
  left: var(--gx-l);      /* alineado con #topLeft, no 4px corrido */
  /* 94 y no 106. El marcador de arriba a la izquierda (#topLeft) mide 86 px y
     termina en 106 contando el margen de la pantalla, así que 94 deja 8 px de
     aire —medido a 1280×800— y devuelve 12 px al panel. Son 12 de los 62 que
     había que encontrar para que el jugador abierto entrara sin scroll. */
  top: calc(var(--gy-t) + 94px);
  /* 276 y no 190. Lo pide la fila de tres fichas: el escalón más largo del
     motor es "sin arquero" y el más ancho en una palabra "IMPOSIBLE", y en
     190 px la ficha quedaba de 47 y el valor tenía que bajar a 8 px para
     entrar — o sea, dejaba de ser "el valor en grande", que es todo el punto.

     Y EL ANCHO COMPRA ALTO, que era lo que faltaba: a 244 px la nota del
     pateador rival ("quieto te entra el 94 % · leyéndolo perfecto, el 33 %")
     caía en tres renglones y "COMO SIEMPRE" envolvía adentro del botón del
     preset. A 276 los dos entran en menos y el panel mide 26 px menos.

     Los 86 px de más se los come el ancho de la cancha, no la altura: a
     1280×800 el panel termina en x=296 de 1280 y el arco arranca en 520.

     El `position: absolute` de arriba hace además de contenedor del "?", que
     se dibuja con `inset: 0` encima del panel: por eso la ayuda no puede
     estirar el panel ni un píxel. */
  width: 276px;
  /* El resto es el punto de contacto, que vive en la misma esquina y más
     abajo. 218 y no 214: el widget arranca en y=570 a 1280×800 (medido), o
     sea 230 px del pie, y con 218 el panel termina en 562 — ocho de aire.
     Con 214 se metía cuatro píxeles adentro, con la pelota de contacto
     dibujada encima de la última perilla. */
  max-height: calc(100% - var(--gy-t) - var(--gy-b) - 94px - 218px);
  overflow-y: auto;
  padding: 11px 12px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  pointer-events: auto;
}
#practicePanel h3 { color: var(--dim); margin-bottom: 12px; }
.ctl { margin-bottom: 13px; }
.ctl:last-child { margin-bottom: 0; }
.ctl .top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: var(--t-small);
  margin-bottom: 6px;
  font-weight: var(--w-body);
  color: var(--dim);
}
.ctl .top b {
  color: var(--accent);
  font-weight: var(--w-strong);
  font-size: var(--t-small);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.ctl input[type="range"] {
  width: 100%;
  height: 3px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 2px;
  outline: none;
}
.ctl input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--ink);
  cursor: pointer;
  border: none;
}
.ctl input[type="range"]::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--ink); cursor: pointer; border: none;
}
/* La nota del nivel elegido (arquero y viento). Son los números medidos que
   trae el motor: el rótulo grande dice CUÁL, y esta línea, cuánto cambia.
   Sin ella "elite" y "bueno" son dos palabras sin escala. */
/* `#practicePanel .nota` y no sólo `.ctl .nota`: la de los tres atributos es
   UNA para los tres, así que cuelga del grupo y no de un control. Sin esto se
   dibujaba con el cuerpo del panel —14 px, más grande que el rótulo que
   explica— y era lo primero que se leía de toda la columna. */
.ctl .nota,
#practicePanel .nota {
  /* Pegada arriba y con aire abajo: la nota es de SU control. Con el mismo
     espacio de los dos lados quedaba más cerca del rótulo del control
     siguiente que de su propio slider, y se leía como si la nota del arquero
     fuera la del viento. */
  margin-top: 4px;
  /* 7 y no 10: la asimetría contra el `margin-top: 4` es lo que hace que la
     nota se lea como del control de arriba, y con 7 sigue siendo casi el
     doble. Los 3 px que se sueltan son por nota y por grupo, y con dos notas
     por grupo son los que hacen entrar EL JUGADOR en el hueco de 1280×800. */
  padding-bottom: 7px;
  font-size: 10px;
  line-height: 1.35;
  color: var(--dim);
  opacity: 0.85;
}
/* ============================================ LA JUGADA: TRES FICHAS

   Barrera, arquero y viento son lo único que cambia entre tiro y tiro, así
   que van arriba y con el VALOR EN GRANDE: se leen de reojo antes de pegarle.
   Antes eran tres reglas de ancho completo con el valor en letra chica al
   costado del rótulo, iguales a las otras cinco perillas del panel, y el
   resultado es el que se ve en shots-ui-antes-r2: ocho controles idénticos
   apilados sin ninguna jerarquía.

   La ficha invierte el peso: el valor manda y el control es un hilo de 3 px
   abajo. Se toca mucho menos de lo que se consulta.                        */

.pFichas {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}
.pFicha {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 6px 7px 7px;
  border: 1px solid var(--line);
  border-radius: 3px;
}
.pFicha > span {
  font-size: 8px;
  font-weight: var(--w-mark);
  /* 0.08em y no el 0.2 de marca del resto del HUD: el rótulo más largo es
     "TU BARRERA" y con el tracking de marca mide 64 px contra los 62 que
     quedan adentro de la ficha — se leía "TU BARRE…". Verificado en la
     captura `practica-desktop-atajar` de la primera pasada. */
  letter-spacing: 0.08em;
  color: var(--dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* El valor. CUATRO tamaños y los elige 80-main con el LARGO del texto, no a
   ojo: los escalones del motor van de "3" a "sin arquero" y una tipografía
   sola no puede servir a los dos.

   Los cortes salen de medir la ficha real (76 px en el panel de 276, 72 en la
   hoja del teléfono) contra el ancho del texto:
     · número        → 24 px. Es lo que se mira de reojo entre tiro y tiro.
     · hasta 7        → 15 px  ("BUENO", "BRISA", "FLOJO")
     · 8 y 9          → 11 px  ("IMPOSIBLE" a 15 px se pasa 21 px del borde)
     · 10 o más       → 9.5 px ("SIN ARQUERO" a 11 px se pasa y envuelve)

   El escalón de 9.5 no es exquisitez: `overflow-wrap: anywhere` evita el
   desborde pero el renglón de más CAMBIA EL ALTO DE LA FICHA, y con eso el
   panel dejaba de medir lo mismo con todos los escalones — que es justo lo
   que hace falta para prometer que entra sin scroll. */
.pFicha > b {
  margin-top: 3px;
  font-family: var(--font-num);
  font-weight: var(--w-display);
  font-size: 15px;
  line-height: 1.05;
  letter-spacing: 0.01em;
  color: var(--accent);
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.pFicha > b.num { font-size: 24px; font-variant-numeric: tabular-nums; }
.pFicha > b.largo { font-size: 11px; }
.pFicha > b.xlargo { font-size: 9.5px; }
/* La regla de la ficha necesita su propio piso: `.ctl input[type=range]` no
   la alcanza (una ficha no es un `.ctl`) y sin esto quedaba el control nativo
   de 16 px con su marco, que adentro de una caja de 62 px se lee como un
   segundo borde. Misma pista de 3 px que el resto del panel. */
.pFicha input[type="range"] {
  width: 100%;
  height: 11px;
  margin-top: 5px;
  -webkit-appearance: none;
  appearance: none;
  background: linear-gradient(rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.16))
    center / 100% 3px no-repeat;
  outline: none;
}
.pFicha input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--ink); cursor: pointer; border: none;
}
.pFicha input[type="range"]::-moz-range-thumb {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--ink); cursor: pointer; border: none;
}

/* ========================================= EL JUGADOR: UNA SOLA UNIDAD

   Marco propio y un rótulo arriba, porque es lo que lo separa de la jugada:
   esto se configura una vez y se queda. Sin el marco los power-ups y los
   atributos volvían a leerse con el mismo peso que la barrera.             */

.pUnit {
  padding: 7px 8px 8px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.02);
}
.pUnitTop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 8.5px;
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  color: var(--dim);
}
/* El "?" — 22 px con mouse, 44 en el teléfono (más abajo). Redondo y no
   cuadrado: es lo único del panel que no cambia nada del juego. */
.pUnitTop button {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: none;
  color: var(--dim);
  font-family: var(--font);
  font-size: 11px;
  font-weight: var(--w-strong);
  line-height: 1;
  cursor: pointer;
}
.pUnitTop button:hover,
.pUnitTop button[aria-expanded="true"] { border-color: var(--accent-dim); color: var(--accent); }

/* ---- los presets

   Tres botones de dos renglones: el nombre y, abajo, los tres números. Los
   números NO son decoración: son lo que enseña que 80 es el neutro sin que
   nadie tenga que leer el diseño. El de "a mano" muestra los valores que
   tenés puestos, así que la fila siempre dice la verdad de los tres.       */
 /* `.seg.pPreset` y no `.pPreset` a secas, y esto costó una medición: la
   definición de `.seg button` vive más abajo en esta misma hoja y tiene la
   MISMA especificidad (0,1,1), así que ganaba por orden y le devolvía a estos
   botones los 9 px con tracking de marca. "COMO SIEMPRE" envolvía en tres
   renglones y la fila medía 50 px en vez de 32. */
.seg.pPreset { margin-bottom: 0; }
/* 8 px y tracking corto, contra los 9 px y 0.2em del resto de los segmentados:
   "COMO SIEMPRE" son doce caracteres y el botón mide 71 px en el panel de 244.
   Con el tracking de marca envolvía en tres renglones y la fila entera medía
   50 px en vez de 35 — quince píxeles que en el teléfono son la diferencia
   entre entrar y scrollear. */
.seg.pPreset button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 5px 2px 6px;
  font-size: 8px;
  letter-spacing: 0.05em;
  line-height: 1.1;
}
.seg.pPreset button i {
  font-style: normal;
  font-family: var(--font-num);
  font-size: 9.5px;
  font-weight: var(--w-strong);
  letter-spacing: 0;
  opacity: 0.82;
  font-variant-numeric: tabular-nums;
}

/* ---- las tres barras

   Aparecen con "a mano" y no antes. No es esconder un control: es que el
   caso normal —el jugador de siempre— se resuelve con un click en el preset,
   y las tres barras cuestan 66 px que en un 360×640 son la diferencia entre
   entrar y scrollear. Cuando los valores no son los de ningún preset, 80-main
   las deja abiertas solas: nunca hay un estado que no se pueda ver.        */
.pBars { display: none; margin-top: 9px; }
.pUnit.manual .pBars { display: block; }

/* ---- el rótulo de una fila que no es un control (POWER-UP + su tecla) */
.pRowLbl {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 5px;
  font-size: 8.5px;
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  color: var(--dim);
}
/* La tecla, como una tecla. Nombrarla acá es lo contrario de la pista de
   controles permanente que se sacó dos veces: está donde se elige la cosa,
   no flotando arriba de la cancha. */
.pRowLbl i {
  font-style: normal;
  min-width: 15px;
  padding: 1px 4px 2px;
  border: 1px solid var(--line);
  border-radius: 2px;
  font-family: var(--font-num);
  font-size: 8.5px;
  letter-spacing: 0;
  text-align: center;
  color: var(--ink);
  opacity: 0.7;
}
.pPuRow { margin-top: 9px; }
/* El selector de guía lo inserta 80-main (buildAssistMenu) como un `.ctl` con
   su rótulo arriba. Adentro de la unidad va compacto: el `.ctl` de escritorio
   reserva 6 px entre rótulo y control y 13 abajo, que acá son dos huecos que
   no separan nada porque la unidad ya tiene marco. */
.pUnit > .ctl { margin: 9px 0 0; }
.pUnit > .ctl .top { margin-bottom: 4px; }
.pUnit > .ctl .seg { margin-bottom: 0; }

/* ---- los power-ups: cuatro en UNA fila

   Cada uno con su ícono, que dibuja el motor. El de "ninguno" no tiene ícono
   (G.PU_NINGUNO.icono es una cadena vacía) y por eso ése —y sólo ése— entra
   con su nombre en letras: una vista que le invente un símbolo es la misma
   trampa que inventarle un rótulo a un escalón.
   `--pu` lo escribe 80-main con el color que publica el motor. */
.seg.pu { margin-bottom: 0; }
.seg.pu button {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 30px;
  padding: 5px 2px;
  font-size: 8px;
}
.seg.pu button svg { display: block; width: 19px; height: 19px; }
/* `currentColor` y no el color del motor directo: así el ícono se apaga y se
   prende con el botón sin una segunda regla, y el color del power-up entra
   una sola vez, en `.on`. Trazo por defecto; relleno sólo donde el motor lo
   pide (`relleno: true`, hoy el rayo). */
.seg.pu button svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.seg.pu button svg path.fill { fill: currentColor; stroke: none; }
.seg.pu button.on {
  color: var(--pu, var(--accent));
  background: color-mix(in srgb, var(--pu, var(--accent)) 18%, transparent);
}

/* ---- el "?" tapa el panel, no lo estira

   `position: absolute` sobre el panel entero: con la ayuda abierta el panel
   mide exactamente lo mismo que cerrado, así que abrirla no puede empujar
   nada al scroll. Es lo que permitió sacar del panel las cuatro líneas de
   metodología sin perderlas.
   `inset: 0` y no un ancho fijo: el panel cambia de forma en las tres
   pantallas (columna, tarjeta, franja acostada) y la ayuda lo sigue sola. */
#pHelp {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow-y: auto;
  padding: 12px 13px 13px;
  border-radius: 3px;
  background: var(--panel-solid, rgba(9, 15, 23, 0.96));
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
#pHelp[hidden] { display: none; }
#pHelp h4 {
  margin: 0 0 4px;
  font-size: 8.5px;
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  color: var(--accent);
  text-transform: uppercase;
}
#pHelp p { margin: 0 0 11px; font-size: 10px; line-height: 1.45; color: var(--dim); }
#pHelp p:last-child { margin-bottom: 0; }
#pHelp b { color: var(--ink); font-weight: var(--w-strong); }
#pHelp .hClose {
  position: absolute;
  top: 8px;
  right: 9px;
  width: 26px;
  height: 26px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: none;
  color: var(--dim);
  font-family: var(--font);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
#pHelp .hClose:hover { border-color: var(--accent-dim); color: var(--accent); }

/* ------------------------------------------------------- la llave

   UNA sola, y sólo donde el panel se pliega (teléfono y apaisado). En
   escritorio no se dibuja: el panel entero está a la vista, que es el punto
   del rediseño.

   Hasta esta tanda eran DOS llaves —una por familia— y el estado tenía cuatro
   combinaciones; medido a 360×640, ninguna de las cuatro entraba sin scroll
   con los seis controles del jugador abiertos. Con una sola, el estado es
   abierto o cerrado y lo que se ve plegado es la línea del motor
   (G.practiceLine), que dice qué hay puesto del lado en el que estás.      */
.pChip {
  display: none;      /* en escritorio no existe; el teléfono la prende */
  min-height: 30px;
  flex-wrap: wrap;
  align-items: center;
  gap: 1px 8px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: none;
  color: var(--dim);
  font-family: var(--font);
  font-size: 9px;
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  text-align: left;      /* los <button> centran por defecto y el estado envuelve */
  cursor: pointer;
}
.pChip b { color: var(--accent); font-weight: var(--w-strong); letter-spacing: 0.02em; }
/* La flecha va pegada al rótulo y no al final del botón: al final se quedaba
   sola en un tercer renglón cuando el estado no entra en uno. */
.pChip span::after { content: ' ▾'; opacity: 0.6; }
.pChip[aria-expanded="true"] span::after { content: ' ▴'; }
.pChip[aria-expanded="true"] { border-color: var(--accent-dim); color: var(--accent); }

/* El cuerpo del panel: en escritorio siempre está. Lo pliega el teléfono. */
#pBody { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
/* La nota de la jugada RESERVA su alto y no lo negocia.

   Es la única línea de ayuda que quedó en el panel, y su texto lo escribe el
   motor: va de "aire quieto" (un renglón) a "quieto te entra el 94 % ·
   leyéndolo perfecto, el 33 %" (tres en la tarjeta del teléfono). Sin reserva,
   mover el arquero cambiaba el alto del panel 28 px y el "entra sin scroll"
   valía sólo para el escalón que estuviera puesto cuando se midió.
   El número sale de medir los trece escalones uno por uno y quedarse con el
   más alto, no de estimarlo: dos renglones a 1.35 son 27, y con la reserva
   puesta el panel mide lo mismo con cualquiera de ellos. */
#pBody > .nota { min-height: 27px; padding-bottom: 0; }

/* ---- las tres barras del jugador

   Regla de 0 a 100 y no segmentado: el porqué está escrito al lado del
   marcado, en 95-body.html. Acá va lo que la regla necesita para ser
   legible, que es UNA cosa: dónde está el neutro.

   `--neutro` lo escribe 80-main leyendo G.ATRIB_NEUTRO (hoy 80). Escrito a
   mano acá sería la cuarta copia de un número que el motor ya publica, que
   es el error que esta misma tanda vino a sacar del 0.42.

   La pista se dibuja como un degradé de 3 px centrado en una caja de 11, y
   no como fondo de la caja: así la marca del neutro puede ser más alta que
   la pista sin que la línea engorde. Con `background-clip` la pista
   desaparecía (mismo hallazgo que en los sliders del teléfono).

   Y el rótulo va AL COSTADO, que es lo contrario de las fichas: el valor de
   un atributo son tres caracteres, y con rótulo arriba cada fila mide 41 px
   y al costado 22, o sea 57 px menos por las tres. Esos 57 son parte de lo
   que hace entrar el panel sin scroll. No es una excepción a la regla: es la
   regla —el ancho manda— aplicada a un contenido distinto.                 */
.ctl.atrib {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 9px;
  margin-bottom: 7px;
}
.pBars .ctl.atrib:last-child { margin-bottom: 0; }
/* `contents` y no `flex`: los dos pedazos del rótulo tienen que ser celdas de
   ESTA grilla, no de una caja propia. Se colocan a mano porque en el DOM
   vienen los dos antes del input (el marcado es el mismo `.top` que usan los
   otros controles) y sin colocarlos el número quedaba en el medio y la regla
   al final. */
.ctl.atrib .top { display: contents; }
.ctl.atrib .top > span { grid-column: 1; grid-row: 1; }
.ctl.atrib .top > b { grid-column: 3; grid-row: 1; min-width: 22px; text-align: right; }
.ctl.atrib input[type="range"] {
  grid-column: 2;
  grid-row: 1;
  height: 14px;
  border-radius: 0;
  background:
    linear-gradient(rgba(53, 224, 138, 0.9), rgba(53, 224, 138, 0.9))
      var(--neutro, 80%) center / 2px 14px no-repeat,
    linear-gradient(rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.16))
      center / 100% 3px no-repeat;
}

/* `.chk` (la casilla del panel de práctica) se fue con su último usuario: el
   viento dejó de ser un sí/no y pasó a ser el nivel de fuerza, con el mismo
   slider que la barrera y el arquero. La casilla de la guía ya se había ido
   antes por lo mismo. Si vuelve a hacer falta una casilla, está en el
   historial. */

/* ---------------------------------------------- de qué lado se juega

   Interruptor de dos posiciones arriba del panel de práctica. Va arriba de
   todo porque cambia qué significan los controles de abajo: el mismo panel
   dice "arquero" de un lado y "pateador rival" del otro.                   */

.seg {
  display: flex;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
}
.seg button {
  flex: 1;
  background: transparent;
  border: 0;
  color: var(--dim);
  font-family: var(--font);
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  padding: 8px 0;
  cursor: pointer;
}
.seg button + button { border-left: 1px solid var(--line); }
.seg button:hover { color: var(--ink); }
.seg button.on { background: var(--accent-dim); color: var(--accent); }

#practicePanel.gk .rShooter { display: none; }
#practicePanel:not(.gk) .rKeeper { display: none; }

/* Del lado del arco no hay ni punto de contacto ni barra de potencia: la
   pelota la patea otro. Dejarlos en pantalla, apagados, es peor que
   sacarlos — invitan a tocarlos justo cuando no hacen nada. */
#hud.gk #contactWrap,
#hud.gk #power,
#hud.gk #powerLabel { display: none; }

/* Y en Partido, lo mismo pero al revés de fase: fuera del modo disparo no
   hay ni contacto ni potencia. El rótulo de la potencia no vuelve NUNCA,
   porque dice "FIJALA · P" (lo escribe updatePowerHUD en 80-main.js) y acá
   la tecla es A: lo que hay que apretar lo dice el pizarrón.
   El widget de contacto se muestra como LECTURA y no como control: en un
   partido el punto de contacto no lo elige el jugador, sale de la carrera, y
   verlo es lo que enseña que la carrera comba. */
#hud.partido:not(.tiro) #contactWrap,
#hud.partido:not(.tiro) #power,
#hud.partido #powerLabel { display: none; }
#hud.partido #contactWrap { pointer-events: none; }

/* El cartel del power-up es de la Práctica y de la Carrera. En un partido
   miente dos veces: no hay power-up armado y el cartel tapa la franja donde
   caen ¡GOL! y FALTA. Se apaga por CSS y no con un guardia adentro de
   syncPuHero() porque `box.style.display = ''` BORRA la propiedad en línea,
   así que la hoja gana sin necesidad de !important. */
#hud.partido #puHero { display: none; }

/* El encabezado del grupo derecho dice "ANTES DE PEGARLE" (lo escribe
   buildHudGroups en 80-main.js) y en Partido abajo va el pizarrón, que son
   las teclas vivas AHORA. Un rótulo que miente sobre lo que hay debajo es
   peor que ninguno. Se apaga y no se le cambia el texto: en el teléfono ya
   no existe desde siempre y nadie lo extrañó. */
#hud.partido #hudPre .gHead { display: none; }

/* La ayuda del primer uso enseña los gestos del lado que se está jugando:
   mostrarle a alguien que está en el arco cómo se maneja la potencia es
   ruido justo en el momento en que menos contexto tiene. */
#hud.gk .tShooter,
#hud:not(.gk) .tKeeper { display: none; }
/* Partido tiene su propia familia de gestos, y las del tiro libre no aplican:
   ahí no hay "arrastrá la cancha para apuntar". */
#hud.partido .tShooter, #hud.partido .tKeeper { display: none; }
#hud:not(.partido) .tPartido { display: none; }

/* ================================================ EL POWER-UP PUESTO

   ARRIBA Y AL MEDIO, grande, con el ícono. Antes vivía en la columna derecha
   como una placa más entre DISTANCIA, BARRERA y VIENTO, y ahí un power-up
   activo se leía como un dato de la jugada: había que saber que existía para
   darse cuenta de que estaba puesto. Es la queja de origen y es literal.

   DÓNDE, medido y no estimado:
     · la franja de arriba al medio la comparte con #carBar, que arranca en
       --gy-t. `--pu-off` lo escribe 80-main.js con el offsetHeight REAL de esa
       placa (48 px en escritorio, 44 en el teléfono) más 9 de aire; sin
       Carrera vale 0 y el hero se queda con la franja entera.
     · el cartel de la jugada (#banner) vive en el 27 % del alto —216 px en
       1280×800, 269 en el teléfono, donde la media query lo manda al 42 %— y
       el hero termina en 90 px con Práctica y en 147 con Carrera. No se tocan
       en ninguna de las cuatro pantallas del arnés.

   `pointer-events: none` porque no es un control: es un cartel. El power-up
   se elige con la tecla Q o con el panel, y un rectángulo grande y clickeable
   en el medio de la pantalla se come los toques de apuntar.

   El COLOR lo publica el motor (G.POWERUPS[i].color) y entra por `--pu`. Acá
   no hay un solo color de power-up escrito: si mañana el de control deja de
   ser verde, el hero cambia solo y la vista 3D también.                     */

#puHero {
  position: absolute;
  left: 50%;
  top: calc(var(--gy-t) + var(--pu-off, 0px));
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 13px;
  max-width: min(90vw, 430px);
  padding: 9px 18px 10px;
  border: 1px solid var(--pu, var(--accent));
  border-radius: 3px;
  background: var(--panel);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  /* Tres capas: el filo oscuro que lo despega del pasto, la sombra que lo
     levanta y el halo del color del power-up. El halo es lo que hace que se
     note "de reojo", que es lo que se pidió. */
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.28),
    0 12px 34px rgba(0, 0, 0, 0.34),
    0 0 30px -6px var(--pu-glow, transparent);
  pointer-events: none;
}
#puHero .phIco { flex: 0 0 auto; width: 36px; height: 36px; }
/* Trazo por defecto y relleno sólo donde el motor lo pide (`relleno: true`,
   hoy el rayo): a 20 px una silueta rellena se convierte en una mancha, y los
   tres se tienen que distinguir entre sí de un vistazo. */
#puHero .phIco path {
  fill: none;
  stroke: var(--pu, var(--accent));
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
#puHero .phIco path.fill { fill: var(--pu, var(--accent)); stroke: none; }
#puHero .phTx { min-width: 0; text-align: left; }
#puHero .phLbl {
  display: block;
  font-size: 8px;
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  color: var(--dim);
}
#puHero b {
  display: block;
  margin-top: 1px;
  font-family: var(--font-num);
  font-size: 27px;
  font-weight: var(--w-display);
  line-height: 1.02;
  letter-spacing: 0.01em;
  color: var(--pu, var(--accent));
  text-transform: uppercase;
}
#puHero .phNota {
  display: block;
  margin-top: 3px;
  font-size: 10px;
  line-height: 1.3;
  color: var(--dim);
}

/* El latido. Es lo único que se mueve en toda la franja de arriba, así que
   con 2.4 s y una opacidad que va de 1 a 0.55 alcanza: más rápido se lee como
   una alarma y esto es un premio. Lo apaga solo el bloque global de
   prefers-reduced-motion. */
@keyframes puLatido {
  0%, 100% { box-shadow: 0 0 0 1px rgba(0,0,0,0.28), 0 12px 34px rgba(0,0,0,0.34),
                         0 0 30px -6px var(--pu-glow, transparent); }
  50%      { box-shadow: 0 0 0 1px rgba(0,0,0,0.28), 0 12px 34px rgba(0,0,0,0.34),
                         0 0 46px -2px var(--pu-glow, transparent); }
}
#puHero.vivo { animation: puLatido 2.4s ease-in-out infinite; }

/* ---- el otro estado: en Carrera, cuánto falta

   La racha ES la mecánica —tres goles seguidos y lo tenés hasta que errás— y
   sin decirlo el poder aparece de la nada. Misma caja y mismo lugar, pero en
   tono bajo y sin ícono: es información, no un premio, y no puede competir
   con el cartel de la jugada que sale justo debajo. */
#puHero.racha {
  gap: 9px;
  padding: 6px 14px 7px;
  border-color: var(--line);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.28);
  animation: none;
}
#puHero.racha b { font-size: 15px; color: var(--ink); }
#puHero.racha .phNota { margin-top: 1px; }

/* ---- el teléfono: la franja entera es del cartel, y las esquinas bajan

   Acá el cartel deja de ser una placa centrada y pasa a ser una BANDA de
   borde a borde. No es una decisión de estilo: medido a 390×844, el marcador
   de la izquierda termina en x=142 y la fila de botones (♪ ≡ ↺ #) arranca en
   x=234, o sea que en el medio quedan 92 px y la palabra SUPEREFECTO mide
   154. Centrado y angosto, el cartel se comía el botón de sonido — verificado
   en la captura `practica-powerup-telefono` de la primera pasada.

   Con la banda, el cartel se queda con la franja y las dos esquinas bajan lo
   que él mide (`--pu-h`, que 80-main publica con el alto REAL). El panel de
   práctica plegado baja también; abierto NO, porque ahí la hoja arranca en el
   borde de arriba y el cartel se esconde (ver la regla del hermano).

   La nota se cae: la frase larga partía la banda en tres renglones y lo que
   tiene que leerse de reojo es CUÁL está puesto — el ícono y la palabra. */
@media (max-width: 700px) {
  #puHero {
    left: var(--gx-l);
    right: var(--gx-r);
    transform: none;
    max-width: none;
    justify-content: center;
    gap: 10px;
    padding: 7px 13px 8px;
  }
  #puHero .phIco { width: 28px; height: 28px; }
  #puHero b { font-size: 20px; }
  #puHero .phNota { display: none; }
  #puHero .phTx { text-align: center; }
  /* `margin-top` y no `top`: el `top` de estos tres lo escriben otras cuatro
     reglas (el safe-area, el modo Mundial, el panel plegado) y pisarlo desde
     acá era pelear con todas. El margen se suma a cualquiera de ellas. */
  #hud.pu #topLeft,
  #hud.pu #hudRight,
  #hud.pu #practicePanel:not(.abierto) { margin-top: var(--pu-h, 0px); }
}
/* Acostado el alto es todo: la placa se achica a una línea con el ícono. */
@media (max-height: 520px) {
  #puHero { padding: 5px 12px 6px; gap: 9px; }
  #puHero .phIco { width: 24px; height: 24px; }
  #puHero b { font-size: 17px; }
  #puHero .phLbl, #puHero .phNota { display: none; }
  /* Y en CARRERA acostada, el cartel de la jugada baja. Es el único caso de
     las cuatro pantallas donde tres cosas se pelean por la misma franja: la
     placa del club arranca en 14 y termina en 64, el cartel del poder va
     debajo (73–110) y el #banner del 20 % cae en 75 — o sea justo encima.
     Medido a 812×375. Con el 34 % el banner arranca en 127 y quedan 17 px de
     aire. Va con `.wc` porque en Práctica acostada no hay placa del club, el
     cartel del poder vive en 14–51 y el banner del 20 % no molesta a nadie —
     y bajarlo ahí se lo metería adentro del panel abierto. */
  #hud.wc.pu #banner { top: 34%; }
}

/* ============================================================== BANNER

   El momento del gol, del lado del DOM. Antes esto era texto verde en la
   fuente del sistema y se leía como un `alert()` con estilos.

   Ahora son tres capas, en el orden en que llegan a la pantalla:
     1. el resplandor (::before) — un halo del color del estado
     2. la barra de barrido (::after) — el gesto de placa de transmisión,
        entra desde el centro hacia afuera
     3. el título, que aparece con el tracking abierto y lo cierra de golpe

   Las clases de estado las pone 70-game.js. Todo lo que sigue está armado
   para DEGRADAR: si no llega ninguna, queda el banner blanco de siempre; si
   llega sólo `.goal`, queda el verde; las variantes sólo cambian color y
   carácter del movimiento, nunca la estructura.                            */

#banner {
  position: absolute;
  left: 50%;
  top: 27%;
  transform: translate(-50%, -8px);
  width: min(92vw, 900px);
  text-align: center;
  opacity: 0;
  transition: opacity 0.28s ease, transform 0.28s cubic-bezier(0.2, 0.9, 0.3, 1);
  pointer-events: none;
}
#banner.show { opacity: 1; transform: translate(-50%, 0); }
#banner.soft {
  width: auto;
  background: rgba(9, 15, 23, 0.62);
  padding: 14px 26px 16px;
  border-radius: 4px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* Resplandor detrás del título, sobre una SOMBRA.

   Son dos capas y el orden importa. El resplandor solo ACLARA el fondo, y
   "¡GOL!" es verde acento sobre pasto: medido sobre los píxeles reales daba
   2.64:1, por debajo del 3:1 que pide un texto grande, y el subtítulo 2.62
   sobre 4.5. El mensaje más importante del juego era el menos legible.

   La sombra va DEBAJO (última en la lista) y oscurece el pasto antes de que
   el resplandor le ponga color; el destello de color se conserva entero
   arriba. Es el mismo criterio que los paneles opacos del resto del HUD:
   acá no puede ser un panel porque el banner es una placa de transmisión y
   no una caja, así que es un viñeteo. */
#banner::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 118%;
  height: 210%;
  transform: translate(-50%, -50%) scale(0.6);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  background:
    radial-gradient(
      closest-side,
      var(--bnr-glow, rgba(255, 255, 255, 0.16)),
      transparent 72%
    ),
    radial-gradient(
      closest-side,
      rgba(4, 8, 13, 0.68),
      rgba(4, 8, 13, 0.5) 46%,
      transparent 80%
    );
}
/* barra de barrido: crece desde el centro, como una placa que se abre */
#banner::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -14px;
  height: 3px;
  transform: scaleX(0);
  background: linear-gradient(
    90deg,
    transparent,
    var(--bnr-bar, var(--ink)) 22%,
    var(--bnr-bar, var(--ink)) 78%,
    transparent
  );
  pointer-events: none;
}
#banner.show::before { animation: bnrGlow 0.9s cubic-bezier(0.16, 1, 0.3, 1) both; }
#banner.show::after { animation: bnrWipe 0.55s cubic-bezier(0.16, 1, 0.3, 1) both; }
/* el mensaje calmo del apunte no lleva producción */
#banner.soft::before, #banner.soft::after { display: none; }

@keyframes bnrGlow {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  40% { opacity: 1; }
  100% { opacity: 0.85; transform: translate(-50%, -50%) scale(1); }
}
@keyframes bnrWipe {
  0% { transform: scaleX(0); opacity: 0; }
  100% { transform: scaleX(1); opacity: 1; }
}

#bannerTitle {
  font-size: var(--t-shout);
  line-height: 0.92;
  text-shadow: 0 4px 34px rgba(0, 0, 0, 0.75);
}
#banner.show #bannerTitle { animation: bnrIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes bnrIn {
  0% { opacity: 0; letter-spacing: 0.3em; transform: translateY(10px) scale(0.94); }
  100% { opacity: 1; letter-spacing: var(--tr-display); transform: none; }
}

#banner.soft #bannerTitle {
  font-family: var(--font);
  font-size: var(--t-title);
  letter-spacing: 0.02em;
  font-weight: var(--w-strong);
  text-transform: none;
  animation: none;
}
#bannerSub {
  margin-top: 11px;
  font-size: var(--t-base);
  /* NO es var(--dim). El subtítulo del banner es el único texto chico que
     cae sobre la cancha sin placa: con el 56 % de --dim daba 2.62:1 sobre
     el pasto y se leía como un fantasma. Acá el gris apagado no ahorra
     jerarquía, sólo información. */
  color: rgba(242, 246, 248, 0.86);
  letter-spacing: 0.03em;
  font-weight: var(--w-body);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.8);
}
#banner.show #bannerSub { animation: bnrSub 0.5s 0.14s ease both; }
@keyframes bnrSub { from { opacity: 0; transform: translateY(6px); } }
#banner.soft #bannerSub { animation: none; }

/* ---- estados

   Cada estado define dos variables (--bnr-glow, --bnr-bar) y el color del
   título. Nada más. Así una clase que no exista todavía no rompe nada y una
   clase nueva se agrega en cuatro líneas.                                  */

#banner.goal #bannerTitle {
  color: var(--accent);
  text-shadow: 0 0 46px rgba(53, 224, 138, 0.55), 0 4px 30px rgba(0, 0, 0, 0.7);
}
#banner.goal { --bnr-glow: rgba(53, 224, 138, 0.28); --bnr-bar: var(--accent); }

/* Al ángulo: el gol que se mira dos veces. Oro sobre verde, letra más
   grande y un destello que barre en diagonal. */
#banner.goal-angulo { --bnr-glow: rgba(255, 209, 92, 0.32); --bnr-bar: var(--gold); }
#banner.goal-angulo #bannerTitle {
  font-size: calc(var(--t-shout) * 1.1);
  background: linear-gradient(174deg, #fffbe8 6%, var(--gold) 46%, #e0a11c 96%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* con la tinta transparente el text-shadow no proyecta nada: el brillo
     tiene que ser un filtro (mismo problema que en .chTitle) */
  text-shadow: none;
  filter: drop-shadow(0 0 34px rgba(255, 200, 80, 0.5))
          drop-shadow(0 4px 20px rgba(0, 0, 0, 0.8));
}
#banner.goal-angulo.show #bannerTitle { animation: bnrAngulo 0.62s cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes bnrAngulo {
  0% { opacity: 0; letter-spacing: 0.34em; transform: translate(14px, -14px) scale(0.9); }
  100% { opacity: 1; letter-spacing: var(--tr-display); transform: none; }
}

/* Por abajo del arquero: rasante. Entra desde un costado, pegado al piso,
   y no rebota — un tiro bajo no festeja para arriba. */
#banner.goal-bajo { --bnr-glow: rgba(53, 224, 138, 0.22); --bnr-bar: var(--accent); }
#banner.goal-bajo #bannerTitle {
  color: var(--accent);
  text-shadow: 0 0 40px rgba(53, 224, 138, 0.5), 0 4px 30px rgba(0, 0, 0, 0.7);
}
#banner.goal-bajo.show #bannerTitle { animation: bnrBajo 0.5s cubic-bezier(0.2, 0.9, 0.25, 1) both; }
@keyframes bnrBajo {
  0% { opacity: 0; letter-spacing: 0.22em; transform: translateX(-34px) skewX(-9deg); }
  100% { opacity: 1; letter-spacing: var(--tr-display); transform: none; }
}

/* Desviado en la barrera: el gol sucio. Verde apagado con una pizca de
   naranja y un temblor corto — la pelota se fue para donde no era. */
#banner.goal-desvio { --bnr-glow: rgba(255, 154, 77, 0.24); --bnr-bar: #ff9a4d; }
#banner.goal-desvio #bannerTitle {
  color: #b6f5cf;
  text-shadow: 2px 0 0 rgba(255, 154, 77, 0.55), -2px 0 0 rgba(53, 224, 138, 0.45),
               0 4px 30px rgba(0, 0, 0, 0.75);
}
#banner.goal-desvio.show #bannerTitle { animation: bnrDesvio 0.55s ease-out both; }
@keyframes bnrDesvio {
  0% { opacity: 0; transform: translateX(-10px) scale(0.96); }
  35% { opacity: 1; transform: translateX(7px); }
  55% { transform: translateX(-4px); }
  75% { transform: translateX(2px); }
  100% { opacity: 1; transform: none; }
}

/* Al palo: el golpe seco. */
#banner.post { --bnr-glow: rgba(255, 209, 92, 0.22); --bnr-bar: var(--gold); }
#banner.post #bannerTitle {
  color: var(--gold);
  text-shadow: 0 0 34px rgba(255, 209, 92, 0.45), 0 4px 26px rgba(0, 0, 0, 0.75);
}
#banner.post.show #bannerTitle { animation: bnrPost 0.42s cubic-bezier(0.3, 1.6, 0.5, 1) both; }
@keyframes bnrPost {
  0% { opacity: 0; transform: scale(1.16); }
  45% { opacity: 1; transform: scale(0.96) rotate(-1.1deg); }
  70% { transform: scale(1.02) rotate(0.5deg); }
  100% { opacity: 1; transform: none; }
}

/* Atajada: no hay festejo. Se desinfla. */
#banner.save { --bnr-glow: rgba(255, 255, 255, 0.1); --bnr-bar: var(--faint); }
#banner.save #bannerTitle {
  color: #cfd8de;
  font-size: calc(var(--t-shout) * 0.82);
  text-shadow: 0 4px 26px rgba(0, 0, 0, 0.8);
}
#banner.save.show #bannerTitle { animation: bnrSave 0.5s cubic-bezier(0.2, 0.8, 0.3, 1) both; }
@keyframes bnrSave {
  0% { opacity: 0; letter-spacing: 0.18em; transform: scale(1.08); }
  100% { opacity: 1; letter-spacing: var(--tr-display); transform: none; }
}

/* ------------------------------------------------------- estadísticas */

#statsBox {
  position: absolute;
  right: var(--gx-r);
  top: calc(var(--gy-t) + 78px);
  width: 176px;
  padding: 11px 13px 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  animation: slideIn 0.3s cubic-bezier(0.2, 0.9, 0.3, 1);
}
@keyframes slideIn { from { opacity: 0; transform: translateX(12px); } }
.srow {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: var(--t-fine);
  padding: 4px 0;
  color: var(--dim);
  font-weight: var(--w-body);
}
.srow + .srow { border-top: 1px solid rgba(255, 255, 255, 0.05); }
.srow b {
  color: var(--ink);
  font-family: var(--font-num);
  font-size: var(--t-base);
  font-weight: var(--w-strong);
  letter-spacing: 0.01em;
  text-align: right;
  font-synthesis-weight: none;
}

/* ------------------------------------------- ayuda táctil (primer uso) */

#touchHelp {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(300px, 84vw);
  padding: 20px 20px 16px;
  background: rgba(9, 15, 23, 0.94);
  border: 1px solid var(--line);
  border-radius: 6px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  display: none;
  pointer-events: auto;
  z-index: 8;
}
#touchHelp.show { display: block; }
#touchHelp .row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--t-base);
  line-height: 1.4;
  color: var(--dim);
  margin-bottom: 13px;
  font-weight: var(--w-body);
}
#touchHelp .row b { color: var(--ink); font-weight: var(--w-mark); }
/* Qué filas se ven según el lado que se juega lo decide la regla de #hud.gk
   de más arriba, no una regla propia de #touchHelp: si hubiera las dos, la
   de acá abajo (más lejos en el archivo) le ganaría a aquella y el modo
   arquero volvería a mostrar los gestos del pateador. */
#touchHelp .ic { font-size: 19px; width: 24px; text-align: center; flex: none; }
#touchHelpOk {
  width: 100%;
  margin-top: 4px;
  padding: 12px;
  font-size: var(--t-base);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-family: var(--font);
  color: #04140c;
  background: var(--accent);
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

/* ============================================================== MENÚ

   IDENTIDAD. El menú era una grilla de tarjetas oscuras: podía ser el panel
   de configuración de cualquier cosa. Ahora se apoya en lo único que este
   juego tiene y ningún otro panel: la cancha que se ve atrás.

     · el fondo repite el corte del césped (franjas verticales apenas
       insinuadas) para que el velo se lea como una continuación del campo
       y no como una capa de software encima
     · un reflector desde arriba, que es de dónde viene la luz en el 3D
     · una línea de tiza —el círculo central— detrás del título
     · la cara condensada de marcador en todos los títulos

   Todo esto vive en #menu y en nada más: durante el juego el HUD sigue
   siendo gris y callado, porque ahí la protagonista es la pelota.          */

#menu, #levelEnd {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* el borde seguro va como padding del velo y no como margen de la ficha:
     con margen se rompe el centrado; con padding la ficha se centra dentro
     de lo que queda, que es justo lo que hay que hacer en apaisado, donde
     el notch se come 44 px de un costado */
  padding: var(--gy-t) var(--gx-r) var(--gy-b) var(--gx-l);
  opacity: 0;
  pointer-events: none;
  /* visibility apagada con retardo: sin esto, un velo a pantalla completa
     con backdrop-filter queda compuesto durante TODA la partida aunque esté
     en opacity 0. El retardo es el mismo que la transición para que el
     desvanecido se siga viendo al cerrar. */
  visibility: hidden;
  transition: opacity 0.32s ease, visibility 0s linear 0.32s;
  z-index: 10;
  font-variant-numeric: tabular-nums;
}
#menu.show, #levelEnd.show {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity 0.32s ease, visibility 0s;
}

#levelEnd {
  background: rgba(4, 7, 11, 0.86);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}

#menu {
  background:
    radial-gradient(120% 70% at 50% -8%, rgba(53, 224, 138, 0.11), transparent 58%),
    radial-gradient(90% 60% at 50% 108%, rgba(255, 209, 92, 0.06), transparent 60%),
    repeating-linear-gradient(
      90deg,
      rgba(255, 255, 255, 0.022) 0 54px,
      rgba(0, 0, 0, 0.045) 54px 108px
    ),
    rgba(4, 7, 11, 0.88);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}
/* el círculo de tiza. Absoluto a propósito: como hijo posicionado NO cuenta
   como ítem del flex y el centrado de la ficha no se entera de que existe */
#menu::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -46px;
  width: min(640px, 88vw);
  aspect-ratio: 1;
  transform: translateX(-50%);
  border: 2px solid rgba(255, 255, 255, 0.045);
  border-radius: 50%;
  pointer-events: none;
}

.card { width: min(680px, 100%); text-align: center; }
/* La ficha nunca puede ser más alta que la pantalla: las grillas de adentro
   se encogen antes que dejar el layout cortado por abajo. */
#menu .card {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  max-height: 100%;
}
#menu .card > div { min-height: 0; }
#menuMain { overflow-y: auto; overflow-x: hidden; padding: 2px 0; }
/* Las páginas con grilla son columnas flex para que la grilla sea lo único
   que ceda alto cuando la ventana es baja: el encabezado y los botones no
   se van nunca fuera de la pantalla. Todas arrancan con display:none puesto
   a mano en el HTML; 80-main.js lo devuelve a '' y entonces manda esto. */
#menuLevels, #menuWC, #menuSchool, #menuDaily, #menuCareer, #menuPartido {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* #menuCareer faltaba en esa lista y se notaba: la ficha crecía hasta
   pasarse de la pantalla y en 375×812 el botón de "Volver" quedaba abajo
   del borde inferior, sin ninguna señal de que estaba ahí.

   CÓMO SE REPARTE EL ALTO, que costó tres intentos:

   1. Nadie se encoge. `flex: none` en todo. Un ítem de flex se achica por
      debajo de su contenido sin avisar y el contenido NO scrollea: se corta.
      El primer intento dejaba el título "Carrera" de 12 px de alto y los
      botones de 19, con las letras partidas al medio. El segundo arreglaba
      eso pero encogía #carDash, y entonces la tabla, la fila de la Selección
      y la vitrina se salían por abajo y quedaban debajo de los botones.

   2. Quien decide cuánto mide la tabla es --rows, no el reparto de flex.
      Es un número por punto de quiebre, se lee de un vistazo y no depende
      de qué otra cosa haya crecido en la pantalla. Es además como ya
      funcionan #levelGrid, #wcGroups y #schoolGrid.

   3. Y si aun así no entra, scrollea la página. Es la salida honesta: se
      ve que hay más y se llega. Cortar un botón no avisa nada. */
#carDash { display: flex; flex-direction: column; }
#menuCareer { overflow-y: auto; overscroll-behavior: contain; }
#menuCareer > div,
#carDash > div { flex: none; }

.btns { margin-top: 34px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
button.big, #leButtons button {
  padding: 13px 26px;
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-family: var(--font);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.16s, border-color 0.16s, transform 0.16s;
}
button.big:hover, #leButtons button:hover {
  background: rgba(255, 255, 255, 0.11);
  border-color: var(--faint);
  transform: translateY(-1px);
}
button.primary, #leButtons button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #04140c;
}
button.primary:hover, #leButtons button.primary:hover {
  background: #4bf39c;
  border-color: #4bf39c;
}

.menuHead { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.menuHead h2 { font-size: var(--t-head); line-height: 1; }
.menuHead .tot { font-size: var(--t-small); color: var(--dim); font-weight: var(--w-body); }
.menuHead .tot b {
  color: var(--ink);
  font-family: var(--font-num);
  font-size: var(--t-title);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  font-synthesis-weight: none;
}

/* ================================================ CAJAS QUE SCROLLEAN

   El problema real: #levelGrid y #wcGroups scrolleaban, pero cortaban una
   fila justo por la mitad y sin ninguna señal. Media tarjeta de nivel
   colgando del borde no se lee como "hay más": se lee como layout roto. En
   el selector del Mundial directamente desaparecían dos de los cuatro
   equipos de los grupos de abajo.

   Tres arreglos, y hacen falta los tres:

   1. ALTO EN MÚLTIPLOS DE FILA. La grilla de niveles tiene fila de alto fijo
      (--lv-row) y su max-height se calcula como N filas + N-1 huecos. Nunca
      cae por la mitad de una tarjeta. N baja con la altura de la ventana.

   2. SOMBRAS DE SCROLL. La receta de capas `local`/`scroll`: las dos tapas
      del color del panel viajan CON el contenido, las dos sombras se quedan
      quietas respecto de la caja. Arriba de todo la tapa cubre la sombra y
      no se ve nada; apenas scrolleás, la tapa se va y la sombra aparece.
      Sale gratis y sin una línea de JS. Por eso estas cajas necesitan fondo
      OPACO (--panel-sunk): con fondo transparente no hay con qué tapar.

   3. BARRA VISIBLE. Fina y con color propio, no la del sistema que en Mac
      se esconde hasta que la tocás.                                        */

.scrollBox {
  position: relative;
  margin-top: 20px;
  min-height: 0;
  display: flex;
}
.scrollBox > * {
  background:
    linear-gradient(var(--panel-sunk) 34%, rgba(7, 12, 19, 0)) local top / 100% 38px no-repeat,
    linear-gradient(rgba(7, 12, 19, 0), var(--panel-sunk) 66%) local bottom / 100% 38px no-repeat,
    radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0))
      scroll top / 100% 16px no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0))
      scroll bottom / 100% 16px no-repeat,
    var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: 4px;
  scrollbar-width: thin;
  scrollbar-color: rgba(242, 246, 248, 0.26) transparent;
  /* El eje vertical, dicho en voz alta: el body lo tenía prohibido para todo
     el árbol y estas cajas no se podían scrollear con el dedo. `contain`
     para que llegar al final no arrastre el velo del menú. */
  touch-action: pan-y;
  overscroll-behavior: contain;
}
.scrollBox > *::-webkit-scrollbar { width: 9px; }
.scrollBox > *::-webkit-scrollbar-track { background: transparent; }
.scrollBox > *::-webkit-scrollbar-thumb {
  background: rgba(242, 246, 248, 0.22);
  border: 3px solid transparent;
  background-clip: padding-box;
  border-radius: 9px;
}
.scrollBox > *::-webkit-scrollbar-thumb:hover { background: rgba(242, 246, 248, 0.4); background-clip: padding-box; }

/* ------------------------------------------------------ grilla niveles */

#levelGrid, #schoolGrid {
  /* 92 = las cuatro líneas de la tarjeta con el nombre en DOS renglones, que
     es lo que pasa con "Aparece el arquero" a este ancho. La fila es fija
     (si no, el alto en múltiplos de fila no significa nada) así que tiene
     que estar medida para el caso peor: acá adentro hay overflow:hidden y
     un desborde no avisa, recorta. */
  --lv-row: 92px;
  --lv-gap: 8px;
  --rows: 5;
  flex: 0 1 auto;
  width: 100%;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  grid-auto-rows: var(--lv-row);
  gap: var(--lv-gap);
  max-height: calc(
    var(--rows) * var(--lv-row) + (var(--rows) - 1) * var(--lv-gap) + 24px
  );
  overflow-y: auto;
  padding: 12px;
}
#schoolGrid { --lv-row: 104px; --rows: 4; grid-template-columns: repeat(auto-fill, minmax(184px, 1fr)); }

button.lvl, #schoolGrid button {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 3px;
  padding: 10px 11px;
  background: rgba(255, 255, 255, 0.045);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
  color: var(--ink);
  font-family: var(--font);
  text-align: left;
  transition: background 0.15s, border-color 0.15s;
}
button.lvl:hover:not(.locked), #schoolGrid button:hover:not(.locked) {
  background: rgba(53, 224, 138, 0.1);
  border-color: var(--accent-dim);
}
button.lvl.locked, #schoolGrid button.locked { opacity: 0.34; cursor: not-allowed; }
/* El :not() no es adorno: `button.lvl > *` pesa (0,1,1) y le ganaba al
   `position:absolute` de .lvPrev (0,1,0). La vista previa volvía al flujo,
   empujaba el texto y `overflow:hidden` se lo comía sin decir nada. */
button.lvl > *:not(.lvPrev),
#schoolGrid button > *:not(.lvPrev) { position: relative; z-index: 1; }
button.lvl .num, #schoolGrid .num { color: var(--dim); }
button.lvl .nm, #schoolGrid .nm {
  font-size: var(--t-small);
  font-weight: var(--w-strong);
  letter-spacing: 0.01em;
  line-height: 1.15;
}
#schoolGrid .nm { font-size: var(--t-lead); line-height: 1.05; }
button.lvl .ft, #schoolGrid .ft, #schoolGrid .hint {
  font-size: var(--t-mark);
  color: var(--accent);
  letter-spacing: 0.06em;
  font-weight: var(--w-mid);
}
#schoolGrid .hint {
  color: var(--dim);
  font-size: var(--t-fine);
  letter-spacing: 0;
  line-height: 1.35;
  text-transform: none;
}
/* line-height 1 fijo: el candado es un emoji y su caja de línea por defecto
   es tres píxeles más alta que la de las estrellas. Con la fila de alto fijo
   eso alcanzaba para que las tarjetas cerradas recortaran por abajo. */
button.lvl .st, #schoolGrid .st {
  font-size: var(--t-small);
  line-height: 1;
  color: var(--gold);
  letter-spacing: 0.1em;
}

/* Vista previa del nivel: 80-main.js inyecta un <canvas class="lvPrev"> acá
   adentro. Va como FONDO de la tarjeta, no como un bloque en el flujo, por
   dos razones: (a) así la tarjeta mide siempre lo mismo tenga o no vista
   previa, que es lo que sostiene el alto en múltiplos de fila de arriba, y
   (b) no hay forma de que desborde. El velo de encima lo hace legible sin
   depender de qué colores dibuje el canvas. */
.lvPrev {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0.42;
  pointer-events: none;
  border-radius: 2px;
}
button.lvl:has(.lvPrev)::after, #schoolGrid button:has(.lvPrev)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(100deg, rgba(6, 10, 16, 0.88) 34%, rgba(6, 10, 16, 0.3) 100%);
}
button.lvl:hover .lvPrev, #schoolGrid button:hover .lvPrev { opacity: 0.6; }

/* -------------------------------------------------------- fin de nivel */

#leStars { margin: 22px 0 6px; font-size: 40px; letter-spacing: 8px; }
#leStars .star { color: rgba(255, 255, 255, 0.13); }
#leStars .star.on { color: var(--gold); text-shadow: 0 0 26px rgba(255, 209, 92, 0.5); }
#leTitle { font-size: var(--t-big); line-height: 1; }
#leSub { margin-top: 12px; font-size: var(--t-base); color: var(--dim); font-weight: var(--w-body); }
#leButtons { margin-top: 28px; display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* =========================================================================
   MUNDIAL 2026
   ========================================================================= */

/* =========================================================================
   LA PORTADA

   Una ficha centrada: encabezado, seis tarjetas de modo del MISMO tamaño en
   una grilla de 3×2, y abajo de todo la barra de la guía de tiro.

   POR QUÉ TODAS IGUALES. Son seis puertas al mismo juego y el jugador elige
   con el nombre y con la etiqueta de estado, no con el tamaño de la caja.
   La única jerarquía es de COLOR y va en una sola tarjeta: `.mode.primary`
   (la Carrera) lleva borde y fondo de acento suave. Es el único relleno de
   acento de la portada; lo demás que está en verde es texto.

   LAS TARJETAS SON LOS BOTONES CABLEADOS (#btnCareer, #btnWorldCup…), así
   que estas reglas se escriben sobre `button.mode` y no sobre una capa de
   presentación. Cuando un módulo no cargó, su botón queda en display:none y
   la tarjeta desaparece sola: la grilla se cierra y no queda un hueco.

   El velo, el círculo de tiza y el reflector de #menu se quedan como están:
   esto es sólo lo que va adentro de la ficha.                             */

/* Seis tarjetas en 3×2 no entran en los 680 px de la ficha normal: a 218 px
   de columna la descripción cae a cinco renglones y el nombre del modo se
   parte al medio. A 860 la columna da 275 y las descripciones ocupan las dos
   o tres líneas para las que están escritas. */
#menu .card.portada { width: min(860px, 100%); }
/* Columna flex y no un bloque suelto: la ficha no puede pasar de la altura
   de la pantalla (#menu .card tiene max-height:100%) y algo tiene que ceder
   cuando no entra. El que cede es .modes, que scrollea; el encabezado, la
   barra de la guía y el pie van con flex:none y no se mueven. Sin esto, en
   500×757 medido, el pie caía en 762 —cinco píxeles abajo del borde— y no
   había forma de llegar a "Ajustes". */
#menu .card.portada > #menuMain {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
#menuMain > .kicker,
#menuMain > .logo,
#menuMain > .tagline { flex: none; }

/* ---- encabezado: versalita, logotipo, línea y bajada */
.kicker {
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  text-transform: uppercase;
  color: var(--faint);
}
.logo {
  margin-top: 12px;
  font-family: var(--font-display);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-display);
  font-synthesis-weight: none;
  font-size: clamp(54px, 8.4vw, 86px);
  line-height: 0.92;
  text-transform: uppercase;
  color: var(--ink);
}
/* la mitad verde de la marca. `em` sin bastardilla: acá no es énfasis, es
   la segunda pieza del logotipo, y por eso van pegadas sin espacio */
.logo em { font-style: normal; color: var(--accent); }
/* la línea divisoria: corta y centrada, para que separe el logotipo de la
   bajada sin partir la ficha en dos */
.logo::after {
  content: "";
  display: block;
  width: 56px;
  height: 2px;
  margin: 18px auto 0;
  background: var(--faint);
}
.tagline {
  margin-top: 15px;
  font-size: var(--t-base);
  font-weight: var(--w-body);
  color: var(--dim);
}

/* ---- la grilla de modos */
.modes {
  margin-top: 30px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  /* la grilla es lo único que cede alto cuando la ventana es baja: el
     encabezado, la barra de la guía y el pie no se van nunca fuera de la
     pantalla. `1 1 auto` con `min-height:0` es lo que la deja encogerse por
     debajo de su contenido; sin el min-height un ítem de grilla no achica */
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  align-content: start;
  /* TODAS LAS FILAS IGUALES. Con filas automáticas cada una mide lo que mide
     su descripción más larga, y medido a 390×844 la tercera daba 160 contra
     167 de las dos de arriba: seis tarjetas que se prometen iguales y no lo
     son. `1fr` en una grilla de alto indefinido reparte parejo y todas
     terminan en el alto de la fila más alta.
     Por eso también `flex-grow: 0`: si la grilla creciera para llenar la
     ficha, esas filas de 1fr se estirarían con ella y en una ventana alta
     las tarjetas quedarían enormes y vacías. */
  grid-auto-rows: 1fr;
}
button.mode {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 172px;
  padding: 15px 16px 14px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line);
  border-radius: 5px;
  color: var(--ink);
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: background 0.16s, border-color 0.16s, transform 0.16s;
}
button.mode:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: var(--faint);
  transform: translateY(-2px);
}
/* LA ÚNICA TARJETA DESTACADA. Va con doble clase (`button.mode.primary`) a
   propósito: `button.primary` es el botón de acción sólido del resto de la
   hoja y pintaría la Carrera de verde entero. Acá el acento es el marco y un
   fondo apenas encendido, que es lo que destaca sin gritar. */
button.mode.primary {
  background: var(--accent-dim);
  border-color: rgba(53, 224, 138, 0.5);
  color: var(--ink);
}
button.mode.primary:hover {
  background: rgba(53, 224, 138, 0.26);
  border-color: var(--accent);
}
.mode .mIco {
  font-size: 20px;
  line-height: 1;
  /* el emoji lo pinta la fuente de color del sistema: sin esto hereda el
     peso 800 del resto de la tarjeta y en Windows sale como caja vacía */
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  font-weight: 400;
}
/* .mName y .mTag ya traen la cara de display y la de versalita de los dos
   grupos tipográficos de arriba; acá sólo van tamaño, color y aire. */
.mode .mName { margin-top: 11px; font-size: 21px; line-height: 1; }
.mode .mDesc {
  margin-top: 8px;
  font-size: var(--t-small);
  line-height: 1.5;
  font-weight: var(--w-body);
  color: var(--dim);
}
/* el estado siempre pegado abajo, para que las seis etiquetas queden en la
   misma línea de la grilla aunque las descripciones midan distinto */
.mode .mTag { margin-top: auto; padding-top: 10px; color: var(--accent); }

/* ---- la barra de la guía de tiro.

   Es la única decisión que se toma antes de patear y vale para los cuatro
   modos, así que es una barra y no una tarjeta: no compite con las seis
   puertas porque no es una puerta. */
#assistBox {
  flex: none;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
}
#assistBox .aLbl {
  flex: none;
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  text-transform: uppercase;
  color: var(--dim);
}
#assistBox .aSlot { flex: none; }
#assistBox .aDesc {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--t-small);
  line-height: 1.4;
  font-weight: var(--w-body);
  color: var(--faint);
}

/* ---- el pie discreto: versión, sonido y las dos pantallas nuevas */
#pF {
  flex: none;
  margin-top: 14px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
/* `margin-left:auto` y no sólo el `space-between` del pie: en el archivo
   único el toggle de versión no se dibuja (la carpeta three no viaja) y con
   un solo hijo el space-between no reparte nada — los links se iban al borde
   izquierdo y el pie quedaba descolgado. */
.fLinks { display: flex; align-items: center; gap: 18px; margin-left: auto; }
/* `.fLinks button` y no `#pF button`: el toggle de versión también es un
   botón adentro del pie, y con el selector de id (1,0,1) el `padding: 0` de
   acá le ganaba a `.vSwitch button` (0,1,1) y le comía los 12 px que separan
   CLÁSICA de 3D. Se leía "CLÁSICA3D", una palabra sola. */
.fLinks button {
  padding: 0;
  /* El blanco de toque es la FILA, no el renglón: medidos a 390×844 los
     links daban 84×14 y con el pulgar se le erra. Estirados al alto del pie
     el rectángulo pasa a 40 px sin que se mueva un píxel de lo que se ve. */
  align-self: stretch;
  font-family: var(--font);
  font-size: var(--t-small);
  font-weight: var(--w-body);
  color: var(--dim);
  background: none;
  border: 0;
  cursor: pointer;
}
.fLinks button:hover { color: var(--ink); }
/* lo único del pie que le sirve al que llega por primera vez */
.fLinks button.destaca { color: var(--accent); }
/* El ♪ es un link más del pie y no una cajita con borde: encajonado era el
   único elemento con marco de toda la fila y se leía como un control de otra
   familia. Ancho fijo porque el glifo cambia (♪ / ✕) y sin él la fila entera
   se corre tres píxeles cada vez que se silencia el juego. */
.fLinks .pIco {
  width: 18px;
  display: grid;
  place-items: center;
  font-size: 14px;
}
.pIco.off { color: var(--faint); }

/* ---- el toggle CLÁSICA | 3D */
.vSwitch {
  display: flex;
  padding: 2px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line);
  border-radius: 3px;
}
.vSwitch button {
  position: relative;
  align-self: auto;
  padding: 4px 12px;
  font-family: var(--font);
  font-size: 9.5px;
  font-weight: var(--w-mark);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  background: none;
  border: 0;
  border-radius: 2px;
  cursor: pointer;
}
/* la activa en pastilla sólida, y la pastilla es NEUTRA: si fuera de acento
   habría dos rellenos de acento en la pantalla y el destaque de la Carrera
   dejaría de ser el único */
.vSwitch button.on { background: rgba(255, 255, 255, 0.13); color: var(--ink); }
/* el marcador de experimental. No dice BETA en un cartel: hace el mismo
   trabajo sin gritar */
.vSwitch .exp {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 5px;
  vertical-align: 1px;
  border-radius: 50%;
  background: var(--accent);
}
/* Atenuado hasta que el jugador terminó el rito de entrada: una bifurcación
   de motor gráfico es una decisión sin significado para alguien que todavía
   no vio la cancha.
   PERO EL MARCO SE QUEDA. Sacándole el fondo Y el borde Y la pastilla, las
   dos palabras quedaban sueltas sobre el velo y se leían pegadas
   —"CLÁSICA3D"—: parecía un texto roto, no un control apagado. Ahora lo que
   baja es el contraste; que es un interruptor de dos posiciones se sigue
   viendo. */
.vSwitch.off { opacity: 0.5; }
.vSwitch.off .exp { display: none; }

/* ---- Entrenamiento: las dos solapas (lecciones / desafíos).
   `.seg` reparte el ancho entre sus botones y se estira a lo que le den; acá
   el contenedor es la pantalla entera, así que el ancho se declara a mano y
   los botones necesitan aire lateral: "Lecciones" y "Desafíos" son palabras
   largas al lado de PATEAR / ATAJAR, para las que se calibró el control. */
.trainTabs { margin: 14px 0 0; width: 300px; max-width: 100%; flex: none; }
.trainTabs button { padding: 8px 10px; letter-spacing: var(--tr-caps); font-size: var(--t-small); }

/* ---- Cómo se patea */
#howBody {
  margin-top: 16px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.howCol {
  padding: 16px 18px;
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: 5px;
  text-align: left;
}
.howCol .mark { display: block; margin-bottom: 10px; }
.howCol p { margin-top: 8px; font-size: var(--t-small); line-height: 1.55; color: var(--dim); }
.howCol p b { color: var(--ink); font-weight: var(--w-mark); }
.howCol p.fine { margin-top: 14px; font-size: var(--t-fine); color: var(--faint); }

/* ---- Ajustes */
#setBody { margin-top: 16px; text-align: left; }
.setRow {
  display: grid;
  grid-template-columns: 130px auto;
  align-items: center;
  gap: 8px 18px;
  padding: 14px 2px;
  border-top: 1px solid var(--line);
}
.setRow:last-child { border-bottom: 1px solid var(--line); }
.setRow .sLbl { font-size: var(--t-base); font-weight: var(--w-mid); }
.setRow .sVal { font-size: var(--t-base); color: var(--dim); }
.setRow .sHint {
  grid-column: 2;
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--faint);
  font-weight: var(--w-body);
}
.setRow .sBtn {
  justify-self: start;
  padding: 7px 16px;
  font-family: var(--font);
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}
.setRow .sBtn:hover { border-color: var(--faint); }
.setRow .sBtn.warn { color: var(--warn); border-color: rgba(255, 122, 110, 0.4); }
.setRow .sSlot .seg { margin-bottom: 0; }

/* -------------------------------------------------- elegir la selección */

#menu .card.wide { width: min(1180px, 100%); }

.wcLead {
  margin-top: 12px;
  max-width: 760px;
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--dim);
  font-weight: var(--w-body);
  text-align: left;
}

#wcResume {
  margin-top: 16px;
  padding: 13px 15px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  text-align: left;
  border: 1px solid rgba(255, 209, 92, 0.42);
  border-radius: 4px;
  background: rgba(255, 209, 92, 0.08);
}
#wcResume .rTx { flex: 1 1 240px; font-size: var(--t-base); font-weight: var(--w-strong); }
#wcResume .rTx span {
  display: block;
  margin-top: 3px;
  font-size: var(--t-small);
  font-weight: var(--w-body);
  color: var(--dim);
}
#wcResume button {
  padding: 9px 16px;
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-family: var(--font);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}
#wcResume button.primary { background: var(--gold); border-color: var(--gold); color: #23180a; }

/* Sin esto el botón deshabilitado se ve igual de verde que el activo y
   parece que el juego no responde al click. */
button.big:disabled,
button.big.primary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--line);
}

#wcGroups {
  /* 172 = encabezado + cuatro equipos con uno de ellos en dos líneas
     ("Bosnia y Herzegovina"), que es el caso peor y el que hacía que la fila
     de abajo quedara cortada por la mitad a 1280×720 */
  --grp-row: 172px;
  --grp-gap: 9px;
  --rows: 3;
  flex: 0 1 auto;
  width: 100%;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: var(--grp-gap);
  /* Acá el alto de fila NO se puede fijar: "Bosnia y Herzegovina" ocupa dos
     líneas y su tarjeta es más alta que las demás. El múltiplo es entonces
     aproximado y quien realmente avisa que hay más son las sombras. */
  max-height: calc(
    var(--rows) * var(--grp-row) + (var(--rows) - 1) * var(--grp-gap) + 24px
  );
  overflow-y: auto;
  padding: 12px;
  text-align: left;
}
.grp {
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--panel-solid);
  overflow: hidden;
  align-self: start;
}
.grp h4 {
  padding: 8px 10px 7px;
  color: var(--dim);
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--line);
}
button.tm {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 9px;
  background: none;
  border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  color: var(--ink);
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  transition: background 0.13s;
}
.grp button.tm:last-child { border-bottom: none; }
button.tm:hover { background: rgba(53, 224, 138, 0.11); }
button.tm.on { background: rgba(53, 224, 138, 0.2); box-shadow: inset 2px 0 0 var(--accent); }
button.tm .tn { flex: 1; font-size: var(--t-small); font-weight: var(--w-mid); line-height: 1.2; }
button.tm .tr { display: flex; gap: 2px; flex: none; }
button.tm .tr i { width: 4px; height: 4px; border-radius: 50%; background: rgba(255, 255, 255, 0.15); }
button.tm .tr i.on { background: var(--gold); }

svg.jsy { display: block; flex: none; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)); }

/* ====================================================== CARRERA =========

   El escudo es la pieza que se repite en todas las pantallas del modo —
   menú, ofertas, marcador, resumen, retiro— así que su regla es una sola y
   sirve tanto para el escudo dibujado como para el archivo real del club.

   Tres cosas y ninguna es decorativa:

     · el lienzo es CUADRADO y el escudo se inscribe adentro. Así escala
       por ALTURA y no por ancho, que es lo que hace que un escudo alto y
       uno ancho pesen igual en la misma fila;
     · el disco neutro que se ve por detrás lo dibuja el propio SVG (no
       este archivo), para que valga igual en la vista 3D, que tiene su
       CSS aparte. Sin disco, un escudo rectangular y uno circular
       desalinean la fila de ofertas;
     · SIN SOMBRA. Acá había un `drop-shadow` en `.crest` y otro más
       fuerte en `.retPath`. Un escudo real ya trae su propio ruido
       gráfico, y una sombra debajo de doce escudos de 20 px en la línea
       de tiempo convierte la fila en una mancha.
   ======================================================================== */

.crest {
  display: block;
  flex: none;
}
img.crest { object-fit: contain; }

/* ---------------------------------------------------- identidad (nuevo) */

/* La pantalla de identidad son dos columnas: la camiseta a la izquierda y
   los campos a la derecha. Debajo de 620 px se apila, y la camiseta queda
   arriba —el mismo orden del DOM—, que es donde tiene que estar: es la que
   convierte cuatro campos en un jugador.

   `min-content` en la primera columna y no un ancho fijo: la camiseta se
   dimensiona sola con su propio `width`, y así el hueco entre las dos
   columnas no depende de un número escrito dos veces. */
.carIdent {
  margin: 20px auto 0;
  width: min(560px, 100%);
  display: flex;
  align-items: center;
  gap: 22px;
  text-align: left;
}
.carFields { flex: 1 1 auto; min-width: 0; }

/* ---- la camiseta

   Los tres colores son variables para que el que cablea pueda vestirla con
   el kit del club o de la Selección sin tocar la hoja. El valor por defecto
   es un gris de utilería con el vivo verde de la marca: todavía no hay club,
   y ponerle uno de mentira sería prometer algo. */
.jsyPrev {
  --jsy-shirt: #1b2530;
  --jsy-trim: var(--accent);
  --jsy-ink: #f2f6f8;
  flex: none;
  width: 172px;
  filter: drop-shadow(0 10px 26px rgba(0, 0, 0, 0.6));
}
.jsyPrev svg { display: block; width: 100%; height: auto; }
.jsyPrev .jBody { fill: var(--jsy-shirt); }
.jsyPrev .jTrim { fill: var(--jsy-trim); }
/* El contorno oscuro es el mismo recurso que usa WC.jerseySVG: sin él, una
   camiseta oscura sobre el panel oscuro no tiene silueta. */
.jsyPrev .jEdge { fill: none; stroke: rgba(0, 0, 0, 0.5); stroke-width: 2.5; }
.jsyPrev .jName {
  font-size: 9.5px;
  fill: var(--jsy-ink);
  letter-spacing: 0.06em;
}
.jsyPrev .jNum {
  font-family: var(--font-num);
  font-size: 42px;
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  fill: var(--jsy-ink);
  font-synthesis-weight: none;
}

/* El ancho ya no lo pone .carId sino la columna que lo contiene: con el
   `width: min(420px,100%)` y el `margin: 0 auto` que tenía cuando vivía
   suelto, los dos campos quedaban descentrados respecto de la camiseta que
   ahora tienen al lado. */
.carId { display: flex; gap: 12px; flex-wrap: wrap; text-align: left; }
.carId .fld { flex: 1 1 220px; display: block; }
.carId .fld.num { flex: 0 0 96px; }
.carId .fld > span { display: block; color: var(--dim); margin-bottom: 6px; }
.carId input {
  width: 100%;
  padding: 11px 13px;
  font-family: var(--font-display);
  font-size: var(--t-title);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-display);
  text-transform: uppercase;
  color: var(--ink);
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: 3px;
  outline: none;
}
.carId .fld.num input { text-align: center; font-variant-numeric: tabular-nums; }
.carId input:focus { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-dim); }
.carId input::placeholder { color: var(--faint); }

/* ---- filas de opciones: pierna hábil y especialidad

   Las dos son lo mismo —una etiqueta arriba y fichas elegibles abajo— así
   que se estilan juntas. Antes la pierna hábil vivía en su propio bloque al
   FINAL del archivo, después del media query del teléfono: cualquier ajuste
   móvil suyo era imposible sin `!important`. Ahora está acá, en la sección
   que le corresponde, y el móvil manda porque va después. */

.fldRow { margin-top: 15px; }
.fldRow .fldLbl { display: block; color: var(--dim); margin-bottom: 7px; }

/* Las fichas ya traen borde propio; el marco de `.seg` alrededor de todas es
   un segundo borde encerrando al primero, y su `margin-bottom` era un hueco
   que nadie había pedido. Se apagan acá en vez de sacarle la clase al
   markup: `.seg` es también lo que emparenta este control con el
   interruptor patear/atajar del panel de práctica. */
.fldRow .seg {
  border: 0;
  border-radius: 0;
  overflow: visible;
  margin-bottom: 0;
  gap: 6px;
}

.fldRow .seg button,
#carStyle button {
  padding: 8px 12px;
  font-family: var(--font);
  font-size: 12px;
  font-weight: var(--w-mid);
  letter-spacing: 0.03em;
  text-transform: none;
  color: var(--dim);
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
  transition: color 0.14s, border-color 0.14s, background 0.14s;
}
.fldRow .seg button:hover,
#carStyle button:hover { color: var(--ink); border-color: var(--faint); }
.fldRow .seg button.on,
#carStyle button.on {
  color: var(--accent);
  background: var(--accent-dim);
  border-color: var(--accent);
}

/* ---- especialidad

   Cuatro tiros libres, cada uno con su línea de explicación. Una tira de
   botones (`.seg`) no sirve: "De rosca alta" más su explicación no entra en
   un cuarto de 375 px. Grilla que cae sola a 2×2 en el teléfono. */
#carStyle {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 6px;
}
#carStyle button { display: block; text-align: left; line-height: 1.15; }
#carStyle .stName {
  display: block;
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: 0.03em;
}
#carStyle .stHint {
  display: block;
  margin-top: 4px;
  font-size: var(--t-fine);
  font-weight: var(--w-body);
  line-height: 1.35;
  color: var(--dim);
}
/* Sobre el fondo verde de la ficha elegida, el gris de la explicación se
   apaga demasiado: se le sube el contraste sin robarle el protagonismo al
   nombre, que es el que está en verde. */
#carStyle button.on .stHint { color: rgba(242, 246, 248, 0.72); }

/* --------------------------------------------------------- la ficha */

#carCardTop {
  margin-top: 16px;
  padding: 15px 17px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--panel-solid);
}
#carCardTop .who { flex: 1 1 180px; font-size: var(--t-head); line-height: 1; }
/* El dorsal cuelga del apellido y no compite con él: mismo renglón, más
   chico y en gris. Es una chapa de camiseta, no un dato. */
#carCardTop .who i { font-style: normal; color: var(--faint); font-size: 0.6em; margin-left: 8px; }
#carCardTop .who span {
  display: block;
  margin-top: 5px;
  font-family: var(--font);
  font-size: var(--t-small);
  font-weight: var(--w-mid);
  letter-spacing: 0;
  text-transform: none;
  color: var(--dim);
}
#carCardTop .stat { flex: none; text-align: right; min-width: 74px; }
#carCardTop .lbl { display: block; color: var(--dim); }
#carCardTop .num {
  display: block;
  margin-top: 3px;
  font-family: var(--font-num);
  font-size: var(--t-num);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  font-synthesis-weight: none;
}
#carCardTop .stat.ovr .num { font-size: var(--t-big); color: var(--accent); }
/* La chapa de la Selección: chiquita, arriba a la derecha de la ficha. Es
   el hito que una carrera argentina cuenta primero. */
#carCardTop .cap {
  flex: none;
  align-self: flex-start;
  padding: 4px 8px;
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: #23180a;
  background: var(--gold);
  border-radius: 2px;
}

/* ------------------------------------------------------ línea de tiempo */

/* La ficha ocupa el ancho entero de la tarjeta porque es una placa de
   transmisión; la tabla no. A 1180 px las seis columnas se separan tanto
   que "Real Madrid" y su media quedan en puntas opuestas de la pantalla y
   el ojo tiene que viajar por un renglón vacío. */
#carDash .scrollBox { width: min(860px, 100%); margin: 14px auto 0; }

#carTimeline {
  --rows: 9;
  flex: 0 1 auto;
  width: 100%;
  min-height: 0;
  max-height: calc(var(--rows) * 34px + 40px);
  overflow-y: auto;
  text-align: left;
}
#carTimeline .tr {
  display: grid;
  grid-template-columns: 34px 26px 1fr 58px 40px 1fr;
  gap: 9px;
  align-items: center;
  padding: 6px 12px;
  font-size: var(--t-small);
  font-weight: var(--w-mid);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
#carTimeline .tr:last-child { border-bottom: none; }
#carTimeline .tr.hd { color: var(--dim); background: rgba(255, 255, 255, 0.04); }
#carTimeline .tr.hd b { font-family: var(--font); font-weight: var(--w-mark); text-align: left; }
/* La fila que se está por jugar: es la única con color, para que el ojo
   caiga ahí y no en las once restantes. */
#carTimeline .tr.now { background: rgba(53, 224, 138, 0.13); box-shadow: inset 2px 0 0 var(--accent); }
#carTimeline .tr.soon { color: var(--faint); }
#carTimeline .tr.soon .crest { opacity: 0.25; }
#carTimeline .tr b {
  font-family: var(--font-num);
  font-weight: var(--w-display);
  letter-spacing: 0;
  font-synthesis-weight: none;
}
#carTimeline .tr .cl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La estrellita de la Selección: dorada, o se lee como parte del nombre. */
#carTimeline .tr .cl i { font-style: normal; color: var(--gold); }
#carTimeline .tr .dl { font-size: var(--t-fine); font-weight: var(--w-mark); }
#carTimeline .tr .dl.up { color: var(--accent); }
#carTimeline .tr .dl.dn { color: var(--warn); }
#carTimeline .tr .tt {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--t-fine);
  color: var(--gold);
}

/* ------------------------------------------------------------- vitrina */

#carCase { margin-top: 14px; display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
/* La misma ficha dorada en el menú y en el retiro: es el mismo objeto —un
   título ganado— y verlo distinto en dos pantallas lo volvería dos cosas. */
#carCase .cup,
.retCase .cup {
  padding: 5px 9px;
  font-size: var(--t-fine);
  font-weight: var(--w-mark);
  color: var(--gold);
  border: 1px solid rgba(255, 209, 92, 0.35);
  border-radius: 2px;
  background: rgba(255, 209, 92, 0.08);
}
#carCase .cup b,
.retCase .cup b { font-variant-numeric: tabular-nums; }
#carCase .none,
.retCase .none { font-size: var(--t-small); color: var(--faint); font-weight: var(--w-body); }

/* ---------------------------------------------------------- la Selección

   Va debajo de la tabla, con su mismo ancho, pero NO es una fila más: no
   tiene edad, ni media, ni club, ni compite por el puesto. Como renglón
   trece se leería como si lo fuera.

   Tres cosas la separan y hacen falta las tres:
     · 8 px de aire — la mitad de los 14 que separan al resto de los bloques,
       así queda claro que sigue perteneciendo a la tabla;
     · su propia caja, en vez de compartir el borde de la tabla;
     · el dorado, el mismo de los títulos y de la chapa "Selección Argentina"
       de la ficha. Un renglón gris más abajo de doce renglones grises no lo
       ve nadie.

   Se probó pegándola al borde inferior de la tabla, sin aire y sin esquinas
   propias, y no anduvo: como #natRow arranca en display:none, la tabla se
   quedaba sin sus esquinas de abajo también cuando no había Selección. */
#natRow {
  width: min(860px, 100%);
  margin: 8px auto 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 13px 10px;
  text-align: left;
  border: 1px solid rgba(255, 209, 92, 0.3);
  border-radius: 4px;
  background: linear-gradient(90deg, rgba(255, 209, 92, 0.11), rgba(255, 209, 92, 0.03));
  box-shadow: inset 2px 0 0 var(--gold);
}

#natRow .nrJsy { flex: none; display: flex; }
#natRow .nrJsy svg { display: block; }
#natRow .nrTx { flex: 1 1 auto; min-width: 0; line-height: 1.2; }
#natRow .nrTx b { display: block; font-size: var(--t-lead); color: var(--gold); }
#natRow .nrTx span {
  display: block;
  margin-top: 3px;
  font-size: var(--t-fine);
  font-weight: var(--w-body);
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Centrado y no alineado a la derecha: esto es una tira, no una tabla. Con
   los números a la derecha, el 4 de "PARTIDOS" caía debajo de la última
   sílaba de su propia etiqueta y parecía de la columna de al lado. */
#natRow .nrStat { flex: none; text-align: center; min-width: 52px; }
#natRow .nrStat i { display: block; font-style: normal; color: var(--dim); }
#natRow .nrStat b {
  display: block;
  margin-top: 3px;
  font-family: var(--font-num);
  font-size: var(--t-num);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  font-synthesis-weight: none;
}
/* Las copas del Mundial ganadas con esta camiseta. Van al final de la fila,
   después de los números, porque son lo que uno cuenta último y recuerda
   primero. */
#natRow .nrCups { flex: none; display: flex; gap: 3px; align-items: center; }
#natRow .nrCups i { font-style: normal; font-size: 15px; line-height: 1; }
#natRow .nrCups:empty { display: none; }

/* -------------------------------------------------------------- ofertas */

.carOffers {
  margin-top: 22px;
  display: grid;
  /* 146 y no 150, que es lo que había: la tarjeta mide min(620px,100%) y con
     10 px de hueco, 4×150+30 = 630 no entra y 4×146+30 = 614 sí. O sea que
     150 partía las CUATRO opciones del mercado normal (tres de afuera más
     renovar) en 3+1, y esa segunda fila de una sola tarjeta costaba 255 px
     de alto y dejaba dos tercios de la fila vacíos. Con 4 px menos las cuatro
     entran en una fila de 147 px cada una — que es más ancho del que ya
     tienen en el teléfono, donde se leen bien.
     Los tres de la cantera no se enteran: auto-fit colapsa la cuarta pista
     vacía y los deja en 200 px, exactamente como antes.
     Ese alto es el que hizo lugar para el panel de puntos, que desde este
     cambio comparte pantalla con las ofertas. */
  grid-template-columns: repeat(auto-fit, minmax(146px, 1fr));
  gap: 10px;
  text-align: left;
}
/* Pegado al panel de puntos el aire de arriba sobra: ya lo puso el panel. */
.carPts + .carOffers { margin-top: 14px; }
button.offer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  padding: 15px 12px 13px;
  color: var(--ink);
  font-family: var(--font);
  background: var(--panel-solid);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.14s, background 0.14s, transform 0.14s;
}
button.offer:hover {
  border-color: var(--accent);
  background: rgba(53, 224, 138, 0.09);
  transform: translateY(-2px);
}
.offer .oLeague { color: var(--dim); }
.offer .oName { font-size: var(--t-lead); line-height: 1.1; }
/* El salto de escalón sólo aparece cuando HAY salto, y entonces se pinta:
   dorado si subís, rojo si bajás. Un renglón que dice lo mismo en las tres
   tarjetas es un renglón que nadie lee. */
.offer .oDiff.up { color: var(--gold); }
.offer .oDiff.dn { color: var(--warn); }
.offer .oKick {
  margin-top: -3px;
  font-size: var(--t-fine);
  font-weight: var(--w-mid);
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------- resumen de temporada */

.carSum {
  margin: 22px auto 0;
  width: min(430px, 100%);
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}
.carSum > div { background: var(--panel-solid); padding: 12px 8px 13px; }
.carSum .lbl { display: block; color: var(--dim); }
.carSum .big {
  display: block;
  margin-top: 5px;
  font-size: 30px;
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  font-synthesis-weight: none;
}
.carSum .big.up { color: var(--accent); }
.carSum .big.dn { color: var(--warn); }
.carSum .big em { font-style: normal; font-size: 0.5em; color: var(--dim); margin-left: 3px; }

/* ---------------------------------------------------------- el retiro */

.carRet { margin-top: 6px; }
.carRet h3 { font-size: var(--t-head); line-height: 1; margin-bottom: 4px; }
.carRet .clubs {
  margin: 20px 0 4px;
  display: flex;
  gap: 7px;
  justify-content: center;
  flex-wrap: wrap;
}

/* --------------------------------------------------- marcador en cancha */

#carBar {
  position: absolute;
  top: var(--gy-t);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 7px 14px 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  font-variant-numeric: tabular-nums;
}
#carBar .cbTx { text-align: left; line-height: 1.15; }
#carBar .cbTx b { display: block; font-size: var(--t-lead); }
#carBar .cbTx span { display: block; margin-top: 2px; color: var(--dim); }
#carBar .cbDots { display: flex; gap: 4px; flex: none; }
#carBar .cbDots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
}
#carBar .cbDots i.goal { background: var(--accent); }
#carBar .cbDots i.miss { background: var(--warn); opacity: 0.75; }
#carBar .cbOvr { flex: none; text-align: right; padding-left: 11px; border-left: 1px solid var(--line); }
#carBar .cbOvr i { display: block; font-style: normal; color: var(--dim); }
#carBar .cbOvr b {
  display: block;
  margin-top: 2px;
  font-family: var(--font-num);
  font-size: var(--t-num);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  font-synthesis-weight: none;
}

/* ------------------------------------------------------------- hitos

   La diferencia entre una planilla y una carrera. Se leen como una placa de
   transmisión: vivo de color a la izquierda, versalita arriba, frase abajo.
   Lo que las separa de un toast de software es todo lo que NO tienen —ni
   ícono de campanita, ni botón de cerrar con una cruz, ni esquina superior
   derecha, ni sombra flotando en el aire.

   DÓNDE: banda de abajo a la izquierda, arriba del punto de contacto. Es la
   única franja que no tapa el arco, ni la barrera, ni ninguno de los cuatro
   widgets del HUD. Centrada como #banner se pisaba con el "¡GOL!", que es
   justo el momento en que se anuncia el primer gol de la carrera.

   ANCHO: el que necesite el texto, con un techo. Una placa que ocupa media
   pantalla para decir "Debut" es una placa mal hecha.                       */

#milestones {
  position: absolute;
  left: var(--gx-l);
  /* 128 px = el punto de contacto (104) más su etiqueta y su aire. Es la
     medida real del widget de abajo a la izquierda, no un número redondo. */
  bottom: calc(var(--gy-b) + 128px);
  width: min(340px, calc(100% - var(--gx-l) - var(--gx-r)));
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  /* Un tap en la cancha es como se patea: esta capa NO puede comérselo.
     Lo único clickeable de acá adentro es #msSkip, que se reactiva solo por
     la regla `#hud button { pointer-events: auto }`. */
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}
#milestones.on {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s ease, visibility 0s;
}
#msList { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }

/* El `#milestones > .ms` del final es para el que prefiera colgar las placas
   directamente del contenedor en vez de usar #msList: las dos formas
   funcionan y ninguna obliga a leer esta hoja para acertarle. */
#msList .ms,
#milestones > .ms {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 100%;
  padding: 9px 14px 10px 12px;
  text-align: left;
  background: rgba(9, 15, 23, 0.9);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 3px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  animation: msIn 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
}
/* Entra desde la izquierda, como una placa que se mete en pantalla. Que
   aparezca desvanecida en el lugar la convierte otra vez en un toast. */
@keyframes msIn { from { opacity: 0; transform: translateX(-22px); } }
/* La salida la pide el que cablea poniendo `.gone`; el nodo se saca del DOM
   cuando termina. Sin esto las placas desaparecen de golpe. */
#msList .ms.gone,
#milestones > .ms.gone {
  animation: msOut 0.28s ease-in both;
}
@keyframes msOut { to { opacity: 0; transform: translateX(-14px); } }

.ms .msIc { flex: none; font-size: 17px; line-height: 1.15; }
.ms .msIc:empty { display: none; }
.ms .msTx { min-width: 0; line-height: 1.2; }
.ms .msKick { display: block; color: var(--gold); margin-bottom: 5px; }
.ms .msKick:empty { display: none; }
.ms .msTx b { display: block; font-size: var(--t-lead); }
/* `b ~ span` y no `span` a secas, y esto ya rompió una vez: la volanta
   (.msKick) también es un span adentro de .msTx, y `.ms .msTx span` le gana
   por especificidad al `.ms .msKick` de arriba —le comía el dorado y la
   dejaba en gris de subtexto—. Con el combinador de hermano posterior la
   regla sólo alcanza a lo que viene DESPUÉS del título, que es exactamente
   el subtítulo. No hace falta ninguna clase de más en el markup. */
.ms .msTx b ~ span {
  display: block;
  margin-top: 4px;
  font-size: var(--t-small);
  font-weight: var(--w-body);
  color: var(--dim);
}

/* Saltear. Chiquito y gris: está para el que ya vio el hito veinte veces, no
   para el que lo está viendo por primera vez. */
#msSkip {
  padding: 5px 10px 6px;
  font-family: var(--font);
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  text-transform: uppercase;
  color: var(--dim);
  background: rgba(9, 15, 23, 0.82);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
#msSkip:hover { color: var(--ink); border-color: var(--faint); }
/* Sin `.on` la capa está invisible pero el botón seguiría capturando toques
   sobre la cancha: `visibility:hidden` lo apaga, y esto lo saca del orden de
   tabulación además. */
#milestones:not(.on) #msSkip { display: none; }

/* ------------------------------------------------ marcador del partido */

/* El marcador de Partido comparte la placa por SELECTOR y no por nodo: son
   dos modos y el que entra a uno sale del otro, pero hideWorldCupHud() sólo
   conoce #wcBar. Ojo con lo que este selector NO arrastra: #wcBar aparece
   otra vez adentro del @media de 700 px, donde se compacta, y esa regla no
   viaja con el cambio de acá. El gemelo para #pBar está escrito allá. */
#wcBar, #pBar {
  position: absolute;
  top: var(--gy-t);
  left: 50%;
  transform: translateX(-50%);
  min-width: 250px;
  padding: 8px 15px 9px;
  text-align: center;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 3px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
#wcRound { color: var(--dim); }
.wcTeams {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 13px;
  margin-top: 7px;
}
.wcSide { display: flex; align-items: center; gap: 7px; min-width: 84px; }
.wcSide.rev { flex-direction: row-reverse; }
.wcSide b {
  font-size: var(--t-base);
  font-weight: var(--w-strong);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.wcScore { display: flex; align-items: baseline; gap: 8px; }
.wcScore b {
  font-family: var(--font-num);
  font-size: 26px;
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 0.9;
  font-synthesis-weight: none;
}
.wcScore i { font-style: normal; font-size: var(--t-lead); color: var(--faint); }
.wcDots { display: flex; justify-content: center; gap: 18px; margin-top: 8px; }
.dotRow { display: flex; gap: 4px; }
/* Un punto por tiro: vacío = todavía no pateó, verde = gol, rojo = erró. */
.dotRow i {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1px solid var(--faint);
}
.dotRow i.goal { background: var(--accent); border-color: var(--accent); }
.dotRow i.miss { background: rgba(255, 122, 110, 0.3); border-color: var(--warn); }
.dotRow i.now { border-color: #fff; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.13); }

/* En Mundial la placa del partido ocupa el centro de la primera fila, así
   que la segunda fila baja lo que mide la placa. Se mueve la VARIABLE y no
   el `top` de cada caja: si se pisara cada `top` haría falta una regla con
   #hud.wc por cada ancho de pantalla, y esas reglas (dos ids) le ganan por
   especificidad a las de los bloques de abajo aunque estén escritas antes.
   Ese es exactamente el enredo que este archivo ya tuvo una vez. */
#hud.wc { --row2: calc(var(--gy-t) + 86px); }
#hud.wc #windBox { top: var(--row2); }

/* ==================================================== EL MODO PARTIDO ====

   Tres clases sobre #hud, del mismo estilo que .gk, .wc y .pu:
     .partido  el modo está activo
     .tiro     el modo disparo está abierto
     .tactil   dispositivo sin teclado (isTouchOnly)                        */

/* ---- el marcador. El resto lo hereda del selector compartido con #wcBar */
#pReloj { color: var(--dim); }
/* La lectura fina que reemplaza a los segundos: se lee de reojo y sin
   números. Y no es decoración: sin esta regla el mismo HTML mide 8 px menos
   y las cuentas de aire del teléfono dejan de cerrar. */
#pMitad { height: 2px; margin-top: 6px; background: rgba(255, 255, 255, 0.14); }
#pMitad i { display: block; height: 100%; width: 0; background: var(--accent); }

/* ---- el reloj del modo disparo */
#pShotClock {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--gy-b) + 96px);
  width: min(280px, 46vw);
  height: 4px;
  display: none;
}
#hud.partido.tiro #pShotClock { display: flex; }
#pShotClock .h { flex: 1 1 50%; display: flex; overflow: hidden; }
/* Cada mitad ancla su relleno al lado del CENTRO y se vacía desde afuera.
   Sin transform y sin direction:rtl: dos flex con justify-content opuestos
   dan la simetría exacta y no hay nada que se pueda desfasar. */
#pShotClock .h.l { justify-content: flex-end; }
#pShotClock .h.r { justify-content: flex-start; }
#pShotClock i { width: 0; height: 100%; background: var(--accent); }
#pShotClock.medio i { background: var(--gold); }
#pShotClock.poco i { background: var(--warn); }

/* ---- la palanca y los tres botones (sólo con .tactil)

   La zona de la palanca NO llega a los botones: `right` la corta antes del
   borde de #pTouch. Sin el corte, un pulgar apoyado al lado de PASE mueve al
   jugador, porque #pStick se comería el rectángulo entero de los botones. */
#pStick {
  position: absolute;
  left: 0;
  top: 38%;
  right: calc(var(--gx-r) + 194px);
  bottom: 0;
  display: none;
  touch-action: none;
}
/* El anillo aparece donde apoyaste el dedo: lo posiciona bindTactilPartido
   con left/top en línea, y se ilumina al cruzar el umbral de sprint, que es
   lo único que hace descubrible el "empujá hasta el fondo para correr". */
#pStick i {
  position: absolute;
  width: 112px;
  height: 112px;
  margin: -56px 0 0 -56px;
  border-radius: 50%;
  border: 1px solid rgba(242, 246, 248, 0.22);
  opacity: 0;
  transition: opacity 0.12s ease, border-color 0.12s ease;
}
#pStick.on i { opacity: 1; }
#pStick.corre i { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(53, 224, 138, 0.16); }
#pTouch {
  position: absolute;
  right: var(--gx-r);
  bottom: var(--gy-b);
  width: 190px;
  height: 210px;
  display: none;
}
#hud.partido.tactil #pStick, #hud.partido.tactil #pTouch { display: block; }
/* 62 y no 44: el mínimo del repo son 44 px ("44 y no 40: es el alto del
   blanco de toque"), pero estos tres se aprietan a ciegas, en movimiento y
   con el pulgar en ángulo. */
#pTouch button {
  position: absolute;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  padding: 0;
  background: rgba(9, 15, 23, 0.72);
  border: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--font);
  font-size: 9px;
  font-weight: var(--w-mark);
  letter-spacing: 0.06em;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
#pTouch button:disabled { opacity: 0.28; }
#pbA { right: 6px; bottom: 126px; border-color: rgba(53, 224, 138, 0.45); }
#pbD { right: 70px; bottom: 66px; }
#pbX { right: 6px; bottom: 6px; }

/* ---- la cortina de entretiempo, pausa y final.
        Hermana de #wcCard y con sus mismas reglas: se comparten por
        selector para que las dos fichas del juego se vean iguales. */
#pCard {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  touch-action: pan-y;
  overscroll-behavior: contain;
  padding: var(--gy-t) var(--gx-r) var(--gy-b) var(--gx-l);
  /* Más claro y menos borroso que el del Mundial (0.88 y blur 16): acá
     detrás hay un partido en curso y la idea es que se vea que sigue ahí.
     Un corte a negro en un partido de seis minutos es un frenazo; los
     jugadores caminando detrás del vidrio son medio segundo de aire. */
  background: rgba(4, 7, 11, 0.78);
  backdrop-filter: blur(11px);
  -webkit-backdrop-filter: blur(11px);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
  z-index: 11;
  font-variant-numeric: tabular-nums;
}
#pCard.show {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0s;
}
#pCardIn { width: min(560px, 100%); margin: auto; text-align: center; }
#pCardIn h3 { font-size: var(--t-head); }
#pCardIn .pScore {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin: 18px 0 22px;
}
#pCardIn .pScore b {
  font-family: var(--font-num);
  font-size: 40px;
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  font-synthesis-weight: none;
}
#pCardIn .pScore span { font-size: var(--t-base); font-weight: var(--w-mark); letter-spacing: 0.06em; }
#pCardIn .pTable { margin: 0 auto; max-width: 380px; text-align: left; }
#pCardIn .pLine { margin-top: 18px; color: var(--dim); font-size: var(--t-small); }

/* ---- la placa ancha de la portada */
button.mode.hero {
  /* `flex: none` y no el `0 1 auto` por omisión: la portada es una columna
     flex donde lo único que puede ceder alto es `.modes`, y un ítem de flex
     se achica por debajo de su contenido SIN avisar —el contenido no
     scrollea, se derrama—. Medido a 360×640: sin esto la placa quedaba de
     60 px con la descripción y la etiqueta montadas sobre la grilla. */
  flex: none;
  width: 100%;
  min-height: 0;
  margin-top: 26px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 14px;
  background: rgba(255, 255, 255, 0.05);
}
button.mode.hero .mIco { grid-row: 1 / 3; font-size: 30px; }
button.mode.hero .mName { margin-top: 0; }
button.mode.hero .mDesc { grid-column: 2; margin-top: 2px; }
button.mode.hero .mTag { grid-column: 3; grid-row: 1 / 3; margin-top: 0; }

/* ---- la pantalla previa.
   `flex: 0 1 auto` + `min-height: 0` + `overflow-y: auto` es lo mismo que
   hacen #levelGrid y #schoolGrid adentro de su .scrollBox: sin los tres, el
   cuerpo no se encoge y las 48 camisetas se desbordan por abajo de la ficha
   sin scroll, o sea que el botón "Jugar el partido" queda fuera de la
   pantalla y no hay forma de llegar a él. */
#partidoBody {
  flex: 0 1 auto;
  width: 100%;
  min-height: 0;
  overflow-y: auto;
  padding: 18px;
  text-align: left;
}
#partidoBody .pBlock + .pBlock { margin-top: 22px; }
/* Cuarenta y ocho camisetas por grilla y dos grillas: sin techo, el botón
   "Jugar el partido" queda a seis pantallas de scroll de la primera
   decisión. Con el techo en dos filas y media —la media es la señal de que
   hay más abajo— los cuatro bloques y el botón entran casi enteros. */
#partidoBody .pJerseys {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
  gap: 8px;
  margin-top: 10px;
  max-height: 172px;
  overflow-y: auto;
}
/* La dificultad son cuatro y se ven las cuatro. */
#partidoBody .pOpts { max-height: none; overflow: visible; }
#partidoBody .pJerseys button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 9px 4px 7px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-fine);
  cursor: pointer;
}
#partidoBody .pJerseys button.on { border-color: var(--accent); background: var(--accent-dim); }
#partidoBody .pRow { display: flex; align-items: baseline; gap: 10px; margin-top: 10px; }
#partidoBody .pKeys { margin-top: 10px; display: grid; grid-template-columns: 84px 1fr; gap: 6px 12px; }
#partidoBody .pKeys kbd {
  font-family: var(--font-num);
  font-size: var(--t-fine);
  letter-spacing: 0.04em;
  padding: 3px 6px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
  text-align: center;
}
#partidoBody .pKeys span { color: var(--dim); font-size: var(--t-small); }
#partidoBody .fine { margin-top: 10px; font-size: var(--t-fine); color: var(--faint); }
#partidoBody .mark { display: block; }
/* La columna de Partido en "Cómo se patea" ocupa la fila entera: la grilla
   es de dos y un tercer hijo dejaría media fila vacía al lado. */
#howPartido { grid-column: 1 / -1; }

/* ------------------------------------------------------ turno del rival */

#wcTurn {
  position: absolute;
  left: 50%;
  top: 31%;
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 14px 22px 15px;
  background: rgba(9, 15, 23, 0.88);
  border: 1px solid var(--line);
  border-radius: 5px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 12px);
  transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.2, 0.9, 0.3, 1);
}
#wcTurn.show { opacity: 1; transform: translate(-50%, 0); }
/* el gol es del RIVAL: acá el verde sería mentirle al jugador */
#wcTurn.goal { border-color: rgba(255, 122, 110, 0.55); }
#wcTurn.miss { border-color: rgba(53, 224, 138, 0.55); }
.wtTx { display: flex; flex-direction: column; text-align: left; }
.wtTx b { font-size: 23px; line-height: 1.02; }
#wcTurn.goal .wtTx b { color: var(--warn); }
#wcTurn.miss .wtTx b { color: var(--accent); }
.wtTx span { margin-top: 5px; font-size: var(--t-small); color: var(--dim); font-weight: var(--w-body); }

/* ------------------------------------------------- cortina del torneo */

#wcCard {
  position: absolute;
  inset: 0;
  display: flex;
  /* `align-items: center` acá recortaba: una tarjeta más alta que la
     pantalla se va por arriba Y por abajo a la vez, y sin scroll no hay
     forma de llegar a ninguno de los dos extremos. Pasaba con la previa del
     Mundial en apaisado y va a pasar con el mercado de pases, que suma
     título, párrafo y hasta cuatro opciones con su explicación.
     El centrado lo hace `margin:auto` en #wcCardIn: centra cuando entra y
     arranca desde arriba cuando no. */
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  touch-action: pan-y;
  overscroll-behavior: contain;
  padding: var(--gy-t) var(--gx-r) var(--gy-b) var(--gx-l);
  background: rgba(4, 7, 11, 0.88);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s linear 0.3s;
  z-index: 11;
  font-variant-numeric: tabular-nums;
}
#wcCard.show {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity 0.3s ease, visibility 0s;
}
#wcCardIn { width: min(620px, 100%); margin: auto; text-align: center; }
.wcHead { color: var(--gold); }
.wcVs {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 24px;
  margin: 24px 0 4px;
}
.wcVs .v { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 136px; }
.wcVs .v b { font-size: var(--t-base); font-weight: var(--w-mark); line-height: 1.25; }
.wcVs .v em { font-style: normal; color: var(--dim); }
.wcVs .x { align-self: center; font-size: var(--t-small); letter-spacing: 0.18em; color: var(--faint); font-weight: var(--w-mark); }
/* en la ficha de resultado el `em` es el marcador, no una etiqueta */
.wcVs .v em.sc {
  font-family: var(--font-num);
  font-size: 32px;
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  text-transform: none;
  color: var(--ink);
  margin-top: -2px;
  font-synthesis-weight: none;
}
.wcVs .x.big {
  font-size: 30px;
  letter-spacing: 0;
  color: var(--dim);
  align-self: flex-end;
  padding-bottom: 2px;
}
.wcBig { margin-top: 10px; font-size: var(--t-big); line-height: 1; }
.wcBig.ok { color: var(--accent); }
.wcBig.no { color: var(--warn); }
.wcNote { margin-top: 12px; font-size: var(--t-base); line-height: 1.6; color: var(--dim); font-weight: var(--w-body); }
.wcTable {
  width: min(440px, 100%);
  margin: 22px auto 0;
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
  text-align: left;
}
.wcTable .tr {
  display: grid;
  grid-template-columns: 18px 1fr 26px 26px 30px;
  gap: 7px;
  align-items: center;
  padding: 7px 11px;
  font-size: var(--t-small);
  font-weight: var(--w-mid);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.wcTable .tr:last-child { border-bottom: none; }
.wcTable .tr.hd {
  color: var(--dim);
  background: rgba(255, 255, 255, 0.04);
}
.wcTable .tr.me { background: rgba(53, 224, 138, 0.13); }
.wcTable .tr.qual { box-shadow: inset 2px 0 0 var(--accent); }
.wcTable .tr b {
  text-align: right;
  font-family: var(--font-num);
  font-weight: var(--w-display);
  letter-spacing: 0;
  font-synthesis-weight: none;
}
.wcTable .tr.hd b { font-family: var(--font); font-weight: var(--w-mark); }
.wcTable .tr .nm { display: flex; align-items: center; gap: 7px; min-width: 0; }
.wcTable .tr .nm span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wcPath { display: flex; justify-content: center; gap: 5px; margin-top: 20px; flex-wrap: wrap; }
.wcPath i {
  font-style: normal;
  padding: 5px 8px;
  font-size: var(--t-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-weight: var(--w-mark);
  color: var(--faint);
  border: 1px solid var(--line);
  border-radius: 2px;
}
.wcPath i.done { color: var(--accent); border-color: var(--accent-dim); }
.wcPath i.now { color: #23180a; background: var(--gold); border-color: var(--gold); }
#wcCardIn .btns { margin-top: 26px; }

/* ================================================== CAMPEÓN DEL MUNDO */

#champion {
  position: absolute;
  inset: 0;
  z-index: 14;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 40%, rgba(30, 23, 4, 0.93), rgba(3, 6, 10, 0.975));
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
#champion.show {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity 0.5s ease, visibility 0s;
}
#confetti { position: absolute; inset: 0; width: 100%; height: 100%; }
.chIn { position: relative; z-index: 2; text-align: center; padding: 0 16px; }

/* rayos girando detrás de la copa */
.chRays {
  position: absolute;
  left: 50%;
  top: 110px;
  width: 760px;
  height: 760px;
  margin: -380px 0 0 -380px;
  border-radius: 50%;
  pointer-events: none;
  background: repeating-conic-gradient(
    from 0deg,
    rgba(255, 209, 92, 0.13) 0deg 7deg,
    transparent 7deg 20deg
  );
  -webkit-mask-image: radial-gradient(circle, #000 10%, transparent 60%);
  mask-image: radial-gradient(circle, #000 10%, transparent 60%);
  animation: chSpin 30s linear infinite;
}
@keyframes chSpin { to { transform: rotate(360deg); } }

.chTrophy {
  filter: drop-shadow(0 14px 42px rgba(255, 190, 60, 0.42));
  animation: chRise 1s cubic-bezier(0.16, 1.1, 0.3, 1) both;
}
.chTrophy svg { display: block; margin: 0 auto; }
@keyframes chRise { from { opacity: 0; transform: translateY(48px) scale(0.72); } }

/* con margen negativo el plinto de la copa tapaba el cuello y los puños de
   la camiseta, que es justo donde vive el color de la selección */
.chJsy { margin-top: 10px; animation: chRise 0.9s 0.3s cubic-bezier(0.16, 1.1, 0.3, 1) both; }
.chJsy svg { margin: 0 auto; filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.65)); }

.chTitle {
  margin-top: 6px;
  font-size: clamp(30px, 6.4vw, 60px);
  line-height: 0.94;
  /* La Ó de "CAMPEÓN" se cortaba: con `background-clip: text` la tinta es el
     fondo y el fondo termina donde termina la caja de relleno, así que la
     tilde del primer renglón caía afuera. El relleno agranda esa caja sin
     tocar el interlineado de los dos renglones. (Mismo problema y mismo
     arreglo que en el veredicto del retiro.) */
  padding-top: 0.16em;
  background: linear-gradient(180deg, #fff8dc 0%, #ffd15c 52%, #d79a15 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* con el texto en transparente, el resplandor tiene que ser un filtro:
     un text-shadow no se ve porque no hay tinta que lo proyecte */
  filter: drop-shadow(0 0 30px rgba(255, 190, 60, 0.4));
  animation: chPop 1s 0.45s cubic-bezier(0.16, 1.1, 0.3, 1) both;
}
@keyframes chPop { from { opacity: 0; letter-spacing: 0.28em; transform: scale(0.9); } }

.chTeam {
  margin-top: 12px;
  font-size: 22px;
  letter-spacing: 0.05em;
  animation: chFade 0.7s 0.8s both;
}
.chSub {
  margin-top: 10px;
  font-size: var(--t-base);
  color: var(--dim);
  font-weight: var(--w-body);
  line-height: 1.6;
  animation: chFade 0.7s 0.95s both;
}
#champion .btns { margin-top: 24px; animation: chFade 0.7s 1.2s both; }
@keyframes chFade { from { opacity: 0; transform: translateY(10px); } }

/* ==================================================== EL RETIRO ==========

   El final del modo Carrera. Pantalla propia y no una tarjeta más adentro de
   #wcCard, por una razón concreta: #wcCard centra su contenido con
   `align-items:center` y no scrollea, así que una tarjeta más alta que la
   pantalla se corta ARRIBA Y ABAJO a la vez, sin ninguna señal. El resumen
   de una carrera de doce temporadas es exactamente eso.

   Acá el que scrollea es .retScroll y el centrado lo hace `margin:auto` en
   .retIn: cuando el contenido entra queda centrado, y cuando no entra
   arranca desde arriba en vez de perder las primeras líneas.

   La producción es la del campeón del mundo bajada un punto: hay oro, pero
   no hay confeti. El tipo se retiró, no salió campeón.                     */

#retireCard {
  position: absolute;
  inset: 0;
  /* entre #wcCard (11) y #champion (14): el retiro tapa la cortina del
     torneo, y una final del Mundial ganada en la última temporada tapa al
     retiro */
  z-index: 13;
  overflow: hidden;
  /* La parada de afuera va OPACA. Con 0.98 el menú se seguía leyendo por
     debajo —"Práctica libre", "El tiro del día"— y la pantalla del retiro
     terminaba compartiendo el fondo con la lista de modos. #champion se
     salva de esto porque cuando aparece el menú siempre está cerrado; acá
     no: al retiro se llega desde la cancha, pero también se vuelve a él. */
  background: radial-gradient(ellipse at 50% 34%, #191308, #04070b 76%);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.45s ease, visibility 0s linear 0.45s;
}
#retireCard.show {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity 0.45s ease, visibility 0s;
}
/* Los rayos del campeón, quietos y a la mitad de fuerza: acá son la luz del
   estadio vacío, no la fiesta. Sin animación a propósito. */
#retireCard::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  width: 900px;
  height: 900px;
  /* El centro queda ARRIBA del veredicto y no detrás: con los rayos naciendo
     justo donde va la palabra grande, las franjas le pasaban por adentro de
     las letras y el degradado dorado del texto se peleaba con ellas. */
  margin: -430px 0 0 -450px;
  pointer-events: none;
  background: repeating-conic-gradient(
    from 0deg,
    rgba(255, 209, 92, 0.06) 0deg 8deg,
    transparent 8deg 24deg
  );
  -webkit-mask-image: radial-gradient(circle, #000 4%, transparent 46%);
  mask-image: radial-gradient(circle, #000 4%, transparent 46%);
}

.retScroll {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-y: auto;
  /* body lleva `touch-action: none` para que un arrastre sobre la cancha no
     mueva la página. Acá hay que devolver el eje vertical o en el teléfono
     esta pantalla no se puede scrollear con el dedo. */
  touch-action: pan-y;
  overscroll-behavior: contain;
  padding: var(--gy-t) var(--gx-r) var(--gy-b) var(--gx-l);
}
.retIn {
  position: relative;
  z-index: 2;
  /* `margin:auto` y no `align-items:center`: centra cuando entra y NO
     recorta cuando no entra, que es la diferencia entre las dos recetas */
  margin: auto;
  width: min(560px, 100%);
  text-align: center;
}

.retKick { color: var(--gold); animation: chFade 0.6s both; }
.retName {
  margin-top: 12px;
  font-size: var(--t-head);
  line-height: 1;
  animation: chFade 0.6s 0.1s both;
}
.retName:empty { display: none; }

/* ---- el veredicto: lo más grande de la pantalla

   Es la única palabra que el jugador va a repetir cuando cuente la carrera,
   así que se lleva el tamaño y el oro. La línea de abajo la explica en
   voz baja. */
.retVerdict { margin-top: 4px; animation: chPop 0.9s 0.25s cubic-bezier(0.16, 1.1, 0.3, 1) both; }
.retVerdict b {
  display: block;
  font-size: clamp(38px, 9vw, 62px);
  line-height: 0.94;
  /* EL ACENTO SE PERDÍA. Con `background-clip: text` la tinta es el fondo, y
     el fondo se pinta sobre la caja de relleno: todo pedazo de letra que
     asome por arriba de esa caja simplemente no existe. Con line-height 0.94
     la tilde de "ÍDOLO" —uno de los cuatro veredictos— quedaba afuera y en
     pantalla se leía "IDOLO".
     Se arregla con relleno y no subiendo el line-height: el relleno agranda
     la caja del fondo sin tocar el interlineado, así una palabra de dos
     renglones sigue igual de apretada. El margen de arriba se descuenta. */
  padding-top: 0.16em;
  background: linear-gradient(180deg, #fff8dc 0%, #ffd15c 52%, #d79a15 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* con la tinta en transparente un text-shadow no proyecta nada: el
     resplandor tiene que ser un filtro (misma razón que en .chTitle) */
  filter: drop-shadow(0 0 26px rgba(255, 190, 60, 0.34));
}
.retVerdict span {
  display: block;
  margin-top: 12px;
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--dim);
  font-weight: var(--w-body);
}
.retVerdict b:empty, .retVerdict span:empty { display: none; }

/* ---- los números

   Misma forma de hijo que .carSum —`.lbl` + `.big`— para que el que cablea
   reutilice el HTML que ya escribe en el resumen de temporada. La grilla es
   `auto-fit` y no tres columnas fijas: acá pueden ser tres datos o seis. */
.retStats {
  margin: 26px auto 0;
  /* Flex y no grid, y esto costó una vuelta: con `repeat(auto-fit, minmax())`
     y cuatro datos en tres columnas queda un agujero del tamaño de una
     celda al lado del último. Con flex, el que sobra se estira y ocupa el
     renglón entero. Sirve para tres datos, para cuatro y para seis, que es
     lo que hace falta cuando el que llena esto todavía no decidió cuántos
     son. */
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
  animation: chFade 0.7s 0.5s both;
}
.retStats:empty { display: none; }
/* 128 px de base no es un número al azar: a 560 (la ficha en la compu) entran
   cuatro en un renglón, y a 355 (un teléfono chico) entran dos, así que
   cuatro datos caen en 2×2 en vez de 3+1. */
.retStats > div { flex: 1 1 128px; background: rgba(11, 19, 29, 0.92); padding: 13px 8px 14px; }
.retStats .lbl { display: block; color: var(--dim); }
.retStats .big {
  display: block;
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  font-synthesis-weight: none;
}
.retStats .big.up { color: var(--accent); }
.retStats .big.gold { color: var(--gold); }
.retStats .big em { font-style: normal; font-size: 0.5em; color: var(--dim); margin-left: 3px; }

/* ---- bloques con título (recorrido, vitrina, comparación) */

.retBlock { margin-top: 26px; animation: chFade 0.7s 0.65s both; }
/* Un rótulo con dos reglitas y NADA abajo es peor que no mostrar el bloque:
   promete una vitrina y entrega un renglón vacío. El que cablea igual puede
   esconderlo a mano —así está documentado en el markup—, pero esto lo cubre
   solo. `:has` es progresivo: donde no exista, el bloque queda como estaba
   antes de esta regla y no se rompe nada. */
.retBlock:has(> :last-child:empty) { display: none; }
.retBlock .rLbl {
  color: var(--faint);
  /* la reglita a los costados del rótulo: es lo que convierte un título de
     sección en un separador, y de paso ordena los tres bloques */
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.retBlock .rLbl::before, .retBlock .rLbl::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* El recorrido: los escudos en orden, del primer club al último. Es un mapa
   de la carrera y no una grilla de logos — si volviste a un club aparece dos
   veces, porque eso es lo que pasó.

   Acá iba una línea de tiempo dibujada por detrás con un ::before. Se sacó:
   una carrera completa son doce escudos y doce escudos NO entran en un
   renglón ni en la compu (12 × 42 px + huecos ≈ 640 sobre 560 de ficha). Con
   dos renglones la línea queda flotando en el medio, uniendo nada. El orden
   de lectura y el rótulo de arriba ya dicen que es un recorrido. */
.retPath {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 12px;
}
/* Sin sombra: ver el bloque `.crest`. El disco del propio escudo ya lo
   despega del panel, y doce sombras seguidas ensucian el recorrido. */

.retCase { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }

/* La comparación contra la mejor carrera anterior. Tres columnas: qué,
   ésta, la mejor. `.win` marca cuál de las dos ganó — sin eso son dos
   columnas de números y el jugador tiene que restar de memoria. */
.retHof {
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
  text-align: left;
}
.retHof .hr {
  display: grid;
  grid-template-columns: 1fr 72px 72px;
  gap: 10px;
  align-items: center;
  padding: 9px 13px;
  font-size: var(--t-small);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.retHof .hr:last-child { border-bottom: none; }
.retHof .hr.hd { color: var(--dim); background: rgba(255, 255, 255, 0.04); }
.retHof .hr i { font-style: normal; color: var(--dim); }
.retHof .hr.hd i { color: var(--dim); }
.retHof .hr b {
  text-align: right;
  font-family: var(--font-num);
  font-size: var(--t-lead);
  font-weight: var(--w-display);
  letter-spacing: 0;
  color: var(--dim);
  font-synthesis-weight: none;
}
.retHof .hr.hd b {
  font-family: var(--font);
  font-size: var(--t-mark);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  text-transform: uppercase;
}
.retHof .hr b.win { color: var(--gold); }
.retHof:empty { display: none; }

.retLine {
  margin-top: 22px;
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--dim);
  font-weight: var(--w-body);
  animation: chFade 0.7s 0.8s both;
}
.retLine:empty { display: none; }

#retireCard .btns { margin-top: 30px; animation: chFade 0.7s 0.95s both; }

/* ============================================ LA ESCUELA · TIRO DEL DÍA

   Dos pantallas nuevas que siguen el lenguaje de #menuLevels y #menuWC. El
   contenido de las dos lo inyecta 80-main.js, así que acá NO se puede
   depender de clases: se estilan los elementos (button, b, span, code) y
   además se ofrecen ganchos opcionales (.nm, .hint, .mark, .big-num) por si
   el que las llena prefiere usarlos.                                       */

#menuSchool .wcLead, #menuDaily .wcLead { max-width: 620px; }

#dailyBody {
  margin-top: 20px;
  padding: 22px 22px 24px;
  background: var(--panel-sunk);
  border: 1px solid var(--line);
  border-radius: 4px;
  text-align: center;
  overflow-y: auto;
  min-height: 0;
}
#dailyBody h3 { font-size: var(--t-head); line-height: 1; }
#dailyBody .mark { color: var(--gold); display: block; margin-bottom: 10px; }
#dailyBody p, #dailyBody .sub {
  margin-top: 10px;
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--dim);
  font-weight: var(--w-body);
}
#dailyBody .big-num {
  display: block;
  margin: 14px 0 4px;
  font-family: var(--font-num);
  font-size: var(--t-big);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-num);
  line-height: 1;
  color: var(--accent);
  font-synthesis-weight: none;
}
/* el código para compartir: monoespaciado de verdad, seleccionable */
#dailyBody code, #dailyBody .code {
  display: inline-block;
  margin-top: 14px;
  padding: 9px 14px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--t-base);
  letter-spacing: 0.14em;
  color: var(--gold);
  background: rgba(255, 209, 92, 0.09);
  border: 1px dashed rgba(255, 209, 92, 0.42);
  border-radius: 3px;
  user-select: all;
  -webkit-user-select: all;
}
#dailyBody .btns { margin-top: 24px; }
#dailyBody button:not(.big) {
  padding: 11px 22px;
  font-size: var(--t-small);
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  font-family: var(--font);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  border-radius: 3px;
  cursor: pointer;
}

/* ------------------------------------------------------------ FOCO

   Todo lo clickeable tiene que decir dónde está el foco cuando se navega
   con el teclado. :focus-visible y no :focus, para que el anillo no salte
   con cada click del mouse. */

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* sobre verde el anillo verde no se ve */
button.primary:focus-visible, #touchHelpOk:focus-visible, .wcPath i.now:focus-visible {
  outline-color: var(--ink);
}
/* estos viven dentro de una caja con overflow:hidden y el anillo de afuera
   quedaría recortado a la mitad */
.grp button.tm:focus-visible,
button.lvl:focus-visible,
#schoolGrid button:focus-visible,
.seg button:focus-visible {
  outline-offset: -2px;
}
/* …salvo las fichas de la identidad: ahí `.seg` ya no tiene el marco con
   overflow:hidden que obligaba a meter el anillo para adentro, y con el
   anillo pegado al borde no se distingue de la ficha elegida. */
.fldRow .seg button:focus-visible { outline-offset: 2px; }

/* -------------------------------------------------- movimiento reducido

   Quien pidió menos movimiento no pide menos información: las animaciones
   se colapsan a su estado final (por eso `both` y duración ~0, no
   `animation: none`, que dejaría en cero lo que aparece con `from`).        */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
  button.mode:hover, button.big:hover { transform: none; }
}

/* ============================================================ RESPONSIVE */

/* ---- ventana baja: la ficha del menú achica cuántas filas muestra antes
        de empujar los botones fuera de la pantalla */
@media (max-height: 780px) {
  #levelGrid { --rows: 4; }
  #wcGroups { --rows: 2; }
  #schoolGrid { --rows: 3; }
  /* EL PANEL DE PRÁCTICA EN VENTANA BAJA.

     El techo del panel no es la pantalla: es dónde arranca el punto de
     contacto. A 1000×700 eso deja 346 px, y el estado de ARRANQUE medía 368 —
     o sea que el panel abría scrolleando, con la fila de la Guía cortada por
     la mitad. Y el arranque es lo único que el jugador no eligió.

     Lo que cede es la NOTA de la jugada (27 px): dice en prosa lo que las
     tres fichas de arriba ya dicen con su número en grande, así que es la
     única línea del panel que se puede sacar sin perder un dato. Con eso el
     arranque entra (341 sobre 346) en todo lo que va de 700 px de alto para
     arriba.

     Con el jugador ABIERTO sigue scrolleando en 700 px de alto (433 sobre
     346) y no se puede evitar sin sacar contenido: los tres atributos, los
     presets, la fila de power-ups y la guía son 259 px y ninguno sobra. Ahí
     el scroll es la respuesta correcta — lo abriste vos y se cierra con la
     misma llave. */
  #pJugadaN { display: none; }
  /* La tabla de la carrera se suma a la misma lógica: es la única caja de
     #menuCareer que puede ceder alto sin perder información —tiene su propio
     scroll— así que es la que baja cuando baja la ventana. */
  #carTimeline { --rows: 6; }
}
@media (max-height: 640px) {
  #levelGrid { --rows: 3; }
  #schoolGrid { --rows: 2; }
  #carTimeline { --rows: 4; }
  .btns { margin-top: 22px; }
}

@media (max-width: 940px) {
  :root { --edge: 14px; }
  #practicePanel {
    top: auto;
    bottom: calc(var(--gy-b) + 214px);
    max-height: calc(100% - var(--gy-t) - var(--gy-b) - 230px);
    /* Mismo motivo que los 276 de escritorio: la fila de tres fichas necesita
       ancho o el valor deja de leerse, y el ancho compra alto en las dos notas
       largas. 264 es lo que entra sin comerse la cancha en una ventana de
       940. */
    width: 264px;
  }
  #statsBox { top: auto; bottom: calc(var(--gy-b) + 190px); }
  #bannerTitle { font-size: clamp(34px, 7vw, 52px); }

  /* Acá el chip de viento ya no entra centrado en una línea: se pasaba de
     largo hasta meterse abajo de ♪ y ☰. Pasa a dos líneas (flecha a la
     izquierda ocupando las dos) y con un ancho máximo que le reserva a los
     botones su mitad de la pantalla. */
  #windBox {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 1px 8px;
    padding: 6px 12px 7px;
    max-width: min(268px, calc(100vw - 2 * (var(--gx-r) + 286px)));
  }
  #windBox .arrow { grid-row: span 2; font-size: 19px; }
  #windBox .w1 { font-size: 10px; letter-spacing: 0.08em; }
  #windBox .w2 { font-size: 9.5px; line-height: 1.25; }

  /* En Mundial —y en Carrera, que usa la misma clase— la placa del partido
     es ancha y va centrada arriba: por debajo de ~940 px le pasa por encima
     a los botones. Baja la COLUMNA entera a la segunda fila, la misma a la
     que ya baja el chip de viento.

     Apunta a #hudRight y no a #tools: 80-main mete los botones adentro de
     esa columna (buildHudGroups), así que ahí adentro son estáticos y
     `top` sobre #tools no hace nada. La regla vieja decía #tools y por eso
     estaba muerta sin que se notara: a 940 px la placa y los botones no se
     tocan igual, y el choque recién aparece en el teléfono. */
  #hud.wc #hudRight { top: var(--row2); }
}

/* ---- apaisado de teléfono: 812×375 y parecidos. Es el caso más apretado
        de todos y el que más se rompía: el panel de práctica se iba para
        arriba de la pantalla, la caja de estadísticas caía justo encima de
        los botones y el widget de contacto tocaba el marcador.

        Va DESPUÉS del bloque de 940 a propósito: los dos aplican a la vez en
        un teléfono acostado y este tiene que ganar. */
@media (max-height: 520px) {
  .wlabel { display: none; }
  #contactWrap {
    width: 96px;
    display: flex;
    flex-direction: column-reverse;
  }
  #contact { width: 96px; height: 96px; }
  #effectInfo { margin-top: 0; margin-bottom: 5px; font-size: 10px; padding: 3px 5px; }
  #power { height: 116px; }
  #powerLabel { display: none; }
  #planView { width: 128px; height: 88px; }
  #planWrap .cap { display: none; }
  #banner { top: 20%; }
  /* los números del tiro ya los cuenta el banner; acá el panel sólo tapa */
  #statsBox { display: none !important; }

  /* El panel de práctica se acuesta. En columna no hay altura que alcance
     —entre el marcador arriba y el widget de contacto abajo quedaban 36 px—
     así que ocupa la franja libre del fondo, entre el contacto y el mapa, y
     sus controles se acomodan en fila. Es el mismo panel, girado. */
  #practicePanel {
    top: auto;
    bottom: var(--gy-b);
    left: calc(var(--gx-l) + 106px);
    right: calc(var(--gx-r) + 208px);
    width: auto;
    max-height: 138px;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 9px 14px;
    padding: 9px 12px 10px;
  }
  /* `auto` y no 112px: con base fija el selector de guía —que tiene TRES
     botones y no dos, como el de rol— no entraba y el `overflow:hidden` del
     .seg cortaba el último: se leía "FÁCIL NORMAL DIFÍ". Cada uno mide lo
     que necesita. */
  #practicePanel .seg { margin-bottom: 0; flex: 0 0 auto; }
  /* Los botones del segmentado traen `padding: 8px 0` porque en el panel de
     escritorio el `.seg` ocupa el ancho entero y el aire lo pone el `flex: 1`.
     Acostado el `.seg` mide lo que mide su contenido, así que sin padding
     lateral las dos opciones quedan pegadas: se leía "PATEARATAJAR". */
  #practicePanel .seg button { padding: 8px 9px; }

  /* ---- acá también se pliega, y es lo único que salva la franja.

     El apaisado ya scrolleaba ANTES de esta tanda: 213 px de contenido en una
     caja de 138. Así que la primera línea de la franja es el interruptor de
     lado y LA LLAVE —dos cosas, entran holgadas— y el cuerpo se acuesta
     debajo cuando se lo pide.

     `flex: 1 1 100%` en el cuerpo y NO `display: contents`. Con `contents`
     las fichas y la unidad del jugador se vuelven hijas de la tira y se
     reparten con la llave en la misma corrida de wrap: el resultado, medido
     en pantalla, era media unidad arriba a la derecha y la otra media tres
     filas más abajo. Con la línea entera para él, el cuerpo envuelve por su
     cuenta y la llave se queda arriba.

     Crece PARA ARRIBA solo: el panel está anclado por `bottom`, así que
     alcanza con soltarle el max-height. El tope deja libre el cartel del
     medio, que en esta altura vive en el 20 % (unos 155 px). */
  #practicePanel:not(.abierto) #pBody { display: none; }
  #pBody {
    flex: 1 1 100%;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px 14px;
  }
  /* Acostado las dos familias van UNA AL LADO DE LA OTRA: la franja mide
     470 px de ancho y 200 de alto, así que apiladas no entran ni de cerca.
     Las bases suman 430 + 14 de hueco, o sea que entran en una corrida; con
     las 250/260 que tenían al principio sumaban 524 y volvían a apilarse.

     ESTO NO ALCANZA PARA SACAR EL SCROLL Y HAY QUE DECIRLO. Medido a 812×375
     con el jugador abierto: 480 px de contenido en la tira apilada, 348 con
     las dos columnas y las barras acostadas, contra 198 de caja. El apaisado
     ya scrolleaba antes de esta tanda (213 sobre 138) y sigue siendo la única
     de las cuatro pantallas que scrollea; lo que cambió es que sobra un 75 %
     de tira y no un 240 %. Subir el tope arriba de 200 lo mete abajo del
     cartel de la jugada, que en esta altura vive en el 20 %. */
  /* `min-width: 0` en las dos y no es adorno: el mínimo automático de un hijo
     flex es su ancho de contenido mínimo, y la unidad del jugador lo tiene en
     ~250 px (la fila de cuatro power-ups más los tres presets). Sin soltarlo,
     210 + 250 se pasan de los 446 de la tira y las dos columnas volvían a
     apilarse aunque la base dijera otra cosa — medido: 426 px de contenido en
     vez de 348. */
  .pFichas, .pUnit { flex: 1 1 210px; min-width: 0; }
  .pUnit { flex-basis: 220px; }
  /* Y las tres barras del jugador se acuestan también: apiladas son 56 px de
     los 200 que hay. En una columna de 220 cada una queda de 66 px, y ahí el
     rótulo NO entra al costado de la pista —"Puntería" se leía "Punterí"—
     así que en apaisado, y sólo acá, el rótulo se va ARRIBA y abajo quedan
     pista y número. Son 29 px por barra contra 56 apiladas, y se lee. */
  .pBars { display: none; }
  .pUnit.manual .pBars { display: flex; gap: 10px; }
  .pBars .ctl.atrib {
    flex: 1 1 0;
    margin-bottom: 0;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 1px 6px;
  }
  .pBars .ctl.atrib .top > span { grid-column: 1 / -1; grid-row: 1; }
  .pBars .ctl.atrib input[type="range"] { grid-column: 1; grid-row: 2; }
  .pBars .ctl.atrib .top > b { grid-column: 2; grid-row: 2; min-width: 0; }
  /* La nota va ÚLTIMA y en línea propia: es de toda la fila de fichas, no de
     una, y al costado de una perilla se lee como si fuera de ésa. */
  #pBody > .nota { order: 3; flex: 1 1 100%; margin-top: 0; padding-bottom: 0; }
  /* El mínimo táctil de 44 px vale acá también: 812×375 es un teléfono
     acostado, con dedo. Estaba escrito sólo adentro de la media query de
     ancho ≤700, y la llave es la única puerta al panel. */
  #practicePanel .pChip {
    display: flex;
    flex: 0 0 auto;
    gap: 8px;
    margin-bottom: 0;
    min-height: 44px;
  }
  #practicePanel .pFicha input[type="range"],
  #practicePanel .pUnit input[type="range"] { height: 20px; }
  #practicePanel.abierto {
    /* 200 y no "lo que haya": arriba de eso el panel se mete abajo del
       cartel de PRÁCTICA y la llave se lee cortada. */
    max-height: 200px;
    overflow-y: auto;
  }
}

/* =============================================== TELÉFONO (≤ 700 px)

   El HUD vertical es un layout propio, no el de escritorio apretado. Lo que
   estaba mal, verificado a 375×812:

     · #windBox se metía abajo de los botones ♪ y ☰ y el texto se cortaba.
       Ahora los dos cuelgan de la MISMA variable --row2: uno pegado a la
       izquierda, el otro a la derecha, y el chip tiene un ancho máximo que
       reserva el lugar de los botones (los cuatro, aunque haya dos
       escondidos: reservar de más no cuesta nada, quedarse corto sí).
     · el marcador quedaba abajo del notch: ahora todo el HUD se ancla a
       --gy-t / --gy-b / --gx-l / --gx-r, que ya traen el safe-area.
     · la barra de potencia y el mapa quedaban cortados por abajo. Además
       del safe-area hay un piso de 12 px, porque en Safari de iOS la barra
       inferior tapa el fondo del viewport fijo y ahí env() todavía da 0.
     · el widget de contacto se comía al pateador y su etiqueta se cortaba.
       Ahora es más chico, tiene halo propio y la etiqueta va ARRIBA de la
       pelota (column-reverse), que es el único lugar donde no hay borde
       que la corte.                                                        */

@media (max-width: 700px) {
  :root {
    --edge: 10px;
    --gy-b: calc(12px + var(--sa-b));
    /* 80px = alto real del marcador de tres líneas en este ancho, medido.
       Con 52 el chip de viento se le metía adentro por 19 px. */
    --row2: calc(var(--gy-t) + 80px);
    --t-num: 17px;
    --t-head: 22px;
  }

  /* ---- fila de arriba */
  .corner { padding: 7px 9px 8px; }
  #topLeft { width: auto; min-width: 132px; max-width: calc(50% - 10px); }
  #topRight { min-width: 76px; }
  .corner .sub { font-size: 9.5px; margin-top: 5px; padding-top: 4px; }

  /* ---- fila de utilidades: viento a la izquierda, botones a la derecha */
  #tools { top: var(--row2); right: var(--gx-r); gap: 6px; }
  #tools button { width: 32px; height: 32px; }
  #windBox {
    top: var(--row2);
    left: var(--gx-l);
    right: auto;
    transform: none;
    /* 4 botones de 32 + 3 huecos de 6 + aire = 170 */
    max-width: calc(100vw - var(--gx-l) - var(--gx-r) - 170px);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 1px 8px;
    padding: 6px 10px 7px;
  }
  #windBox .arrow { grid-row: span 2; font-size: 19px; }
  #windBox .w1 { font-size: 10px; letter-spacing: 0.08em; }
  #windBox .w2 { font-size: 9.5px; line-height: 1.25; }

  /* ---- fila de abajo: contacto | mapa | potencia */
  #contactWrap {
    left: var(--gx-l);
    bottom: var(--gy-b);
    width: 84px;
    display: flex;
    flex-direction: column-reverse;
  }
  #contact { width: 84px; height: 84px; }
  .wlabel { display: none; }
  #effectInfo {
    margin-top: 0;
    margin-bottom: 6px;
    font-size: 9px;
    letter-spacing: 0.02em;
    padding: 3px 4px;
  }
  #power { right: var(--gx-r); bottom: var(--gy-b); width: 28px; height: 104px; }
  #powerNum { font-size: 11px; top: 5px; }
  #powerLabel { display: none; }
  #planWrap { right: calc(var(--gx-r) + 38px); bottom: var(--gy-b); padding: 4px; }
  #planView { width: 96px; height: 68px; }
  #planWrap .cap { display: none; }
  /* En el teléfono el panel entero no entra al lado de la cancha, así que
     se PLIEGA: en reposo se ven tres cosas —el interruptor de lado y las dos
     llaves, LA CANCHA y EL JUGADOR— y los controles de cada familia aparecen
     cuando se los pide.
     Antes acá decía `#practicePanel .ctl { display: none }` a secas, y eso
     dejaba a la Clásica sin barrera, sin arquero y sin viento en el teléfono
     —los controles estaban en el DOM y andaban, pero no había forma de
     verlos—. El interruptor de lado sigue siendo lo primero: sin él no hay
     manera de irse al arco, porque en el teléfono tampoco hay tecla G.
     Sin `!important`, porque el display del panel lo maneja 80-main según
     el modo.

     `.abierto` la pone 80-main cuando hay CUALQUIERA de los dos grupos
     abierto, y es la que dispara la tarjeta. Con dos clases (`.open` y
     `.openP`) todas las reglas de la tarjeta habrían tenido que escribirse
     dos veces, y una tarjeta que se ve distinta según qué grupo abriste es
     exactamente el bug que nadie mira hasta que aparece. Las dos clases
     sueltas deciden UNA sola cosa: cuál de los dos grupos se muestra. */
  /* `bottom` y `max-height` SE RESETEAN. Los hereda la regla de ≤940 px, y
     con un `top` propio el panel dejaba de medir lo que mide su contenido y
     se estiraba de 74 px hasta el pie: una caja transparente de 151×544 con
     `pointer-events:auto` encima del 40 % izquierdo de la cancha, que se
     comía los toques (tocabas para apuntar y no pasaba nada). */
  #practicePanel {
    /* 86 y no 74: el marcador de arriba a la izquierda mide 71 px y termina
       en 81, así que a 74 el interruptor de lado le entraba 7 px por abajo.
       Medido a 360×640; con 86 quedan 5 px de aire y el HUD plegado no tiene
       una sola superposición. */
    top: 86px; left: 8px; width: auto; padding: 0;
    bottom: auto; max-height: none;
    background: none; border: 0;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    /* y aunque el alto sea el correcto, el envoltorio vacío no tiene por qué
       recibir toques: los recibe el interruptor, que es lo único que se ve */
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 7px;
  }
  /* Plegado y desplegado los decide `.abierto`. Lo del teléfono es OTRA cosa
     y es lo que sigue: cerrado el panel no es una tarjeta —es transparente, y
     la llave flota sobre la cancha con vidrio propio—, y abierto vuelve a
     serlo. Los márgenes entre piezas los pone el `gap` de la columna. */
  #practicePanel .pChip { display: flex; margin-bottom: 0; }
  #practicePanel:not(.abierto) #pBody { display: none; }
  /* NADA DE ESTA COLUMNA SE ENCOGE, y hay dos razones distintas.

     `#roleSeg` es un `.seg`, y `.seg` lleva `overflow: hidden`: con overflow
     distinto de `visible` el mínimo automático de un hijo flex es CERO, así
     que era el único de la columna que podía ceder —la llave tiene min-height
     44 y el cuerpo es un bloque— y cedía TODO. Medido con el panel abierto:
     pasaba de 25 px a 2. En el teléfono no hay tecla G, o sea que ese botón es
     la única forma de irse al arco, y quedaba invisible e intocable.

     `#pBody` hereda `flex: 1 1 100%` de la media query de apaisado, que aplica
     a la vez que ésta entre 561 y 700 px de ancho. En un contenedor en COLUMNA
     ese 100 % es del ALTO, así que el cuerpo se iba a una segunda columna de
     wrap: medido a 667×375, el grupo se dibujaba en x=791 de un viewport de
     667 — abrías la llave y veías un rectángulo vacío. */
  #practicePanel > .seg { flex: 0 0 auto; }
  #pBody { flex: 0 0 auto; flex-direction: column; }
  /* Y la columna NO envuelve. La media query de apaisado deja
     `flex-wrap: wrap`, y las dos aplican a la vez entre 561 y 700 px de
     ancho: en una columna que envuelve, lo que no entra de alto se va a una
     SEGUNDA COLUMNA. Lo que sobra tiene que ir al scroll que el panel ya
     tiene, no al costado. */
  #practicePanel { flex-wrap: nowrap; }
  /* desplegado: vuelve a ser una tarjeta, con su propio scroll si hace
     falta. El ancho se ata al viewport para que a 320 px no se desborde, y
     el alto deja libre la mitad de abajo, que es donde vive la potencia. */
  #practicePanel.abierto {
    /* Desplegado gana la capa. La columna derecha del HUD se dibuja después
       (80-main la crea a mano) y sin esto las placas de DISTANCIA, BARRERA
       y VIENTO flotaban ENCIMA de la hoja abierta, que es peor que taparlas:
       parecían dos capas peleadas. Taparlas mientras se configura no pierde
       nada —el panel dice esas mismas tres cosas— y se destapan al cerrar,
       que está a un toque. */
    z-index: 6;
    width: min(272px, calc(100vw - 16px));
    /* ABIERTO ES UNA HOJA, Y OCUPA LA PANTALLA.

       Hasta ahora el tope era `top: 86px` y `100% - 217px`: los 86 de arriba
       más los 121 que el punto de contacto ocupa desde el pie, para no
       meterse encima de los controles con los que se patea. La razón era
       buena cuando el panel plegado seguía siendo una caja transparente con
       `pointer-events: auto` que se comía los toques sin verse. Ya no es el
       caso: abierto es opaco, tiene z-index propio y lo abriste vos; cerrarlo
       está a un toque en la misma llave. Mientras configurás no estás
       pateando.

       Y el número lo obligó la medición, no el gusto: a 360×640 el tope viejo
       daba 423 px de caja para 596 de contenido, y con `top: 86` los mejores
       recortes llegaban a 604 contra 532 — o sea que el jugador quedaba
       cortado igual. Desde el borde de arriba son 610, y ahí entra entero con
       todo puesto (medido: 553).

       CERRADA la hoja no tapa nada: la cancha se ve entera menos la llave y
       el interruptor de lado, que es exactamente lo que se pidió. */
    top: var(--gy-t);
    max-height: calc(100% - var(--gy-t) - var(--gy-b) - 8px);
    overflow-y: auto;
    padding: 10px 11px 11px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 3px;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    pointer-events: auto;
    gap: 9px;
  }
  /* Todo hijo directo de la tarjeta ocupa el ancho: en la columna con
     `align-items:flex-start` un grupo mide lo que mide su control más ancho,
     y los sliders quedaban de 120 px en una tarjeta de 272. */
  #practicePanel.abierto > * { width: 100%; }
  /* Con la hoja abierta el cartel del power-up NO queda medio tapado: se va.
     La hoja arranca en el borde de arriba, que es donde vive #puHero, y una
     placa asomando por debajo de otra se lee como dos capas peleadas — que es
     exactamente lo que ya pasó con la columna derecha del HUD. Mientras la
     hoja está abierta el poder puesto lo dice el botón encendido de la fila,
     que está a la vista; al cerrar, el cartel vuelve.
     Funciona porque #puHero es hermano POSTERIOR de #practicePanel en
     95-body.html, y porque su display lo maneja 80-main con estilo en línea
     sólo para apagarlo: acá no hace falta !important. */
  #practicePanel.abierto ~ #puHero { display: none; }
  /* adentro de la tarjeta los botones ya no necesitan fondo propio */
  #practicePanel.abierto #roleSeg, #practicePanel.abierto .pChip {
    background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  #roleSeg {
    margin: 0;
    pointer-events: auto;
    background: var(--panel);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
  /* 44 px de alto, que en el teléfono no se negocian: acá NO hay tecla G, así
     que este interruptor es la única forma de irse al arco. Medido a 390×844
     y a 360×640 quedaba en 25 px — abajo del mínimo táctil y abajo de lo que
     el propio comentario de este archivo declara. El `padding` solo no
     alcanza porque la fila vive en una columna flex que la puede achicar. */
  #roleSeg button { padding: 6px 14px; font-size: 9px; min-height: 44px; }
  /* La llave. 44 px de alto es el mínimo táctil y no se negocia; el estado va
     en el propio botón (×3 · BUENO · SIN VIENTO) porque en el teléfono no hay
     lugar para un panel que lo cuente aparte, y un botón que no dice qué hay
     puesto obliga a abrirlo sólo para mirar.
     La FORMA está arriba, en `.pChip`. Acá va sólo lo que es del teléfono: el
     vidrio propio (plegada flota sobre la cancha, sin tarjeta detrás) y el
     ancho máximo. */
  #practicePanel .pChip {
    /* La columna derecha del HUD (#hudRight, en 80-main.js) se reserva
       hasta 46vw y está anclada al borde: pasada la mitad de la pantalla
       esto le entra por abajo y el rótulo termina cortado por la placa de
       BARRERA. Medido a 360×640 con el tope puesto: el botón llega a 175 y
       la columna arranca en 184. Cuando no entra en una línea, envuelve. */
    max-width: calc(52vw - 20px);
    min-height: 44px;
    pointer-events: auto;
    background: var(--panel);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
  /* Adentro de la tarjeta el tope de ancho no corre: ahí el ancho lo pone la
     tarjeta y con 52vw las llaves quedaban más cortas que los sliders. */
  #practicePanel.abierto .pChip { max-width: none; }
  /* Los sliders son de dedo. La pista se dibuja como un degradé de 4 px
     centrado en vez de ser el fondo de la caja: así el blanco de toque crece
     sin que la línea engorde. Con `padding` + `background-clip` la pista
     desaparecía. El ALTO lo pone el bloque de las seis reglas, más abajo. */
  #practicePanel.abierto .ctl input[type="range"] {
    background: linear-gradient(rgba(255,255,255,0.22), rgba(255,255,255,0.22))
      center / 100% 4px no-repeat;
    border-radius: 0;
  }
  /* Los tres atributos vuelven a poner la marca del neutro encima de la
     pista de dedo: la regla de arriba pisa el background entero, y sin esto
     el 80 —el juego de siempre— desaparece justo en la pantalla donde no hay
     teclado para escribir el número. */
  #practicePanel.abierto .ctl.atrib input[type="range"] {
    background:
      linear-gradient(rgba(53,224,138,0.9), rgba(53,224,138,0.9))
        var(--neutro, 80%) center / 2px 16px no-repeat,
      linear-gradient(rgba(255,255,255,0.22), rgba(255,255,255,0.22))
        center / 100% 4px no-repeat;
  }
  #practicePanel.abierto .ctl input[type="range"]::-webkit-slider-thumb { width: 18px; height: 18px; }
  #practicePanel.abierto .ctl input[type="range"]::-moz-range-thumb { width: 18px; height: 18px; }
  #practicePanel.abierto .ctl { margin-bottom: 4px; }
  #practicePanel.abierto .ctl .nota { padding-bottom: 2px; }
  /* el segmentado de la Guía trae el margen del panel de escritorio y acá
     abría un hueco de 14 px justo arriba de la letra chica */
  #practicePanel.abierto .ctl .seg { margin-bottom: 0; }
  /* Los cuatro power-ups y los tres presets: el mínimo táctil también acá.
     En una tarjeta de 272 px cada power-up queda de 66 px de ancho, que es
     de sobra para un ícono de 19. */
  #practicePanel.abierto .seg.pu button,
  #practicePanel.abierto .seg.pPreset button { min-height: 44px; }
  /* LAS SEIS REGLAS DE LA HOJA MIDEN 34 Y NO 44, y es una concesión medida.

     44 px es el mínimo táctil y hasta esta tanda las tres reglas del panel lo
     respetaban. Ahora son SEIS —tres fichas y tres atributos— y a 44 son
     264 px de pista sola en una hoja de 610: no entra, y lo que se pierde por
     no entrar (la mitad del jugador abajo del pliegue) es peor que lo que se
     pierde bajando a 34.

     34 no es un número inventado: es el alto de dedo que ya usa el resto del
     HUD del teléfono (♪ y ☰ miden 36) y, sobre todo, en una regla lo que se
     agarra es el POMO y se arrastra en horizontal — el blanco útil es el
     ancho entero del control, 226 px, no su alto. El pomo sigue midiendo 18. */
  #practicePanel.abierto .ctl input[type="range"],
  #practicePanel.abierto .pFicha input[type="range"] {
    height: 34px;
    background: linear-gradient(rgba(255,255,255,0.22), rgba(255,255,255,0.22))
      center / 100% 4px no-repeat;
    border-radius: 0;
  }
  #practicePanel.abierto .pFicha input[type="range"]::-webkit-slider-thumb { width: 18px; height: 18px; }
  #practicePanel.abierto .pFicha input[type="range"]::-moz-range-thumb { width: 18px; height: 18px; }
  /* El "?" también es de dedo. */
  #practicePanel .pUnitTop button { width: 34px; height: 34px; font-size: 14px; }
  #statsBox { display: none !important; }

  /* El cartel arranca abajo de la columna derecha del HUD. A 27 % —el valor
     de escritorio— cae en 173 px, justo encima del chip de viento (183) y de
     la placa de barrera: medido a 360×640, 86×52 px de solape con el viento,
     y el cartel "Movés la pelota por la cancha…" se leía cortado a la mitad.
     La columna termina en 235 y el punto de contacto arranca en 544, así que
     a 42 % (269) el cartel entero entra en la franja libre. Vale para todos
     sus estados —el "¡GOL!" también se pisaba, y ése es peor porque llega
     cuando uno está mirando el arco. */
  #banner { top: 42%; }
  #bannerTitle { font-size: clamp(30px, 11vw, 44px); }
  #bannerSub { font-size: var(--t-small); margin-top: 8px; }
  #banner::after { bottom: -10px; height: 2px; }

  /* ---- menús */
  #menu::before { top: -80px; border-width: 1.5px; }

  /* ---- la portada en el teléfono.
     Dos columnas y no una: apilada, la grilla de seis mide 6×150 + 5×10 más
     el encabezado y no entra ni scrolleando cómodo. En dos columnas son tres
     filas y la portada del jugador nuevo entra entera en 390×844.
     Las seis siguen midiendo IGUAL, que es de lo que se trata. */
  .kicker { font-size: 8.5px; }
  .logo { font-size: clamp(44px, 15vw, 60px); }
  .logo::after { margin-top: 14px; }
  .tagline { margin-top: 12px; font-size: var(--t-small); }
  .modes { margin-top: 20px; grid-template-columns: repeat(2, 1fr); gap: 10px; }
  button.mode { min-height: 150px; padding: 12px 12px 11px; }
  .mode .mName { margin-top: 9px; font-size: 18px; }
  .mode .mDesc { margin-top: 6px; }

  /* La barra se apila: `GUÍA DE TIRO · TECLA T` y el segmentado en la misma
     línea, y la explicación abajo. En una sola fila el segmentado bajaba a
     150 px y "DIFÍCIL" se cortaba. */
  #assistBox { flex-wrap: wrap; margin-top: 14px; padding-top: 13px; gap: 10px; }
  #assistBox .aSlot { flex: 1 1 auto; }
  #assistBox .aDesc { flex: 1 1 100%; }
  /* 44 y no 40: es el alto del blanco de toque de los links, y en el
     teléfono es donde importa. */
  #pF { height: 44px; gap: 12px; }
  .fLinks { gap: 14px; }
  #howBody { grid-template-columns: 1fr; }
  .setRow { grid-template-columns: 1fr; }
  .setRow .sHint { grid-column: 1; }

  /* Dos columnas y no tres: a 104 px de ancho un nombre de dieciocho letras
     se parte en tres renglones y ya no entra en la fila de alto fijo. */
  #levelGrid { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); --lv-row: 96px; padding: 10px; }
  #schoolGrid { grid-template-columns: 1fr; --lv-row: 84px; padding: 10px; }
  #wcGroups { grid-template-columns: 1fr 1fr; --grp-gap: 6px; padding: 10px; }
  .wcLead { font-size: var(--t-small); }
  #dailyBody { padding: 16px; }

  /* el marcador manda arriba: el resto del HUD se corre para no pisarlo */
  #wcBar { min-width: 0; padding: 6px 11px 7px; }
  .wcScore b { font-size: 21px; }
  .wcSide { min-width: 62px; }
  .wcSide b { font-size: var(--t-small); }
  .dotRow i { width: 6px; height: 6px; }
  #hud.wc #topLeft, #hud.wc #topRight { display: none; }

  /* ---- Partido en el teléfono.

     A 360 px el marcador mide 272 y las dos esquinas 142.5 + 165.6: se pisan.
     El Mundial lo resuelve escondiendo las dos esquinas (la línea de arriba);
     acá se esconde SÓLO la izquierda —tu jugador es identidad, no estado, y
     se lee entero en la pausa y en el entretiempo— y la columna derecha baja
     a la segunda fila, igual que #hud.wc #hudRight. El pizarrón NO se puede
     esconder: es el canal de enseñanza del modo. */
  #hud.partido #topLeft { display: none; }
  #hud.partido #hudRight { top: var(--row2); }

  /* EL GEMELO DE `#wcBar { min-width: 0 }` DE ACÁ ARRIBA, y sin él las
     cuatro reglas de abajo no sirven: #pBar hereda `min-width: 250px` del
     selector compartido y se queda CLAVADO en 250 px pisando el radar. La
     regla que compacta el marcador del Mundial vive adentro de este mismo
     @media y apunta sólo a #wcBar, o sea que NO viaja con el cambio de
     selector de allá arriba. Compartir un selector no es heredar un modo. */
  #hud.partido #pBar { min-width: 0; padding: 6px 11px 7px; }
  #hud.partido #pBar .wcSide b { display: none; }
  #hud.partido #pBar .wcSide { min-width: 0; gap: 0; }
  #hud.partido #pBar .wcTeams { gap: 9px; margin-top: 4px; }
  #hud.partido #pBar .wcScore b { font-size: 19px; }

  /* El radar se muda arriba a la izquierda, al hueco que dejó #topLeft. Y no
     abajo: abajo a la derecha es donde vive hoy, que es exactamente donde va
     el pulgar derecho, y abajo a la izquierda está la palanca. */
  #hud.partido #planWrap { left: var(--gx-l); right: auto; top: var(--gy-t); bottom: auto; padding: 3px; }
  #hud.partido #planView { width: 88px; height: 60px; }

  /* La placa ancha vuelve a ser una tarjeta apilada. A 340 px la grilla de
     tres columnas deja la descripción en una tira de ochenta píxeles, la
     etiqueta se le monta encima y la placa entera se derrama sobre la
     grilla de abajo. La forma de columna es la de las otras seis y a este
     ancho es la única que entra. */
  button.mode.hero {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    margin-top: 20px;
    min-height: 0;
    padding: 12px 12px 11px;
  }
  button.mode.hero .mIco { font-size: 22px; }
  button.mode.hero .mName { margin-top: 9px; font-size: 18px; }
  button.mode.hero .mDesc { grid-column: auto; margin-top: 6px; }
  button.mode.hero .mTag { grid-column: auto; grid-row: auto; margin-top: 10px; padding-top: 0; }

  /* ---- carrera en el teléfono
     La tabla de seis columnas no entra en 360 px: se cae la de títulos,
     que es la única prescindible (los títulos igual están enteros en la
     vitrina, justo abajo). El resto se aprieta. */
  #carCardTop { padding: 12px 13px; gap: 10px 12px; }
  /* Escudo y nombre se quedan con el primer renglón enteros y las tres
     cifras bajan JUNTAS al segundo. Repartidas —edad arriba, valor y media
     abajo— la ficha se lee en zigzag. */
  #carCardTop .who { font-size: var(--t-title); flex: 1 1 100px; }
  #carCardTop .stat { flex: 1 1 0; min-width: 58px; text-align: left; }
  #carCardTop .stat.ovr .num { font-size: 30px; }
  #carCardTop .cap { order: 9; align-self: auto; }
  #carTimeline .tr {
    grid-template-columns: 26px 20px 1fr 56px 38px;
    gap: 7px;
    padding: 6px 9px;
    font-size: var(--t-fine);
  }
  /* La columna de títulos se cae entera, encabezado incluido: si sólo se
     esconden las celdas, el "TÍTULOS" del encabezado queda solo y se
     desborda a un segundo renglón. Los títulos igual están completos en la
     vitrina, que está justo debajo. */
  #carTimeline .tr > :nth-child(6) { display: none; }
  .carOffers { grid-template-columns: 1fr 1fr; gap: 7px; }
  button.offer { padding: 11px 8px 10px; gap: 7px; }
  .offer .oName { font-size: var(--t-base); }
  .carSum .big { font-size: 24px; }
  .carRet .clubs { gap: 5px; }

  #carBar {
    min-width: 0;
    max-width: calc(100vw - 2 * var(--edge));
    gap: 7px;
    padding: 5px 9px 6px;
  }
  #carBar .cbTx { flex: 1 1 auto; min-width: 0; }
  #carBar .cbTx b {
    font-size: var(--t-fine);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  #carBar .cbTx span { display: none; }
  #carBar .cbDots { gap: 3px; }
  #carBar .cbDots i { width: 6px; height: 6px; }
  #carBar .cbOvr { padding-left: 7px; }
  #carBar .cbOvr b { font-size: 17px; }

  #wcTurn { top: 40%; padding: 11px 16px 12px; gap: 11px; }
  .wtTx b { font-size: 18px; }
  .wtTx span { font-size: var(--t-fine); }

  .wcVs { gap: 12px; }
  .wcVs .v { width: 104px; }
  .wcBig { font-size: 30px; }
  .wcTable .tr { grid-template-columns: 16px 1fr 24px 24px 28px; font-size: var(--t-fine); padding: 6px 8px; }
}

/* Renovar no es una oferta más: es la única tarjeta que ya conocés, así que
   se marca con el vivo dorado en vez de competir con las tres del mercado. */
button.offer.renew { border-color: rgba(255, 209, 92, 0.42); }
button.offer.renew:hover { border-color: rgba(255, 209, 92, 0.72); }
.oDiff.renew { color: var(--gold); }

/* Y volver al país tampoco es una oferta más: es la tarjeta que aparece
   recién a los 30 y que el jugador no vio en veinte años de carrera. Va en
   celeste —el único acento del modo que no está usado por el ascenso, el
   descenso ni la renovación— para que se lea de un vistazo que es OTRA cosa
   antes de leer una palabra. */
button.offer.home { border-color: rgba(111, 183, 232, 0.45); }
button.offer.home:hover { border-color: rgba(111, 183, 232, 0.78); }
.oDiff.home { color: #6fb7e8; }

/* La pierna hábil y la especialidad se estilan arriba, con el resto de la
   identidad (buscá "filas de opciones"). Vivían acá abajo, después del media
   query del teléfono, y eso las volvía intocables desde el móvil. */

/* ============================== LA CARRERA EN EL TELÉFONO ================

   Va SEPARADO del bloque grande de arriba y AL FINAL del archivo a
   propósito. El archivo pasa las mil novecientas líneas y ya tenía reglas de
   carrera sueltas después del media query, que ganaban por orden sin que
   nadie lo hubiera decidido. Todo lo que sigue son ajustes de teléfono para
   las pantallas nuevas del modo, y al ir último gana por orden cuando empata
   la especificidad — que es lo que uno espera de un bloque responsive.

   Referencia de medida: 375×812 con el navegador ocupando todo.             */

@media (max-width: 700px) {
  /* ---- identidad: la camiseta arriba, los campos abajo

     Es el mismo orden del DOM, así que el lector de pantalla y la vista
     cuentan lo mismo. La camiseta baja a 132 px: a 172 se comía la mitad de
     la pantalla y empujaba la especialidad abajo del teclado. */
  .carIdent { flex-direction: column; align-items: center; gap: 15px; margin-top: 16px; }
  .carFields { width: 100%; }
  .jsyPrev { width: 132px; }
  /* Dos y dos, siempre. Con `auto-fit` a 148 px el ancho justo de un iPhone
     chico caía en una sola columna y las cuatro fichas se convertían en una
     lista de cuatro renglones altísima. */
  #carStyle { grid-template-columns: 1fr 1fr; gap: 5px; }
  #carStyle button { padding: 7px 9px; }
  #carStyle .stHint { font-size: 10px; }
  .fldRow { margin-top: 12px; }

  /* ---- la tabla no puede comerse la pantalla entera
     Seis filas y no nueve: abajo de la tabla están la Selección, la vitrina
     y los tres botones, y todo eso tiene que entrar sin que haya que
     adivinar que hay más. */
  #carTimeline { --rows: 6; }

  /* ---- la Selección: el subtítulo se cae, igual que en #carBar. El nombre
     del país y los dos números son lo que hay que leer. */
  #natRow { gap: 9px; padding: 8px 10px 9px; }
  #natRow .nrTx b { font-size: var(--t-small); }
  #natRow .nrTx span { display: none; }
  #natRow .nrStat { min-width: 40px; }
  #natRow .nrStat b { font-size: var(--t-lead); }

  /* ---- hitos
     128 px = el punto de contacto del teléfono (84) más la chapa del efecto
     (que en este ancho va ARRIBA de la pelota, por el column-reverse) más
     aire. Medido: con 116 el botón de saltear le pisaba 3 px a "centro ·
     alt 13° · sin comba". Y el ancho se ata al de la pantalla: una placa de
     340 px sobre 375 tapa la cancha entera. */
  #milestones {
    bottom: calc(var(--gy-b) + 128px);
    width: calc(100% - var(--gx-l) - var(--gx-r) - 34px);
    gap: 6px;
  }
  #msList { gap: 6px; }
  #msList .ms, #milestones > .ms { padding: 7px 11px 8px 9px; gap: 8px; }
  .ms .msIc { font-size: 15px; }
  .ms .msTx b { font-size: var(--t-base); }
  .ms .msTx b ~ span { font-size: var(--t-fine); }

  /* ---- las cortinas: el párrafo del mercado de pases son siete renglones
     a 13 px y empuja las ofertas abajo del pliegue */
  .wcNote { font-size: var(--t-small); line-height: 1.55; }

  /* ---- el retiro */
  .retIn { width: 100%; }
  .retName { font-size: var(--t-title); }
  .retVerdict span { font-size: var(--t-small); }
  .retStats { margin-top: 20px; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); }
  .retStats > div { padding: 10px 6px 11px; }
  .retStats .big { font-size: 24px; }
  .retBlock { margin-top: 20px; }
  .retBlock .rLbl { gap: 9px; margin-bottom: 11px; }
  .retPath { gap: 8px 9px; }
  /* 66 px para la última columna y no 58: "LA MEJOR" en versalitas con
     tracking mide 62, y a 58 se partía en dos renglones y desalineaba el
     encabezado entero. */
  .retHof .hr { grid-template-columns: 1fr 60px 66px; gap: 8px; padding: 8px 10px; font-size: var(--t-fine); }
  .retHof .hr b { font-size: var(--t-base); }
  .retLine { font-size: var(--t-small); }
  #retireCard .btns { margin-top: 24px; }
  /* Los dos botones del retiro, uno abajo del otro y a todo el ancho: son la
     última pantalla del modo y no hay ningún apuro por apretarlos en una
     fila de dos que quedan de 160 px cada uno. */
  #retireCard .btns { flex-direction: column; gap: 9px; }
  #retireCard .btns button { width: 100%; }
}

/* Apaisado con poca altura: es como se juega en el teléfono, y es donde el
   retiro tiene 320 px de alto para contar doce temporadas. La producción se
   achica; la información no se toca. */
@media (max-height: 520px) {
  .retVerdict b { font-size: clamp(30px, 7.5vh, 44px); }
  .retStats { margin-top: 16px; }
  .retBlock { margin-top: 16px; }
  #retireCard .btns { margin-top: 18px; }
  #retireCard::before { display: none; }
  #milestones { bottom: calc(var(--gy-b) + 96px); }

  /* ---- Partido acostado. 375 px de alto no dan para un arco vertical de
     210: los tres botones van en fila y el radar se cae —a ese tamaño se
     come más de un cuarto de la altura útil, y para qué lado atacás ya lo
     dice el pizarrón—. La palanca corre su corte otro tanto.
     Condicionado a `.tactil` a propósito: en una ventana de escritorio de
     esta forma el radar se queda, y ahí sigue vivo un choque que Partido no
     trajo (el Mundial y la Práctica con viento ya lo tienen). */
  #hud.partido.tactil #planWrap { display: none; }
  #pTouch { width: 214px; height: 62px; }
  #pbA { right: 0; bottom: 0; } #pbD { right: 76px; bottom: 0; } #pbX { right: 152px; bottom: 0; }
  #pStick { right: calc(var(--gx-r) + 218px); }
  /* La placa ancha se comprime a una fila: el ícono, el nombre y la
     etiqueta. La descripción la reemplaza la pantalla previa. */
  button.mode.hero { margin-top: 14px; padding: 9px 12px; }
  button.mode.hero .mDesc { display: none; }

  /* ---- LA PORTADA EN APAISADO

     844×390: el alto útil son 346 px y el encabezado centrado se come 170
     de entrada. Con la grilla en 3×2 la segunda fila caía entera abajo del
     pliegue y el corte se leía como el final de la portada.

     Se aprieta el encabezado (el logotipo baja a 38 px y la bajada se va: la
     dicen las seis descripciones) y la grilla pasa a 6×1 en una sola fila.
     Las seis siguen midiendo igual entre sí. */
  .kicker { font-size: 8.5px; }
  .logo { font-size: clamp(30px, 4vw, 40px); margin-top: 6px; }
  .logo::after { margin-top: 10px; }
  .tagline { display: none; }
  .modes { margin-top: 12px; grid-template-columns: repeat(6, 1fr); gap: 8px; }
  button.mode { min-height: 0; padding: 10px 10px 9px; }
  .mode .mIco { font-size: 16px; }
  .mode .mName { margin-top: 7px; font-size: 15px; }
  .mode .mDesc { margin-top: 5px; }
  #assistBox { margin-top: 12px; padding-top: 10px; }
  #pF { margin-top: 8px; height: 32px; }

  /* La identidad en apaisado: la camiseta baja a 128 px y las filas se
     juntan. Con 172 la ficha entera medía 360 px sobre 355 disponibles y el
     botón de empezar quedaba pisando el borde. */
  .jsyPrev { width: 128px; }
  .carIdent { margin-top: 12px; gap: 16px; }
  .fldRow { margin-top: 10px; }
  .carId input { padding: 8px 11px; }

  /* El tablero: menos aire en todos lados, y la tabla en DOS temporadas.
     Parece poco y es lo correcto: en apaisado el alto útil son 347 px y la
     ficha, la fila de la Selección, la vitrina y los tres botones se comen
     240. Con dos filas más el encabezado entra justo; con tres empieza a
     scrollear la página, que funciona igual pero se disfruta menos. */
  #carCardTop { margin-top: 10px; padding: 10px 13px; }
  #carDash .scrollBox { margin-top: 9px; }
  #carTimeline { --rows: 2; }
  #carCase { margin-top: 9px; }
  #menuCareer > .btns { margin-top: 14px; }

  /* El párrafo de entrada se va. Es el mismo texto que la tarjeta del menú
     principal ya trae en su descripción —el jugador acaba de leerlo para
     llegar hasta acá— y en apaisado sus dos renglones son la diferencia
     entre una tabla de dos temporadas y una de ninguna. Mismo criterio que
     #powerLabel, .wlabel y #planWrap .cap, que también se caen acá. */
  #menuCareer > .wcLead { display: none; }

  /* El subtítulo de la Selección también, por la misma razón que en #carBar:
     el país y los dos números son lo que hay que leer. */
  #natRow .nrTx span { display: none; }
}

/* Apaisado ANCHO (el teléfono de costado, no el de costado y chico). Acá la
   tabla conserva su columna de "Títulos" —la que se cae por debajo de 700 px
   de ancho— y entonces la vitrina de abajo dice exactamente lo mismo dos
   veces. Sacándola entran los tres botones sin scrollear.

   La condición de ancho no es decoración: por debajo de 701 px se juntan los
   dos media queries, la columna de títulos ya no está, y si además sacáramos
   la vitrina los títulos no quedarían en ninguna parte. */
@media (max-height: 520px) and (min-width: 701px) {
  #carCase { display: none; }
}

/* ====================== TELÉFONO ACOSTADO (≤700 px de ancho y ≤520 de alto)

   Plegado, el panel se acuesta: el interruptor PATEAR/ATAJAR y la llave van
   UNO AL LADO DEL OTRO en vez de apilados.

   No es estética. Apilados ocupan de y=86 a y=183, y el cartel de la jugada
   —`#banner`, que a esta altura cae en 150— les pasa la línea de texto por
   encima justo a la altura de la llave: medido a 667×375, el estado se leía
   "×3 · BUENO ·" y "SIN VIENTO" quedaba atrás del cartel. Acostados terminan
   en 132 y el cartel pasa limpio por debajo.
   Hay lugar de sobra a lo ancho: la llave sola usaba de x=8 a x=235 en un
   viewport de 667. Lo que faltaba era usarlo. */
@media (max-width: 700px) and (max-height: 520px) {
  #practicePanel:not(.abierto) { flex-direction: row; align-items: flex-start; }
  #practicePanel:not(.abierto) > * { width: auto; }
}
