/* ==========================================================================
   El Camino DT — Movimiento
   --------------------------------------------------------------------------
   Toda la vida del producto vive acá, en un archivo, para que se pueda leer
   entera y se pueda apagar entera. Son cuatro trabajos y ninguno decora:

   1. CONTINUIDAD. Trece documentos que se sentían trece recargas pasan a ser
      una aplicación: el chrome y el escudo NO se repintan al cambiar de
      pantalla —se quedan quietos, porque no cambiaron— y lo único que se
      cruza es la superficie de trabajo. La pantalla nueva llega desde abajo
      si vas hacia adelante y desde arriba si volvés: la dirección del viaje
      es un dato y se ve.

   2. LA ESCENA. Salir a la cancha no es cambiar de pantalla. `partido.html`
      no aparece: se PINTA, con una raya de cal que baja y va dejando el
      campo detrás. Es el único momento de autor del juego y por eso es el
      único que dura medio segundo. Ocurre unas cuarenta veces por temporada.

   3. EL ACUSE. Los controles contestan: la acción principal, que pinta su
      propia raya mientras la semana se simula; el marcador, que salta cuando
      entra un gol; y desde el 1/9/2026 los botones corrientes, que se hunden
      un punto cuando se los pulsa, y las tablas, que se presentan de nuevo
      cuando lo que muestran ya no es la misma lista.

   4. LO QUE SE VA. La mitad que faltaba. Hasta el 1/9/2026 el sistema sólo
      sabía llegar: los ocho modales y el panel del desplegable se apagaban
      de un fotograma a otro, así que de cada interacción estaba animada la
      mitad de abrir y era un corte la de cerrar. No le faltaba movimiento a
      esta interfaz —le faltaba la mitad del que ya tenía—.

   Nada de esto es imprescindible: sin JavaScript y sin transiciones de
   documento la interfaz queda exactamente donde estaba, seca pero entera.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. ENTRE PANTALLA Y PANTALLA
   --------------------------------------------------------------------------
   `navigation: auto` hace que el navegador tome una foto de la pantalla que
   se va y otra de la que llega, y anime entre las dos. No hace falta ni un
   router ni una sola línea de JavaScript: siguen siendo trece documentos con
   sus enlaces de verdad, su historial y su F5.
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

/* Lo que NO se recarga. Sacar un elemento del recorte de la raíz y darle
   nombre propio es decirle al navegador "este de acá es el mismo de antes":
   en vez de desvanecerse con el resto, se queda. El chrome es el estadio y
   el escudo es tu club — ninguno de los dos se fue a ningún lado. */
.chrome { view-transition-name: chrome; }
.crest[data-f='crest-club'] { view-transition-name: escudo-club; }

/* El chrome mide 74px con subnavegación y 44px sin ella (`carrera`, `club`,
   `nueva`, `sorteo`). Sin esto, el navegador estira la foto de uno hasta la
   altura del otro y la barra se ve aplastada medio segundo. Con `none` la
   foto conserva su tamaño y lo que sobra se recorta desde arriba, que es
   como crece una barra: hacia abajo. */
::view-transition-old(chrome),
::view-transition-new(chrome) {
  object-fit: none;
  object-position: top left;
}

/* El escudo es el mismo archivo en las dos pantallas. Cruzar dos imágenes
   idénticas al 50 % las apaga a las dos por 240ms; dejar la nueva encima y
   quietas no se nota, que es justo lo que se busca. */
::view-transition-old(escudo-club),
::view-transition-new(escudo-club) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-old(escudo-club) { opacity: 0; }
::view-transition-new(escudo-club) { opacity: 1; }

/* Y LO QUE SÍ SE MUEVE: LA SOLAPA.

   El segundo piso del chrome son siete solapas y la que estás mirando lleva un
   subrayado de 2px. Como cada solapa es un DOCUMENTO, ese subrayado se apagaba
   debajo de «Jugadores» y se encendía debajo de «Entrenamiento» sin recorrer
   los ciento y pico de píxeles que hay entre las dos.

   Es exactamente el problema del punto 1 al revés, y por eso vale la pena
   nombrarlo acá: de la barra sabíamos decir que NO se había ido a ningún lado,
   y el único elemento que de verdad cambia de sitio al navegar era el que
   aparecía en su destino sin haber pasado por el camino. Con nombre propio, el
   navegador reconoce que el subrayado de la pantalla que se va y el de la que
   llega son EL MISMO, y lo lleva de uno al otro.

   Hay UNO por documento y por eso el nombre puede ser fijo: `aria-current`
   marca una solapa y sólo una, y dos elementos con el mismo
   `view-transition-name` en la misma pantalla cancelan la transición entera.
   `page` y `location` son las dos maneras de estar debajo de una solapa —ver
   `app.css`— y las dos pintan el mismo subrayado, así que nunca coinciden.

   Se pierde solo si no hay transición: sin foto que cruzar el subrayado
   aparece donde tiene que aparecer, que es lo que hacía hasta hoy. */
