/* partido.css */
/* ==========================================================================
   El Camino DT — Día del partido
   --------------------------------------------------------------------------
   Una sola pantalla con tres trabajos simultáneos: mirar, entender y corregir.
   Por eso la retícula es de tres columnas y no de pestañas: si el DT tiene que
   cambiar de panel para hacer un cambio, deja de mirar el partido — y el
   partido no se detiene.

   El campo es la excepción de movimiento del sistema. En el resto del producto
   el movimiento es de 120–200ms y comunica un cambio de estado; acá el
   movimiento ES el dato. La regla que sigue vigente es la otra: nada se mueve
   que no signifique algo.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. RETÍCULA
   --------------------------------------------------------------------------
   Las columnas laterales son de ancho fijo porque su contenido es una lista de
   dorsales y nombres: no gana nada con más ancho y el campo sí. El hairline
   entre columnas es el gap, no un borde: una sola línea entre dos paneles.
   -------------------------------------------------------------------------- */

.match {
  display: grid;
  /* LA COLUMNA DE LA ALINEACIÓN ERA 236 Y CORTABA UN APELLIDO POR LISTA.
     -----------------------------------------------------------------
     La fila del once ya está apretada hasta el hueso —30px de puesto en
     versalita condensada, 18 de dorsal, 20 de medidor y 36 de nota, todos
     medidos uno por uno en el bloque de `.lineup__row`— así que al nombre le
     quedaban 93,3px y no había de dónde sacarle más ADENTRO de la fila. Los
     píxeles tenían que salir del panel, y ésa es la decisión de maqueta que
     faltaba tomar.

     MEDIDO SOBRE LOS 27.849 APELLIDOS DISTINTOS del juego, con la fuente y el
     tamaño reales de `.lineup__name` leídos del sitio servido:

         columna del nombre   apellidos que se cortan
              93,3px            1.567  (5,63 %)   ← 1,3 por lista de 23
             123,3px              243  (0,87 %)   ← 1 cada cuatro listas

     «Martínez Quarta» mide 112,4 y «Lewandowski» 93,3: los dos entran ahora y
     ninguno entraba antes. El percentil 99 de los apellidos del juego es 123,0,
     que es exactamente lo que la columna pasa a medir.

     LOS TREINTA PÍXELES SE LOS PAGA EL CAMPO Y LOS TIENE DE SOBRA. Su piso
     medido es 440px —pasado ese punto el disco del jugador deja de achicarse—
     y en la ventana más angosta donde esta retícula de tres columnas se aplica
     (1241px, que es donde la de abajo toma el relevo) el campo mide 695 y pasa
     a 665: **225px por encima del piso**. A 1280 son 264 y a 1600, 584.

     Y las dos columnas quedan parejas —266 y 262— que es lo que ya insinuaba
     el 236 contra 262: la de la derecha siempre fue la ancha. */
  grid-template-columns: 266px minmax(0, 1fr) 262px;
  gap: var(--sp-5);
  padding: var(--sp-5);
  background: var(--bg-page);
  /* Chrome y miga: lo que queda es de las tres columnas — ni un píxel más.
     Esta pantalla NO se baja: bajar la página durante un partido es perder de
     vista el campo, que es justo lo que la pantalla existe para no hacer. Las
     dos listas que crecen solas —el banquillo y la cronología— se desplazan
     dentro de su propio panel, y el campo se estrecha antes que nada. */
  height: calc(var(--alto-ventana) - var(--chrome-h) - var(--subnav-h) - 27px);
}

/* Cada columna es su propia caja cerrada: lo que no entra se desplaza adentro,
   nunca empuja a la página. */
.match > .band { background: var(--bg-panel); min-height: 0; overflow: hidden; }

/* La columna de la gente: el banquillo es lo elástico. El once nunca se
   recorta —son los once que están jugando— y la ayuda del pie tampoco. */
.match__once { grid-template-rows: auto auto auto minmax(0, 1fr) auto; align-content: stretch; }

/* «NUESTRA ALINEACIÓN» EN UN RENGLÓN. Es el título más largo de la pantalla y
   vive en la columna más angosta: por debajo de unos 1150px de ventana se
   doblaba en dos, y el renglón que ganaba el encabezado se lo perdía la lista
   —que es lo que hay que mirar— porque esta columna reparte su alto entre
   filas fijas y una elástica.

   Entra sin apretar nada: el título pide 153px y la formación 34, y la columna
   da 211. Lo único que hacía falta era decirle que no se parta. El recorte con
   puntos suspensivos es la red de abajo, para el día que alguien meta un club
   de nombre largo en «Once de …»: antes de empujar la columna, se recorta. */
.match__once .panel__title {
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ESA RED NO ESTABA ATADA, Y EL DÍA LLEGÓ. El recorte de arriba no se disparaba
   nunca: en vez de recortarse, el título EMPUJABA la columna entera y la lista
   se salía del panel. Es el mismo defecto que el rótulo del once rival de acá
   abajo —`.match__rival .band__sub`, con la cuenta puesta— entrando por el
   encabezado en vez de por el rótulo, y se arregla con la misma línea.

   LA MECÁNICA, PORQUE EL `text-overflow` DE ARRIBA HACE CREER QUE YA ESTÁ
   RESUELTO: `.band` es una retícula sin columnas declaradas (`app.css`), o sea
   una pista `auto`, y una pista `auto` se planta en el min-content de su hijo
   más ancho. El `min-width: 0` del título le baja el piso AL TÍTULO, pero no le
   baja el min-content al `.panel__head`, que es flex y lo suma entero: título
   + canalón + formación. Con la pista pasada de ancho, al título le sobra sitio
   y no se recorta jamás — la que se recorta es la columna.

   MEDIDO A 1280×800 CON «Once de Independiente», que es la captura que lo
   destapó. La caja del panel da 232px de contenido y el encabezado pedía
   206 + 8 + 53 = 267: la pista se plantó en 267,3 y los 35px de diferencia se
   los comió el `overflow: hidden` de `.match > .band`. Lo que se perdía no era
   el título sino la ÚLTIMA COLUMNA de las 23 filas —la nota, 36px— más el
   «5 cambios» del rótulo de suplentes. O sea: la pantalla cortaba el dato para
   no cortar un nombre, y ni siquiera dejaba barra para ir a buscarlo.

   NO ES UN CLUB RARO. El título sólo dice «Once de …» cuando el partido no se
   dirige —el ajeno y el amistoso que elegiste mirar—, y ahí el presupuesto del
   renglón son 171px. Contados los 1.659 nombres de club del juego con la fuente
   y el tamaño reales de `.panel__title`:

       «Once de <club>» por encima de 171px    998  (60,2 %)

   «Nuestra alineación» mide 164 y por eso el panel se veía sano: el caso que
   entra es el que no lleva nombre de club. Con la línea puesta, esos 998 se
   recortan con puntos —«Once de Independi…»— y las 23 notas vuelven adentro,
   que era la decisión que el bloque de arriba ya había tomado y no se estaba
   aplicando.

   LO QUE NO ARREGLA, DICHO: 60,2 % es mucho recorte. De los 171px del renglón,
   61 se los lleva la formación del encabezado. Devolvérselos al título bajaría
   el recorte a 306 clubes (18,4 %), pero esa formación NO es la del marcador:
   `formacion-eco` se repinta con cada cambio y `meta-l`/`meta-v` se escriben una
   sola vez al cargar. Sacarla de acá deja a la vista sólo la que se queda vieja,
   así que eso no es maqueta: es `partido.js`, y se decide aparte. */
.match__once .panel__head { min-width: 0; }

.match__once .lineup--banquillo { min-height: 0; overflow: auto; overscroll-behavior: contain; }

/* La columna de los datos: lo elástico es la cronología, que es lo único que
   crece con el partido. El once del rival queda anclado abajo.

   OJO CON ESTA LÍNEA: declara UNA FILA POR HIJO —seis— y el `minmax()` está en
   la CUARTA porque el cuarto hijo es `.crono`. Si alguien agrega o saca un hijo
   de la sección, la elástica se queda en su posición y le cae al vecino: el
   rótulo se estira y la cronología se planta en cero. No tira ningún error y el
   desborde total de la columna NO CAMBIA, así que medir `scrollHeight -
   clientHeight` no lo ve. Se caza leyendo el `grid-template-rows` computado y
   buscando una fila en `0px`.

   EL PISO DE 58px NO ES DECORACIÓN, y esto es lo que pasaba sin él. Medido el
   4/9/2026 a 1280×720 con un partido de 45' y seis sucesos:

     · `.crono` medía CERO. El rótulo «Cronología» y su contador —«6»— se
       dibujaban igual, encima de un hueco de nada: la pantalla anunciaba una
       lista que no existía.
     · Y el once del rival tampoco estaba entero: la columna se desbordaba 94px
       y `.match > .band` es `overflow: hidden`, así que las CUATRO ÚLTIMAS
       filas —Florentín, Fernández, Salas y Arce— quedaban recortadas y sin
       forma de llegar a ellas. Ni barra ni aviso.

   O sea que la columna no mostraba ni una cosa ni la otra. No hay reparto que
   arregle eso: los bloques fijos piden 625px y la columna mide 552. Con el
   rótulo en un renglón (abajo) se recuperan 34 y siguen faltando 39.

   LA CUENTA DE POR QUÉ ACÁ FALTA Y EN LA COLUMNA DE AL LADO NO. `.match__once`
   reparte lo mismo y su lista elástica —el banquillo— se queda con 126px sin
   despeinarse, porque sus bloques fijos suman 369. Los de acá suman 584: la
   diferencia son los 191px de `.vs`, que la otra columna no tiene. El `.vs` no
   da nada —se midió: apretarle el canalón de 6 a 4 devuelve 10px, y lo único
   que devuelve de verdad es borrar una estadística—, así que el alto sale de
   donde ya se estaba perdiendo solo.

   LO QUE CUESTA, DICHO ENTERO: el once del rival pasa a desplazarse, igual que
   el banquillo de al lado. A 1280×720 se ven 6 filas de once en vez de las 7 de
   antes —pero las once se ALCANZAN, que antes no—, y la cronología pasa de 0 a
   60px, que es el suceso corto entero y sobra.

   DE DÓNDE SALE EL 58, QUE NO ES UN NÚMERO REDONDO NI UNA PREFERENCIA: es EL
   PISO MÁS ALTO QUE DEJA EL ONCE DEL RIVAL ENTERO A 1440×900, que es el
   portátil de referencia. Ahí la pareja «cronología + once» reparte 390px y el
   once pide 330: quedan 60,3 para la cronología, y 58px de token dan 60,3 de
   pantalla con el zoom del sitio puesto. Está medido de a un píxel y el corte
   es exacto: con 58 el once mide 317 de 317 y no se recorta nada; **con 59 ya
   le falta 1px** y la última fila —Arce— empieza a pedir barra.

   O SEA QUE ESTE PISO NO TIENE UN PÍXEL DE HOLGURA PARA ARRIBA. Si algún día
   esta columna engorda un renglón —una estadística más en el `.vs`, un
   marcador más alto—, el once deja de entrar entero a 900 y no va a haber
   ningún error que lo avise: hay que volver a medir el corte, no subir el piso
   a ojo. Para abajo sí sobra: por encima de 960 de alto el piso ni se toca —a
   1440×960 la cronología se lleva 120 y el once entra igual— y por debajo de
   900 el once se desplaza pase lo que pase, porque la columna ya no da para
   los once (a 880 le faltan 19px, a 801 le faltan 95): eso no lo causa el
   piso.

   Y NO SE PONE EL PISO SÓLO EN LA FRANJA QUE LO NECESITA. Se probó atarlo a
   `max-height: 800`, que es donde la fila del once pasa de 22 a 27, y es peor:
   justo encima de 800 el once crece 55px de golpe, se come el reparto y la
   cronología volvía a cero. Un piso con agujero arriba del umbral es el
   defecto de nuevo, con otra fecha de aparición. */
/* Y LA MISMA REGLA ENTRA POR OTRA PUERTA: no sólo el ALTO mueve el reparto,
   también la CUENTA DE HIJOS. El `minmax()` está en la cuarta posición porque
   el cuarto hijo es `.crono`; si alguien agrega o saca un hijo de la sección,
   se queda donde está y pasa a tocarle al vecino — el rótulo se estira a cero
   y la lista que tenía que crecer queda de alto fijo.

   Medido el 4/9/2026 metiendo un séptimo hijo en la posición 2, y lo que hay
   que saber es cómo NO se ve: no da ningún error, y el desborde total de la
   columna tampoco cambia —cambia quién lo paga—, así que `scrollHeight -
   clientHeight` dice que no pasó nada. Se caza leyendo `grid-template-rows`
   computado y buscando una fila en `0px`.

   Es el mismo defecto que arregla el piso de arriba, con otro disparador. Por
   eso los puntos que pasan de página estrenaron en el entretiempo y no acá:
   con el piso puesto esta columna ya no regala alto, y su reparto no tiene un
   píxel de holgura para un inquilino nuevo. Ver «El panel pasa páginas» en
   `DESIGN.md`. */
.match__rival { grid-template-rows: auto auto auto minmax(58px, 1fr) auto minmax(0, auto); align-content: stretch; }

/* EL ROTULO DEL ONCE RIVAL, EN UN RENGLON. Es el mismo defecto que el título de
   la columna de al lado y se arregla igual: «Once de Independiente Rivadavia»
   doblaba en TRES renglones y medía 62px, contra los 27 de «Cronología», que es
   su vecino de la misma columna. Los 35 de diferencia eran para un rótulo.

   El sistema deja doblar al PRIMER rótulo de un `.band__sub` a propósito —ver
   `app.css`, «tiene que poder doblarse si algún día le toca una columna
   angosta»—. Ésta es esa columna angosta, y acá doblar se paga con la fila
   elástica. El recorte con puntos suspensivos es la red: antes de empujar la
   columna, se recorta. La formación no se toca —ya es `nowrap` por el sistema—
   y no se encoge, que es lo único que hay que decirle de más.

   EL `min-width: 0` DEL CONTENEDOR NO SOBRA, y sin él este arreglo hace un
   estropicio peor que el que arregla. Es la trampa que ya cuenta el bloque de
   la pantalla apilada, más abajo: `.band` es una retícula sin columnas
   declaradas (`app.css`), o sea una pista `auto`, y una pista `auto` se planta
   en el min-content de lo que lleva. Con el rótulo en `nowrap` ese min-content
   pasó de un renglón corto a los 333px de «Once de Independiente Rivadavia»
   entero: la pista creció a 333 dentro de una columna de 260, el `.band__sub`
   midió 346 y la formación se fue a 108px FUERA del panel, donde el
   `overflow: hidden` se la comía. El rótulo entraba en un renglón, sí, y la
   formación desaparecía. Poniendo en cero el piso del contenedor la pista
   vuelve a 237, el rótulo se recorta con puntos —«Once de Independiente
   Riva…»— y la formación vuelve adentro. Medido a 1280×720. */
.match__rival .band__sub { white-space: nowrap; min-width: 0; }
.match__rival .band__sub > .label:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.match__rival .band__sub > .label:not(:first-child) { flex-shrink: 0; }

/* Y el once del rival se desplaza dentro de su panel, como el banquillo de la
   columna de al lado. Es la otra mitad del piso de arriba: sin esto, lo que la
   cronología se lleva se lo come el `overflow: hidden` del panel y las últimas
   filas del once se pierden sin barra, que es exactamente el defecto que esto
   viene a arreglar. */
.match__rival .lineup--rival { min-height: 0; overflow: auto; overscroll-behavior: contain; }

/* La columna central respira distinto: el campo necesita margen propio para
   que la línea de banda no toque el hairline del panel.

   Y es un CONTENEDOR: la pizarra de abajo se parte en dos columnas o se apila
   según lo que mida esta columna, que no es una función del ancho de la
   ventana —depende de cuántas columnas queden en pie, y a 1240px se cae la del
   rival y la central gana 274px de golpe—. Preguntarle a la ventana daría la
   respuesta equivocada justo en los tamaños intermedios. */
.match__campo {
  container: campo / inline-size;
  /* Y es el marco de la HOJA: cuando la pizarra abierta ya no cabe debajo del
     campo, se abre SOBRE él, y se coloca contra esta caja. */
  position: relative;
  gap: var(--sp-5);
  padding: var(--sp-5) var(--sp-7);
  /* Y es la única columna que se desplaza como último recurso. No debería hacer
     falta nunca —la cuenta del campo le deja sitio a todo—, pero entre
     recortarle el pie a la pizarra y dejar que este panel se baje unos
     píxeles, se baja. */
  overflow-y: auto;
}

/* --------------------------------------------------------------------------
   2. MARCADOR
   --------------------------------------------------------------------------
   Escudo, nombre y cifra. El minuto va debajo del resultado porque es el dato
   que cambia solo: si estuviera al lado, competiría con la cifra que el DT
   está mirando.
   -------------------------------------------------------------------------- */

.marcador {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-6);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--line);
}