.nav-sub__item[aria-current='page']::after,
.nav-sub__item[aria-current='location']::after {
  view-transition-name: solapa;
}

/* Y LAS DOS FOTOS NO SE CRUZAN, por lo mismo que las del escudo: son dos barras
   macizas del mismo violeta y del mismo alto, así que fundir una en la otra al
   50 % las apaga a las dos a mitad de camino y el subrayado viaja pálido. Lo
   que anima es el GRUPO —el recorrido de un sitio al otro—, que es todo lo que
   hay que contar acá.

   Y de paso arregla el caso feo: cuatro pantallas del juego no tienen segundo
   piso (`carrera`, `club`, `nueva`, `sorteo`). Yendo del plantel a una de ésas
   el subrayado no tiene par que lo espere, y sin esto se quedaría apagándose
   solo durante 240ms sobre una barra que ya mide treinta píxeles menos. Con la
   foto vieja en cero, sale de la pantalla en el mismo instante que su
   pantalla. */
::view-transition-old(solapa) { animation: none; opacity: 0; }
::view-transition-new(solapa) { animation: none; opacity: 1; }

/* La superficie de trabajo. Sale rápido y entra con calma: una salida lenta
   se lee como espera, una llegada lenta se lee como llegada.

   Son DOS animaciones sobre el mismo elemento y no una, porque el fundido y
   el recorrido no quieren la misma curva. Con la curva de llegada —que gasta
   el 90 % del camino en el primer tercio— un fundido se termina antes de que
   el ojo lo registre y el cambio vuelve a ser seco. El recorrido sí la
   quiere: es lo que hace que la pantalla aterrice en vez de deslizarse. */
::view-transition-old(root) {
  animation: mov-sale-funde var(--dur-fast) linear both,
             mov-sale-corre var(--dur-fast) var(--ease) both;
}
::view-transition-new(root) {
  animation: mov-entra-funde var(--dur-pantalla) ease-out both,
             mov-entra-corre var(--dur-pantalla) var(--ease-entrada) both;
}

@keyframes mov-sale-funde  { to   { opacity: 0; } }
@keyframes mov-sale-corre  { to   { transform: translateY(calc(-1 * var(--mov-viaje, 10px))); } }
@keyframes mov-entra-funde { from { opacity: 0; } }
@keyframes mov-entra-corre { from { transform: translateY(var(--mov-viaje, 10px)); } }

/* Volver es el mismo viaje al revés. `movimiento.js` marca la raíz cuando la
   navegación es del historial —el botón atrás, el gesto, Alt+←— y el signo
   del recorrido se invierte: la pantalla vieja vuelve por donde vino. */
:root[data-mov='atras'] { --mov-viaje: -10px; }

/* --------------------------------------------------------------------------
   2. LA ESCENA — se encienden los reflectores
   --------------------------------------------------------------------------
   El día del partido llega como cualquier otra pantalla: la alineación, el
   marcador y la pizarra ya están puestos en el primer fotograma. Lo único
   que se toma su tiempo es el CAMPO, que sube desde el negro con un punto de
   escala, como cuando prenden las luces sobre el césped.

   **Nada tapa nada.** Una versión anterior bajaba una cortina opaca sobre la
   pantalla entera; ocultaba información durante medio segundo y se leía como
   un telón, no como un partido. La regla que quedó de ese intento: en una
   interfaz densa, el momento de autor se hace sobre UN elemento —el que es
   el motivo de la pantalla— y nunca escondiendo el resto.

   Es un fundido con escala sobre el lienzo y nada más: sin `filter`, que
   obligaría al compositor a repasar un canvas que se repinta sesenta veces
   por segundo durante los noventa minutos siguientes. El relleno es
   `backwards` y no `both` a propósito — sostiene el negro durante la espera
   y después devuelve el lienzo a su estilo natural, sin dejarle puesto un
   `transform` de por vida.
   -------------------------------------------------------------------------- */

:root[data-pantalla='partido'] .pitch__lienzo {
  animation: mov-reflectores var(--dur-escena) var(--ease-entrada) backwards;
}

/* Cuando SÍ hubo transición de documento, el campo espera a que termine. Sin
   esta espera, los reflectores se encienden por debajo de la foto de la
   pantalla anterior y no los ve nadie. */
:root:not(.sin-vt)[data-pantalla='partido'] .pitch__lienzo {
  animation-delay: var(--dur-pantalla);
}

@keyframes mov-reflectores {
  from { opacity: 0; transform: scale(0.985); }
}

/* --------------------------------------------------------------------------
   3. EL ACUSE
   -------------------------------------------------------------------------- */

/* La punta de la acción principal se inclina hacia donde te lleva. El botón
   no se mueve —esa regla del sistema sigue en pie—; se mueve su flecha, que
   es la que promete el viaje. */
.action .i { transition: transform var(--dur-fast) var(--ease); }
.action:hover .i { transform: translateX(2px); }
.action:active .i { transform: translateX(0); }

/* Lo que NO lleva acuse: Continuar. Pulsarlo navega en el mismo latido, así
   que una barra de progreso en el botón sería una espera inventada — y la
   respuesta a ese clic ya es la pantalla entera, que cambia. Un botón que
   además se ilumina estaría contando dos veces la misma cosa. */

/* El gol. `data-gol` ya existía y ya teñía la cifra de cal; lo que faltaba
   era el salto. Entra una vez por gol —el atributo sólo cambia cuando cambia
   el marcador— y vuelve al tamaño exacto del que salió. */
.marcador__cifra[data-gol='true'] {
  animation: mov-gol 420ms var(--ease-entrada);
}