.marcador__eq { display: flex; align-items: center; gap: var(--sp-5); min-width: 0; }
.marcador__eq--visita { flex-direction: row-reverse; }

.marcador__ident { display: grid; gap: 1px; min-width: 0; }
.marcador__eq--visita .marcador__ident { text-align: right; }

.marcador__nombre {
  font-size: var(--fs-lg);
  font-weight: 700;
  font-stretch: var(--wd-condensed);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.marcador__meta { font-size: var(--fs-xs); color: var(--text-muted); }

.marcador__centro { display: grid; justify-items: center; gap: 1px; }

.marcador__cifra {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  font-size: var(--fs-3xl);
  font-weight: 700;
  font-stretch: var(--wd-condensed);
  line-height: var(--lh-tight);
  font-variant-numeric: tabular-nums;
}
/* El guion del marcador se queda apagado y NO cuenta para el contraste, porque
   lleva `aria-hidden` en el marcado: es un separador tipográfico entre dos
   cifras enormes, no un dato. Quien lo escucha oye «dos a uno» y no «dos guion
   uno», y quien lo mira ya tiene los dos números. La marca de `aria-hidden` es
   la que lo declara presentacional; sin ella sería sólo un texto ilegible. */
.marcador__guion { color: var(--ink-600); }

/* El gol se anuncia una vez y se apaga. Un marcador que parpadea sin parar es
   ruido; uno que destella cuando cambia es información.

   Se pinta en CAL y no en el color de canal. Dos razones que apuntan
   al mismo lado: un gol es el mejor valor que da esta pantalla, no un control
   que puedas pulsar; y la regla vieja de que el acento no entra al campo
   sigue en pie — con el violeta gobernando lo interactivo, un marcador
   violeta se leería como un botón. */
.marcador__cifra[data-gol='true'] { color: var(--good); }

.marcador__reloj {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* EL GLOBAL DE LA LLAVE. Debajo del reloj y más chico que él: es el segundo
   número de la cabecera y no puede competir con el marcador de hoy, que es el
   que se mira mientras rueda la pelota.

   Se colorea porque contesta una pregunta cerrada —¿alcanza?— y las tres
   respuestas ya tienen color en el sistema: verde el que pasa, ámbar el
   igualado (que en una vuelta es alargue, no eliminación) y arcilla el que va
   abajo. Es el mismo trío que usan las bandas de la mesa y el temple del que
   vende; un cuarto color acá sería un vocabulario nuevo para nada.

   La cabecera no lo reserva cuando no existe: el hueco lleva `hidden` y en una
   ida o un partido único no ocupa una línea en blanco debajo del reloj. */
.marcador__global {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

/* EL TIEMPO QUE HACE. El tercer renglón de la caja del medio, y el más chico
   de los tres: el marcador es el número, el reloj es cuándo, y esto es una
   condición que no cambia en todo el partido. En la voz apagada y sin color,
   igual que en las otras tres pantallas que lo dicen — ver `.clima` en
   `app.css`, que es la forma larga del mismo parte.

   `inline-flex` y no la rejilla de `.clima`: acá es una línea sola dentro de
   una columna centrada, sin consecuencia debajo, y una rejilla de dos columnas
   la habría estirado a todo el ancho de la caja.

   Y LO QUE CUESTA ESTÁ MEDIDO, porque en esta pantalla todo lo que no es campo
   se lo cobra al campo: veintidós píxeles de marcador, que a 1440x900 con la
   pizarra plegada son 805x521 de cancha contra 786x509, o sea un 4,6 % del
   área. Se paga a sabiendas: es un dato del partido que no cambia en noventa
   minutos y que explica lo que se ve pasar en la cancha.

   No hace falta re-medir `--sin-campo` a mano: `medirLoQueNoEsCampo()` lo suma
   solo. Los números de arriba son para el que venga a agregar el renglón
   veintitrés y quiera saber cuánto lleva gastado. */
.marcador__clima {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.marcador__clima .i { color: var(--text-secondary); }

.marcador__global[data-va='arriba'] { color: var(--good); }
.marcador__global[data-va='igual']  { color: var(--warn); }
.marcador__global[data-va='abajo']  { color: var(--danger); }

/* LA PANTALLA DEL PARTIDO, CON ASPECTO DE TRANSMISIÓN (16/10/2026)
   --------------------------------------------------------------------------
   Alberto eligió la variante B de la hoja del partido 2D: los colores, la
   cancha y la interfaz de una transmisión de partido —verdes vivos, azul y
   rojo de equipos, blanco limpio— para el marcador y la fila de controles.
   Se toma la estética, no la marca: ni logos ni textos ajenos. Los tonos
   viven acá y sólo acá. */
.match__campo {
  --tv-azul: #1f6fd9;
  --tv-blanco: #ffffff;
  --tv-tinta: #0b1424;
}

/* EL MARCADOR: DOS TARJETAS DE COLOR Y LA CIFRA EN EL MEDIO (16/10/2026, la
   «C» de la hoja del marcador). Alberto: «está todo muy amontonado y no se
   nota mucho los colores de cada equipo», y después «muy grande queda»: a la
   escala de los botones de abajo (46 px). Cada equipo es una tarjeta en
   el color de su camiseta, con el escudo grande adentro —con el halo o la
   placa que pide ESE color, ver `marcarEscudo()`— y la sigla; el borde es el
   segundo color, así que dos clubes blancos (River, Vélez) se distinguen por
   el rojo y el azul. En el medio, sobre tinta, la cifra grande y debajo el
   minuto en ácido. Abajo, chico, el clima. El nombre entero queda para el
   lector de pantalla. Es una retícula para que el orden del marcado —local,
   cifra, visita— no cambie. */
.marcador--compacto {
  --alto-tarjeta: 46px;
  display: grid;
  grid-template-columns: auto auto auto;
  grid-template-areas: 'l c v' 'k k k';
  justify-content: center;
  align-items: stretch;
  gap: var(--sp-3) var(--sp-5);
  padding-bottom: var(--sp-4);
}
.marcador--compacto .marcador__eq--local { grid-area: l; }
.marcador--compacto .marcador__eq--visita { grid-area: v; flex-direction: row-reverse; }
.marcador--compacto .marcador__centro { grid-area: c; }
.marcador--compacto .marcador__clima { grid-area: k; justify-self: center; margin: 0; }
.marcador--compacto .marcador__meta { display: none; }
.marcador--compacto .marcador__eq {
  flex-direction: row;
  justify-content: center;
  gap: var(--sp-3);
  min-width: 140px;
  height: var(--alto-tarjeta);
  padding: 0 var(--sp-4);
  border: 3px solid var(--s, transparent);
  border-radius: 10px;
  background: var(--k, var(--tv-azul));
  color: var(--t, var(--tv-blanco));
}
.marcador--compacto .marcador__ident { display: block; }
.marcador--compacto .marcador__nombre {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.marcador__sigla { display: none; }
.marcador--compacto .marcador__sigla {
  display: block;
  color: inherit;
  font-size: var(--fs-lg);
  font-weight: 800;
  letter-spacing: 0.03em;
}
.marcador--compacto .marcador__escudo { position: relative; display: inline-flex; align-items: center; }
.marcador--compacto .marcador__escudo .crest--lg { width: 30px; height: 30px; --halo: 0.55px; }

/* EL BRILLO DE METAL: una franja diagonal clara que cruza el escudo en unos
   700 ms cada siete segundos, recortada a la silueta con la máscara del mismo
   PNG (no se sale del borde). Sólo anima `transform`. El visitante va medio
   ciclo corrido: los dos nunca brillan juntos. Con «reducir movimiento», nada. */
.marcador__brillo {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: var(--escudo) center / contain no-repeat;
  mask: var(--escudo) center / contain no-repeat;
}
.marcador__brillo::before {
  content: '';
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: 0;
  width: 55%;
  background: linear-gradient(100deg, rgb(255 255 255 / 0) 0%, rgb(255 255 255 / 0.7) 50%, rgb(255 255 255 / 0) 100%);
  transform: translateX(-120%) skewX(-16deg);
  animation: brillo-de-metal 7s cubic-bezier(0.45, 0, 0.3, 1) infinite;
  will-change: transform;
}
.marcador__eq--visita .marcador__brillo::before { animation-delay: -3.5s; }
@keyframes brillo-de-metal {
  0%, 90% { transform: translateX(-120%) skewX(-16deg); }
  100% { transform: translateX(230%) skewX(-16deg); }
}
@media (prefers-reduced-motion: reduce) {
  .marcador__brillo { display: none; }
}
.marcador--compacto .marcador__centro,
.marcador--compacto .marcador__fila { display: contents; }
/* La cifra ES la caja de tinta del medio, y el minuto se apoya abajo, adentro
   de la misma celda: así el clima y el global, que viven en el mismo bloque
   del marcado, pueden irse al renglón de abajo. */
.marcador--compacto .marcador__cifra {
  grid-area: c;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: var(--sp-3);
  min-width: 96px;
  height: var(--alto-tarjeta);
  padding: 5px var(--sp-4) 0;
  border-radius: 10px;
  background: var(--tv-tinta);
  color: var(--tv-blanco);
  font-size: var(--fs-xl);
  font-weight: 800;
  line-height: 1;
}
.marcador--compacto .marcador__guion { color: var(--ink-500); }
.marcador--compacto .marcador__cifra[data-gol='true'] { color: var(--accent); }
.marcador--compacto .marcador__reloj {
  grid-area: c;
  align-self: end;
  justify-self: center;
  padding-bottom: 5px;
  color: var(--accent);
  font-size: var(--fs-2xs);
  font-weight: 800;
  line-height: 1;
}
.marcador--compacto .marcador__global { grid-area: k; justify-self: start; align-self: center; margin: 0; }

/* EN EL TELÉFONO, las tres piezas entran en 343 px: tarjetas más bajas, el
   escudo y la sigla más chicos, y menos aire entre piezas. La regla de abajo
   (≤560) apila el marcador grande del entretiempo, que comparte esta hoja;
   ésta la deshace para el compacto. */
@media (max-width: 560px) {
  .marcador.marcador--compacto { --alto-tarjeta: 44px; gap: var(--sp-2) var(--sp-2); align-items: stretch; }
  .marcador--compacto .marcador__eq,
  .marcador--compacto .marcador__eq--visita { min-width: 0; gap: var(--sp-2); padding: 0 var(--sp-3); border-width: 3px; border-radius: 10px; }
  .marcador--compacto .marcador__eq--visita { flex-direction: row-reverse; }
  .marcador--compacto .marcador__escudo .crest--lg { width: 26px; height: 26px; --halo: 0.5px; }
  .marcador--compacto .marcador__sigla { font-size: var(--fs-md); }
  .marcador--compacto .marcador__cifra { min-width: 0; padding: 5px var(--sp-3) 0; border-radius: 10px; font-size: var(--fs-lg); gap: var(--sp-2); }
  .marcador--compacto .marcador__reloj { font-size: var(--fs-2xs); padding-bottom: 4px; }
}

/* LA FILA DE CONTROLES, QUE SE VEA (16/10/2026, «los botones de acción que
   se vean»). Pastillas claras y grandes sobre la tinta: Reanudar/Pausa, que
   es el principal, en ácido; las demás en blanco hueso con texto de tinta, y
   la elegida en el azul de la transmisión. Sin barra de fondo: el azul noche
   las escondía. */
.match__campo .transport { gap: var(--sp-3); }
.match__campo .transport .segmented {
  gap: var(--sp-2);
  padding: 0;
  border: 0;
  background: none;
}
.match__campo .transport .btn,
.match__campo .transport .segmented__btn {
  min-height: 40px;
  padding: var(--sp-3) var(--sp-5);
  border: 0;
  border-radius: var(--r-pill);
  background: #e9edf3;
  color: var(--tv-tinta);
  box-shadow: none;
  font-size: var(--fs-md);
  font-weight: 800;
}
.match__campo .transport [data-f='pausa'] { background: var(--accent); color: var(--ink-1000); }
.match__campo .transport [data-f='pausa'] .i { color: var(--ink-1000); }
.match__campo .transport .segmented__btn[aria-pressed='true'],
.match__campo .transport .planteo-btn[aria-expanded='true'] {
  background: var(--tv-azul);
  color: var(--tv-blanco);
  box-shadow: none;
}
/* EL HOVER NO PUEDE BORRAR EL TEXTO. `modo-club.css` y `seleccion.css` le dan
   al botón segmentado un hover propio —texto claro y aro ácido, pensado para
   la pastilla oscura— y sobre la pastilla blanca de acá eso era blanco sobre
   blanco (1:1, medido). Cada estado dice acá su fondo Y su texto, con una
   especificidad que le gana a las dos hojas. */
@media (hover: hover) {
  .match__campo .transport .btn:hover,
  .match__campo .transport .segmented__btn:hover { background: #ffffff; color: var(--tv-tinta); box-shadow: none; }
  .match__campo .transport .segmented__btn[aria-pressed='true']:hover,
  .match__campo .transport .planteo-btn[aria-expanded='true']:hover { background: #1a5fbe; color: var(--tv-blanco); }
  .match__campo .transport [data-f='pausa']:hover { background: var(--accent-strong); color: var(--ink-1000); }
}
.match__campo .transport .btn:focus-visible,
.match__campo .transport .segmented__btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
@media (max-width: 560px) {
  .match__campo .transport { gap: var(--sp-2); }
  .match__campo .transport .btn,
  .match__campo .transport .segmented__btn { min-height: 40px; padding: var(--sp-2) var(--sp-4); font-size: var(--fs-sm); }
}

/* --------------------------------------------------------------------------
   3. EL CAMPO
   --------------------------------------------------------------------------
   Ancho gobernado por la altura disponible: el campo es una proporción fija
   (105 × 68) y lo que no puede hacer es empujar los controles fuera de la
   pantalla. Se estrecha antes de crecer hacia abajo.
   -------------------------------------------------------------------------- */

.pitch {
  position: relative;
  /* CUÁNTO ALTO LE QUEDA A LA CANCHA, Y QUIÉN LO DICE.
     Lo dice `--campo-alto`, y lo escribe `medirLoQueNoEsCampo()` restándole a
     la caja de la columna sus hermanos, los huecos y el relleno. La cuenta que
     había acá lo reconstruía desde la ventana —chrome, subnav, «37px de miga y
     borde» y `--sin-campo`— y esos 37 eran DIECISÉIS PÍXELES CORTOS: no
     contaban el canalón de `.match` (24) ni el borde del panel (2), contra los
     10 que ya traían de más. La cancha se llevaba dieciséis de ancho que no
     tenía, se estiraba quince de alto, y el borde de abajo terminaba 3,7px
     PINTADOS por debajo del relato — el hueco de 12 tapaba el resto y por eso
     se leía como un roce y no como un desborde.

     La cuenta de abajo queda como ESTIMACIÓN del primer cuadro, la que rige
     hasta que el guion mide; la constante ya va en 53. Es lo mismo que hacía el
     `427` de `--sin-campo`: un valor razonable para el instante en que todavía
     no hay nada medido. Quien manda es el estilo en línea que pone el guion.

     Es una variable y no un número porque la pizarra ocupa cuatro filas, tres
     o dos según el ancho de la columna, y cada fila que se ahorra son 39px que
     el campo se lleva: 427 con las cuatro, 388 con tres, 346 con dos. Los tres
     medidos sobre la pantalla, no estimados, y los tres incluyen los DOS
     renglones que la nota tiene reservados, que es lo que llega a ocupar
     cuando cuenta cómo terminó una llave.

     La regla de siempre: cada cosa que entra o sale del alto fijo se la cobra
     o se la devuelve al campo, que se estrecha antes de empujar un control
     fuera de la pantalla. Una palanca nueva se paga con ancho de campo.

     PERO SE LA COBRA HASTA UN PISO, que es lo que faltaba y por lo que la
     pizarra abierta dejaba el campo en 192x124 a 1440x900 y en 2x2 a 1280x720.
     La regla decía «el campo se estrecha antes que nada» y nadie había escrito
     dónde deja de tener sentido estrecharlo. Está escrito en el motor de
     dibujo y se puede medir: `RADIO_JUGADOR()` es `max(7, vista.u * 1.75)`, o
     sea que por debajo de `u = 4px` por metro el disco del futbolista DEJA DE
     ACHICARSE. Achicar más el campo ya no achica a los once: sólo los amontona.

     Ese punto son 440px PINTADOS de campo —`u = 4` con el 4,4 % de canalón que
     `medir()` reserva a cada lado—, y acá se escriben en píxeles de
     maquetación, que es lo que entiende esta hoja: `440 / --escala-sitio`.
     Medido en el navegador, no estimado: con el campo a 407px de maquetación,
     `vista.u` da 3,90 y `RADIO_JUGADOR()` da exactamente 7.

     Qué pasa cuando el piso se toca lo decide `medirLoQueNoEsCampo()`: la
     pizarra deja de ser hermana del campo y se abre como HOJA sobre él. */
  --campo-piso: calc(440px / var(--escala-sitio));
  --campo-alto: calc(var(--alto-ventana) - var(--chrome-h) - var(--subnav-h) - 53px - var(--sin-campo, 427px));
  width: min(100%, max(var(--campo-piso), calc(var(--campo-alto) * 1.544)));
  margin-inline: auto;
  /* CON LA CÁMARA, LA CAJA YA NO ES 105:68 (16/10/2026). De 981 para arriba
     la cancha se lleva TODO el alto que le queda a la columna —`--campo-alto`—
     y no sólo el que le tocaba por proporción: la cámara de cerca encuadra un
     pedazo y la entera se centra con la tribuna arriba y abajo. El ancho sigue
     saliendo de la misma cuenta, así que el piso y la hoja de la pizarra no
     cambian. Donde la página rueda, la proporción vuelve (abajo). */
  height: var(--campo-alto);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--ink-1000);
  overflow: hidden;
  cursor: crosshair;
}

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

/* «CANCHA ENTERA». Arriba a la derecha, sobre la tribuna: es un mando del
   lienzo y vive con él, sin cobrarle un renglón a la fila de controles (que a
   1280 ya va justa). Encendido, lleva el tilde y el borde de acento como los
   botones de la fila. */
.pitch__entera {
  position: absolute;
  z-index: 2;
  top: var(--sp-3);
  right: var(--sp-3);
  padding: var(--sp-2) var(--sp-4);
  border: 0;
  border-radius: var(--r-sm);
  background: rgb(11 20 36 / 0.82);
  color: #ffffff;
  font: inherit;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  cursor: pointer;
}
.pitch__entera[aria-pressed='true'] { background: #1f6fd9; }
.pitch__entera[aria-pressed='true']::before { content: '✓ '; }
.pitch__entera:disabled { cursor: default; opacity: 0.7; }
@media (hover: hover) {
  .pitch__entera:not(:disabled):hover { background: rgb(30 42 62 / 0.95); }
}

/* Etiqueta al vuelo: sólo aparece bajo el cursor y por eso puede ser opaca.
   Se dibuja en HTML y no en el canvas para que el nombre tenga la misma
   tipografía y el mismo antialiasing que el resto de la pantalla. */
.pitch__tip {
  position: absolute;
  z-index: 2;
  transform: translate(-50%, -140%);
  display: grid;
  gap: 1px;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--ink-950);
  white-space: nowrap;
  pointer-events: none;
}
/* Al que está pegado a la línea de fondo no le cabe el cartel arriba: se le
   pone abajo. El salto es de arriba a abajo y nunca a medio camino, para que
   el cartel no baile mientras el cursor recorre el campo. */
.pitch__tip[data-abajo='true'] { transform: translate(-50%, 40%); }
.pitch__tip[hidden] { display: none !important; }
.pitch__tip b { font-size: var(--fs-sm); font-weight: 700; color: var(--text-primary); }
.pitch__tip span { font-size: var(--fs-2xs); color: var(--text-muted); }

/* --------------------------------------------------------------------------
   3 bis. EL CARTEL DEL GOL Y DE LA TARJETA
   --------------------------------------------------------------------------
   Dos segundos sobre el campo con el nombre entero del que marcó o del que vio
   la tarjeta, y su club. Vive dentro de `.pitch` y fuera de flujo: no le cobra
   un píxel a nadie.

   NO ES UN MODAL Y NO DEBE PARECERLO. No hay botón, no hay foco que atrapar y
   no se tapa la pantalla: es un rótulo que pasa. La Regla del Foco del sistema
   dice que el momento de autor se hace sobre UN elemento —el que es el motivo
   de la pantalla— y nunca escondiendo el resto, y acá ese elemento es el campo.

   ESTE COMENTARIO DECÍA ADEMÁS «no se detiene el partido», Y ERA FALSO: dejó de
   serlo el día que `partido.js` frenó la simulación mientras dura el cartel del
   gol, y nadie volvió acá a corregirlo. Desde el 1/9/2026 frena en los tres
   —gol, amarilla y roja—, a pedido. Lo que sigue siendo cierto es lo que esa
   frase quería decir: el que se detiene es el RELOJ DE LA SIMULACIÓN y no la
   pantalla. El transporte sigue diciendo que el partido está en marcha, el
   dibujo sigue corriendo y el campo debajo sigue contestando al cursor
   —`pointer-events: none`—, así que esto no atrapa a nadie. El porqué entero
   está en `partido.js`, en «Y MIENTRAS HAY UN CARTEL, EL PARTIDO NO SIGUE».

   EL VELO ES DEL CAMPO, NO DE LA PÁGINA, y por eso puede ser oscuro sin apagar
   nada: lo que atenúa son veintidós discos que en ese instante están parados
   y el marcador, la alineación y la cronología siguen a plena luz al lado.

   Y ES EL ÚNICO VELO. Hasta el 1/9/2026 había DOS anuncios del mismo gol, uno
   encima del otro: debajo de éste, el lienzo pintaba su propio lavado de acento
   al 12 % con la palabra GOL en el medio, que era el anuncio de antes de que
   este cartel existiera. Se leía por debajo del 62 % de acá, en verde y
   desenfocada, atrás del nombre. Se fue el lavado y se fue la palabra; queda el
   que dice QUIÉN.
   -------------------------------------------------------------------------- */

.cartel {
  position: absolute;
  inset: 0;
  z-index: 3;
  /* Escudo y texto uno al lado del otro, los dos centrados en el campo. `column`
     y no dos columnas declaradas: el escudo mide lo suyo y el texto lo que le
     haga falta, sin repartir un ancho que ninguno de los dos conoce. */
  display: grid;
  grid-auto-flow: column;
  align-content: center;
  justify-content: center;
  align-items: center;
  gap: var(--sp-6);
  padding: var(--sp-6);
  /* Ni un evento: el campo debajo sigue respondiendo al cursor, que es lo que
     hace que esto sea un rótulo y no una capa modal. */
  pointer-events: none;
  background: color-mix(in srgb, var(--ink-1000) 62%, transparent);
}
.cartel[hidden] { display: none !important; }

/* El escudo del club al que se le adjudica. Crece con la columna igual que el
   nombre, y con los mismos dos topes de sentido común: por debajo de 40px un
   escudo es una mancha y por encima de 84 le compite al nombre, que es lo que
   este cartel vino a decir. */
.cartel__escudo { display: grid; }
.cartel__escudo .crest {
  width: clamp(40px, 9cqi, 84px);
  height: auto;
  aspect-ratio: 1;
  object-fit: contain;
}

/* El bloque de texto. Alineado a la izquierda porque ahora tiene un vecino: los
   tres renglones centrados al lado de un escudo se leen como tres cosas
   sueltas y no como una ficha. */
.cartel__info { display: grid; gap: var(--sp-2); justify-items: start; text-align: left; }

/* Y EN UNA CANCHA ANGOSTA SE APILA. Con el escudo al lado, el nombre más largo
   del universo se queda sin ancho antes que la cancha se quede sin píxeles: por
   debajo de 520px de columna el escudo sube y los tres renglones vuelven al
   centro, que es el reparto que ya funcionaba. El número está medido con
   «Athanasios Papathanasiou-Gerofokas», no elegido. */
@container campo (max-width: 520px) {
  .cartel { grid-auto-flow: row; justify-items: center; gap: var(--sp-4); }
  .cartel__info { justify-items: center; text-align: center; }
}

/* Y EN UN TELÉFONO DE 360 NO ALCANZA CON APILAR: hay que achicar. La cancha ahí
   mide 265x172 y el cartel apilado con el nombre más largo del universo pide
   ocho píxeles más de los que tiene — comprobado, escondía justo 8 en las cinco
   ventanas de 360 y ninguna de 390.

   El corte son 285px de COLUMNA y está medido, no elegido: la columna del campo
   da 227 a 320 de ventana, 266 a 360, 280 a 375, 295 a 390 y 318 a 414. En 285
   entran los tres teléfonos angostos y se quedan afuera el 390 y el 414, que ya
   entraban sin apretar nada.

   Lo que se achica es todo junto y en un solo paso: el escudo, los huecos, el
   canalón y las dos tipografías de abajo. El rótulo del suceso NO se toca —es
   el que dice qué pasó— y el nombre baja a 18px, que en esta escala sigue
   siendo el tamaño de un título de panel. */
@container campo (max-width: 285px) {
  .cartel { padding: var(--sp-4); gap: var(--sp-3); }
  .cartel__info { gap: 2px; }
  .cartel__quien { font-size: var(--fs-lg); }
  .cartel__club { font-size: var(--fs-sm); }
  .cartel__escudo .crest { width: 34px; }
}

/* Y UN ESCALÓN MÁS PARA EL TELÉFONO MÁS CHICO QUE EXISTE. A 320 de ventana la
   columna da 227 y la cancha queda en 227x147: ni con el escalón de arriba
   entra el nombre más largo, faltaban quince píxeles. Acá el nombre baja al
   tamaño del dato base —el mismo de la lista de suplentes de al lado— y el
   escudo a 28, que sigue siendo un escudo reconocible y deja de competir.

   Es el último escalón a propósito, y LO QUE NO ALCANZA SE DICE: en una ventana
   de 320 —un iPhone SE de primera generación, la cancha más chica que el juego
   dibuja— el nombre más largo del universo todavía se pasa unos once píxeles
   del alto del cartel, y el `overflow: hidden` del campo se los recorta. Se
   probó apilar y no apilar y se probó bajar otro escalón de tipografía: en esa
   cancha no entran un escudo, un rótulo, un nombre de treinta y cuatro
   caracteres y un club de treinta y dos, y el siguiente recorte tendría que
   QUITARLE algo al cartel en vez de achicarlo.

   Se paga a sabiendas y con la cuenta a la vista: son once píxeles de la última
   línea, en el teléfono más chico que existe, y sólo con el nombre más largo de
   los 46.634 del juego. `medir-cartel.html` barre desde 360 por eso, y lo dice
   ahí también para que nadie crea que 320 está cubierto. */
@container campo (max-width: 240px) {
  .cartel { padding: var(--sp-2); gap: var(--sp-2); }
  .cartel__que { font-size: var(--fs-2xs); }
  .cartel__quien { font-size: var(--fs-md); line-height: 1; }
  .cartel__club { font-size: var(--fs-xs); }
  .cartel__escudo .crest { width: 28px; }
}

/* EL QUÉ, en versalitas y del color del suceso. Tres palabras como mucho: es el
   rótulo más corto de la pantalla y aguanta las mayúsculas (ver la regla de las
   versalitas en DESIGN.md). */
.cartel__que {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.cartel[data-tipo='gol'] .cartel__que      { color: var(--good); }
.cartel[data-tipo='amarilla'] .cartel__que { color: var(--amber-500); }
.cartel[data-tipo='roja'] .cartel__que     { color: var(--danger); }

/* EL NOMBRE ENTERO, que es el motivo por el que este cartel existe. Se recorta
   antes que desbordar el campo, y puede doblar: acá no hay nada debajo que
   correr —el cartel está fuera de flujo— así que dos renglones no cuestan nada
   y un nombre partido en tres puntos sí. */
.cartel__quien {
  max-width: 100%;
  /* Crece con la COLUMNA y no con la ventana: `campo` es el contenedor que ya
     declara `.match__campo`, y la cancha mide entre 423 y 1.567px de ancho
     según la pantalla — un tamaño fijo sería enorme en una y no se leería en la
     otra. Los topes son los dos tamaños del sistema que tienen sentido acá: el
     de la navegación primaria abajo y el del nombre de un futbolista en su
     ficha arriba, que es exactamente lo que esto es.

     El 4 % está medido contra el peor caso —la cancha en su piso con el nombre
     más largo del universo— y no elegido: ver `medir-cartel.html`. */
  font-size: clamp(var(--fs-xl), 4cqi, var(--fs-3xl));
  font-weight: 700;
  line-height: 1.1;
  color: var(--text-primary);
  text-wrap: balance;
}

.cartel__club { font-size: var(--fs-md); color: var(--text-secondary); }

/* La entrada: sube dos píxeles y aparece. Es la excepción de movimiento del
   campo dicha en pequeño — el resto de la pantalla no se mueve. */
@media (prefers-reduced-motion: no-preference) {
  .cartel:not([hidden]) { animation: cartel-entra var(--dur) var(--ease-entrada) both; }
  @keyframes cartel-entra {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
  }
}

/* --------------------------------------------------------------------------
   4. RELATO Y TRANSPORTE
   -------------------------------------------------------------------------- */

/* EL RELATO NO SE VE (24/9/2026: «quitemos el relato de abajo» —Alberto—).
   Sigue en el documento porque es la región viva del partido —el lector de
   pantalla cuenta la jugada con ella— pero no ocupa un renglón debajo de la
   cancha: lo que pasa lo dice la cancha, y lo que importa queda en la
   cronología de la derecha. Es el recorte de siempre de «sólo para el lector»:
   fuera de la vista y del flujo, sin `display: none`, que lo callaría.

   Y POR ESO NO LLEVA TINTA NI ANIMACIÓN (27/9/2026). Acá vivían la regla de
   la línea visible —una altura fija y el recorte con puntos suspensivos—, la
   tinta que separaba el aviso del ambiente y del gol, y el fundido de llegada
   del aviso. Las tres pintaban una línea que nadie ve, y la de la altura
   encima se pisaba con esta. Alberto volvió a ver el relato el 27/9 con la
   hoja anterior al 24/9 guardada en caché bajo la clave de esta —es el
   borde envenenado de `el-borde-se-envenena`—, y sacarlas es además lo que
   le cambia la clave a este archivo. */
.relato {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.transport { display: flex; align-items: center; justify-content: center; gap: var(--sp-5); }

/* --------------------------------------------------------------------------
   5. PIZARRA — táctica, estrategia y cambios
   --------------------------------------------------------------------------
   Los cuatro controles que el DT tiene durante el partido, en el orden en que
   los usa: la forma, la intención, el ritmo y la salida. Cada uno es una fila
   con su etiqueta a la izquierda, para que se lean como una lista de
   decisiones y no como una barra de herramientas.

   Cuántas filas ocupan es cosa del ancho que haya, y no un capricho: ninguno de
   los cuatro segmentados llega a la mitad de la columna central, así que
   apilarlos siempre sería pagar ochenta píxeles de alto por un vacío a la
   derecha. Y el alto de esta caja sale del campo —es la misma pantalla y no se
   baja—, o sea que ese vacío se cobra en cancha. Tres repartos, de menos a más
   ancho: las cuatro en fila, las dos cortas compartiendo renglón, y las cuatro
   en dos columnas de dos.
   -------------------------------------------------------------------------- */

.pizarra {
  display: grid;
  gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-6);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--ink-950);
}

/* Los dos repartos anchos son de la pizarra DEL PARTIDO y no del componente:
   en el entretiempo la misma caja vive en una columna angosta, donde partirla
   sería obligar a cada segmentado a doblarse en dos renglones. Por eso cuelgan
   del contenedor `campo`, que sólo existe en esta pantalla.

   Y se le pregunta a la columna, no a la ventana: a 1240px se cae la columna
   del rival y la central gana 274px de golpe, así que el mismo ancho de
   ventana da columnas centrales muy distintas. Las medidas son por dentro, que
   es lo que mide un contenedor.

   PRIMER PASO, el de los portátiles de 1440: no entran las cuatro filas en dos
   columnas, pero sí las dos cortas —ritmo y salida— compartiendo renglón. Cada
   una pide 323px con su etiqueta; dos más el canalón y el relleno de la caja
   son los 710. Una fila menos son 39px que se le devuelven al campo. */
@container campo (min-width: 710px) {
  .pizarra { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--sp-7); }
  /* La forma y la intención siguen mandando un renglón entero cada una: son las
     dos filas anchas y partirlas las doblaría. */
  .pizarra__row:nth-child(1),
  .pizarra__row:nth-child(2),
  .pizarra__ellos,
  .pizarra > .pizarra__lectura,
  .pizarra > .pizarra__nota { grid-column: 1 / -1; }
  /* Acá había un `--sin-campo: 388px`, y ya no dice nada: desde que
     `medirLoQueNoEsCampo()` lo MIDE y lo escribe en el estilo en línea del
     campo, ninguna de estas tres constantes se aplicaba nunca. Y las tres
     habían quedado cortas —en este mismo reparto la suma real es 564, no
     388—, así que además de muertas mentían. La medida manda; los repartos
     que siguen abajo son de la retícula, que es lo suyo. */
}

/* SEGUNDO PASO: las cuatro en dos columnas de dos. 900px es donde entran —421
   pide la fila más ancha, la de las cinco estrategias, 233 la más angosta, y
   el resto son etiquetas, canalones y relleno—. Se lee por columnas y no por
   filas: a la izquierda la forma y la intención, a la derecha el ritmo y la
   salida. Por eso el flujo es por columna, y la primera se mide por su
   contenido: repartir mitad y mitad doblaría las estrategias en dos renglones,
   que es justo el renglón que veníamos a sacar. */
@container campo (min-width: 900px) {
  .pizarra {
    /* Colocación EXPLÍCITA, y no `grid-auto-flow: column`. El flujo automático
       por columna funcionó mientras todos los hijos fueran iguales; con el plan
       del rival puesto a mano en la tercera columna, el algoritmo reacomodaba
       el resto y la pizarra salía en desorden —el ritmo arriba, la táctica
       abajo y fuera de la caja—. Seis piezas y seis coordenadas: no hay nada
       que adivinar. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.85fr);
    grid-template-rows: repeat(4, auto);
    column-gap: var(--sp-7);
  }

  /* Izquierda la forma y la intención, al medio el ritmo y la salida: se lee
     por columnas, de lo que se decide una vez a lo que se corrige jugando. Las
     dos miden IGUAL —`1fr` y `1fr`, no `max-content`—, porque desde que los
     desplegables se estiran `max-content` significa «todo lo que haya»: la
     táctica se llevaba 656px para escribir «4-4-2» y el ritmo quedaba apretado
     contra el borde. Cuatro decisiones del mismo peso, del mismo ancho. */
  .pizarra__row:nth-child(1) { grid-area: 1 / 1; }
  .pizarra__row:nth-child(2) { grid-area: 2 / 1; }
  .pizarra__row:nth-child(3) { grid-area: 1 / 2; }
  .pizarra__row:nth-child(4) { grid-area: 2 / 2; }

  /* El rival, en la tercera columna y los dos renglones. NO suma alto: entra en
     el que ya existía, que es la única forma de que la cancha no lo pague —se
     dimensiona con lo que le sobra a esta caja. */
  .pizarra__ellos { grid-area: 1 / 3 / span 2 / auto; }

  /* La nota cruza las tres. Va al tercer renglón mientras haya dos por encima;
     cuando la pizarra se apaga —un partido ajeno se mira, no se dirige— queda
     sola y sube a la primera, o la caja reservaría el alto de dos filas
     vacías. */
  .pizarra > .pizarra__lectura { grid-column: 1 / -1; grid-row: 3; }
  .pizarra > .pizarra__nota { grid-column: 1 / -1; }
  .pizarra > .pizarra__nota:not(:only-child) { grid-row: 4; }

  /* Dos filas de pizarra en vez de cuatro son 80px que vuelven al campo. La
     cuenta del alto fijo se paga siempre; acá se cobra en ancho de cancha —y
     cuánto exactamente lo mide el guion, no esta hoja. */
}

/* `[hidden]` no alcanza solo: `.pizarra` es `display: grid` y una declaración
   de display gana siempre al `display: none` que el atributo trae de la hoja
   del navegador. */
.pizarra[hidden] { display: none; }

/* --------------------------------------------------------------------------
   LA HOJA — la pizarra cuando ya no cabe debajo del campo
   --------------------------------------------------------------------------
   La regla vieja era «la palanca nueva se paga con ancho de campo» y no tenía
   fondo: con la pizarra abierta, `--sin-campo` llegaba a 623 sobre los 522 que
   hay a 1280x720 y el campo salía de 2x2 píxeles, con la columna desbordada
   111px por abajo. A 1440x900 salía de 192x124. Un campo así no es un campo
   chico: es un campo que no se puede mirar.

   EL PISO ESTÁ MEDIDO Y ESTÁ EN EL MOTOR DE DIBUJO, no elegido a ojo: por
   debajo de 440px pintados de ancho, `RADIO_JUGADOR()` se planta en su mínimo
   de 7px y los once dejan de achicarse con la cancha —sólo se amontonan—.
   Estrechar más allá de ahí no compra nada.

   Y ES UN INTERRUPTOR, NO UN TOPE. Sirve de tope de último recurso (el
   `max()` del `.pitch`), pero lo que hace de verdad es decidir el reparto:
   mientras el campo aguante el piso, la pizarra va DEBAJO y se paga con
   cancha, que es lo de siempre y lo que pasa a 1920x1080. Cuando no aguanta,
   la pizarra sale del flujo y se abre SOBRE el campo. El campo recupera
   entonces el tamaño que tendría con la pizarra cerrada.

   POR QUÉ TAPAR EL CAMPO Y NO PARTIR LA DIFERENCIA. Se midieron las dos
   salidas que había sobre la mesa y ninguna llega a 1280x720:

   - Piso duro + la pizarra desplazándose por dentro: a 1280x720 quedan 522px
     para todo, 195 son el marcador, el relato y el transporte, y el piso del
     campo pide 264 de alto. A la pizarra le sobran 51px de los 418 que mide.
     Un panel de control mirado por una ranura de 51px no es un panel.
   - Que la pizarra se pliegue sola por debajo de cierto alto: deja al DT sin
     poder replantear con el partido corriendo en 1280x720, que es media
     pantalla. El propio archivo lo dice arriba: poder corregir mientras corre
     «es medio juego».

   Lo que se pierde tapando es la VISTA del campo, y sólo mientras la pizarra
   está abierta —un clic la cierra, y el botón que la cierra queda debajo de la
   hoja, a la vista—. No se pierde el partido: el marcador, el reloj y el
   relato, que es la descripción en texto de lo que pasa en la cancha, quedan
   los tres fuera de la hoja. El partido tampoco se detiene.

   La hoja se coloca sobre la caja del campo con dos medidas que escribe
   `medirLoQueNoEsCampo()` —`offsetTop` y `offsetHeight` del campo, en píxeles
   de MAQUETACIÓN, que es lo que entiende `top`—. Se miden y no se calculan por
   el mismo motivo que `--sin-campo`: una constante acá se rompe la próxima vez
   que el marcador crezca un renglón.
   -------------------------------------------------------------------------- */
.match__campo[data-planteo='hoja'] .pizarra {
  position: absolute;
  z-index: 3;
  top: var(--hoja-arriba, 0);
  right: var(--sp-7);
  left: var(--sp-7);
  height: var(--hoja-alto, auto);
  /* Opaca y con sombra: si dejara ver el césped por debajo, los desplegables
     se leerían sobre jugadores en movimiento. */
  align-content: start;
  background: var(--ink-950);
  box-shadow: var(--sombra-modal);
  /* Y si aun tapando el campo entero no entra —a 1280x720 la pizarra apilada
     mide 418 y la caja del campo 327—, se desplaza por dentro. Es el único
     sitio donde la pizarra se desplaza, y cae del lado correcto: arriba están
     los cuatro mandos y abajo el plan del rival y la nota, que son lectura. */
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* El botón que la abre. Lleva la flecha del desplegable y la gira al abrir,
   que es el mismo gesto que ya hacen los cuatro mandos de adentro. */
.planteo-btn { display: inline-flex; align-items: center; gap: var(--sp-2); }
.planteo-btn .i { transition: transform var(--dur-fast) var(--ease); }
.planteo-btn[aria-expanded='true'] .i { transform: rotate(180deg); }

.pizarra__row {
  display: grid;
  /* 88 y no 78: «Estrategia» mide 81px y se cortaba por tres. Medido, no
     estimado — es el rótulo más largo de los cuatro. */
  grid-template-columns: 88px 1fr;
  align-items: center;
  gap: var(--sp-5);
}

.pizarra__row .segmented { flex-wrap: wrap; }

/* El desplegable de la pizarra se fue a `app.css`: lo usan la pizarra del
   partido y el mando de la previa, o sea dos pantallas. El plan de enfrente se
   fue por lo mismo: lo pintan el partido y el entretiempo. */

.pizarra__nota { font-size: var(--fs-xs); color: var(--text-muted); }

/* Dos renglones reservados en la pizarra del partido. La nota cambia sola —el
   resultado de una llave ocupa el doble que "elegí un titular"—, y si el hueco
   creciera con ella empujaría la caja fuera de la pantalla justo cuando más
   cosas dice. Se paga una vez, en la cuenta del campo, y no cada vez. */
.match__campo .pizarra > .pizarra__nota { min-height: 31px; }
.pizarra__nota strong { color: var(--text-secondary); font-weight: 600; }

/* --------------------------------------------------------------------------
   6. ALINEACIÓN
   --------------------------------------------------------------------------
   La fila de jugador de esta pantalla NO es la fila de atributo: no hay escala
   1–20 que rellenar. Comparte su altura (22px) y su ritmo para que las tres
   columnas midan igual, pero su dato propio es la condición física, que es lo
   que decide un cambio.

   LA CONDICIÓN DEJÓ DE SER EL FONDO DE LA FILA. Durante mucho tiempo el
   relleno era la fila entera escalada en X, y el argumento era bueno —el DT ve
   la caída sin leer un número—; lo que no se había mirado es qué pasa cuando
   hay DIECIOCHO. Al saque los dieciocho están cerca del 100 %, así que las
   dieciocho barras miden casi lo mismo y el panel se lee como un gráfico de
   barras dentado en el que ninguna barra dice nada. La señal era chica y el
   ruido, de dieciocho renglones de alto.

   La piel de FM26 resuelve las dos cosas de una: la fila pasa a ser una
   SUPERFICIE PAREJA con su esquina redondeada —la lista se lee como una lista,
   que es lo que es— y la condición se muda a un medidor cápsula de 26px, el
   `.meter__track` del sistema, que es la misma forma con la que la referencia
   dibuja sus barras. Un borde recto y deliberado en vez de dieciocho bordes
   accidentales.
   -------------------------------------------------------------------------- */

.lineup { display: grid; gap: var(--sp-1); }

.lineup__row {
  position: relative;
  display: grid;
  /* EL NOMBRE ES LO QUE SE LEE, y en esta fila es lo único que mide distinto en
     cada renglón: todo lo demás son anchos fijos que hay que apretar hasta lo
     que de verdad ocupan. La columna del medidor le costó 38px al apellido la
     primera vez que entró, y «K. Lom…» no es un renglón de alineación.

     Medido y no estimado: un dorsal de dos cifras en condensada mide 16 y la
     cápsula lee igual a 20 que a 32. Con el canalón a 4px la fila gasta 12px
     MENOS de lo fijo que antes de que el medidor existiera.

     LA COLUMNA DEL PUESTO ERA 28 Y «MCO» MIDE 35,4, y es exactamente el defecto
     que cuenta el párrafo de abajo sobre la columna de la nota, otra vez: los
     28 se midieron con la versalita en 10px —«MCD» daba 26 de tinta—, `--fs-2xs`
     subió a 13 y nadie volvió a medir ESTA columna. Lo que se veía es que la
     etiqueta se derramaba 7,4px y le caía 3,4 ENCIMA del dorsal: «MCO14»,
     «MCD23», que no son un puesto y un número sino una palabra que no existe.
     Cinco de los doce puestos llevan tres letras; dos se montan —MCO a −3,4 y
     MCD a −2,6— y otros dos quedan a dos píxeles pelados, DFC y DFD, que a esta
     escala se lee igual de mal.

     NO SE ARREGLA CENTRANDO, y se probó antes de tocar nada: «MCO» no ENTRA en
     la celda, así que centrar derrama lo mismo por los dos lados y la colisión
     queda IDÉNTICA —los mismos −3,4 medidos—. Lo único que mueve es la otra
     punta: PO se mete 3,3px y EI 6,9, y ahí se pierde el riel izquierdo, que es
     lo que permite barrer con el ojo veintitrés renglones de puestos.

     SE ARREGLA EN LA ETIQUETA Y NO EN LA COLUMNA. La versalita pasa a la misma
     anchura condensada que ya usa el dorsal pegado a ella —ver `.lineup__pos`—:
     «MCO» baja de 35,4 a 29,6, la columna cierra en 30 y el canalón más apretado
     queda en 4,4. El nombre paga DOS píxeles —95,3 a 93,3— en vez de los ocho
     que costaba llevar la columna a 36. Y los ocho no son teóricos: a 87,3 se
     empiezan a cortar apellidos que hoy entran enteros —«Lomónaco» en la fila,
     y «Lewandowski» (93,4) o «Aubameyang» (90,9) en cuanto se dirige afuera—.
     El entretiempo sí llevó su columna a 36 y ahí sigue estando bien: esa fila
     tiene una cabecera con «Pos» encima, que mide 30,6 y pide la columna ancha
     aunque la etiqueta de abajo se achique. Medido después de este cambio: su
     canalón más apretado pasó de 5,4 a 10,4 y ningún apellido nuevo se corta.

     LO QUE ESTE CAMBIO NO ARREGLA, dicho para que no se lea como arreglado: por
     debajo de 980 la lista se parte en dos columnas y al nombre le quedaban
     27,6px: los VEINTITRÉS apellidos salen como «Ta…», medido a 390. Ahí estos
     dos píxeles también se pagan —quedan 25,6— y no se notan porque no hay nada
     que perder: esa pantalla ya no tenía nombres antes de este cambio. Es otro
     defecto y necesita otra fila, no otra columna.

     LA COLUMNA DE LA NOTA ERA 30 Y LA PASTILLA MIDE 37, y ahí estaba el defecto
     que se veía: «6,5» medía 28 cuando la escala de datos era de 13px, la
     escala subió dos escalones y nadie volvió a medir esta columna. Como la
     pastilla va anclada a la derecha, los siete píxeles que le sobran se le
     caían encima al medidor por la izquierda: no quedaba «pegada» al riel gris,
     estaba **montada sobre él 3px**. Medido, no mirado.

     Los números de ahora, con el aire de la pastilla apretado a 4px —que es lo
     único que esta fila puede tocar de un componente compartido, y ya lo dice
     el bloque de abajo—: una nota normal mide 33 y «10,0», que el motor puede
     dar porque la nota va de 3 a 10, mide 43. Con 36 de columna la normal entra
     con tres de sobra y la de dos cifras se come el canalón sin llegar al riel.
     El nombre paga seis píxeles, que es lo que había que pagar. */
  grid-template-columns: 30px 18px minmax(0, 1fr) 20px 36px;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  height: var(--row-h);
  padding: 0 var(--sp-3);
  /* 5px y no 3: es el escalón hacia el radio de FM26, y sobre una superficie
     llena se nota — sobre un relleno que casi nunca llegaba al borde, no. */
  border-radius: var(--r-sm);
  background: var(--bg-row);
  text-align: left;
  isolation: isolate;
  transition: background var(--dur-fast) var(--ease);
}
@media (hover: hover) {
  .lineup__row:hover { background: var(--bg-hover); }
}

/* EL AIRE DE LA LISTA. La fila nació midiendo lo mismo que la fila de atributo
   —22px, el `--row-h` de las tablas— y en una tabla eso está bien: una tabla se
   barre con el dedo por una columna. Esta lista no se barre, se LEE: son
   veintitrés renglones apilados en la columna más angosta de la pantalla, cada
   uno con puesto, dorsal, apellido, medidor y nota, y a 22px con 2px entre
   medio el bloque deja de tener renglones y pasa a ser un muro.

   El aire va ADENTRO de la fila y no entre las filas: la fila tiene superficie
   propia desde que es una tarjeta de FM26, así que lo que separa un renglón del
   siguiente ya es el fondo, y estirar el canalón sólo habría despegado unas
   cápsulas que ya estaban despegadas. Con 27px la caja respira alrededor del
   nombre de 13px —siete arriba y siete abajo— que es la proporción de la fila
   del menú y la de la bandeja, las otras dos listas largas del juego.

   Sólo en el partido. `.et` hereda esta fila y su pantalla tiene otra cuenta
   —una sola columna y un portátil de 900 como piso—, así que la altura nueva se
   aplica desde `.match`, que es donde está el muro. Y con su devolución escrita
   en la respuesta a pantalla: en una ventana baja el aire se lo paga el
   banquillo, que es lo único elástico de la columna, y cinco píxeles por
   renglón le comen dos suplentes de los que se ven. */
.match .lineup__row { height: var(--fila-lectura); }

/* El medidor de condición. Es el `.meter__track` del sistema con dos cambios,
   y los dos son de significado, no de forma:

   - El relleno normal es NEUTRO y no de acento. El acento es de lo que
     responde al dedo; y además, al saque los dieciocho están al 100 % y
     dieciocho cápsulas violetas serían color que no informa nada.
   - Por debajo del 60 % se vuelve ámbar —«atención», que es exactamente lo que
     pide una pierna fundida— y ahí sí el color significa. Es `--warn` y no un
     ámbar nuevo: el sistema ya tiene el color de atención.

   Sin cifra al lado, que es la excepción que esta pantalla ya tenía declarada:
   en el partido en vivo la lista se mira de reojo. En el entretiempo, donde la
   condición ES la decisión, la fila crece y lleva su número. */
/* El riel se hunde en vez de posarse. El `.meter__track` del sistema es
   `--ink-800`, que es EL MISMO color que la fila desde que la fila tiene
   superficie: con los dos iguales no se veía el riel, sólo el relleno, y un
   81 % se leía como un guion en lugar de como una cápsula a medio llenar. Un
   tono más oscuro que la fila lo convierte en una ranura, que es lo que dice
   «esto se llena hasta acá». */
/* Dieciséis y no veinte, y los cuatro píxeles son para la nota: la pastilla de
   una nota de dos cifras —«10,0», que el motor puede dar porque la nota va de 3
   a 10— mide 43 contra los 36 de su columna, y sin este aire le tocaba el riel.
   Medido con las tres notas posibles: 10 px de canalón con una nota normal, 1
   con la de dos cifras, y ninguna encima del riel.

   No se pierde nada: el ancho de la cápsula no es el dato —el dato es cuánto se
   llena— y a 16 px se lee igual que a 20. Lo que no se leía era la nota. */
.lineup__meter { width: 16px; height: 5px; background: var(--ink-1000); }
.lineup__meter .meter__fill { background: var(--ink-400); }
.lineup__row[data-cansado='true'] .meter__fill { background: var(--warn); }

/* LA VERSALITA VA CONDENSADA, y no es un adorno: es lo que hace que «MCO» entre
   en su columna sin quitarle ancho al apellido. La anchura es la MISMA que la
   del dorsal que va pegado a ella —`--wd-condensed`, ver `.lineup__num`—, así
   que el par «MCO 14» se lee como una sola cosa en vez de como dos dialectos
   distintos a cuatro píxeles.

   Medido, con el tamaño y el tracking intactos: MCO 35,4 → 29,6 · MCD 34,6 →
   29,4 · DFD 29,9 → 26 · DFC 29,7 → 25,3 · PO 21,4 → 17,9. Lo que NO se toca es
   el cuerpo: 13px es el piso de la escala y bajarlo era la otra salida, la que
   arregla un renglón rompiendo la escala de todos. */
.lineup__pos {
  font-size: var(--fs-2xs);
  font-weight: 700;
  font-stretch: var(--wd-condensed);
  letter-spacing: var(--tracking-label);
  color: var(--text-muted);
}

.lineup__num {
  font-size: var(--fs-sm);
  font-weight: 700;
  font-stretch: var(--wd-condensed);
  color: var(--text-secondary);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.lineup__name {
  font-size: var(--fs-sm);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* LA NOTA ES EL COMPONENTE `.rating`, la pastilla del sistema, y no una tinta
   suelta. Es lo que hace FM26 en su columna de media —pastilla rellena en cada
   fila, con el corte en 7,00, que resulta ser exactamente el nuestro— y acá
   además termina con dos formas de escribir lo mismo: la ficha y el historial
   ya usaban la pastilla y la alineación no.

   Veintidós pastillas rellenas en una alineación no contradicen la regla de que
   una acción por fila no se rellena: **esto no es una acción, es un valor**, y
   el relleno contesta «esto es lo que hay» y no «tocá acá».

   Acá sólo queda lo que es DE LA FILA: el tamaño y que se alinee a la derecha
   con sus hermanas. Los colores viven en el componente. */
/* El aire lateral es de la FILA y no del componente: en la columna más angosta
   del juego, seis píxeles a cada lado de una cifra de tres glifos son doce que
   no informan. Los colores, el radio y el peso siguen viviendo en `.rating`. */
.lineup__rate { font-size: var(--fs-sm); justify-self: end; padding-inline: var(--sp-2); }

/* Marcas de suceso pegadas al nombre: gol, amarilla, cambio. */
.lineup__marks { display: inline-flex; align-items: center; gap: 3px; margin-left: var(--sp-3); vertical-align: -2px; }
.lineup__marks .i { width: 11px; height: 11px; }
.lineup__marks .i--gol { color: var(--good); }
.lineup__marks .i--amarilla { color: var(--amber-500); }
/* La roja y el botiquín son las dos marcas que se leen antes que el nombre, y
   por eso son las dos únicas que van al color de peligro: en una tira de
   ochenta píxeles con dieciocho renglones, el DT las tiene que encontrar sin
   buscarlas. La expulsión además apaga el renglón entero —lo hace `[data-fuera]`,
   que ya existía para el que salió— así que el color no está solo. */
/* El renglón del hueco: es una nota al pie de la alineación y no un futbolista,
   así que se lee como lo que es —apagado, sin nota y sin medidor— pero conserva
   la retícula de la fila para que la columna del puesto siga alineada. */
.lineup__row--hueco { opacity: 0.42; cursor: default; }
.lineup__row--hueco .lineup__name { font-style: italic; }

/* EL HUECO SE ENCIENDE CUANDO SE LE PUEDE MANDAR A ALGUIEN. Apagado al 42 % es
   una nota al pie —«acá falta uno»— y así tiene que verse mientras no haya
   nadie elegido. Con un titular elegido pasa a ser un destino, y un destino que
   sigue apagado es un destino que nadie encuentra: el `box-shadow` de
   `[data-destino]` solo, sobre un renglón al 42 %, no se ve.

   Se sube a 0,85 y no a 1: sigue sin ser un futbolista, y la diferencia con los
   diez que sí lo son tiene que quedar a la vista incluso encendido. */
.lineup__row--hueco[data-destino='true'] { opacity: 0.85; cursor: pointer; }

.lineup__marks .i--roja { color: var(--danger); }
.lineup__marks .i--roto { color: var(--danger); }
/* La estrella del pateador designado va en ámbar y no en el color de canal:
   el acento es del chrome —lo que está activo, dónde estás— y esto es un dato
   del futbolista, como su gol o su amarilla. */
.lineup__marks .i--parada { color: var(--amber-500); opacity: 0.8; }
.lineup__marks .i--roja { color: var(--danger); }

/* Los tres estados del flujo de cambio. Elegido: el que va a salir o moverse.
   Destino: los que pueden recibir ese movimiento. El resto se apaga, porque un
   botón que no hace nada durante una selección es una promesa falsa. */
.lineup__row[aria-pressed='true'] {
  background: var(--accent-wash-hi);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.lineup[data-eligiendo='true'] .lineup__row:not([data-destino='true']):not([aria-pressed='true']) {
  opacity: 0.4;
}
.lineup__row[data-destino='true'] { box-shadow: inset 0 0 0 1px var(--line-strong); }
@media (hover: hover) {
  .lineup__row[data-destino='true']:hover { background: var(--bg-active); }
}

/* Un futbolista que todavía puede entrar, salir o cambiar de puesto se agarra.
   El que ya salió no: su renglón es el registro de algo que pasó. La regla es
   de las dos pantallas que usan esta lista —el partido y el entretiempo—, así
   que vive con el componente y no en la hoja de una de ellas. */
.lineup__row[draggable='true'] { cursor: grab; }
.lineup__row[draggable='true']:active { cursor: grabbing; }

/* El renglón bajo el cursor mientras algo se arrastra encima. Existe aparte del
   `:hover` porque durante un arrastre el navegador congela el hover: sin esta
   marca, el destino se elige a ciegas. Es el mismo violeta que el destino
   elegido, que es lo que va a pasar al soltar. */
.lineup__row--recibe {
  background: var(--accent-wash-hi);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* El que ya salió se apaga, y deja de responder al cursor: su renglón pasó a
   ser el registro de lo que pasó. `--bg-row` y no `none` desde que la fila
   tiene superficie propia — un `none` la volvía transparente al pasar por
   encima, que es lo contrario de "acá no hay nada que tocar". */
.lineup__row[data-fuera='true'] { opacity: 0.45; }
@media (hover: hover) {
  .lineup__row[data-fuera='true']:hover { background: var(--bg-row); }
}

/* Alineación del rival: mismo ritmo, sin interacción y sin condición física.
   No la conocés, así que no se dibuja. El medidor se esconde en vez de
   quitarse, para que las dos listas midan sus columnas igual. */
.lineup--rival .lineup__row { cursor: default; }
.lineup--rival .lineup__meter { visibility: hidden; }
@media (hover: hover) {
  .lineup--rival .lineup__row:hover { background: var(--bg-row); }
}

.band__sub {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-hairline);
}

/* --------------------------------------------------------------------------
   7. ESTADÍSTICAS ENFRENTADAS
   -------------------------------------------------------------------------- */

.vs { display: grid; gap: var(--sp-3); }

.vs__row { display: grid; grid-template-columns: 30px 1fr 30px; align-items: center; gap: var(--sp-4); }

.vs__cifra { font-size: var(--fs-sm); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--text-primary); }
.vs__cifra--v { text-align: right; }

.vs__medio { display: grid; gap: var(--sp-1); }

.vs__label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: center;
}

/* --------------------------------------------------------------------------
   EL DATO QUE ACABA DE CAMBIAR
   --------------------------------------------------------------------------
   Esta pantalla es la que más cambia del juego y era la que menos lo decía: en
   62 KB de hoja había TRES transiciones y un fotograma. La cancha cuenta lo que
   pasa AHORA; los paneles cuentan lo que YA pasó, y se actualizaban como si no
   hubiera pasado nada.

   LA REGLA SALE DE CONTAR, NO DE ELEGIR. Medido sobre un tiempo entero (44
   minutos de juego, 293 segundos reales a Normal y ocho veces menos a Rápido),
   cuántas veces cambia cada dato:

     posesión      123      notas de los 22   233      relato   146
     tiros          18      faltas             11      córners    8
     a puerta        3      adelantados         0      sucesos    7

   Son DOS FAMILIAS y el corte no es de gusto: **lo que se PROMEDIA se mueve
   solo y todo el tiempo; lo que se CUENTA ocurre.** La posesión, las notas y el
   relato derivan de todo lo jugado y cambian cada dos segundos a Normal y varias
   veces por segundo a Rápido: un acuse ahí no es un latido, es un estrobo, y
   además mentiría —no pasó nada, se corrió un promedio—. Los remates, las
   faltas, los córners y los sucesos de la cronología SON hechos, y son entre 3 y
   18 por tiempo: a Rápido, uno cada dos segundos en el peor caso.

   De ahí la regla, que vale para cualquier dato que se agregue después:

     **ACUSA LO QUE SE CUENTA, NO LO QUE SE PROMEDIA.**

   Dos de los cuatro candidatos con los que empecé —el relato y las notas— los
   mató la medición, que es para lo que se mide antes y no después.
   -------------------------------------------------------------------------- */

/* La cifra que subió, y SÓLO la del lado que subió: el acuse dice además QUIÉN,
   que es la mitad del dato. Sube al blanco del texto primario y vuelve al suyo.

   NO MUEVE LA FILA. La escala va sobre un `span` en línea, así que no le pide un
   píxel a la retícula —estas filas miden 4px de barra y el panel entero entra
   por poco—, y el 1,18 es más que el 1,12 del marcador porque esto es un número
   de 13px en una columna de seis: al tamaño del marcador no se vería. */
.vs__cifra[data-subio] {
  animation: vs-subio var(--dur) var(--ease-entrada);
}

@keyframes vs-subio {
  0%   { transform: scale(1); }
  30%  { transform: scale(1.18); color: var(--text-primary); }
  100% { transform: scale(1); }
}

.vs__cifra { display: inline-block; }

.vs__track { display: flex; height: 4px; border-radius: var(--r-pill); overflow: hidden; background: var(--ink-800); }
.vs__fill { height: 100%; transition: flex-grow var(--dur) var(--ease); }
/* La barra enfrentada es un REPARTO, no un estado: se lee, no se pulsa. */
.vs__fill--l { background: var(--good); flex: var(--l, 1) 1 0; }
.vs__fill--r { background: var(--ink-500); flex: var(--r, 1) 1 0; }

/* El acento marca lo TUYO, no el lado izquierdo. Cuando el Rivera juega de
   visitante su barra está a la derecha, y pintar de cal la del rival sería
   usar el acento para señalar al que no elegiste — el cuarto uso que la Regla
   de la Cal no admite. */
.vs[data-nuestro='1'] .vs__fill--l { background: var(--ink-500); }
.vs[data-nuestro='1'] .vs__fill--r { background: var(--good); }

/* --------------------------------------------------------------------------
   8. CRONOLOGÍA
   -------------------------------------------------------------------------- */

/* La cronología crece todo el partido. Con scroll propio, el once del rival
   sigue estando debajo al minuto 90; sin él, empuja la columna y hay que bajar
   la página entera para ver quién juega enfrente. Su tope ya no es una fracción
   de la pantalla sino el hueco que le deja la columna: es la fila elástica de
   las tres columnas de esta pantalla. */
.crono {
  display: grid;
  align-content: start;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
}

.ev {
  display: grid;
  grid-template-columns: 26px 14px minmax(0, 1fr);
  align-items: start;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--line-hairline);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.ev:last-child { border-bottom: 0; }
.ev__min { font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ev .i { width: 13px; height: 13px; color: var(--icon-quiet); margin-top: 1px; }
/* EL SUCESO QUE ACABA DE PASAR. Es aquello por lo que despegaste la vista de la
   cancha, y llegaba sin distinguirse de los veinte de arriba.

   ENTRA SÓLO EL NUEVO, y esto es la mitad del trabajo: `pintarCrono()` rehace
   TODAS las filas con `replaceChildren`, así que una animación sobre `.ev` las
   haría parpadear a todas en cada suceso — la lista entera temblando para
   contar que llegó un renglón. La marca la pone el guion comparando cuántos
   sucesos hay contra cuántos había, y la lleva sólo la primera fila, que es la
   más nueva: la cronología va del último al primero.

   Baja desde arriba, que es de donde viene: el renglón nuevo empuja a los otros
   hacia abajo. Seis píxeles y el fundido del sistema; ni un color nuevo — el
   tipo de suceso ya se pinta solo y no hace falta decirlo dos veces. */
.ev[data-nuevo] {
  animation: ev-llega var(--dur) var(--ease-entrada);
}

@keyframes ev-llega {
  from { opacity: 0; transform: translateY(-6px); }
}

.ev[data-tipo='gol'] { color: var(--text-primary); }
.ev[data-tipo='gol'] .i { color: var(--good); }
.ev[data-tipo='amarilla'] .i { color: var(--amber-500); }
.ev[data-tipo='roja'] .i { color: var(--danger); }
.ev[data-tipo='roja'] { color: var(--text-primary); }
.ev[data-tipo='lesion'] .i { color: var(--danger); }
.ev[data-tipo='cambio'] .i { color: var(--text-secondary); }
.ev b { font-weight: 600; color: var(--text-primary); }

/* El club que protagoniza el suceso, detrás del texto. En una cronología de dos
   equipos, "gol" sin dueño obliga a mirar el minuto y adivinar de quién fue. */
.ev__eq { color: var(--text-muted); }

.crono__vacio { padding: var(--sp-6) 0; font-size: var(--fs-sm); color: var(--text-muted); }

/* --------------------------------------------------------------------------
   9. RESPUESTA A PANTALLA
   --------------------------------------------------------------------------
   Estructural, no fluida. Por debajo de 1240px cae la columna del rival: entre
   ver el campo y ver el once del contrario, el campo gana. Por debajo de 980px
   la alineación propia pasa a ser una banda horizontal encima del campo, que
   es la única forma de que el campo siga siendo el elemento más grande.
   -------------------------------------------------------------------------- */

@media (max-width: 1240px) {
  /* Los mismos treinta píxeles que arriba, y acá hacían más falta: con el panel
     en 226 al nombre le quedaban 84 y se cortaba el 8 % de los apellidos. El
     campo, que en esta franja no comparte con la tercera columna, mide 719 en
     la ventana más angosta (981px) y pasa a 689 — 249 por encima del piso. */
  .match { grid-template-columns: 256px minmax(0, 1fr); }
  .match__rival { display: none; }
}

@media (max-width: 980px) {
  /* Apiladas, las columnas ya no caben en una pantalla y el alto fijo dejaría
     medio banquillo recortado: acá la página sí se baja, y cada panel vuelve a
     medir lo que mide su contenido. */
  .match { grid-template-columns: minmax(0, 1fr); height: auto; }
  .match > .band { overflow: visible; }
  .match__once, .match__rival { grid-template-rows: none; align-content: start; }
  .match__once .lineup--banquillo { overflow: visible; }
  .crono { max-height: 32vh; }
  .match__campo { order: -1; }
  .pitch { width: 100%; height: auto; aspect-ratio: 105 / 68; }
  .lineup { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lineup--titulares { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Y LA COLUMNA DEL CAMPO DEJA DE MEDIR LO QUE MIDE SU PIEZA MÁS ANCHA.
     `.band` es una retícula sin columnas declaradas (`app.css`), o sea una
     pista `auto`, y una pista `auto` se planta en el min-content de lo que
     lleva: acá el transporte, que son 494 px de «Empezar» más Lento / Normal /
     Rápido en una fila que no dobla. La pista se quedaba en 494 y arrastraba
     con ella al marcador, al campo y al relato —los cuatro medían 494 en una
     ventana de 390, y el nombre del visitante y «Rápido» quedaban fuera de la
     pantalla—. El `min-width: 0` de `.band` no lo tapa: lo que hay que poner
     en cero es el piso de la PISTA.

     Con el piso en cero el transporte sería el único que se sale, así que
     además dobla. Es el orden correcto de las dos: la pista deja de contagiar
     el ancho, y la pieza ancha se hace cargo del suyo. */
  .match__campo { grid-template-columns: minmax(0, 1fr); }
  .transport { flex-wrap: wrap; }

  /* LA CRONOLOGÍA VUELVE EN EL APILADO (28/9/2026). El `display: none` de 1240
     se llevaba la columna del rival ENTERA, y con ella las estadísticas y la
     cronología: en el teléfono no había dónde ver quién hizo el gol ni cuándo,
     porque el relato está escondido desde el 24/9 justamente porque «lo que
     importa queda en la cronología». El `max-height: 32vh` de arriba ya estaba
     escrito para ella: la regla la quería visible y otra la apagaba.

     Va debajo de la cancha y antes de nuestra alineación —primero lo que pasó,
     después los cambios—, y sin el once rival, que en una columna son 450 px
     más entre la cronología y tus suplentes. Y la cronología deja pasar el
     gesto: acá la página rueda (ver la bandeja del portal, mismo defecto). */
  .match__rival { display: grid; order: 0; }
  .match__once { order: 1; }
  .match__rival .lineup--rival,
  .match__rival .lineup--rival ~ *,
  .match__rival .band__sub:has(+ .lineup--rival) { display: none; }
  .crono { overscroll-behavior: auto; }
  /* «54 %» no se parte: la columna de la cifra es angosta y el `%` bajaba solo
     a otro renglón. */
  .vs__cifra { white-space: nowrap; }
}

/* --------------------------------------------------------------------------
   Y EN EL TELÉFONO LA LISTA VUELVE A UNA COLUMNA
   --------------------------------------------------------------------------
   Las dos columnas de arriba son correctas para una tablet y falsas para un
   teléfono, y no por poco: a 390 el panel mide 351, cada mitad se queda con
   157 y de ahí salen primero los 132 de lo fijo —puesto, dorsal, medidor,
   nota y sus cuatro canalones—. Al apellido le quedaban 25,6px y los
   VEINTITRÉS salían «Ta…», «Es…», «C…». Una alineación sin apellidos no es una
   alineación: es una lista de puestos con nota.

   La cuenta es una recta —cada píxel de ventana le da medio al apellido— y por
   eso el umbral se despeja en vez de elegirse. Medido en la pantalla con la
   carrera sembrada, la pista del nombre con dos columnas:

     980 → 302   ·   760 → 204   ·   640 → 146
     540 →  98   ·   430 →  45   ·   390 →  26

   La vara no es «que entre algo», es **que entre lo mismo que en el escritorio**:
   la columna del once medía 236 y ahí el apellido tenía 93,3. Dos columnas dan
   93,4 a los 531px de ventana, medido y no despejado. Por debajo de eso, una.

   ESA VARA SE MOVIÓ Y HAY QUE DECIRLO. El 1/9/2026 el panel del escritorio pasó
   de 236 a 266 —cortaba 1,3 apellidos por lista de 23, medido sobre los 27.849
   del juego; ver el bloque de `.match` arriba— así que el apellido de arriba
   tiene ahora 123,3 y no 93,3. La igualdad que despejó este umbral ya no se
   cumple entre 561 y 980: ahí dos columnas dan 107,8, que es MENOS que el
   escritorio. No es una regresión —antes daban 25,6— pero tampoco es la vara
   que dice este párrafo. Despejada con la misma recta, la igualdad nueva cae en
   591px. **No se movió el umbral** por lo que dice el párrafo de abajo: 560 ya
   era el quiebre del teléfono en esta hoja, y meter otro a treinta píxeles es
   volver a abrir la franja que nadie mide. Queda anotado como residuo medido.

   EL NÚMERO ES 560 Y NO 531 A PROPÓSITO: 560 YA ERA el quiebre del teléfono en
   esta hoja —el del marcador, acá abajo, con el que ahora comparte bloque— y
   dos quiebres a treinta píxeles uno del otro son la franja que nadie vuelve a
   medir. A 561 la pista da 107,8: cuando este párrafo se escribió eso era MÁS
   que los 93,3 del escritorio y el margen se pagaba en una tablet chica. Con el
   escritorio en 123,3 es MENOS, y es el residuo que el párrafo de arriba deja
   anotado. La frase se corrige acá y no en una nota nueva: una nota que
   describe un estado se mueve con el estado, y dos frases del mismo bloque
   diciéndose lo contrario a veinte renglones de distancia son peor que una
   frase vieja sola.

   Y VA EN EL BLOQUE QUE YA EXISTÍA, no en uno propio con la misma consulta:
   dos `@media` idénticos a veinte renglones de distancia es el patrón donde un
   día alguien edita uno sin ver el otro. Una consulta, un bloque.

   Lo que cuesta: veintitrés renglones apilados en vez de doce. Por debajo de
   980 esta pantalla ya rueda la página —lo dice el bloque de arriba—, así que
   el alto es lo que hay de sobra; el ancho no.
   --------------------------------------------------------------------------
   Y EL MARCADOR, EN EL MISMO TELÉFONO
   --------------------------------------------------------------------------
   Escudo y nombre uno al lado del otro necesitan un renglón que en 319 px no
   existe: cada lado se queda con unos 110, el escudo se come 45 y al nombre le
   sobran tres letras y los puntos suspensivos —«In…» contra «Independiente
   Rivadavia»—, mientras «Local · 4-3-1-2» se parte en tres renglones.

   Se gira el eje: escudo arriba, nombre abajo, los dos centrados. Es el mismo
   contenido y las mismas tres columnas —el resultado sigue en el medio, que es
   lo que la sección de arriba declara—, pero el nombre pasa a tener el ancho
   de la columna entera en vez de lo que sobra al costado del escudo, y con dos
   renglones disponibles entra sin recortarse.
   -------------------------------------------------------------------------- */

@media (max-width: 560px) {
  /* La lista del once, a una columna: la cuenta está arriba. */
  .lineup,
  .lineup--titulares { grid-template-columns: minmax(0, 1fr); }

  /* `start` y no el `center` heredado: con los tres bloques centrados, la línea
     del clima —que vive en la columna del medio y es la más ancha de las tres—
     quedaba a la altura del nombre del local y los dos se leían como un solo
     renglón revuelto. Alineados arriba, los dos escudos y el resultado empiezan
     en la misma línea y cada columna crece hacia abajo por su cuenta. */
  .marcador { gap: var(--sp-4); align-items: start; }
  .marcador__eq,
  .marcador__eq--visita { flex-direction: column; gap: var(--sp-3); }
  /* SÓLO `text-align`, NUNCA `justify-items`. Los dos centran, y no es lo
     mismo: `justify-items: center` le saca a los hijos el `stretch` que los
     hace medir el ancho de su pista, y pasan a medir SU CONTENIDO. Acá adentro
     vive la línea de goleadores de `entretiempo.html` —que comparte esta hoja—,
     que es `nowrap` con puntos suspensivos y cuenta con que alguien le imponga
     un ancho: sin `stretch` se estiraba a los 209 px del texto entero, salía
     de la pantalla y los puntos suspensivos no aparecían nunca. Medido: la
     pantalla pasó de 0 px de desborde a 28 a 390, y a 36 a 360. El texto se
     centra igual con `text-align`, que es lo que hacía falta. */
  .marcador__ident,
  .marcador__eq--visita .marcador__ident { text-align: center; }

  /* Y el nombre deja de recortarse para doblar: acá el recorte no es la red de
     abajo sino el caso normal, y un nombre de club recortado no identifica a
     nadie. Dos renglones y el tamaño de la escala que sigue. */
  .marcador__nombre {
    font-size: var(--fs-md);
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
}

/* LA VENTANA JUSTA DEVUELVE EL AIRE DE LA FILA. Entre 641 y 800 de alto la
   columna del once reparte un presupuesto que ya estaba ajustado: los 27px de
   la fila salen del banquillo —lo único elástico— y a 720 lo dejan en hueco de
   pieza y media, que no es una lista de suplentes, es una mirilla. Ahí la fila
   vuelve a los 22px de tabla, que es lo que había, y la densidad la elige la
   pantalla y no una preferencia.

   Sólo en el reparto de alto fijo: apilada (por debajo de 980 de ancho) o con
   la página bajándose (por debajo de 692 de alto) el banquillo no paga nada,
   así que ahí la fila se queda con su aire. */
@media (min-width: 981px) and (min-height: 692px) and (max-height: 800px) {
  .match .lineup__row { height: var(--row-h); }
}

/* Pantallas bajas: no hay reparto que alcance —el campo se volvería una tira—,
   así que se devuelve el scroll antes que dar una pantalla ilegible.

   EL UMBRAL SON 691 Y ESTÁ MEDIDO, no elegido: hasta el 1/9/2026 decía 640 y
   era falso. La cuenta cierra recién en 692. Entre 641 y 691 el campo ya estaba
   clavado en su piso —`--campo-piso`, donde los once dejan de achicarse— y todo
   lo que le sobraba a la columna se lo comía el relato: a 1600×689 la cancha
   caía nueve píxeles por debajo del hueco, y a 981×684 lo pisaba de lleno. El
   marco fijo no se rompía; escondía.

   Que no se viera es lo de siempre: `.match__campo` tiene `overflow-y: auto`
   como último recurso, pero la cancha se sale de su FILA y no de la columna, o
   sea que la columna nunca se entera y la barra no aparece nunca.

   MEDIDO CON EL MARCADOR PESADO, que es lo que mueve el número: la caja del
   medio tiene dos renglones que aparecen solos —el clima y el global de una
   llave de vuelta— y con los dos puestos el umbral pasa de 661 a 692. Un umbral
   afinado a un sábado de liga no es más generoso: es el mismo defecto con fecha
   de aparición. La vara es `herramientas/medir-relato-y-cancha.html`.

   Lo que cuesta, dicho entero: un portátil con 641–691px de ventana útil —un
   1366×768 con la barra del navegador puesta es justo eso— pasa a rodar la
   página durante el partido. Se paga a sabiendas: la alternativa era una cancha
   que ya no se achica más tapando el relato. */
/* En el teléfono la caja es más alta que 105:68: con la cámara de cerca se
   encuadra un pedazo y los veintidós ocupan media pantalla. El alto sale de la
   ventana, para que marcador, reloj y cancha entren juntos en una pantalla. */
@media (max-width: 560px) {
  .pitch { aspect-ratio: auto; height: clamp(220px, calc(100svh - 380px), 440px); }
}

@media (max-height: 691px) {
  .match { height: auto; min-height: 0; }
  .match > .band { overflow: visible; }
  .match__once .lineup--banquillo { overflow: visible; }
  .match__rival .lineup--rival { overflow: visible; }
  /* Si la página se baja igual, el campo deja de pagarle el alto a los
     controles: se le da una medida propia en vez de la resta. */
  .pitch { width: min(100%, 620px); height: auto; aspect-ratio: 105 / 68; }
}

@media (prefers-reduced-motion: reduce) {
  /* El campo sigue moviéndose: es el contenido, no un adorno. Lo que se apaga
     es la estela del balón, que es lo único decorativo del lienzo. */
  .pitch { --sin-estela: 1; }
}

/* ==========================================================================
   EL AMBIENTE DE PRETEMPORADA
   --------------------------------------------------------------------------
   Un amistoso de julio no se juega de noche en un estadio: se juega a las cinco
   de la tarde en un predio, y el campo tiene que decirlo antes de que nadie lea
   el rótulo. Es el mismo campo y el mismo motor —no hay una segunda forma de
   dibujar— con la paleta corrida: el verde sube tres pasos de luminancia y se
   entibia, la banda del corte se separa más del fondo porque una cancha de
   entrenamiento se corta y se ve, y la cal baja de blanco puro a cal de verdad.

   Se hace con los TRES tokens que el motor ya leía (`--campo`, `--campo-franja`
   y `--campo-linea`) y ni una línea de dibujo nueva. Que un cambio de ambiente
   completo quepa en tres propiedades es la prueba de que aquella decisión —leer
   la paleta del documento en vez de escribirla en el guion— estaba bien tomada.

   El atributo lo pone `partido.js` ANTES de que el motor lea los colores; ver
   el comentario de `ES_DE_PRETEMPORADA` allá.
   ========================================================================== */

:root[data-ambiente='pretemporada'] {
  --campo:        hsl(126 34% 24%);
  --campo-franja: hsl(126 32% 29%);
  /* La cal de un predio no es blanco de estadio: se lava con la tierra y con el
     sol. A 88 % sigue dando 6,4:1 contra el campo, muy por encima del piso. */
  --campo-linea:  hsl(76 12% 88%);
}

/* Y el marco del campo acompaña. La placa que lo contiene es la misma del
   sistema; lo que cambia es que el borde deja de ser el hairline neutro y toma
   el verde del césped, que es lo que hace que el conjunto se lea como una
   cancha al sol y no como un campo claro dentro de una noche. */
:root[data-ambiente='pretemporada'] .pitch {
  border-color: hsl(126 26% 30%);
  background: hsl(126 30% 14%);
}

/* --------------------------------------------------------------------------
   ENTRE 981 Y 1240: CRONOLOGÍA, ESTADÍSTICAS Y SUPLENTES EN PESTAÑAS
   --------------------------------------------------------------------------
   En esta franja la columna del rival se cae (bloque de 1240) y con ella las
   estadísticas y la cronología: con el relato escondido, en una laptop chica
   no había dónde ver quién hizo el gol. Alberto, 28/9/2026: «resolvé la
   cronología en 981–1240» y «sumá también las estadísticas».

   SE PROBARON DOS REPARTOS Y LOS DOS COSTABAN DEMASIADO, medidos con el
   recálculo del campo forzado (`medirLoQueNoEsCampo()` dimensiona la cancha
   con el alto que le deja su columna):
     · una tira debajo de la cancha: a 1100x768 la cancha pasaba de 731x473 a
       538x348, y a 504x326 con las estadísticas;
     · todo apilado en la columna izquierda: la cancha quedaba entera pero a
       1024x700 entraban 0,4 filas de suplentes y medio suceso.
   Así que la parte baja de la columna izquierda se COMPARTE: la cancha no
   pierde nada y lo que se elige se lleva todo el alto que queda. */
.abajo { display: none; }

@media (min-width: 981px) and (max-width: 1240px) {
  .abajo { display: flex; margin-top: var(--sp-2); min-width: 0; }
  /* Tres rótulos en una columna de 225: sin esto pedían 313 px de mínimo,
     ensanchaban la pista del once y empujaban las notas afuera. */
  .abajo .segmented__btn {
    /* `auto` y no `0`: a partes iguales eran 75 px cada una y «✓ Sucesos» no
       entraba mientras «Datos» y «Banco» sobraban. */
    flex: 1 1 auto;
    min-width: 0;
    padding-inline: var(--sp-1);
    font-size: var(--fs-xs);
    letter-spacing: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* El tilde del elegido se queda (es el idioma de todos los segmentados del
     juego) pero más pegado, que al lado de «Sucesos» en 75 px no entraba. */
  .abajo .segmented__btn[aria-pressed='true']::before { margin-right: 2px; }
  .match__once { grid-template-columns: minmax(0, 1fr); }

  .match { grid-template-rows: auto minmax(0, 1fr); }
  .match__campo { grid-column: 2; grid-row: 1 / span 2; }
  .match__once { grid-column: 1; grid-row: 1; grid-template-rows: none; align-content: start; }
  .match__rival {
    display: grid;
    grid-column: 1;
    grid-row: 2;
    grid-template-rows: auto minmax(0, 1fr);
    align-content: stretch;
    min-height: 0;
  }
  .match__rival > * { display: none; }

  /* Suplentes: el once vuelve a ocupar la columna entera, como antes. */
  .match[data-ver='suplentes'] .match__once { grid-row: 1 / span 2; grid-template-rows: auto auto auto auto minmax(0, 1fr); }
  .match[data-ver='suplentes'] .match__rival { display: none; }
  .match:not([data-ver='suplentes']) .match__once > .band__sub,
  .match:not([data-ver='suplentes']) .match__once > .lineup--banquillo,
  .match:not([data-ver='suplentes']) .match__once > .pizarra__nota { display: none; }

  /* Cronología y estadísticas: la franja del rival, con sólo lo elegido. */
  .match[data-ver='crono'] .match__rival > .band__sub:has(+ .crono) { display: flex; }
  /* Con tope: en una ventana baja (1024x640) la página ya rueda y la
     cronología crecía a sus 1.000 px, dejando una página de 1.431. Y deja pasar
     el gesto, que en ese caso rueda la página. */
  .match[data-ver='crono'] .match__rival > .crono { display: grid; max-height: 60vh; overscroll-behavior: auto; }
  .match[data-ver='stats'] .match__rival > .panel__head { display: flex; }
  .match[data-ver='stats'] .match__rival > .vs { display: grid; align-content: start; }
  .match__rival .vs__cifra { white-space: nowrap; }
}

/* impetu.css */
/* ==========================================================================
   El Camino DT — EL ÍMPETU DEL PARTIDO (`.impetu`)
   --------------------------------------------------------------------------
   El dibujo que cuenta quién tuvo el partido y cuándo se dio vuelta: barras a
   los dos lados de un eje horizontal, una cada cinco minutos, con la pelotita
   del gol encima. Medido de FM26 el 4/9/2026 (`referencia/fm26/notas.md`, «La
   PAUSA del partido»). Lo que se dibuja y por qué está en `entretiempo.js`,
   en `pintarImpetu()`; acá está sólo el aspecto.

   1. LOS COLORES SON LOS DE LA ESTADÍSTICA ENFRENTADA, y tienen que serlo: en
      este panel el ímpetu es una vista más, hermana de las cifras, y las tres
      vistas de cifras ya dicen «lo verde es tuyo». Que el dibujo lo dijera con
      otro color obligaría a aprender dos códigos para el mismo panel.

   2. EL EJE ES UN HAIRLINE, no un borde. Es la línea del cero y no un marco:
      con un trazo grueso el dibujo se lee como dos gráficos apilados en vez de
      uno solo con dos lados.

   3. EL CORTE DEL DESCANSO VA PUNTEADO Y APAGADO. Divide, no informa: si
      pesara igual que las barras competiría con el dato.

   4. LA BARRA NO SE ANIMA AL ENTRAR. Se probó y se sacó: son dieciocho barras
      y la entrada escalonada convertía un gráfico que se lee de un vistazo en
      una animación que hay que esperar. Lo que sí responde es el `title` de
      cada barra, que llega cuando la pedís.
   ========================================================================== */

.impetu {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* El rival, en el gris del sistema — el mismo `--ink-500` que la mitad ajena
   de la estadística enfrentada. */
.impetu__barra { fill: var(--ink-500); }
.impetu__barra--mia { fill: var(--good); }

.impetu__eje {
  stroke: var(--line);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.impetu__corte {
  stroke: var(--ink-600);
  stroke-width: 1;
  stroke-dasharray: 2 3;
  vector-effect: non-scaling-stroke;
}

/* El gol del rival también se ve: es parte de la historia del partido, y un
   gráfico que sólo marca los propios cuenta la mitad. */
.impetu__gol { fill: var(--text-muted); }
.impetu__gol--mio { fill: var(--good); }

/* La lectura en palabras, que es texto de verdad y no un pie de foto: es lo
   que se anuncia y lo que queda si el dibujo no se puede mirar. */
.impetu__resumen {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: center;
}

/* --------------------------------------------------------------------------
   CUANDO OCUPA EL CAMPO (día del partido, con el partido terminado)
   --------------------------------------------------------------------------
   Se coloca DENTRO de la caja de la cancha y encima del lienzo escondido, así
   que hereda su alto sin que nadie tenga que recalcular nada: `--campo-alto`
   ya reservó ese sitio y `medirLoQueNoEsCampo()` sigue contando lo mismo.

   Se centra en vez de estirarse: la cancha es mucho más alta que el gráfico y
   un ímpetu de 400 px de alto sería un cartel, no un dato. */
.pitch__impetu {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 var(--sp-7);
}

/* Acá el dibujo tiene ancho de sobra —es la columna más ancha de la pantalla—
   así que se le pone un techo: estirado a 900 px, cinco minutos de partido
   medirían cincuenta y el gráfico se leería como una empalizada. */
.pitch__impetu .impetu {
  max-width: 560px;
  margin: 0 auto;
}

.pitch__impetu .impetu__resumen { font-size: var(--fs-xs); }

/* El rótulo, centrado sobre el dibujo y con el mismo aire que el resumen de
   abajo: entre los dos encuadran el gráfico en una caja que es mucho más alta
   que él. */
.pitch__impetu-rotulo {
  display: block;
  text-align: center;
  margin-bottom: var(--sp-5);
}

/* banquillo.css */
/* ==========================================================================
   El Camino DT — EL CONSEJO DEL BANQUILLO (`.consejo`)
   --------------------------------------------------------------------------
   La placa donde el cuerpo técnico propone una cosa mientras se juega, con un
   botón que la hace. Medida de FM26 el 4/9/2026. Las reglas están en
   `scripts/banquillo.js`; acá está el aspecto, y son cuatro decisiones.

   1. FLOTA SOBRE EL CAMPO, ABAJO A LA IZQUIERDA. No cuesta un píxel de
      maquetación —`position: absolute` dentro de `.pitch`, fuera del flujo— y
      por eso no entra en la cuenta de `medirLoQueNoEsCampo()`. Abajo a la
      izquierda porque el relato vive debajo del campo y el cartel del gol
      entra por el centro: son tres cosas que no se pueden pisar.

   2. NO TAPA EL PARTIDO: ocupa poco más de un tercio del ancho y deja ver la
      jugada. El DT decide MIRANDO lo que el consejo comenta; una placa que
      tapara la cancha volvería el consejo una interrupción.

   3. EL FONDO ES EL MISMO PATRÓN QUE EL CARTEL DEL GOL —un `color-mix` sobre
      `--ink-1000`— para que las dos superficies flotantes del campo se lean
      como la misma capa. NO es `--velo`: ése es el backdrop de los diálogos,
      la capa que oscurece la pantalla entera, y usarlo acá habría sido pedirle
      a un token que haga un trabajo que no es el suyo. El cartel va al 62 %
      porque dura dos segundos y no se lee palabra por palabra; éste va al 92
      porque tiene una frase que hay que leer sobre césped en movimiento.

   4. «HAZLO» ES LA ACCIÓN Y SE VE COMO TAL; el descarte es una X sin peso. Lo
      que no se hace es esconder el «no»: un consejo del que no se pueda salir
      es un cartel que estorba, y el DT tiene que poder decir que no en el
      mismo gesto en que lo lee.
   ========================================================================== */

.consejo {
  position: absolute;
  left: var(--sp-5);
  bottom: var(--sp-5);
  z-index: 3;
  max-width: min(38%, 380px);
  display: grid;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--ink-1000) 92%, transparent);
  backdrop-filter: blur(6px);
}

.consejo__quien { color: var(--accent-texto); }

.consejo__texto {
  margin: 0;
  font-size: var(--fs-xs);
  line-height: 1.45;
  color: var(--text-secondary);
}
.consejo__texto b { color: var(--text-primary); font-weight: 700; }

.consejo__acciones { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-1); }

.consejo__si {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border: 0; border-radius: var(--r-sm);
  background: var(--accent); color: var(--text-on-accent);
  font-size: var(--fs-2xs); font-weight: 700;
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  cursor: pointer;
}
@media (hover: hover) {
  .consejo__si:hover { background: var(--accent-strong); }
}

.consejo__no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: none; color: var(--text-muted); cursor: pointer;
}
@media (hover: hover) {
  .consejo__no:hover { color: var(--text-primary); border-color: var(--ink-500); }
}

/* ══ EN EL CELULAR SE APRIETA, Y ESTÁ MEDIDO ══
   La primera versión de esta media query sólo estiraba la placa a todo el
   ancho, y a 375 px eso tapaba el **56 %** de la cancha —288×118 sobre
   306×198—, que es exactamente lo que la decisión 2 de arriba dice que no hay
   que hacer. Una regla que se contradice a sí misma en la pantalla más chica
   no es una regla.

   Se aprieta lo que no es el mensaje: el rótulo «Banquillo» se va —en un
   teléfono, una placa con dos botones sobre la cancha no se confunde con otra
   cosa—, el texto baja un punto y el relleno se acorta. Lo que NO se toca es
   el blanco de toque de los botones: en el celular se juega con el dedo. */
@media (max-width: 900px) {
  .consejo {
    left: var(--sp-3);
    right: var(--sp-3);
    max-width: none;
    gap: var(--sp-1);
    padding: var(--sp-3) var(--sp-4);
  }
  .consejo__quien { display: none; }
  .consejo__texto { font-size: var(--fs-2xs); line-height: 1.35; }
  .consejo__acciones { margin-top: 0; }
}

/* menu.css */
/* ==========================================================================
   El Camino DT — El menú del botón derecho
   --------------------------------------------------------------------------
   Cero tokens nuevos. Es la superficie del diálogo —panel sobre línea fuerte—
   con las medidas de la fila de estado: 24px de alto útil, icono apagado a la
   izquierda y texto en 13px.

   SIN SOMBRA, a diferencia del diálogo. La única sombra del sistema existe
   porque un modal tapa la pantalla entera y tiene que despegarse del plano;
   este menú mide 200px y se apoya sobre lo que estabas mirando, así que le
   alcanza con un borde en Línea Fuerte, que es un paso más claro que
   cualquier borde de la pantalla que hay debajo.
   ========================================================================== */

.menu {
  position: fixed;
  /* Por encima del chrome pegajoso (20), que es lo más alto del sistema. */
  z-index: var(--z-flotante);
  display: grid;
  /* `minmax(0, 1fr)` y no la columna automática: una fila del menú lleva el
     texto de la acción a la izquierda y su pista a la derecha —«Cambiar el
     número · Ahora lleva el 2»— y las dos juntas piden más que el ancho máximo
     del menú. Con la columna midiéndose por su contenido, las filas se salían y
     el menú aparecía con una BARRA DE DESPLAZAMIENTO HORIZONTAL abajo, que en
     un menú de cinco renglones no es un control, es un defecto. Con la columna
     acotada a cero, `.menu__texto` hace lo que ya sabía hacer: recortarse. */
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  min-width: 200px;
  /* Y un poco más de ancho antes de recortar nada: el menú de un futbolista
     lleva su nombre entero —«Ver la ficha de Lucas Ruiz»— y a 280 empezaba a
     comerse el apellido con una pista al lado que sí entraba. */
  max-width: 340px;
  max-height: calc(var(--alto-ventana) - 2 * var(--sp-4));
  overflow-x: hidden;
  overflow-y: auto;
  padding: var(--sp-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--bg-panel);
}

.menu__item {
  display: flex;
  align-items: center;
  /* Sin esto la fila se niega a bajar de su contenido —es el `min-width: auto`
     de todo elemento flexible— y la columna acotada de arriba no sirve de
     nada: el que tiene que ceder es el texto de la acción. */
  min-width: 0;
  gap: var(--sp-4);
  min-height: 26px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-xs);
  font-size: var(--fs-md);
  color: var(--text-secondary);
  text-align: left;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

/* CON EL DEDO, 44. La lista de los mínimos táctiles vive en `app.css` —«EL
   DEDO»— y ahí están los ochenta controles del juego; éste es la excepción que
   tiene que estar acá, porque `menu.css` se carga después de `app.css` y la
   regla base de arriba declara `min-height`: a igual especificidad ganaría la
   de este archivo, y el renglón de allá sería una regla muerta que se lee como
   si funcionara. Se corrigió después de escribirlo así y medir 30 px igual.

   POR QUÉ IMPORTA MÁS ACÁ QUE EN UNA TABLA. En una lista, errarle a un renglón
   por dos píxeles abre la ficha del futbolista de al lado y se vuelve; acá
   EJECUTA. Los renglones de este menú venden, mandan a la reserva, sacan del
   banco y cambian el número de la camiseta, y ninguno pregunta después. Un
   menú es la superficie donde el error de puntería es más caro del juego, y
   era la única que había quedado en 30.

   Y LA MISMA VARA QUE EL RESTO: `pointer: coarse` más el ancho, que es la
   pareja con la que `app.css` reparte los 44. Con qué se toca decide el
   mínimo; el ancho está para que una tableta apaisada, que muestra el juego en
   su forma de escritorio, no pierda densidad. */
@media (pointer: coarse) and (max-width: 860px) {
  .menu__item { min-height: 44px; }
}

.menu__item .i { color: var(--icon-quiet); }

/* El hueco de un ítem sin icono. Mide lo que mide un `.i--sm` para que el texto
   quede en la misma columna que el de los ítems que sí lo llevan. */
.menu__hueco { width: 13px; flex: none; }

/* El foco se dibuja como el hover y no sólo con el anillo: en un menú abierto
   con el teclado, el ítem enfocado ES la selección. */
.menu__item:focus {
  background: var(--bg-hover);
  color: var(--text-primary);
}
@media (hover: hover) {
  .menu__item:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
  }
}

.menu__item:focus .i { color: inherit; }
@media (hover: hover) {
  .menu__item:hover .i { color: inherit; }
}

/* Una acción que no se puede hacer se muestra apagada con su motivo al lado,
   igual que la tabla del plantel muestra el veto: esconderla dejaría al DT
   buscando una acción que él cree que existe. */
.menu__item[disabled] {
  color: var(--text-disabled);
  cursor: default;
  background: none;
}

.menu__item[disabled] .i { color: var(--text-disabled); }

.menu__texto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.menu__pista {
  margin-left: auto;
  padding-left: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  white-space: nowrap;
  /* Y cede antes de empujar. La pista la escribe el dato —el motivo por el que
     algo no se puede, que puede ser una frase entera— y sin esto no se recorta
     ninguna de las dos: el `max-width` del menú corta la pista contra el borde
     con `overflow: hidden`, o sea en silencio y sin puntos suspensivos. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* El pie. Aparece sólo en el menú que no tenía ninguna acción que ofrecer —el
   mapa— y dice cómo llegar al menú del navegador. No es un ítem: no se enfoca,
   no se pulsa y no entra en el recorrido del teclado, así que se dibuja como lo
   que es, la letra chica de abajo, separada por la misma línea que separa los
   grupos. */
.menu__pie {
  margin: var(--sp-2) 0 0;
  padding: var(--sp-3) var(--sp-3) var(--sp-2);
  border-top: 1px solid var(--line-hairline);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.menu__sep {
  height: 1px;
  margin: var(--sp-2) 0;
  border: 0;
  background: var(--line-hairline);
}

/* Aparece fundiéndose y no creciendo: el menú ya sale del punto que tocaste,
   que es toda la relación de causa que necesita. Esa decisión sigue en pie —el
   desplegable SÍ crece desde su botón porque su botón está en un sitio fijo de
   la pantalla y el menú nace bajo el puntero—; lo que faltaba era irse. */
.menu { animation: menu-aparece var(--dur-fast) var(--ease); }

@keyframes menu-aparece { from { opacity: 0; } }

/* Y SE VA, que hasta el 1/9/2026 no hacía: `menu.js` llamaba a `.remove()` y el
   menú desaparecía entre dos fotogramas después de haber llegado fundiéndose.
   Es la Regla de la Mitad que Falta —ver `movimiento.css`, punto 4— en el
   hermano del desplegable, y se resuelve igual: el guion pone la marca, espera
   lo que dura esto y recién ahí lo saca del DOM.

   Deja de recibir clics en el mismo instante en que empieza a irse. Importa más
   acá que en el desplegable: los ítems de este menú venden a un futbolista y lo
   mandan a la reserva, y un menú que ya se está yendo no puede aceptar el
   segundo clic de un doble clic apurado. */
.menu[data-yendose] {
  animation: menu-se-va var(--dur-fast) var(--ease-salida) forwards;
  pointer-events: none;
}

@keyframes menu-se-va { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .menu { animation: none; }
  /* La salida no se apaga, se acorta: la regla global de `app.css` la deja en
     1ms, y su `forwards` es lo que mantiene al menú invisible hasta que el
     guion lo saca. Con `none` se quedaría a la vista los 140ms de la espera. */
  .menu[data-yendose] { animation-duration: 1ms; }
}