@keyframes mov-gol {
  0%   { transform: scale(1); }
  24%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* La repisa de clubes, cuando pasás a otra división o a otro país.

   Es el mismo trabajo que el punto 1 —contar que lo que estás mirando ya no es
   lo de antes— a la escala de un panel en vez de una pantalla. Sin esto, ir de
   la Primera a la Primera Nacional cambia treinta bloques de color de golpe y
   no se lee como una lista nueva: se lee como un parpadeo.

   ESCALONA POR FILA Y NO POR CARTA. Una grilla de siete columnas entra en
   cinco tiempos, no en treinta: escalonar carta por carta hace una ola que
   cruza la pantalla en diagonal y tarda más en terminar de lo que tarda el ojo
   en volver a la primera. La fila la calcula `nueva.js` con las columnas que
   de verdad haya, así que en una ventana angosta —tres columnas— siguen siendo
   pocos tiempos y no diez.

   EL TOPE ES LO QUE HACE QUE NO MOLESTE: pase lo que pase, la última carta
   arranca a 100ms de la primera. Un escalonado sin tope es una animación que
   crece con los datos, y el Federal A tiene treinta y siete clubes.

   Y NO ENTRA AL BUSCAR, que es la mitad del trabajo: `pintarClubes()` corre en
   cada tecla, y una repisa que se reconstruye con cada letra es un tartamudeo.
   La marca la pone `nueva.js` sólo cuando cambia el CONJUNTO. */
.clubes--entra .carta {
  animation: mov-carta-entra var(--dur) var(--ease-entrada) both;
  animation-delay: min(calc(var(--fila, 0) * 26ms), 100ms);
}

/* Seis píxeles y no veinte: la carta ya está en su sitio, sólo se presenta. */
@keyframes mov-carta-entra {
  from { opacity: 0; transform: translateY(6px); }
}

/* Los dos primeros pasos del selector, cuando pasás de uno a otro.

   Es el mismo trabajo que la repisa de clubes y con la misma cuenta de filas:
   contar que lo que estás mirando es una lista nueva. Vale la pena acá más que
   en ningún otro sitio porque los tres pasos son el MISMO documento —no hay
   transición de pantalla que los separe— y sin esto elegir Argentina cambia
   veintiuna cartas por cinco filas sin que nada diga que pasó algo.

   El escalonado y el tope son los de allá: la última fila arranca a 100ms de la
   primera, pase lo que pase. La marca la pone `escalonarEntrada()`, que es una
   sola función para las tres listas de esta pantalla. */
.paso--entra .nacion,
.paso--entra .liga {
  animation: mov-carta-entra var(--dur) var(--ease-entrada) both;
  animation-delay: min(calc(var(--fila, 0) * 26ms), 100ms);
}

/* El pie del selector, cuando elegís un club.

   Es el cierre del gesto y no un adorno: el clic pasa arriba, en la repisa, y
   la consecuencia —quién es, en qué puesto queda, y el botón de empezar—
   aparece abajo, lejos de donde estabas mirando. Sin acuse, la mitad de las
   veces no se ve que el pie cambió.

   Entra sólo lo de ADENTRO y no la banda: la banda del pie está fija y no se
   fue a ningún lado. Es la misma Regla de la Barra Quieta del punto 1, un piso
   más abajo. */
.pie--entra > * {
  animation: mov-pie-entra var(--dur) var(--ease-entrada) both;
}

@keyframes mov-pie-entra {
  from { opacity: 0; transform: translateY(4px); }
}

/* EL BOTÓN QUE SE PULSA, y por qué NO se mueve ni un píxel.

   `.action` contestaba al clic desde el primer día —se va a violeta hondo— y
   los otros cuatro botones del sistema no contestaban nada: `.btn`, el
   segmentado, la pastilla de filtro y el botón de icono tenían `:hover` y ahí
   se terminaba, así que apretar y no apretar se veían igual. En una pantalla
   donde casi todo lo que se toca es uno de esos cuatro, ésa es la mitad de la
   sensación de que la interfaz no contesta.

   LA REGLA DEL SISTEMA SIGUE EN PIE: el botón no se mueve. Un botón que se
   hunde 1px es el reflejo fácil y acá está mal, porque estos controles viven
   metidos en tablas de filas de 22px y en rieles de 26 — un píxel de viaje
   corre el texto de al lado y se lee como un salto de maquetación, no como un
   apretón. Lo que contesta es el TONO.

   LO QUE SÍ CAMBIA ES CUÁNDO. La bajada es instantánea y la vuelta es la
   transición de siempre, y ahí está todo el efecto: con los 120ms puestos en
   los dos sentidos, el color empieza a viajar cuando el dedo ya se está yendo
   y el botón parece contestar tarde. Apretar tiene que ocurrir en el
   fotograma del clic; soltar puede tomarse su tiempo. Es la misma asimetría
   que el punto 4 —salir rápido, llegar con calma— vista desde un botón.

   Y SE HUNDE CON `brightness` Y NO CON UN COLOR NUEVO, que fue el primer
   intento y estaba mal: `.btn:hover` YA se va a `--bg-active`, así que darle
   ese mismo tono al `:active` es escribir una regla que en escritorio no se ve
   nunca —al botón se lo aprieta con el puntero encima, siempre—. El sistema ya
   tenía la respuesta escrita dos veces, en el `:active` de la acción del chrome
   y en el del botón de peligro: se le baja el brillo a lo que haya. Sirve
   además para los tres que no tienen fondo en reposo, porque lo que oscurece es
   el fondo del `:hover` cuando lo hay y el rótulo cuando no.

   El 0,86 no es nuevo: es el que ya usa `chrome.css`. */
.btn:active:not([disabled]),
.icon-btn:active,
.segmented__btn:active,
.pais:active {
  filter: brightness(0.86);
  transition-duration: 0s;
}
/* El segmentado sin elegir no tiene fondo ni en reposo ni al pasar por encima
   —sólo cambia de color—, así que hace falta darle una superficie que hundir o
   apretarlo sería oscurecer cuatro letras. El elegido no lo necesita: ya está
   en violeta pleno y se hunde dentro de su propio color. */
.segmented__btn:active:not([aria-pressed='true']) { background: var(--bg-hover); }

/* LA TABLA QUE YA NO MUESTRA LO MISMO.

   Es el trabajo de la repisa de clubes —contar que lo que estás mirando es una
   lista nueva— en la pieza más usada del juego: la tabla. Tocar «Arqueros» en
   el plantel cambiaba treinta renglones de golpe, y treinta renglones que
   cambian de golpe no se leen como otra lista sino como un parpadeo; el ojo se
   queda en el renglón donde estaba, que ahora dice otra cosa.

   Y ACÁ NO SE ESCALONA, que es lo contrario de lo que hace la repisa. La
   repisa son cartas de 96px en cinco filas y el escalonado le sienta bien; una
   tabla son renglones de 22 y una ola que los recorra de a 26ms es un temblor,
   no una presentación — además de gastarse el tiempo de escaneo, que es el
   principio del producto. La tabla se presenta ENTERA y de una vez, con el
   mismo fundido de seis píxeles del sistema. Cero fotogramas nuevos.

   LA MARCA LA PONE EL GUION Y SÓLO CUANDO CAMBIA EL CONJUNTO, igual que en la
   repisa: ordenar por otra columna y filtrar por línea son listas nuevas,
   repintar la misma lista porque cambió un dato no lo es. Una tabla que se
   presenta cada vez que se repinta es un tartamudeo. */
/* SIN `both`, que es la única diferencia con la repisa y no es un descuido.
   La repisa escalona, así que sus cartas necesitan que el relleno las sostenga
   invisibles durante su retardo; acá no hay retardo que sostener. Y el relleno
   dejaría al `tbody` con un `transform` puesto para siempre, que es la trampa
   que `movimiento.js` documenta para el `main`: un transform, aunque sea de
   cero, convierte al elemento en el bloque contenedor de todo lo que tenga
   dentro en `position: fixed`. Una tabla no puede quedarse con eso armado. */
.data-table--entra tbody {
  animation: mov-carta-entra var(--dur) var(--ease-entrada);
}

/* LA PANTALLA QUE CONTESTA.

   Tres pantallas del juego son una conversación: la previa, el entretiempo y el
   portal. Elegís un tono y te dicen cómo cae; movés el planteo y te dicen cómo
   te va a ir; tocás un día del calendario y te dicen qué hay. Las respuestas ya
   estaban declaradas en el marcado con `role="status"` y se escribían en
   silencio: quien las escucha con voz se enteraba, quien las mira no.

   NACIÓ TRES VECES Y POR ESO ESTÁ ACÁ. Se escribió en `entretiempo.css`, se
   copió a `previa.css` y el portal iba a ser la tercera. Tres hojas con el
   mismo nombre y el mismo gesto son tres sitios donde cambiar una duración —el
   mismo camino que hicieron los modales esta misma tarde, que estuvieron
   escritos tres veces antes de consolidarse.

   Y ACÁ NO SE MIDE CADENCIA, que es la diferencia con el punto de arriba: en
   esas tres pantallas nada cambia si el DT no lo pide, así que el ritmo lo pone
   su mano y esto no puede volverse un estrobo. El día que una pantalla que se
   mueva sola quiera contestar, hay que medir antes cada cuánto cambia — la
   cuenta y el porqué están en `partido.css`, en «el dato que acaba de cambiar».

   El cuándo lo decide `contestar()`, en `mundo.js`: acusa sólo si el texto dice
   otra cosa, nunca por repintado. */
[data-contesta] {
  animation: mov-contesta var(--dur) var(--ease-entrada);
}

@keyframes mov-contesta {
  from { opacity: 0; transform: translateY(3px); }
}

/* --------------------------------------------------------------------------
   4. LO QUE SE VA
   --------------------------------------------------------------------------
   Los tres puntos de arriba son de agosto y los tres animan LLEGADAS. Mirado
   entero en septiembre, el sistema tenía un agujero con forma: sabía aparecer
   y no sabía irse. La pantalla que se va tiene su fotograma —punto 1—, pero
   los OCHO modales del juego y el panel del desplegable se apagaban de un
   cuadro al siguiente, y ésos son los dos que se abren y se cierran cincuenta
   veces por sesión.

   El síntoma es difícil de nombrar mirando una foto y obvio usándolo: cada
   cosa que tocás entra con calma y desaparece de un tirón, así que la interfaz
   se siente cuidada al abrir y brusca al cerrar. No le faltaban efectos —le
   faltaba la mitad de los que ya tenía—.
   -------------------------------------------------------------------------- */

/* LOS OCHO MODALES, EN UN SOLO GESTO Y EN UN SOLO SITIO.

   Estaba escrito TRES VECES —`mesa-llega` en `mesa.css`, `card-llega` en
   `card.css`, y otra vez para el parte del movimiento— con los mismos cuatro
   píxeles y el mismo 2 % en las tres, y los otros CINCO modales del juego no
   lo tenían: la pregunta de dos botones, `--ancho`, `--trato`, `--pre` y la
   llegada a un club nuevo aparecían y desaparecían secas. Tres copias de una
   regla y cinco sitios sin ella es la definición de una regla que tiene que
   vivir en el sistema. El gesto es EXACTAMENTE el que ya hacían esas tres; lo
   único que cambia es quién lo escribe y que ahora también se va.

   VA POR TRANSICIÓN Y NO POR FOTOGRAMAS, y eso es lo que compra la salida. Una
   animación sobre `[open]` sólo puede correr mientras el atributo está puesto,
   y al cerrar el atributo se va en el mismo instante que la caja: no hay
   ningún momento en el que exista un modal cerrándose. Con `allow-discrete`,
   `display` y `overlay` dejan de saltar y esperan a que la transición termine,
   así que el modal se queda en la capa superior los 120ms que tarda en irse.
   `@starting-style` es la otra mitad: sin él la llegada no tiene desde dónde
   salir —el modal nace ya con su estilo final— y sólo se vería la salida.

   Sin soporte, `display` salta como saltaba y el modal aparece y desaparece
   seco: se pierde el gesto, no se pierde el modal. Es la Regla del Respaldo
   Pesimista del punto 5, que acá sale gratis porque la escribe el navegador.

   EL VELO SE TOMA MÁS TIEMPO QUE LA CAJA, al llegar y al irse, y eso ya estaba
   decidido: si los dos duraran lo mismo, el fondo se apagaría de golpe y el
   modal se leería como un salto de corte en vez de como algo que se pone
   encima. Lo que es nuevo es que la asimetría también valga al revés — el velo
   sobreviviendo a la caja es lo que devuelve la pantalla de atrás en vez de
   destaparla.

   `:where()` para el estado de reposo, para que cualquier hoja que quiera
   otra cosa para su modal gane sin tener que enterarse de que esto existe. */
/* LA CAJA SE APAGA EN `--dur-fast` PERO SE QUEDA EN LA CAPA SUPERIOR
   `--dur-pantalla`, y las dos duraciones distintas de esta misma regla son
   deliberadas. El velo se toma el doble que la caja —está tres reglas más
   abajo— y el `::backdrop` es del elemento: si `overlay` y `display` se fueran
   a los 120ms con la caja, el modal saldría de la capa superior y se llevaría
   puesto el velo a mitad de su propio fundido. El elemento aguanta hasta que
   termina lo ÚLTIMO que se está yendo, que es el velo. */
:where(.dialogo) {
  opacity: 0;
  transform: translateY(4px) scale(0.98);
  transition:
    opacity var(--dur-fast) var(--ease-salida),
    transform var(--dur-fast) var(--ease-salida),
    overlay var(--dur-pantalla) allow-discrete,
    display var(--dur-pantalla) allow-discrete;
}

/* Y MIENTRAS SE VA NO RECIBE UN CLIC. Cerrado deja de ser modal en el acto,
   así que durante los 240ms que tarda en irse queda una caja visible y encima
   de todo que ya no atrapa el foco: sin esto, un clic apurado sobre lo que hay
   debajo se lo come un modal que el DT ya cerró. Es la misma línea que llevan
   el panel del desplegable y el menú del botón derecho. */
:where(.dialogo):not([open]) { pointer-events: none; }

:where(.dialogo)::backdrop {
  opacity: 0;
  transition:
    opacity var(--dur-pantalla) var(--ease-salida),
    overlay var(--dur-pantalla) allow-discrete,
    display var(--dur-pantalla) allow-discrete;
}

.dialogo[open] {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-pantalla) ease-out,
    transform var(--dur-pantalla) var(--ease-entrada),
    overlay var(--dur-pantalla) allow-discrete,
    display var(--dur-pantalla) allow-discrete;
}

.dialogo[open]::backdrop {
  opacity: 1;
  transition:
    opacity var(--dur-escena) var(--ease),
    overlay var(--dur-escena) allow-discrete,
    display var(--dur-escena) allow-discrete;
}

@starting-style {
  .dialogo[open] { opacity: 0; transform: translateY(4px) scale(0.98); }
  .dialogo[open]::backdrop { opacity: 0; }
}

/* El panel del desplegable se va por su cuenta y su regla vive en
   `controles.css`, al lado de la geometría que la necesita: de qué lado del
   botón se abrió es una cuenta de `colocarPanel()`, y el gesto de entrada y el
   de salida salen los dos de esa respuesta. Separarlos dejaría media regla acá
   sin el dato que la explica. */

/* --------------------------------------------------------------------------
   5. EL RESPALDO
   --------------------------------------------------------------------------
   Hay más motivos para que no haya transición que navegadores que no la
   soporten: una recarga, entrar desde fuera del sitio, o —el que más cuesta
   descubrir— que la pestaña esté oculta, porque el navegador saltea toda
   transición que nadie está mirando. En cualquiera de esos casos no hay foto
   que cruzar y la pantalla entra sola, con el mismo gesto y la misma
   duración: se pierde la continuidad del chrome, no se pierde la vida.

   Por eso `movimiento.js` da por sentado que NO hay transición y sólo retira
   esta marca cuando el evento le confirma que sí la hay, antes del primer
   pintado. Al revés —detectar soporte y confiar— el respaldo no entraría
   nunca en los tres casos de arriba y el juego se quedaría seco.
   -------------------------------------------------------------------------- */

/* `mov-hecho` la retira en cuanto termina, para no dejarle al `main` un
   `transform` puesto de por vida (ver `movimiento.js`).

   Y ESPERA AL DATO CUANDO LA PANTALLA SE ESCRIBE SOLA. Las veintidós que
   llevan `data-pinta-js` traen el `main` vacío y lo llenan sus guiones cientos
   de milisegundos después; sin la espera, la bienvenida corría sobre el
   cascarón y el contenido llegaba después, seco (los números, en
   `movimiento.js`). `movimiento.js` retira `sin-pintar` en
   `DOMContentLoaded`, que es el momento en que las veinticuatro ya están
   escritas — comprobado una por una, no supuesto.

   Las que traen su `main` en el marcado —`home` y `espera`— no llevan el
   atributo y entran en el acto, como siempre: la puerta del juego no puede
   esperar a ciento cuarenta guiones para verse. */
:root.sin-vt:not(.mov-hecho) main:not([data-pinta-js]),
:root.sin-vt:not(.mov-hecho):not(.sin-pintar) main[data-pinta-js] {
  animation: mov-entra-funde var(--dur-pantalla) ease-out both,
             mov-entra-corre var(--dur-pantalla) var(--ease-entrada) both;
}

/* MIENTRAS TANTO, EL CASCARÓN NO SE MUESTRA. No es por estética: una tabla con
   sus cabeceras y ninguna fila, o un contador en cero, no es «cargando» — es
   una respuesta, y es falsa. El chrome sí se ve desde el primer fotograma
   (vive fuera del `main`), así que lo que se pone en suspenso es la superficie
   de trabajo y no la pantalla.

   VA SÓLO CUANDO NO HUBO TRANSICIÓN DE DOCUMENTO. Con transición, el navegador
   retiene el pintado de la pantalla nueva hasta que está lista, así que la
   foto que cruza YA tiene el contenido: esconder el `main` ahí lo único que
   haría es fotografiarlo vacío. `sin-vt` es exactamente esa pregunta y ya está
   contestada antes del primer pintado. */
:root.sin-vt.sin-pintar main[data-pinta-js] { opacity: 0; }

/* --------------------------------------------------------------------------
   6. QUIEN PIDE QUIETO
   --------------------------------------------------------------------------
   El `*` de `app.css` no alcanza a llegar al árbol de la transición: sus
   pseudoelementos no son elementos del documento y hay que apagarlos por
   nombre. Sin animaciones, la transición termina en el primer fotograma y el
   cambio de pantalla vuelve a ser instantáneo, que es lo que se pidió.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }

  :root.sin-vt:not(.mov-hecho) main:not([data-pinta-js]),
  :root.sin-vt:not(.mov-hecho):not(.sin-pintar) main[data-pinta-js],
  :root[data-pantalla='partido'] .pitch__lienzo,
  .marcador__cifra[data-gol='true'],
  .clubes--entra .carta,
  .paso--entra .nacion,
  .paso--entra .liga,
  .pie--entra > * { animation: none !important; }

  .action:hover .i { transform: none; }
}
