/* ============================================================================
   Cimientos
   ============================================================================
   Lo que había aquí era el CSS que genera la plantilla de ASP.NET: la fuente
   clavada en 14px, un anillo de foco con un halo blanco y un `margin-bottom`
   de 60px para empujar el pie. Nada de eso era una decisión.

   El tema es **oscuro por defecto** y el claro existe: los colores salen de las
   variables de Bootstrap 5.3 (`--bs-body-bg`, `--bs-secondary-bg`…), así que casi
   todo el CSS de este fichero ya funcionaba en los dos sin tocarlo. Lo que NO
   sale gratis está marcado con «ojo con el tema» más abajo.
   ============================================================================ */

:root {
  /* El acento es el dorado del marco de las cartas multicolor. No es un color de
     maná: si fuera azul o rojo, un mazo mono-color parecería estar seleccionado.

     Este tono es el del tema OSCURO: 7,34:1 contra el fondo, medido. Sobre blanco
     ese mismo oro da 2,1:1 —ilegible—, así que el tema claro usa otro más abajo.
     Un acento no puede ser un color, tienen que ser dos. */
  --mtg-acento: #e0aa3e;
  --mtg-acento-vivo: #f0bc55;
  --mtg-acento-texto: #1b1a17;
  --mtg-acento-halo: rgba(224, 170, 62, 0.45);

  /* Velo para una fila que pide atención. Translúcido a propósito: se mezcla con el
     fondo del tema, así que el texto sigue contrastando con él. */
  --mtg-atencion-fondo: rgba(224, 170, 62, 0.16);

  /* Plata y bronce del podio de una liga. **Van con el acento**, que hace de oro, y como
     él necesitan un tono por tema: son colores claros por naturaleza y sobre blanco se
     hunden. Estos son los del tema OSCURO; el claro los redefine más abajo.

     **Lo que hay que separar aquí es el TONO, no la luminancia**, y hay que separarlo de
     DOS cosas: de los otros dos metales y del color del texto normal. Las dos se midieron
     y las dos fallaron a la primera:

     · Un bronce «realista» (#d08b4a) daba **1,34 contra el oro** —y 1,07 en el tema
       claro—: los dos eran marrón-naranja y a 14 px eran el mismo color. Resuelto
       llevándolo a rojo cobrizo.
     · Una plata gris (#b3c2d1) daba **1,40 contra el color del texto** (#dee2e6), que en
       Bootstrap es también un gris azulado: una cifra en plata se leía como texto normal.
       Lo preguntó el organizador antes de que se viera. Resuelto haciéndola **azul acero**
       —sigue leyéndose como el metal— para que la separe la saturación y no solo el brillo.

     Y una tercera cosa que solo apareció midiendo: el bronce de este tema estaba en
     **4,25 sobre el fondo**, por debajo del 4,5 que pide un texto normal. Pasaba
     desapercibido porque la cifra estaba escrita y dada por buena. Aclarado a #ee6c4d
     sube a 5,06 y de paso gana separación de tono contra el oro (28° frente a 21).

     Cifras de aquí, sobre `--bs-body-bg` (#212529): oro 7,34 · plata 6,24 · bronce 5,06.
     Y contra el color del texto: 1,61 · 1,90 · 2,34. */
  /* El oro del podio **tiene variable propia y no reutiliza el acento**, aunque en este tema
     valgan lo mismo. No es redundancia: el acento significa «esto se pulsa» y una medalla no
     se pulsa, así que atarlos obligaba a que el metal cargara con el contraste que necesita un
     botón. Separados, el tema claro puede darle un amarillo de verdad. */
  --mtg-oro: var(--mtg-acento);
  --mtg-plata: #7fa8d8;
  --mtg-bronce: #ee6c4d;

  /* El velo de una ficha con imagen de fondo: opaco donde va el texto y abriéndose
     hacia la derecha para dejar ver el tapete. Usa el color del cuerpo, así que sirve
     en los dos temas sin declararse dos veces.

     Vive aquí porque **la forma compacta se usa en dos sitios**: todos los listados
     en móvil, y las jornadas de una liga en cualquier tamaño. Con dos copias, el día
     que se ajustara una quedaría la otra distinta sin que nadie lo decidiera. */
  /* ---- Lo que mide como mínimo una caja de lista de torneo ----
     La usan las dos rejillas que pintan esa caja —«Barajas por preparar» en la portada y las pestañas de «Mis
     barajas»—, y está en una sola variable porque **son la misma caja**: con el número escrito dos veces, el
     día que se ajuste una quedaría la otra distinta sin que nadie lo decidiera.

     **38 rem no es un número redondo, es el único que cumple las dos cosas que pidió el organizador**: una
     caja por fila en la portada y dos en «Mis barajas». Sale de medir los contenedores, y el dato que lo hace
     posible es que **los dos dejan de crecer** —la página tiene ancho máximo—:

       | Ventana        | Portada | «Mis barajas» |
       | 1280           |   730   |     1256      |
       | 1440           |   826   |     1416      |
       | 1600           |   922   |     1576      |
       | 1920 y más     |  1051   |     1776      |

     Para una sola columna en la portada hace falta un mínimo mayor que (1051 − 8) / 2 = **521**; para dos en
     «Mis barajas» y nunca tres, entre (1776 − 16) / 3 = **587** y (1256 − 8) / 2 = **624**. La intersección es
     587-624, y 38 rem son 608. El margen más justo es el de las tres columnas: hacen falta 1864 px de
     contenedor y el tope es 1776, o sea **88 px**. Si algún día crece el ancho máximo de la página, «Mis
     barajas» pasará a tres — y entonces hay que volver a esta cuenta, no ajustar a ojo. */
  --mtg-caja-lista-min: 38rem;

  --mtg-velo-ficha: linear-gradient(
    90deg,
    var(--bs-body-bg) 0%,
    var(--bs-body-bg) 52%,
    rgb(from var(--bs-body-bg) r g b / 0.72) 78%,
    rgb(from var(--bs-body-bg) r g b / 0.55) 100%);

  /* Superficie de una caja que tiene que parecer **elevada** sobre el panel que la
     contiene. Un velo translúcido y no un `--bs-*-bg`, y está medido: sobre el panel
     (`--bs-secondary-bg`, #343a40) tanto `--bs-body-bg` como `--bs-tertiary-bg` son más
     **oscuros**, así que una caja pintada con ellos sale como un agujero negro en lugar
     de como un relieve. Un blanco al 7 % aclara en oscuro y un negro al 5 % oscurece en
     claro: en los dos temas se lee como «un escalón por encima». */
  --mtg-celda-fondo: rgba(255, 255, 255, 0.07);

  /* Alto mínimo de lo que se toca con un dedo. Solo se aplica con puntero grueso
     —ver el bloque de táctil—, para no inflar las tablas densas con ratón. */
  --mtg-toque: 44px;
}

/* El oro oscurecido del tema claro: 5,94:1 sobre blanco y 5,64:1 sobre el gris de
   Bootstrap, los dos medidos. El texto encima pasa a ser blanco. */
[data-bs-theme="light"] {
  --mtg-acento: #855c0e;
  --mtg-acento-vivo: #6b4a0b;
  --mtg-acento-texto: #ffffff;
  --mtg-acento-halo: rgba(133, 92, 14, 0.35);
  --mtg-atencion-fondo: rgba(133, 92, 14, 0.12);
  /* Plata y bronce oscurecidos, por lo mismo que el oro: los del tema oscuro son claros y sobre
     blanco se hunden.

     **El bronce del tema claro es rojo y no cobre, y costó tres intentos.** Aquí el oro no es un
     dorado sino `#855c0e`, un marrón oscuro —el dorado de verdad da 2,1 sobre blanco y no se
     puede usar—, así que cualquier bronce «realista» acaba siendo el mismo marrón: el primero
     (#8a5220) daba **1,07 contra el oro** y el segundo (#a33c14) se quedaba en 1,10 con solo 22°
     de separación de tono. Los dos los vio el organizador antes que ninguna medición.
     Con rojo puro la separación sube a **39° de tono y 1,29 de contraste**, que es lo máximo que
     da de sí este tema sin tocar el acento.

     No choca con el rojo de peligro de Bootstrap (#dc3545): este es más oscuro y menos rosado, y
     además vive en una tabla donde no hay ninguna acción destructiva con la que confundirlo.

     Medidos sobre blanco: plata 5,08 y bronce 7,66. La plata va en **azul acero** y no gris,
     porque un gris medio se confundía con el texto secundario — que es justo con lo que comparte
     celda, ya que los ceros del medallero van en él. */
  /* Y aquí es donde se nota que el oro del podio sea variable propia: el acento de este tema
     (#855c0e) es un **marrón**, porque tiene que aguantar como color de botón; para una medalla
     se leía como bronce viejo y no como oro. Lo dijo el organizador viéndolo.

     Este es más amarillo de verdad —saturación 100 % contra el 89 % del acento, y el tono sube
     de 39° a 45°— y aun así da **4,92 sobre blanco**, con margen sobre el 4,5 de un texto normal.
     De paso separa mejor del bronce: 1,56 frente al 1,29 que daba el acento. */
  --mtg-oro: #8f6b00;
  --mtg-plata: #41729f;
  --mtg-bronce: #a80f0f;
  /* Un poco más que el 7 % del tema oscuro: el mismo porcentaje de negro sobre un panel
     claro se nota menos, y medido daba 1,12 de relieve frente a 1,24. */
  --mtg-celda-fondo: rgba(0, 0, 0, 0.08);
}

html {
  /* 16px en todas partes. La plantilla bajaba a 14 en móvil, que es justo donde
     una tabla de clasificación con ocho columnas menos se lee. */
  font-size: 16px;
}

body {
  /* La cifra de un desempate y un marcador se leen mejor con cifras de ancho fijo:
     las columnas de números quedan alineadas sin recurrir a monoespaciada. */
  font-variant-numeric: tabular-nums;

  /* Pie pegado abajo con flexbox. Antes esto lo hacía el andamiaje de ASP.NET con
     `.footer { position: absolute; bottom: 0 }` sostenido por un `html{position:relative}`
     y un `body{margin-bottom:60px}` en otro fichero. Tres reglas repartidas en dos
     sitios, y al quitar dos de ellas el pie se soltó de la página: un `absolute` sin
     ancestro posicionado se ancla al bloque contenedor inicial, así que se quedaba
     clavado a la altura de la primera pantalla y **se superponía al contenido** en
     cuanto la página era más larga que la ventana.

     Con `margin-top: auto` el pie baja solo cuando sobra sitio y fluye cuando no.
     No hay altura mágica que mantener sincronizada. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

body > footer {
  margin-top: auto;
  padding-block: 1rem;
}

/* ============================================================================
   La pantalla del juez en móvil: pestañas y barra fija
   ============================================================================
   En escritorio la ronda y la clasificación se ven a la vez, una debajo de otra, y
   nada de este bloque aplica. En un móvil eso obligaba a desplazarse una pantalla
   entera para consultar la tabla entre resultado y resultado, y las acciones de
   juez —que es lo que se pulsa al final de cada ronda— quedaban al fondo del todo.

   Qué panel se ve lo dice `data-panel` en `#ronda-y-clasificacion`. Lo pinta el
   servidor («ronda») y lo restaura site.js tras cada intercambio de HTMX, porque el
   fragmento se reemplaza entero al guardar un resultado y sin eso el juez volvería
   a la pestaña de ronda aunque estuviera revisando la clasificación.
   ============================================================================ */
/* **Las pestañas valen en las dos vistas**, y esto antes vivía encerrado en la media
   query de móvil. Sacarlo fuera no añadió código: la maquinaria —el atributo en el
   contenedor, el servidor pintándolo y site.js restaurándolo tras cada intercambio— no
   dependía del tamaño para nada.

   El motivo de fondo no es ganar espacio: **las dos vistas se usan en secuencia**. El
   bucle del juez es meter resultados, cerrar la ronda, mirar la tabla y emparejar; nunca
   necesita las dos a la vez. Y la clasificación necesita el ancho, porque tiene nueve
   columnas y crecerá con el top y los grupos: a media pantalla le quedarían unos 600 px,
   el mismo apretón que se acaba de arreglar en móvil.

   Que la forma sea la misma arriba y abajo también significa **un solo estado que
   mantener**, en lugar de dos comportamientos según el tamaño. */
.mtg-pestanas {
  display: flex;
  gap: 0.5rem;
}

/* Qué mitad se ve. Fuera de la media query a propósito: es la regla que hace que la
   estructura sea la misma en las dos vistas. */
[data-panel="ronda"] .mtg-panel-clasificacion,
[data-panel="clasificacion"] .mtg-panel-ronda {
  display: none;
}

/* Pestañas clásicas: una línea que separa del contenido y un subrayado de acento en la
   activa. **Deliberadamente distintas de las del grafo de fases**, que son pestaña
   rellena con anillo: son dos niveles anidados —fases fuera, ronda y clasificación
   dentro— y con el mismo lenguaje visual uno se leería como el otro.

   **Iguales en móvil y en escritorio**, y eso corrige un fallo de significado, no de
   gusto: en móvil la activa era un botón **relleno de amarillo**, y en esta aplicación el
   amarillo significa «esto se pulsa». La pestaña activa parecía la que había que pulsar,
   así que se leía justo del revés. Con el subrayado, la activa se lee como activa porque
   está *unida* al contenido de abajo, y el amarillo deja de mentir.

   El mecanismo no cambia: el estado sigue viviendo en el atributo del contenedor, que es
   lo que le hace sobrevivir al intercambio de HTMX. */
.mtg-pestanas {
  gap: 0;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--bs-border-color);
}

.mtg-pestanas .btn {
  border: 0;
  border-radius: 0;
  margin-bottom: -1px;
  padding: 0.45rem 1.1rem;
  box-shadow: inset 0 -2px 0 0 transparent;
  --bs-btn-color: var(--bs-secondary-color);
}

/* La activa, **para cualquier juego de pestañas de la aplicación**: se pinta por `aria-selected`, que
   es el atributo que `site.js` mantiene en los tres mecanismos que existen.

   Antes esto **enumeraba los pares panel/atributo** —`[data-panel="ronda"] [data-mtg-pestana="ronda"]`,
   y así con los cuatro— con el motivo escrito de que «el día que aparezca un tercer juego se añade
   aquí». Apareció —las cuatro vistas de la baraja— y **no se añadió**: sus pestañas funcionaban, pero
   no había forma de saber cuál estaba activa, ni subrayado ni nada. Lo vio el organizador en pantalla.

   Con `aria-selected` el problema desaparece por construcción en vez de por acordarse: un juego nuevo
   de pestañas se pinta solo, y de paso lo visible y lo que anuncia un lector de pantalla **no pueden
   discrepar**, que es lo que pasaba justo aquí.

   `aria-current="page"` es la segunda mitad de la misma regla, para las pestañas que son **enlaces de
   navegación entre páginas** —las tres pantallas de administración—: ahí `role="tab"` mentiría (promete
   un panel que cambia sin navegar), así que la activa la declara el atributo de un enlace, y esta regla
   la pinta igual. */
.mtg-pestanas .btn[aria-selected="true"],
.mtg-pestanas .btn[aria-current="page"] {
  --bs-btn-color: var(--bs-body-color);
  box-shadow: inset 0 -2px 0 0 var(--mtg-acento);
  font-weight: 600;
}

/* El ancho lo reparte `flex-fill` **del marcado**, no de aquí: Bootstrap lo declara con
   `!important` y le gana a cualquier `flex` de esta hoja. Aquí hubo un `flex: 0 0 auto` para
   escritorio que no pintaba nada — medido: las dos pestañas ocupaban 652 px de 1304 igual—,
   y se quitó en lugar de dejar una regla muerta que hacía creer lo contrario. */

@media screen and (max-width: 767.98px) {
  /* ---- El distintivo «abandonó» se esconde, y el tachado se queda de señal ----
     En la ficha de mesa el lado mide **109 px en móvil** y 250 en escritorio. La palabra «abandonó»
     ocupa 72 y **no encoge** —un distintivo con el texto en una línea no puede—, mientras que el
     nombre sí, porque es lo único flexible del lado. El resultado, medido: un «Alejandro Fernández»
     se quedaba en **dos caracteres**, «Al…», al lado de un distintivo que ocupaba dos tercios del
     hueco. Con «Ana», tres letras, ya se recortaba. Lo encontró una pasada de QA, no la pantalla.

     Se esconde **igual que el rótulo largo de la barra de acciones**: fuera de flujo y con
     `clip-path`, así que sigue siendo texto para el lector de pantalla y el nombre recupera el sitio
     —de 2 caracteres a 13, que es todo el que hay—. En escritorio no se toca: ahí caben los dos.

     La señal que se queda es **el tachado del nombre**, que ya estaba y tiene dos ventajas sobre el
     distintivo: es por jugador y no cuesta ancho. Se descartó abreviarlo a un «✕» (10 caracteres,
     pero es un icono sin rótulo, que es justo lo que se decidió no copiar de Tolaria) y bajarlo de
     línea (13 caracteres y la palabra entera, pero +24 px de alto por ficha con abandono). */
  /* ---- Cambiar de ronda: en móvil, un desplegable ----
     La franja de botones crece con el número de rondas y el ancho no. A 375 px caben **10**, y una liga
     de 24 jugadores tiene 23 rondas: medido, el documento pasaba a **765 px** y el navegador aleja la
     página entera, que es como se ve roto en un teléfono. El desplegable mide lo mismo con 3 rondas que
     con 39, se queda en una línea de 44 px y dice «Ronda 7 de 23» en vez de un «7» pelado.

     Y con eso el título de al lado sobra: repetirlo era el mismo defecto que se acaba de quitar del
     distintivo de estado. Se esconde con `clip-path`, no con `display: none`, porque **sigue siendo el
     encabezado de la sección** para un lector de pantalla. */
  /* ---- Las tres pestañas del listado, apretadas para que quepan en una fila ----
     A 375 px el hueco es de 351 y las tres piden **437** con el relleno de escritorio, así que se
     partían en dos líneas dentro de cada botón y la fila medía **86 px**. Bajando a 0,85 rem de letra
     y 0,35 de relleno entran en una sola de 44.

     El número está **medido contra el peor caso y no contra los datos de hoy**: con las cifras de una
     sola cifra aguantaban valores más cómodos (0,9 rem), pero en cuanto un contador llega a dos
     dígitos vuelven a partirse. Comprobado con 9, 17 y 128 en las tres a la vez: solo esta pareja
     sobrevive a las tres. */
  .mtg-listado .mtg-pestanas .btn {
    padding: 0.45rem 0.35rem;
    font-size: 0.85rem;
  }

  .mtg-selector-rondas {
    display: none;
  }

  .mtg-titulo-de-ronda {
    position: absolute;
    clip-path: inset(50%);
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  .mtg-mesa .mtg-abandono-marca {
    position: absolute;
    clip-path: inset(50%);
    width: 1px;
    height: 1px;
    /* El relleno del distintivo impide bajar de 16×8 aunque la anchura sea de 1 px: con
       `box-sizing: border-box` el contenido no puede medir menos que cero, así que queda el relleno.
       Está fuera de flujo y recortado, o sea inofensivo, pero una caja en absoluto que mide más de lo
       que dice es la clase de cosa que aparece luego en un `scrollWidth` y no se entiende. */
    padding: 0;
    overflow: hidden;
  }

  .mtg-pestanas {
    margin-bottom: 0.85rem;
  }

  /* Lo único que cambia en móvil: llegan a los 44 px del dedo. La forma —subrayado en la
     activa— es la misma que en escritorio a propósito. Aquí la activa era un **botón relleno
     de amarillo** y se leía como «púlsame», que es lo que significa el amarillo en toda la
     aplicación. */
  .mtg-pestanas .btn {
    min-height: var(--mtg-toque);
  }

  /* La barra de juez pasa a ser una **botonera de icono y rótulo**, pegada abajo. `sticky`
     y no `fixed` a propósito: al llegar a su sitio natural del documento se queda ahí, no
     tapa el pie, y no hay que reservar hueco con un padding fantasma ni pelearse con
     `env(safe-area-inset-bottom)`.

     Antes era un `<details>` que se plegaba a 44 px porque desplegado medía 275 —un tercio
     de la pantalla— con los botones a fila completa. Con cuatro huecos en una fila mide ~60
     más la línea de estado, así que **ya no hace falta plegarla**: se fue el `<summary>`, y
     con él el estado en `sessionStorage` que `site.js` restauraba en cada intercambio. */
  .mtg-barra-acciones {
    position: sticky;
    bottom: 0;
    z-index: 1020;
    background: var(--bs-body-bg);
    box-shadow: 0 -0.35rem 0.85rem rgba(0, 0, 0, 0.25);
    padding: 0.5rem 0.5rem 0.35rem !important;
  }

  /* El título se queda para el lector de pantalla pero no gasta un renglón: `clip-path`
     como la cabecera de las tablas en modo ficha, no `display: none`. */
  .mtg-barra-acciones .mtg-barra-acciones-titulo {
    position: absolute;
    clip-path: inset(50%);
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  /* Cuatro huecos iguales, orden fijo. `grid` y no `flex` para que los botones midan lo
     mismo aunque los rótulos no: con `flex` el ancho lo decidiría el texto y el dedo
     tendría que aprender un objetivo distinto en cada estado. */
  .mtg-acciones {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 0;
  }

  .mtg-acciones .mtg-accion-boton {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    width: 100%;
    min-height: 3.5rem;
    padding: 0.4rem 0.15rem;
    border: 0;
    border-radius: var(--bs-border-radius);
    font-size: 0.6875rem;
    line-height: 1.15;
  }

  /* El icono solo existe en móvil: en escritorio los botones son texto. */
  .mtg-acciones .mtg-accion-icono {
    display: block;
    width: 1.375rem;
    height: 1.375rem;
  }

  /* ---- Un botón de la barra lleva UN rótulo, el mismo en los dos tamaños ----
     `mtg-accion-rótulo`, y no necesita reglas: se ve siempre.

     Hubo un mecanismo de **dos** rótulos, largo y corto, para cuando el de escritorio no cabía en los 75 px
     de móvil: el corto se enseñaba y el largo se escondía con `clip-path` para seguir siendo el nombre
     accesible. Se quitó al poner los rótulos enteros también en móvil, porque el corto tiraba justo el
     complemento que hace falta —«Emparejar» en vez de «Emparejar ronda 2», «Cerrar» en vez de «Cerrar la
     liga»— y porque, ya iguales, era **el rótulo escrito dos veces** y libre de separarse sin que nadie lo
     viera: solo se ve uno de los dos a la vez.

     Y no cuesta alto: los rótulos parten en dos líneas y el hueco ya medía dos. Medido, la barra se queda
     en 78 px con cuatro botones. La palabra más larga que existe, «inscripción», ocupa 54 px de los 70
     disponibles.

     Si algún día vuelve a hacer falta un rótulo distinto en móvil, la trampa está escrita: el `<span>` que
     se vea **no puede llevar `aria-hidden`**, porque el icono también está oculto y el botón se quedaría
     sin nombre accesible ninguno. */

  /* Los secundarios pierden el contorno: en una fila de cuatro, cuatro bordes hacen ruido y
     el hueco ya los separa. El principal conserva su relleno de acento, que es lo que lo
     distingue — y sigue siendo el único dorado. */
  .mtg-acciones .btn-outline-secondary.mtg-accion-boton,
  .mtg-acciones .btn-outline-danger.mtg-accion-boton {
    background: transparent;
  }
}

/* El porqué de una acción que falta. Vive **en el contenido y fuera de la barra**, justo encima:
   la barra lleva acciones y nada más.

   Estuvo dentro con dos partes, un resumen y un detalle, y las dos cosas estaban mal: ocupaba sitio
   fijo en una barra pegada, y el resumen **repetía lo que el distintivo de la cabecera ya dice**
   («Ronda 1 de 3 · 4 sin resultado»). Quedó solo lo que no está en ningún otro sitio. */
.mtg-nota-de-estado {
  color: var(--bs-secondary-color);
  font-size: 0.875rem;
  margin-bottom: 0;
}

/* La forma de **escritorio** de la misma barra: una fila de botones de texto, como siempre. Es el
   mismo marcado — el rótulo es el mismo arriba y abajo, igual que una tabla ancha sigue siendo una
   `<table>` y se vuelve fichas por debajo de 768 px.

   Va en su propio `@media` y no como regla base **a propósito**: el bloque de móvil está antes en
   el fichero, así que unas reglas base con la misma especificidad lo pisarían por orden de fuente.
   Pasó: la botonera salió en tres filas de 301 px. Acotando los dos lados, el orden deja de
   importar. */
@media (min-width: 768px) {
  /* El icono se apaga aquí y se vuelve a encender **dentro de `.mtg-acciones`**, unas líneas más abajo.
     Parece un rodeo y no lo es: la clase la usa además el campeón de una liga, donde no hay barra y sí
     tiene que seguir apagado en escritorio. */
  .mtg-accion-icono {
    display: none;
  }

  /* ---- El icono también en escritorio ----
     Lo pidió el organizador al ver las dos formas seguidas: en móvil cada botón llevaba icono y arriba
     no, así que el mismo botón se reconocía de dos maneras distintas según el tamaño. Con el icono en
     los dos, lo único que cambia entre formas es **cómo se apila**, que es la regla que ya sigue el
     resto de la aplicación.

     Solo se enciende dentro de `.mtg-acciones`: la clase la usa además el campeón de una liga, donde no
     hay barra y el `display: none` de arriba sigue valiendo.

     **1,125 rem = 18 px**, que es el tamaño de icono de escritorio que el proyecto ya fijó al arreglar
     el botón de imprimir; los 1,375 rem de la botonera de móvil aquí se comerían el alto del botón. Y
     el `flex: 0 0 auto` no es adorno: sin él el icono es un hijo flexible y se estruja antes que el
     texto cuando el rótulo es largo —«Emparejar ronda 2»—, que es justo al revés de lo que se quiere. */
  .mtg-acciones .mtg-accion-boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
  }

  .mtg-acciones .mtg-accion-icono {
    display: block;
    flex: 0 0 auto;
    width: 1.125rem;
    height: 1.125rem;
  }

  .mtg-acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  /* ---- Cambiar de ronda: la franja de botones es de escritorio ---- */
  .mtg-ir-a-ronda {
    display: none;
  }

  /* **Y puede saltar de línea.** Un `.btn-group` va en `nowrap` por defecto, así que la franja crecía
     a lo ancho sin techo: son 25,5 px por ronda y una liga tiene N−1 rondas, de modo que **a 992 px se
     rompía con 27 rondas y a 1280 con 35** — ligas de 28 y de 36 jugadores, nada exótico. Medido con
     el salto de línea: 23 rondas siguen en una fila a 992 px, y de 27 a 50 pasan a dos y ahí se quedan,
     así que deja de existir un número a partir del cual se rompe.

     El precio es cosmético y conocido: `.btn-group` redondea las esquinas del primero y del último del
     grupo, no de cada línea, así que el primer botón de la segunda fila tiene las esquinas izquierdas
     rectas. Se acepta a cambio de que no haya desbordamiento. */
  .mtg-selector-rondas {
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 0.25rem;
  }

  /* **Y los botones no se estiran.** `.btn-group > .btn` de Bootstrap lleva `flex: 1 1 auto`, así que al
     saltar de línea los que quedan sueltos se reparten el ancho sobrante: medido a 805 px con 23 rondas,
     los 4 de la segunda fila salían a **144 px cada uno** contra los 27-35 de arriba. Lo vio el
     organizador y describía justo eso.

     El `min-width` va un paso más allá de no estirarse: la primera fila **ya era irregular** —27 px los
     de una cifra y 35 los de dos—, así que igualándolos queda una rejilla uniforme en todas las filas en
     lugar de solo «las de abajo como las de arriba». 2,2 rem son los 35 px que ya medía el más ancho, o
     sea que no crece nada: solo deja de encoger el estrecho. */
  .mtg-selector-rondas > .btn {
    flex: 0 0 auto;
    min-width: 2.2rem;
  }
}

/* ============================================================================
   El grafo de fases del torneo
   ============================================================================
   Cuenta **dos cosas a la vez**, y por eso usa dos canales visuales distintos:

   - **La bola rellena** dice en qué fase está el torneo. Es un hecho, cambia poco.
   - **La pestaña con anillo** dice qué fase estás mirando. Es navegación.

   Si las dos usaran el mismo canal —dos adornos sobre la bola— no se podrían leer a
   la vez, que es justo el punto ciego de la referencia de la que salió esto.

   Y es navegación, no un mando: pulsar un nodo no mueve el torneo de fase.
   ============================================================================ */
.mtg-fases {
  display: flex;
  align-items: stretch;
  position: relative;
  gap: 0;
}

/* La línea que une los nodos, por detrás de las bolas. */
.mtg-fases::before {
  content: "";
  position: absolute;
  top: 1.85rem;
  left: 12%;
  right: 12%;
  height: 1.5px;
  background: var(--bs-border-color);
  z-index: 0;
}

.mtg-fase {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.7rem 0.25rem 0.6rem;
  border-radius: var(--bs-border-radius) var(--bs-border-radius) 0 0;
  text-decoration: none;
  color: var(--bs-secondary-color);
  min-width: 0;
}

.mtg-fase-bola {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--bs-border-color);
  background: var(--bs-body-bg);
  font-weight: 600;
  z-index: 1;
}

.mtg-fase-rótulo {
  font-size: 0.85rem;
  text-align: center;
  line-height: 1.25;
}

/* Fase que el torneo dejó atrás: se puede consultar, y se ve que se recorrió. */
.mtg-fase-pasada {
  color: var(--bs-body-color);
}

.mtg-fase-pasada .mtg-fase-bola {
  border-color: var(--mtg-acento);
  color: var(--mtg-acento);
}

/* Canal 1: donde está el torneo. Relleno macizo, que es lo que se ve de un vistazo. */
.mtg-fase-actual .mtg-fase-bola {
  background: var(--mtg-acento);
  border-color: var(--mtg-acento);
  color: var(--mtg-acento-texto);
}

.mtg-fase-actual .mtg-fase-rótulo {
  color: var(--mtg-acento);
  font-weight: 600;
}

/* Canal 2: lo que estás mirando. Pestaña unida al cuerpo, más anillo. */
.mtg-fase-mirando {
  background: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}

.mtg-fase-mirando .mtg-fase-bola {
  box-shadow: 0 0 0 3px var(--bs-secondary-bg), 0 0 0 4.5px var(--mtg-acento);
}

/* Fase por la que el torneo no va a pasar. El tachado es **solo visual**: el motivo va
   en el `title` y en un texto oculto, porque un lector de pantalla no anuncia un
   tachado. Sin frase añadida al lado: ocupaba demasiado. */
/* **Sin `opacity`**, y está medido: con `opacity: .5` el rótulo daba 3,48:1 en oscuro y
   2,97:1 en claro, por debajo del mínimo. La opacidad multiplica contra el fondo, que es
   justo el motivo por el que no se usa nunca para atenuar texto. La señal de «omitida»
   la dan el borde discontinuo y el tachado, que no cuestan contraste. */
.mtg-fase-omitida {
  color: var(--bs-secondary-color);
}

.mtg-fase-omitida .mtg-fase-bola {
  border-style: dashed;
  color: var(--bs-secondary-color);
}

.mtg-fase-omitida .mtg-fase-rótulo {
  text-decoration: line-through;
}

/* Fase futura: no hay nada que mirar todavía. No es un enlace, así que no se enfoca. */
.mtg-fase-cerrada {
  cursor: default;
}

a.mtg-fase:hover:not(.mtg-fase-mirando) {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

/* El cuerpo de la fase, pegado al grafo para que la pestaña parezca unida a él. */
.mtg-fase-cuerpo {
  background: var(--bs-secondary-bg);
  border-radius: 0 0 var(--bs-border-radius) var(--bs-border-radius);
  padding: 1rem;
}

/* La franja de características: siempre visible, siempre de solo lectura. Los controles
   para cambiarlas viven en la fase de inscripción, que es la única donde se pueden
   cambiar. */
.mtg-caracteristicas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1.1rem;
  margin: 0 0 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--bs-border-color);
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
}

.mtg-caracteristicas strong {
  color: var(--bs-body-color);
  font-weight: 600;
}

@media (max-width: 575.98px) {
  .mtg-fase-rótulo {
    font-size: 0.75rem;
  }

  .mtg-fase {
    padding-left: 0.1rem;
    padding-right: 0.1rem;
  }

  .mtg-fases::before {
    left: 14%;
    right: 14%;
  }
}

/* Quien abandonó, en la clasificación y en los pareos.

   El tachado va **solo sobre el nombre**, nunca sobre la fila: una línea encima de «3-0-0» o de
   «58,3» cuesta leerlas, y un cero tachado se parece a otra cosa.

   Y va **fino**, que es lo que se pidió y lo que hace que el nombre siga leyéndose. `line-through`
   pelado usa el grosor de la fuente; `text-decoration-thickness: 1px` lo fija, y
   `text-decoration-color` con el color secundario lo baja de intensidad sin tocar el del texto
   —bajar el del texto sería justo el fallo de contraste que estas convenciones prohíben—.

   Nunca es el único canal: al lado va el distintivo «abandonó en la N», con palabras. El tachado
   también marca el nodo omitido del grafo de fases, pero ahí significa «esta fase no existe» y el
   contexto no se confunde: son un rótulo de navegación y un nombre de persona. */
.mtg-abandonado {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--bs-secondary-color);
}

/* ============================================================================
   LA MESA COMO FICHA
   ============================================================================
   Los pareos **no son una tabla**, y esto sustituye a la variante compacta que lo
   intentaba. Un emparejamiento es una unidad, no una fila de celdas que se comparen
   con las de al lado; y para anidar franja, píldora y dos mitades dentro de un `<td>`
   había que pelearse con el layout de tabla.

   La clasificación sí sigue siendo una `<table>`: allí las nueve columnas se comparan
   **entre filas**, que es lo que hace tabular a una tabla.

   La forma es la misma en móvil y en escritorio; lo único que cambia es cuántas caben
   al lado. Y la ficha es la que reutilizará el cuadro del top, donde no hay tabla
   ninguna: por eso es un componente y no una media query.

   Cinco huecos, y cada uno resuelve algo que antes se apretaba:
     · franja arriba    → «Mesa 4», y a la derecha la fecha cuando exista el agendado
     · dos mitades      → nombre, corona del ganador y sus distintivos, con sitio
     · píldora central  → el ESTADO de la mesa; el marcador es su forma más común
     · renglón de abajo → lo que el marcador no puede decir
   ============================================================================ */
.mtg-mesas {
  display: grid;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

/* **`min-width: 0` en el elemento de la rejilla, o la pista crece con el nombre más largo.** El tamaño
   mínimo automático de un hijo de `grid` es su contenido mínimo, así que la columna se dimensionaba por la
   ficha peor: medido a 375 px, un grupo con «Bruno Gil Lopez» pedía **354 px de ficha en una pista de
   309** y otro con nombres cortos se quedaba en 320. Es la misma trampa que ya está escrita para el nombre
   dentro de la ficha —sin `min-width: 0` un hijo flexible no baja de su ancho de contenido y el `ellipsis`
   no se activa nunca—, un nivel más arriba y en `grid` en vez de `flex`.

   Venía de antes de que los grupos tuvieran caja y **se cortaba contra el borde de la pantalla**, que es
   por lo que no se había visto: la ficha se salía 11 px del panel y el nombre del segundo jugador se iba
   con ella. Al meter cada grupo en su caja la ficha empezó a cruzar un borde dibujado y se vio a la
   primera. */
.mtg-mesas > li {
  min-width: 0;
}

.mtg-mesa {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  padding: 0.35rem 0.6rem 0.45rem;
  /* Un toque no debe seleccionar el texto de dos fichas: el síntoma era una banda gris
     en varias a la vez. El nombre del jugador se deja seleccionable aparte. */
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Sin resultado: pide atención con el mismo velo del acento que el resto de la
   aplicación, no con una clase contextual de Bootstrap —esas fijan un fondo claro y
   dejan el texto del tema encima, ilegible en oscuro—. */
.mtg-mesa-pendiente {
  background: var(--mtg-atencion-fondo);
}

.mtg-mesa-franja {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.15rem;
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
}

/* Aquí hubo un ⚠ del peligro de corregir una ronda cerrada, primero dentro de la píldora
   —donde el acento lo volvía invisible— y luego en la franja. Se quitó de las dos: era una
   señal **pasiva** en un sitio que el juez no está mirando. Ese peligro se cobra ahora
   donde ocurre, con una confirmación al elegir el marcador, y la píldora lo insinúa con
   `.mtg-mesa-marcador-cerrada`. */

.mtg-mesa-cuerpo {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* Las dos mitades reparten el ancho a partes iguales y **no crecen con el nombre**:
   `flex: 1 1 0` con `min-width: 0` es lo que mantiene la píldora centrada aunque un
   lado se llame «Lim-Dûl» y el otro «José María Fernández». Sin el `min-width` un
   nombre largo empuja a la píldora fuera del centro. */
.mtg-lado {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem 0.35rem;
  border-radius: var(--bs-border-radius-sm);
}

.mtg-lado-derecho {
  justify-content: flex-end;
  text-align: right;
}

.mtg-lado-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Copiar un nombre sí tiene sentido, así que este trozo escapa del `user-select` de
     la ficha. */
  user-select: text;
}

/* ---- En móvil los dos nombres se apilan y la píldora se va al lado ----
   **El nombre disponía de 74,7 px de los 375**, o sea el 20 % de la pantalla, y ahí entran 7-8 caracteres:
   «Alejandro Fernández» se quedaba en «Alejand…» y con «Bruno Gil Lago» en «Bruno G…». Lo señaló el
   organizador.

   La salida **no es bajar la letra**, y está medido: de 16 px a 12 —un 25 % menos— se compran **4
   caracteres**, y de paso el nombre pasaría a ser lo más pequeño de la ficha, que es exactamente el error
   que ya se cometió en el cuadro impreso y hubo que deshacer. El problema no era el cuerpo de letra sino
   el reparto del ancho: en una fila, dos nombres y una píldora de 67 px se reparten 288.

   Apilados, cada nombre coge **el ancho entero menos la píldora**. Se hace con `grid` y colocación
   explícita, no con `flex-wrap`: la píldora tiene que ocupar **las dos filas** a la derecha —es el objetivo
   táctil y el estado de la mesa, así que sigue siendo lo primero que se ve y se toca— y eso una fila
   envuelta no lo da.

   Dos detalles que hacen falta: los dos lados se alinean **a la izquierda** (el derecho pierde su
   `flex-end`, que apilado dejaba un nombre a cada extremo y se leía como dos columnas), y va en
   `@media screen` porque al imprimir las media queries **miden la hoja** y allí la ficha se aplana a una
   línea por mesa. */
@media screen and (max-width: 767.98px) {
  .mtg-mesa-cuerpo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 0.4rem;
    row-gap: 0.1rem;
  }

  .mtg-mesa-cuerpo > .mtg-lado {
    grid-column: 1;
  }

  .mtg-mesa-cuerpo > .mtg-lado-derecho {
    grid-row: 2;
    justify-content: flex-start;
    text-align: left;
  }

  .mtg-mesa-cuerpo > .mtg-mesa-marcador {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}

/* El ganador: **corona y negrita, sin velo de fondo**. El velo estuvo primero y se quitó por
   redundante — con la corona al lado, teñir además la mitad era decir lo mismo dos veces, y
   el amarillo pasó a significar «esto se pulsa», que es lo que hace la píldora.

   Sigue sin depender del color: la corona lleva un «gana» oculto y el marcador está ahí. */
.mtg-lado-gana {
  font-weight: 600;
}

/* El bye no tiene segundo lado. El hueco se deja vacío en lugar de estirar el primero:
   así las mitades siguen alineadas con las de las fichas de al lado en la rejilla. */
.mtg-lado-vacio {
  padding: 0;
}

.mtg-corona {
  flex: none;
  color: var(--mtg-acento);
}

/* La píldora. Fondo sólido y no un borde: es el ancla visual de la ficha. Tabular para
   que «2 : 1» y «10 : 8» no bailen de ancho entre fichas.

   **El amarillo significa una sola cosa: esto se pulsa.** Es la regla que hace que el
   juez no tenga que aprenderse nada — si está en acento, se puede tocar; si no, no—.
   Por eso la píldora va en acento **tanto sin marcador como con él**, mientras la mesa
   sea editable: antes una mesa resuelta se pintaba en gris y no había forma de saber que
   se podía corregir. Y por eso el ganador dejó de llevar velo: el amarillo ya estaba
   diciendo otra cosa. */
.mtg-mesa-marcador {
  flex: none;
  min-width: 4.2rem;
  padding: 0.2rem 0.5rem;
  border: 0;
  border-radius: var(--bs-border-radius-sm);
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
}

button.mtg-mesa-marcador {
  position: relative;
  background: var(--mtg-acento);
  color: var(--mtg-acento-texto);
}

/* Bye o mesa bloqueada: **resaltada pero no amarilla**, porque su resultado no se puede
   cambiar. El relieve lo da el fondo terciario del tema, no un borde.

   La segunda regla es para una píldora que **sí es un botón pero no es editable**: se pulsa
   para saber por qué está bloqueada, no para cambiarla. Hace falta la especificidad de
   `button.…-fijo`, porque `button.mtg-mesa-marcador` pinta el acento y le gana a una clase
   sola — sin esto, una mesa bloqueada seguía saliendo amarilla y el amarillo mentía. */
.mtg-mesa-marcador-fijo {
  color: var(--bs-secondary-color);
  font-weight: 400;
}

button.mtg-mesa-marcador.mtg-mesa-marcador-fijo {
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  cursor: help;
}

/* Ronda cerrada con pareos posteriores: **acento en contorno**. Sigue diciendo «esto se
   pulsa» —la regla del amarillo no cambia— pero se lee como «esto está cerrado, tocarlo es
   deliberado». Un relleno más fuerte habría dicho lo contrario.

   El contorno con `box-shadow` interior y no con `border`: un borde suma 2 px al alto de la
   píldora y con ella a la ficha, y la lista dejaría de tener fichas iguales. */
button.mtg-mesa-marcador-cerrada {
  background: transparent;
  color: var(--mtg-acento);
  box-shadow: inset 0 0 0 1px var(--mtg-acento);
}

/* ---- La hora de una mesa ----
   Vive en el hueco derecho de la franja, que llevaba reservado y **vacío** desde que existe
   la ficha esperando al agendado. Es el mismo componente en las dos fichas —la de la fase de
   rondas y la del cuadro—, así que el estilo va una vez.

   **No va en acento**, y eso no contradice que el amarillo signifique «esto se pulsa»: la
   regla es que lo amarillo se pulsa, no que solo lo amarillo se pulse — la píldora de una
   mesa bloqueada ya era el precedente. Aquí además el acento pelearía con la píldora del
   resultado, que es la acción principal de la ficha; una franja de 12 px con dos amarillos
   no tendría jerarquía ninguna.

   Hereda el tamaño y el color de la franja: es un dato de la franja que además se pulsa. */
.mtg-mesa-hora {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  flex: none;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  white-space: nowrap;
}

button.mtg-mesa-hora {
  position: relative;
  border-radius: var(--bs-border-radius-sm);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 0.2em;
}

/* Sin hora, el rótulo es «Agendar» y ahí sí conviene que se lea como una acción: el subrayado
   punteado solo, sobre dos palabras cortas, se pierde en una franja de 12 px. */
.mtg-mesa-hora-vacia {
  font-weight: 600;
}

button.mtg-mesa-hora:hover,
button.mtg-mesa-hora:focus-visible {
  color: var(--bs-body-color);
}

/* Sin permiso o fuera de plazo: **el mismo sitio y el mismo dibujo, sin subrayado**. La hora se
   sigue viendo —es información del evento, igual que el número de mesa— y lo que desaparece es
   la forma de cambiarla. */
.mtg-mesa-hora-fija {
  text-decoration: none;
}

.mtg-icono-hora {
  width: 1em;
  height: 1em;
  /* La franja alinea por **línea base** y un SVG se apoya en ella, así que sin esto el icono
     queda montado sobre el texto. Es la misma corrección —y la misma cifra— que ya hizo falta
     en la celda de la medalla de la clasificación de liga y en `.mtg-icono-junto`. */
  vertical-align: -0.1em;
  flex: none;
}

/* El objetivo táctil es **la píldora**, no la ficha entera: pulsar cualquier parte de la
   caja abría el diálogo y resultaba desconcertante. Pero una píldora de ~27 px no llega
   al mínimo de 44 px del dedo, así que en puntero grueso se **agranda el área sin
   agrandar la píldora**: el pseudo-elemento se sale por arriba y por abajo hacia el
   relleno de la ficha, donde no hay nada que pulsar —el centro de la franja está libre y
   los nombres van a los lados—. Así el dedo tiene sus 44 px y la ficha no crece.

   Con ratón no hace falta: 27 px se aciertan de sobra, y el rectángulo invisible solo
   sería una forma de robar clics. */
@media (pointer: coarse) {
  /* Crecía 9 px por los cuatro lados y **arriba ya no está libre**: desde que la franja tiene la hora, esa
     expansión se metía 2,6 px dentro de su objetivo táctil —medido— y en esa banda el dedo abría el diálogo
     del resultado en vez del del horario. Arriba se queda en 6, que deja 0,4 px de holgura y mantiene el
     objetivo en **45,4 px**, por encima del mínimo. El comentario de arriba decía «donde no hay nada que
     pulsar»; era verdad y dejó de serlo. */
  button.mtg-mesa-marcador::after {
    content: "";
    position: absolute;
    inset: -6px -0.25rem -9px;
  }

  /* La hora, con el mismo mecanismo: el área crece hacia el relleno de la ficha y hacia el
     hueco entre fichas, sin que la franja crezca. Si creciera, la ficha entera subiría ~20 px
     y en el cuadro se llevaría por delante las tres cifras medidas de su geometría (93,97 la
     ficha, 70,19 la casilla vacía). */
  button.mtg-mesa-hora::after {
    content: "";
    position: absolute;
    inset: -13px -0.35rem;
  }
}

/* ---- El puesto, y quién entra en el cuadro ----
   El puesto en grande ocupando la línea, y a su izquierda «top» con la cifra debajo, en
   pequeño. Al ser pequeño no se confunde con el puesto, que es el número que manda.

   Sustituye a un velo de fondo en la fila y a un «top 4» debajo del número. El velo teñía
   media tabla, y la etiqueta debajo competía con el puesto por el mismo sitio.

   Dos señales que no se pisan: la **línea** dice dónde está el corte y la **etiqueta** dice
   quién entra. Hacen falta las dos porque con abandonos no coinciden — si el tercero
   abandonó, los cuatro de un top 4 llegan hasta el puesto 5, y él no lleva etiqueta. */
.mtg-puesto {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.mtg-puesto-numero {
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1;
  color: var(--bs-body-color);
  font-variant-numeric: tabular-nums;
}

.mtg-puesto-top {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.1rem 0.25rem;
  border-radius: var(--bs-border-radius-sm);
  /* **Fondo opaco y no un velo**, exactamente por lo mismo que el chip de semilla: un velo hereda lo
     que haya debajo, y aquí debajo puede haber el velo de atención de una fila. Medido sobre el velo,
     el acento daba **4,09 en oscuro y 4,28 en claro** —por debajo del 4,5 de un texto normal, y esto
     además se lee a 8,8 px—; con fondo opaco, **6,33 y 5,64**. Quitarlo del todo también pasaría
     (5,47 y 5,01, el mismo salto que dio la corona al perder su velo), pero se queda sin la forma de
     chip y sigue dependiendo de lo que tenga debajo. Y esto no es adorno: es la señal que dice quién
     entra en el corte. */
  background: var(--bs-tertiary-bg);
  color: var(--mtg-acento);
  font-size: 0.55rem;
  font-weight: 700;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.mtg-puesto-top > span {
  font-size: 0.7rem;
  letter-spacing: 0;
}

/* La línea de corte: va **debajo del último que entra**, así que su sitio se calcula en el
   servidor y no se puede desfasar de la etiqueta. En acento y de 2 px para que se distinga
   de las divisiones normales de la tabla. */
.mtg-línea-de-corte > * {
  border-bottom: 2px solid var(--mtg-acento) !important;
}

/* La semilla delante del nombre, solo en el cuadro. Ancho fijo para que los números de una
   y de dos cifras no desalineen los nombres de una columna. */
.mtg-puesto-chip {
  flex: none;
  min-width: 1.35rem;
  padding: 0 0.2rem;
  border-radius: var(--bs-border-radius-sm);
  /* Fondo **opaco** y no un velo. Con velo, el chip hereda lo que haya debajo, y encima del velo
     de atención de una ficha sin jugar se quedaba en **3,85 de contraste** — medido. Un velo sobre
     otro velo no se puede razonar: el color depende de la pila entera. */
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* ============================================================================
   EL CUADRO ELIMINATORIO
   ============================================================================
   Dos formas de la misma cosa, y el interruptor **no vuelve al servidor**: el marcado
   se pinta siempre por mitades y el CSS decide si van una detrás de otra (en línea) o
   enfrentadas con la final en medio (a dos lados). La preferencia la recuerda site.js
   en localStorage, como el tema.

   Las mesas de cada columna van **centradas frente al hueco entre las dos que las
   alimentan**, que es lo que hace legible el cruce: la semifinal aparece a media altura
   exacta entre sus dos cuartos. Sale de `justify-content: space-around` sobre una
   columna a la altura completa — sin trigonometría, y sobrevive a que una ficha crezca.

   Los **conectores** son pseudo-elementos con bordes, la técnica de referencia: sin SVG,
   sin posiciones absolutas y sin JavaScript. Dicen la **estructura** y van en neutro; el
   **resultado** lo dice la flecha del ganador, en acento. Separar las dos cosas es lo que
   evita un cuadro lleno de color donde no se distingue qué es dato y qué es adorno.
   ============================================================================ */
.mtg-cuadro-cabecera {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.mtg-cuadro {
  overflow-x: auto;
  padding-bottom: 0.5rem;
}

/* ---- Móvil: una sola columna, sin conectores ----
   A 375 px no caben dos lados ni tres columnas, y unas líneas que no llevan a ninguna
   parte visible son peor que ninguna.

   **Y se lee como el cuadro doblado, no «por rondas».** El orden lo pidió el organizador el 24 de agosto de
   2026, de arriba abajo: la mitad izquierda entera de fuera hacia dentro, la final —con el tercer y cuarto
   puesto si lo hay—, y la mitad derecha **de dentro hacia fuera**:

     Ronda de 32 · Ronda de 16 · Cuartos · Semifinales · **FINAL (+ 3.º y 4.º)** · Semifinales · Cuartos ·
     Ronda de 16 · Ronda de 32

   Así que **los rótulos repetidos son intencionados**: es el espejo, y cada mitad dice de qué ronda es. Este
   documento afirmaba lo contrario —que la repetición era el defecto y que había que agrupar por rondas— y era
   una conclusión nuestra, no suya; queda retirada.

   Lo que sí estaba mal es el **orden interno de la mitad derecha**, que salía de fuera hacia dentro (32, 16,
   cuartos, semis) en vez de al revés, y que el **tercer puesto caía al final de todo** en vez de junto a la
   final. Medido en `Cuadro top 32` a 375 px antes del arreglo: 9 rótulos con la mitad derecha del revés. */
.mtg-cuadro-mitad,
.mtg-cuadro-columna {
  display: flex;
  flex-direction: column;
}

.mtg-cuadro-titulo {
  margin: 0 0 0.5rem;
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.mtg-cuadro-mesas {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0 0 1rem;
}

.mtg-cuadro-centro {
  margin-bottom: 1rem;
}

/* El partido por el tercer puesto, **fuera de la rejilla**: no forma parte de la llave, de él no sale
   ningún conector, y dentro de la columna central movería el punto medio de la final —que es donde
   apuntan los codos de las semifinales—. Ancho de una ficha del cuadro para que se lea como una más. */
.mtg-cuadro-tercero {
  margin-top: 1.5rem;
  max-width: 16rem;
}

/* ---- El espejo del móvil: la mitad derecha del revés y el tercer puesto junto a la final ----
   El truco es **`display: contents` en el cuadro**, que en móvil no pierde nada —ahí no hay rejilla, ni
   conectores, ni scroll horizontal (medido: `scrollWidth == clientWidth == 375`)— y a cambio saca sus tres
   hijos al mismo contenedor flexible que el tercer puesto. Sin eso no hay forma de meterlo **entre** la final
   y la mitad derecha: vive fuera del cuadro a propósito, así que `order` no lo alcanzaría.

   Y vive fuera por un motivo que sigue vigente en escritorio y **que estas reglas no tocan**: dentro de la
   columna central movería el punto medio de la final, que es donde apuntan los codos de las semifinales.

   Los `order` van a partir de 1 porque **el valor por defecto es 0**: así la cabecera y el interruptor, que
   no lo declaran, se quedan delante sin tener que enumerarlos. La barra de acciones va detrás de todo. */
@media (max-width: 991.98px) {
  #mtg-cuadro-fragmento {
    display: flex;
    flex-direction: column;
  }

  .mtg-cuadro {
    display: contents;
  }

  .mtg-cuadro-mitad-a {
    order: 1;
  }

  .mtg-cuadro-centro {
    order: 2;
  }

  .mtg-cuadro-tercero {
    order: 3;
  }

  /* De dentro hacia fuera: semifinales, cuartos, ronda de 16, ronda de 32. Cada columna conserva su
     rótulo arriba, que es lo que hace legible el espejo. */
  .mtg-cuadro-mitad-b {
    order: 4;
    flex-direction: column-reverse;
  }

  #mtg-cuadro-fragmento > mtg-barra-acciones,
  #mtg-cuadro-fragmento > .mtg-barra-acciones {
    order: 5;
  }
}

/* El interruptor de forma **no se ofrece en móvil**: ahí el cuadro es siempre una columna,
   así que pulsarlo no haría nada. Un control sin efecto es peor que su ausencia. */
[data-mtg-cuadro-forma] {
  display: none;
}

@media (min-width: 992px) {
  [data-mtg-cuadro-forma] {
    display: inline-block;
  }
}

.mtg-cuadro-pendiente {
  margin: 0;
  padding: 0.75rem;
  border: 1px dashed var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  color: var(--bs-secondary-color);
  font-size: 0.85rem;
}

.mtg-cuadro-ganador {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--mtg-acento);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-atencion-fondo);
}

/* ============================================================================
   LA FICHA DE UN CRUCE
   ============================================================================
   Los dos jugadores **apilados** y cada uno con **su** marcador en el borde derecho,
   como en los cuadros oficiales. No es capricho: en una columna de cuadro —estrecha por
   construcción— la ficha horizontal dejaba el nombre en 15 px de los 32 que necesita.
   ============================================================================ */
.mtg-cruce {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  overflow: hidden;
  background: var(--bs-body-bg);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* La franja del número de mesa, cruzando las dos columnas de la ficha. Misma forma que la de la fase
   de rondas: el número a la izquierda y el hueco de la fecha a la derecha, vacío hasta que exista el
   agendado. Cuesta 22 px de alto por ficha y se paga a cambio de que las dos fichas de la aplicación
   se lean igual. */
.mtg-cruce-franja {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin: 0;
  padding: 0.15rem 0.5rem;
  border-bottom: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
}

.mtg-cruce-pendiente {
  background: var(--mtg-atencion-fondo);
}

/* El hueco de un cruce sin decidir. Mismo tamaño que una ficha —el cuadro se pinta entero desde
   el corte, así que estas casillas son la mitad del cuadro durante casi todo el torneo— y en
   discontinuo, que dice «aquí falta algo» sin competir con el oro de lo que ya está decidido. */
.mtg-cruce-vacio {
  border-style: dashed;
  /* El color del borde **no** es el de un borde cualquiera: en una ficha vacía la línea es lo único
     que dice que ahí hay un hueco, así que es un gráfico con significado y se le piden 3:1.
     `--bs-border-color` daba **1,41 y 1,10** —medido, el mismo fallo que tuvieron los conectores—;
     con el color de texto secundario, 5,76 y 6,17. */
  border-color: var(--bs-secondary-color);
  background: none;
  color: var(--bs-secondary-color);
}

/* Longhands, y no `border-style: dashed`. **`border-width` vale `medium` —3 px— por defecto** y solo
   computa a 0 cuando el estilo es `none`, así que el atajo resucitaba a 3 px los tres lados que
   nunca declararon anchura: la ficha vacía medía 73 px donde la de verdad mide 70, y el hueco
   cambiaba de forma al llenarse. Medido, no visto. */
.mtg-cruce-vacio .mtg-cruce-lado + .mtg-cruce-lado {
  border-top-style: dashed;
  border-top-color: var(--bs-secondary-color);
}

/* Quien ya se ganó el sitio se lee **con el color del cuerpo**, no atenuado como el resto del hueco. La
   ficha entera va apagada porque no hay nada que jugar, pero el nombre que ya se sabe es justamente el
   dato que se busca al acabar una mesa: apagarlo igual que «por decidir» lo escondía. */
.mtg-cruce-vacio .mtg-cruce-lado:not(.mtg-cruce-lado-vacio) .mtg-cruce-nombre {
  color: var(--bs-body-color);
}

/* La franja de un hueco vacío no lleva fondo: con él parecía una ficha de verdad a medio cargar.

   Y **solo el borde de abajo**, que es el único que declara anchura. Aquí volvió a morder lo de siempre:
   con `border-top-style` la franja resucitaba un borde superior de `medium` —3 px— y la ficha vacía
   medía 97 en vez de 94. Segunda vez en la misma sesión. */
.mtg-cruce-vacio .mtg-cruce-franja {
  border-bottom-style: dashed;
  border-bottom-color: var(--bs-secondary-color);
  background: none;
}

.mtg-cruce-vacio .mtg-cruce-marcador {
  border-left-style: dashed;
  border-left-color: var(--bs-secondary-color);
}

.mtg-cruce-vacio .mtg-cruce-marcador {
  background: none;
}

/* La final pesa más que un cuartos, y hasta ahora no: todas las cajas eran iguales y eso
   era media razón de que el cuadro pareciera soso. */
.mtg-cruce-final {
  border-color: var(--mtg-acento);
  box-shadow: 0 0 0 1px var(--mtg-acento);
}

.mtg-cruce-lados {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mtg-cruce-lado {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.5rem;
  min-width: 0;
  min-height: 2rem;
}

.mtg-cruce-lado + .mtg-cruce-lado {
  border-top: 1px solid var(--bs-border-color);
}

/* ---- Quien pasa se lleva su fila entera ----
   Y esto **devuelve al acento su único significado**, que es lo que estaba mal antes: la caja de
   marcador decía a la vez «se pulsa» y «ganó éste», y por eso se leía turbia. Ahora cada objeto
   dice una cosa — la caja, que se pulsa; la fila, quién ganó.

   El premio no era el objetivo y es lo mejor del cambio: la fila del ganador, la línea que sale de
   ella y la caja de la ronda siguiente quedan todas en oro y **seguidas**, así que el camino del
   campeón se lee como un hilo continuo por todo el cuadro. Un mismo idioma en vez de tres marcas
   distintas.

   Cuarto intento y van tres descartados por sutiles: un triangulito `▸` al final de la línea (se
   perdía), una barra de acento de 3 px al principio (no gustó) y la cifra sola (no se veía). El
   patrón estaba claro. */
.mtg-cruce-gana {
  background: var(--mtg-acento);
  color: var(--mtg-acento-texto);
  font-weight: 600;
}

/* El chip de semilla sobre fila dorada. Se compone **con** el acento y no con un velo encima: así el
   color resultante es opaco por construcción y se puede medir, que es la lección de las dos capas
   translúcidas.

   Y se mezcla con `--bs-body-color`, no con `--mtg-acento-texto`, aunque el segundo parezca lo
   natural: el texto del chip **es** `--mtg-acento-texto`, así que acercar el fondo a ese color resta
   contraste en los dos temas. Medido: daba 4,04 en claro. `--bs-body-color` es justo el contrario
   del texto del acento en ambos temas —claro donde el otro es oscuro—, así que separa en vez de
   juntar, sin necesidad de un valor por tema. */
.mtg-cruce-gana .mtg-puesto-chip {
  background: color-mix(in srgb, var(--bs-body-color) 18%, var(--mtg-acento));
  color: var(--mtg-acento-texto);
}

/* De qué grupo viene el jugador, dentro del chip del puesto: `1 G4`. **Se quita al imprimir** —ver el
   bloque de impresión—, porque en papel la columna de un top 32 mide 28 mm y el chip ya se lleva 14 px de
   los 111: doblarlo se comería el nombre, que es el dato. En pantalla no hay ese problema. */
.mtg-puesto-grupo {
  font-weight: 400;
}

.mtg-cruce-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: text;
}

/* La corona del campeón dentro de la final: ahí no hay dónde pasar, así que en vez de la marca de
   «avanza» va la corona.

   El `color: inherit` no es cosmética: la corona se pinta con `currentColor` y por defecto lleva el
   acento, así que sobre la fila dorada del ganador quedaba **oro sobre oro — invisible**, con 1,00
   de contraste medido. Y una corona que no se ve no da error: el SVG carga perfectamente. Sobre la
   fila del ganador tiene que ir en el color de esa fila, como el nombre. */
.mtg-cruce .mtg-corona {
  margin-left: auto;
  color: inherit;
}

.mtg-cruce-lado-vacio {
  color: var(--bs-secondary-color);
  font-style: italic;
}

/* ---- El marcador: la caja entera dice «esto se pulsa» ----
   Dos celdas en el borde derecho, cada una alineada con su jugador, y **un solo botón** aunque
   enseñe dos cifras. Va en acento **si es editable**, con resultado y sin él, que es la misma regla
   que la píldora de la fase de rondas: el amarillo significa una cosa en toda la aplicación.

   Aquí hubo una excepción declarada —acento por resultado, la cifra del ganador dorada y la del
   perdedor oscura— y **se ha retirado**: quien gana se marca en su fila, así que la caja ya no
   tiene que decir dos cosas. */
.mtg-cruce-marcador {
  display: grid;
  grid-template-rows: 1fr 1fr;
  align-self: stretch;
  min-width: 2.2rem;
  border: 0;
  border-left: 1px solid var(--bs-border-color);
  background: var(--mtg-acento);
  color: var(--mtg-acento-texto);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.mtg-cruce-marcador > span {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.4rem;
}

/* El separador entre las dos cifras, sobre el acento: sin él las dos cifras de un `2 1` se leen
   como un número de dos dígitos. */
.mtg-cruce-marcador > span + span {
  border-top: 1px solid color-mix(in srgb, var(--mtg-acento-texto) 25%, transparent);
}

/* Lo que **no** se puede pulsar —un bye, una mesa bloqueada por abandono, un torneo terminado—
   va resaltado pero **no amarillo**, igual que en la fase de rondas. Y el marcador se lee con el
   color del cuerpo, no con el secundario: es un dato, no una anotación. */
.mtg-cruce-marcador-fijo {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

/* Y con la misma especificidad que en la fase de rondas, por el mismo motivo: una mesa del cuadro
   bloqueada **es un botón** —se pulsa para saber por qué— pero no puede salir en acento, que significa
   «esto se puede cambiar». `button.mtg-cruce-marcador` le ganaría a la clase sola. */
button.mtg-cruce-marcador.mtg-cruce-marcador-fijo {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  cursor: help;
}

button.mtg-cruce-marcador.mtg-cruce-marcador-fijo > span + span {
  border-top-color: var(--bs-border-color);
}

.mtg-cruce-marcador-fijo > span + span {
  border-top-color: var(--bs-border-color);
}

button.mtg-cruce-marcador {
  cursor: pointer;
}

button.mtg-cruce-marcador:hover,
button.mtg-cruce-marcador:focus-visible {
  box-shadow: inset 0 0 0 2px var(--mtg-acento-vivo);
}

.mtg-cruce-nota {
  grid-column: 1 / -1;
  margin: 0;
  padding: 0.2rem 0.5rem 0.3rem;
  border-top: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
  text-align: center;
}

/* ---- El objetivo táctil, igual que en la fase de rondas ----
   La caja de marcador mide ~64 px de alto en total pero cada celda ~32, y lo que se pulsa
   es el botón entero, así que ya pasa de 44. No hace falta agrandar nada. */

/* ============================================================================
   ESCRITORIO: LAS DOS FORMAS
   ============================================================================
   `print` en la lista de medios, y no es un adorno: **al imprimir, las media queries miden la
   hoja**, no la ventana. Un A4 vertical son ~700 px de CSS y un horizontal ~1050, así que dejando
   esto solo en `min-width: 992px` la impresión salía **en la forma de una columna** — seis hojas de
   un top 32 con las mesas apiladas—. Lo descubrió el organizador imprimiendo, no yo, y le pasó dos
   veces porque la primera lo tapé con un zoom que iba por otro lado.

   Con `print` en la lista, en papel se aplica siempre la forma de escritorio y el ancho de la hoja
   deja de decidir la maqueta. Es la misma lección que arriba con las tablas, del revés: el modo
   ficha es **de pantalla** (`@media screen and (max-width: …)`) y esto es **de pantalla ancha y de
   papel**. */
@media print, (min-width: 992px) {
  /* ---- Cada mesa ocupa un hueco de altura igual ----
     Es lo que hace que los conectores sean exactos sin una sola cuenta, y sustituye a un
     `justify-content: space-around` que los rompía. El razonamiento:

     Una columna con la mitad de mesas que la anterior reparte la misma altura entre la mitad
     de huecos, así que **el hueco de una mesa cubre exactamente los dos huecos de las mesas
     que la alimentan**. Su centro cae en la frontera entre esos dos, que es justo el punto
     medio de la pareja.

     Con eso, el codo mide `50%` **del hueco** y siempre acierta. Antes medía 50% de la ficha,
     que solo coincide en la primera columna: medido en un top 32, el codo necesitaba 39, 78 y
     157 px por ronda y media siempre 39. De ahí las líneas cortadas.

     El aire entre fichas lo da el relleno del hueco, no un `gap`: un `gap` restaría altura al
     reparto y descuadraría el 50%. */
  .mtg-cuadro-mesas {
    flex: 1 1 auto;
    gap: 0;
    margin-bottom: 0;
  }

  .mtg-cuadro-hueco {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    padding: 0.25rem 0;
  }

  /* **La ficha llena su hueco a lo ancho**, y esto no es estética: el codo sale de `left: 100%`
     del hueco, así que si la ficha no llega al borde, la línea arranca en el aire. Medido en un
     top 32: hueco de 256 px, ficha de 104 → el conector nacía **152 px** a la derecha de la caja
     de la que decía salir y aterrizaba pegado a la columna siguiente, sin tocar nada. Un flex
     hijo se queda en su ancho de contenido por defecto, y con nombres cortos («J04») eso es un
     tercio de la columna. */
  .mtg-cuadro-hueco > .mtg-cruce {
    flex: 1 1 auto;
    min-width: 0;
  }

  .mtg-cuadro-columna {
    flex: 0 0 16rem;
    min-width: 16rem;
  }

  /* La final es **una columna más**: su rótulo arriba, en la misma línea que «SEMIFINALES» y
     «CUARTOS DE FINAL». Antes el bloque centraba todo su contenido en vertical y el rótulo bajaba
     con la ficha, así que la final era la única ronda sin título visible arriba. La ficha se
     centra sola en lo que queda, con márgenes automáticos. */
  .mtg-cuadro-centro {
    display: flex;
    flex-direction: column;
    flex: 0 0 16rem;
    min-width: 16rem;
    margin-bottom: 0;
  }

  .mtg-cuadro-centro > .mtg-cruce,
  .mtg-cuadro-centro > .mtg-cuadro-pendiente {
    margin-block: auto;
  }

  /* ---- En línea: todas las rondas de izquierda a derecha ----
     Las dos mitades se disuelven con `display: contents` y cada columna se coloca en su
     ronda con `grid-column`, así que la mitad A y la mitad B de la misma ronda caen en la
     misma columna, una encima de otra. Es exactamente el orden de un cuadro en línea, y
     sale del mismo marcado que la forma a dos lados.

     **Los rótulos son una fila propia de la rejilla** (`auto`), no un trozo del alto de cada
     columna, y eso no es maquetación: es lo que hace exacto el conector de la última columna. Con
     el rótulo dentro, la zona de contenido de la mitad A empezaba media cabecera más abajo que la
     de la final, y el codo de la semifinal se quedaba corto por **media altura de rótulo** — la
     línea moría a media calle antes de llegar a la final. Sacándolo, las tres zonas arrancan a la
     misma altura y el `50%` del hueco vuelve a acertar sin una sola cuenta, igual que en el resto
     del cuadro. Las columnas lo consiguen con `subgrid`: heredan la fila del rótulo y la de su
     contenido de la rejilla de arriba. */
  .mtg-cuadro[data-mtg-cuadro="linea"] {
    display: grid;
    grid-template-rows: auto 1fr 1fr;
    gap: 0 1.5rem;
    align-items: stretch;
  }

  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-mitad {
    display: contents;
  }

  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-columna {
    grid-column: var(--ronda);
  }

  /* La mitad de arriba ocupa la fila del rótulo y la suya. */
  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-mitad-a .mtg-cuadro-columna {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: 1 / 3;
  }

  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-mitad-b .mtg-cuadro-columna {
    grid-row: 3;
  }

  /* El rótulo de ronda solo una vez: en la mitad de abajo sería el mismo repetido. Va con
     `display: none` y no con `visibility: hidden`, que seguía **ocupando** el alto de una cabecera
     dentro de la fila de la mitad B y desigualaba las dos mitades. */
  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-mitad-b .mtg-cuadro-titulo {
    display: none;
  }

  /* La final: rótulo en la fila de rótulos y ficha centrada en las dos filas de las mitades, que es
     exactamente el punto medio de las dos semifinales. */
  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-centro {
    display: grid;
    grid-template-rows: subgrid;
    grid-column: var(--ronda);
    grid-row: 1 / -1;
  }

  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-centro > .mtg-cruce,
  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-centro > .mtg-cuadro-pendiente {
    grid-row: 2 / 4;
  }

  /* ---- A dos lados: la final en el centro ----
     La mitad B se dibuja en espejo, así que su cuadro «crece» hacia el centro. Reduce el
     ancho a la mitad, que es lo que hace legible un top 16 o 32. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] {
    display: flex;
    gap: 1.5rem;
    align-items: stretch;
  }

  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad {
    display: flex;
    flex-direction: row;
    gap: 1.5rem;
  }

  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b {
    flex-direction: row-reverse;
  }

  /* En espejo, el marcador va al borde izquierdo y la flecha apunta hacia el centro. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cruce {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cruce-lados {
    grid-column: 2;
  }

  /* `grid-row: 2` y no 1: la fila 1 es la franja del número de mesa. Con el 1 heredado de antes de la
     franja, el marcador se metía en la fila de la franja y la ficha del espejo pasaba de 94 a 146 px de
     alto — medido. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cruce-marcador {
    grid-column: 1;
    grid-row: 2;
    border-left: 0;
    border-right: 1px solid var(--bs-border-color);
  }

  /* En espejo el número de mesa va también al otro lado, para que quede en el borde de arranque. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cruce-franja {
    flex-direction: row-reverse;
  }

  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b button.mtg-cruce-marcador {
    border-right-color: var(--mtg-acento);
  }

  /* Aquí iba la barra del que pasa por el borde derecho, para la mitad en espejo. Sobra desde que
     la fila entera va en acento: un relleno no tiene lado. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cruce .mtg-corona {
    margin: 0 auto 0 0;
  }

  /* ---- Los conectores ----
     Un codo por mesa, dibujado con **dos bordes de una sola caja**: `border-top` traza el
     tramo horizontal que sale del centro de la ficha y `border-right` baja por el extremo
     hasta el punto medio de la pareja. La mesa de abajo hace el espejo vertical
     (`border-bottom` + `border-right`), así que las dos juntas forman la llave completa.

     Y la mesa de la ronda siguiente pone su propio **tramo de entrada** con `::before`, que
     es lo que cierra el hueco: sin él la llave moría a media calle. Se vio midiendo — la
     vertical llegaba al punto medio correcto y se quedaba a 12 px de la ficha siguiente.

     Pseudo-elementos y bordes: sin SVG, sin JavaScript y sin geometría calculada. La altura
     del codo es `50% + medio hueco`, que es exactamente la distancia del centro de la ficha
     al punto medio de su pareja.

     El color es el del texto secundario y no `--bs-border-color`: ese daba **1,41 de
     contraste** —medido— y una línea que no se ve no hace legible nada. Un conector es un
     gráfico con significado, así que se le pide 3:1; así pasa de 5,7. Y sigue siendo neutro
     porque el acento está reservado a la flecha del que pasa: la línea dice la estructura,
     el color dice el resultado. */
  /* El color de la línea es **una variable en el hueco**, no un `border-color` en el
     pseudo-elemento, y eso no es estilo: es lo único que funciona. Los tramos del codo se
     declaran con los atajos `border-top` / `border-right` / `border-bottom`, que llevan el color
     dentro, y sus selectores —`.mtg-cuadro-mitad .mtg-cuadro-hueco:nth-child(odd)::after`— son
     más específicos que cualquier `.mtg-hilo-ganador::after`. El resultado, medido: la vertical
     del ganador salía en oro y **el brazo horizontal que sale de su ficha seguía gris**, y la
     línea de la semifinal a la final —que es solo brazo— salía gris entera. Con la variable la
     cascada se resuelve en el hueco y ya no hay carrera de especificidad. */
  .mtg-cuadro-hueco {
    position: relative;
    --mtg-hilo: var(--bs-secondary-color);
  }

  .mtg-cuadro-hueco.mtg-hilo-ganador {
    --mtg-hilo: var(--mtg-acento);
  }

  /* **Todas** las mesas de una mitad sacan su codo, incluida la última columna: su destino es la
     final, que vive fuera de la mitad. Esto llevaba `:not(:last-child)` y el resultado fue que
     las semifinales se quedaban sin conectar con la final — se vio en pantalla, no compilando.

     Y no hace falta excluir la final: no está dentro de ninguna mitad, así que esta regla no la
     alcanza. */
  .mtg-cuadro-mitad .mtg-cuadro-hueco::after {
    content: "";
    position: absolute;
    left: 100%;
    width: 0.75rem;
    /* 50% **del hueco**, no de la ficha: el hueco cubre a las dos mesas alimentadoras, así que
       la mitad de su altura es exactamente la distancia de su centro al punto medio. */
    height: 50%;
    border-right: 2px solid var(--mtg-hilo);
  }

  .mtg-cuadro-mitad .mtg-cuadro-hueco:nth-child(odd)::after {
    top: 50%;
    border-top: 2px solid var(--mtg-hilo);
  }

  .mtg-cuadro-mitad .mtg-cuadro-hueco:nth-child(even)::after {
    bottom: 50%;
    border-bottom: 2px solid var(--mtg-hilo);
  }

  /* Una columna con **una sola mesa** —la última de cada mitad— no forma pareja con nadie, y a dónde
     apunta su codo depende de la forma del cuadro:

     - **A dos lados** la final está a su misma altura, así que es solo el tramo horizontal. Sin
       esto, la vertical de una semifinal única apuntaba a un sitio donde no hay nada.
     - **En línea** la final está en el medio de las dos mitades, así que hace falta codo de verdad:
       la mitad de arriba baja y la de abajo sube. Esta regla se aplicaba en las dos formas, y en
       línea era la causa de que la línea de la semifinal saliera recta y muriera en el aire a media
       distancia de la final.

     La mitad de arriba ya lo hace bien con la regla general —es hija única, luego también impar—;
     la de abajo necesita el espejo vertical, y va justo debajo. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad .mtg-cuadro-hueco:only-child::after {
    height: 0;
    border-right: 0;
    border-bottom: 0;
    top: 50%;
    bottom: auto;
    border-top: 2px solid var(--mtg-hilo);
  }

  /* En línea, la semifinal de la mitad de abajo tiene la final **encima**, así que su codo sube. Es
     hija única y por tanto impar, así que la regla general la manda hacia abajo: aquí se le da la
     vuelta. */
  .mtg-cuadro[data-mtg-cuadro="linea"] .mtg-cuadro-mitad-b .mtg-cuadro-hueco:only-child::after {
    top: auto;
    bottom: 50%;
    border-top: 0;
    border-bottom: 2px solid var(--mtg-hilo);
  }

  /* ---- El hilo del que pasa ----
     La línea que sale de una mesa **resuelta** va en acento, así que el recorrido del torneo se
     dibuja en oro a medida que se juega y lo que queda por jugar se queda en gris. La clase la pone
     el servidor mirando quién ganó, no un `:has()`: así la regla es la misma que decide el campeón.

     El tramo de entrada de una mesa va siempre en acento porque **una mesa solo existe cuando sus
     dos alimentadoras se resolvieron** — emparejar la ronda siguiente es lo que la crea—, de modo que
     su línea de entrada siempre forma parte de un camino ya decidido. Por eso el `::before` lleva
     el acento directamente y no `--mtg-hilo`: no depende de quién ganó **esta** mesa.

     Aquí había una lista de selectores con `border-color` que no pintaba nada: los tramos se
     declaran más abajo con atajos `border-*` de la misma especificidad y, al ir después, ganaban.
     Un `border-color` puesto antes de un `border-top` es como no ponerlo. */

  /* ---- El camino de un jugador ----
     Idea tomada de Tolaria: al pulsar a alguien se resalta **todo su recorrido** por el cuadro, que
     es la pregunta que uno se hace mirando un top 32. Se atenúa lo demás en lugar de encender lo
     suyo: encender competiría con el acento, que ya significa otras dos cosas aquí. */
  .mtg-cuadro-siguiendo .mtg-cruce {
    opacity: 0.45;
    transition: opacity 0.12s ease-in-out;
  }

  .mtg-cuadro-siguiendo .mtg-cruce:has(.mtg-cruce-seguido) {
    opacity: 1;
  }

  /* El tramo de entrada de la ronda siguiente. */
  .mtg-cuadro-columna:not(:first-child) .mtg-cuadro-hueco::before,
  .mtg-cuadro-centro .mtg-cruce::before {
    content: "";
    position: absolute;
    top: 50%;
    right: 100%;
    width: 0.75rem;
    border-top: 2px solid var(--mtg-acento);
  }

  .mtg-cuadro-centro .mtg-cruce {
    position: relative;
  }

  /* ---- En espejo, todo por el otro lado ----
     **Acotado a `doslados`**, y eso era un fallo: sin el acotado, la mitad B sacaba sus conectores
     por la izquierda también en la forma en línea, donde las dos mitades fluyen hacia la derecha.
     El resultado eran líneas apuntando hacia fuera del cuadro en la mitad de abajo. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cuadro-hueco::after {
    left: auto;
    right: 100%;
    border-right: 0;
    border-left: 2px solid var(--mtg-hilo);
  }

  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cuadro-hueco:only-child::after {
    border-left: 0;
  }

  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-mitad-b .mtg-cuadro-columna:not(:first-child) .mtg-cuadro-hueco::before {
    right: auto;
    left: 100%;
  }

  /* La final recibe por los dos lados cuando el cuadro va a dos lados, y solo por la
     izquierda cuando va en línea. */
  .mtg-cuadro[data-mtg-cuadro="doslados"] .mtg-cuadro-centro .mtg-cruce::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 100%;
    width: 0.75rem;
    border-top: 2px solid var(--mtg-acento);
  }
}

.mtg-mesa-explicacion {
  margin: 0.15rem 0 0;
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
  text-align: center;
}

/* Dos por fila desde 992 px y tres desde 1400. Es lo que la pestaña a todo el ancho
   hace posible: a media pantalla no cabían. */
@media (min-width: 992px) {
  .mtg-mesas {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1400px) {
  .mtg-mesas {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---- Los botones de marcador del diálogo de resultado ----
   Altura generosa **en ratón y en táctil**, no solo con puntero grueso. Aquí no se
   aplica el criterio de las tablas densas: el diálogo existe para tomar UNA decisión y
   hay pantalla de sobra, así que no hay nada que apretar. Medidos en 38 px con los
   tamaños por defecto de Bootstrap, que para el gesto más repetido de la aplicación
   —quince veces por ronda— es poco. */
.mtg-boton-marcador {
  min-height: 3.25rem;
  font-size: 1.15rem;
  font-weight: 600;
}

/* ============================================================================
   Tablas que se convierten en fichas en pantalla estrecha
   ============================================================================
   El HTML sigue siendo una `<table>`, que es lo correcto para una tabla: se lee
   igual con un lector de pantalla y no hay marcado duplicado. Lo que cambia por
   debajo del punto de ruptura es cómo se dibuja cada fila.

   El motivo, medido en un viewport de 390 px con la clasificación: ocho columnas
   necesitaban 421 px y solo había 366, así que las filas se partían y crecían a
   81 px de alto. Y con un nombre real —«Sin Yuanes No Hay Paraíso»— hacían falta
   548: no es que sobre una columna, es que **una tabla de ocho columnas no es el
   formato de un móvil**. Quitar la columna redundante dejaba la tabla todavía
   84 px corta.

   Cómo se usa: `mtg-tabla-fichas` en la tabla, `data-ficha-titulo` en la celda que
   manda —el nombre— y `data-etiqueta` en las que necesitan que se diga qué son,
   porque la cabecera deja de estar. Nada depende del orden ni del número de
   columnas: la fila de la ronda pierde una en solo lectura y sigue funcionando.
   ============================================================================ */
/* **Una tabla no repinta la superficie sobre la que se apoya.** Bootstrap pinta cada celda
   con `--bs-table-bg`, que en tema oscuro es `#212529` — más oscuro que el panel de la fase
   (`#343a40`)—, y en modo ficha cada celda es un bloque: el resultado eran rectángulos
   negros sobre el panel. Transparente, el panel se ve a través y la ficha es una pieza y no
   un mosaico. El velo de «pide atención» sigue mandando, porque su regla es más específica. */
.mtg-tabla-fichas {
  --bs-table-bg: transparent;
}

/* Ni el ordinal ni el menú de acciones son texto que alguien quiera copiar, y en táctil un
   toque sobre ellos puede iniciar una **selección de texto** que se extiende por la ficha y
   por la de al lado: parece que al pulsar los tres puntos «se selecciona más de los tres
   puntos». Que haya banda en dos filas a la vez es justo lo que descarta un estado del
   botón, porque solo un elemento puede estar pulsado. */
.mtg-tabla-fichas td[data-ficha-orden],
.mtg-tabla-fichas td[data-ficha-acciones] {
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Y en un puntero sin hover, `:hover` **se queda pegado** tras el toque: con `table-hover`
   la fila se queda teñida hasta que se toca otra cosa. En modo ficha cada celda es un
   bloque, así que eso se ve como una banda y no como el resaltado de una fila. */
@media (hover: none) {
  .mtg-tabla-fichas {
    --bs-table-hover-bg: transparent;
  }
}

@media screen and (max-width: 767.98px) {
  .mtg-tabla-fichas {
    /* Los huecos de las dos esquinas, en un sitio. El de la derecha tiene que dar para el
       valor destacado más su unidad —«15 pts»— sin pisar el nombre. */
    --mtg-hueco-orden: 2.1rem;
    --mtg-hueco-destacado: 5.5rem;
  }

  .mtg-tabla-fichas thead {
    /* `clip` y no `display: none`: la cabecera sigue existiendo para el lector de
       pantalla, que la usa para anunciar cada celda. */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .mtg-tabla-fichas,
  .mtg-tabla-fichas tbody,
  .mtg-tabla-fichas tbody tr,
  .mtg-tabla-fichas tbody td {
    display: block;
    width: auto;
  }

  .mtg-tabla-fichas tbody tr {
    /* Las dos esquinas —el ordinal y el dato destacado— van en posición absoluta, y el
       nombre ocupa una línea entera. Así la ficha tiene una estructura fija: arriba
       quién es, debajo sus cifras, y **no depende del orden ni del número de columnas**.
       Con flex a secas el orden de las celdas decidía dónde caía cada cosa. */
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    /* El hueco horizontal es justo el que cabe: con 0,85 rem las cinco cifras de la
       clasificación se iban a dos líneas en un móvil de 390 px y la ficha crecía de 71 a
       94 px — en una tabla de 22 jugadores, media pantalla de más. Cada cifra lleva su
       etiqueta, así que no necesita tanto aire para distinguirse de la de al lado. */
    gap: 0.15rem 0.6rem;
    padding: 0.7rem 0.25rem;
    padding-left: var(--mtg-hueco-orden);
    border-bottom: 1px solid var(--bs-border-color);
  }

  /* El hueco del ordinal se reserva **solo si hay ordinal**. La tabla de preinscritos no lo tiene —no
     existe: el orden de inscripción se asigna al confirmar— y sin esto el nombre salía sangrado 34 px
     contra un hueco vacío, que a 375 px es una décima parte del ancho y se la come el nombre.

     `:has()` y no una clase en el marcado: quien sabe si hay ordinal es la propia fila, y una clase
     paralela se puede olvidar el día que se añada una tabla nueva. */
  .mtg-tabla-fichas tbody tr:not(:has(td[data-ficha-orden])) {
    padding-left: 0.25rem;
  }

  /* El ordinal —el puesto, el número de mesa— en la esquina de arriba a la izquierda. */
  .mtg-tabla-fichas tbody td[data-ficha-orden] {
    position: absolute;
    left: 0.25rem;
    top: 0.75rem;
    width: calc(var(--mtg-hueco-orden) - 0.5rem);
    text-align: end !important;
    color: var(--bs-secondary-color);
  }

  /* ---- La etiqueta del corte, en la esquina del ordinal ----
     En escritorio va **a la izquierda del puesto**, en fila. En una ficha de móvil no cabe: el hueco
     del ordinal es una caja en absoluto de 1,6 rem dimensionada para un número de dos cifras, y la
     fila «top 32 · 15» se salía por la derecha **encima del nombre**. Se vio en pantalla, no
     midiendo, y la lección es que un cambio visual se prueba en los dos tamaños: esto entró con el
     Top Cut verificando solo escritorio.

     Se apila —el puesto arriba, la etiqueta debajo— y el hueco se ensancha **solo cuando hay
     etiqueta**, con `:has()`: ensancharlo siempre indentaría también el plantel y las demás tablas
     de ficha, que no la llevan. */
  .mtg-tabla-fichas:has(.mtg-puesto-top) {
    --mtg-hueco-orden: 2.9rem;
  }

  /* `column` y no `column-reverse`: **el orden del marcado ya no es el mismo en las dos tablas**. En la
     de un torneo el chip va antes del número (celda alineada a la derecha, el chip cabe a su izquierda);
     en la de una liga va después, porque ahí la celda alinea a la izquierda y el chip delante empujaba
     el número de las filas del corte y los puestos dejaban de estar en columna.

     Con `column` manda el orden de cada marcado y las dos quedan igual en ficha —número arriba, etiqueta
     debajo—, que es lo que hay que conservar: apiladas caben en el hueco del ordinal, y en fila la
     etiqueta se salía por la derecha **encima del nombre**. */
  /* `center` y no `flex-end`: apilados, el número y el chip tienen anchos muy distintos —10 px contra
     26 medidos— y alineándolos a la derecha el número quedaba colgando de una esquina del chip en vez
     de encima de él. Centrados se leen como una unidad. Lo vio el organizador en pantalla. */
  .mtg-tabla-fichas .mtg-puesto {
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
  }

  /* ---- Lo que solo tiene sentido como tabla ----
     El desglose por jornada de una liga vive aquí: en escritorio son doce columnas que se leen en
     vertical, y en una ficha serían doce bloques sueltos compitiendo con el nombre y los puntos. Se
     probó antes a esconder solo las jornadas no jugadas y seguía siendo demasiado.

     En la ficha se conserva **el resumen que decide**: el medallero y las jornadas jugadas. El detalle
     de qué hizo cada día es una consulta de escritorio. */
  .mtg-tabla-fichas .mtg-solo-tabla {
    display: none;
  }

  /* Aquí vivía una regla que escondía las medallas a cero en ficha. **Se quitó**: el efecto era el
     contrario del buscado, porque cada ficha acababa con un número distinto de elementos y la lista se
     veía descuadrada. Ahora salen las tres siempre y el cero va apagado — la estructura manda sobre el
     ahorro de tinta. `mtg-celda-vacia` se conserva para las columnas de jornada, que sí desaparecen. */
  .mtg-tabla-fichas td.mtg-celda-vacia {
    display: none;
  }

  /* ---- En ficha, «jornadas N» va ANTES que las medallas ----
     En la tabla el orden de las columnas es el del desempate —puntos, medallas, jornadas—, y ahí tiene
     sentido porque las cabeceras lo explican. En una ficha no hay cabeceras y sí un efecto molesto: las
     medallas aparecen o no según el jugador, así que con ellas delante **«jornadas 4» cambiaba de sitio
     en cada fila** y la lista parecía descuadrada. Lo vio el organizador.

     Con las medallas al final, el dato fijo está siempre en el mismo punto y lo variable se acumula
     detrás. Se hace con `order` y no reordenando el marcado, para no cambiar la tabla de escritorio. */
  .mtg-tabla-fichas td.mtg-celda-medalla {
    order: 1;
  }

  /* ---- Que «jornadas 4» quede a la misma altura que las medallas ----
     La fila alinea sus celdas por **línea base**, y una medalla es un `inline-flex` con un SVG dentro:
     a 1,1 em su caja crecía a 26,8 px contra los 20,4 del texto, así que «jornadas» caía **4,8 px más
     abajo** que los iconos de al lado. Lo vio el organizador; medido, el desfase entre centros era de
     casi 2 px y el de los bordes, de 4,8.

     Con el icono a 1 em y la medalla alineada por el medio, el desfase baja a 0,8 px. No se toca el
     `align-items` de la fila: eso reordenaría también el nombre y el resto de tablas de ficha. */
  .mtg-tabla-fichas .mtg-medalla {
    vertical-align: middle;
  }

  .mtg-tabla-fichas .mtg-medalla-icono {
    width: 1em;
    height: 1em;
  }

  /* El botón del detalle sí crece: es lo único que se pulsa de la ficha, así que su icono va a 1,35 rem
     —el mismo tamaño que los de la barra de acciones— en lugar de heredar el de la medalla, que está
     dimensionado para acompañar a una cifra. El objetivo táctil ya eran 44 px de alto; esto hace que se
     **vea** tan grande como es. */
  .mtg-tabla-fichas .mtg-ver-jornadas .mtg-medalla-icono {
    width: 1.35rem;
    height: 1.35rem;
  }


  /* El torneo pinta el chip **antes** que el número, así que en ficha hay que darle la vuelta para que
     el puesto quede arriba. La liga ya lo pinta después y no necesita nada. */
  .mtg-tabla-fichas .mtg-puesto:has(> .mtg-puesto-top:first-child) {
    flex-direction: column-reverse;
  }

  /* El dato que manda —los puntos, el marcador— grande y en la esquina derecha. Alineado
     ahí abajo se lee en columna al recorrer la lista, que es como se busca a alguien. */
  .mtg-tabla-fichas tbody td[data-ficha-destacado] {
    position: absolute;
    right: 0.25rem;
    top: 0.55rem;
    width: calc(var(--mtg-hueco-destacado) - 0.5rem);
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.1;
    text-align: end !important;
    /* Guarda, y está aquí por un fallo que llegó a producción: la tabla de ronda puso
       en esta esquina el estado «sin jugar» y el distintivo de «no se presentó
       ninguno». Al estar en absoluto, el texto se partió en dos líneas y **se
       superpuso al nombre y al botón** — un fallo silencioso, porque el navegador no
       se queja de que dos cosas ocupen el mismo sitio.

       Con esto un valor demasiado largo se recorta con puntos suspensivos en lugar
       de invadir la ficha: falla a la vista y no por la espalda. **Esta esquina es
       solo para valores cortos**; lo que sea una frase va a la segunda línea. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* «15 pts» y no «Puntos 15»: la unidad detrás y pequeña se lee como una cifra, no como
     un campo de formulario. En escritorio no aparece — ahí lo dice la cabecera. */
  .mtg-tabla-fichas tbody td[data-ficha-destacado][data-sufijo]::after {
    content: " " attr(data-sufijo);
    font-size: 0.55em;
    font-weight: 600;
    color: var(--bs-secondary-color);
  }

  .mtg-tabla-fichas tbody td {
    /* Bootstrap le pone un borde inferior a cada celda; en ficha eso serían ocho
       rayas por jugador. El borde lo lleva la fila. */
    border: 0;
    padding: 0;
    text-align: start !important;
  }

  /* El nombre se queda con la primera línea entera —`flex-basis: 100%`—, así que el resto
     de las cifras baja siempre a la segunda. Con `auto` cabía alguna al lado del nombre
     cuando el nombre era corto, y la ficha no tenía una forma fija. */
  .mtg-tabla-fichas tbody td[data-ficha-titulo] {
    flex: 1 1 100%;
    /* El hueco de la esquina derecha lo reserva **el nombre**, no la fila: el valor
       destacado solo ocupa la primera línea, así que apretar también la segunda le
       quitaba 88 px a las cifras y las repartía en tres líneas en lugar de dos. */
    padding-right: var(--mtg-hueco-destacado) !important;
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.35;
    /* Un nombre que no cabe **se recorta con puntos suspensivos, no salta de línea**. Saltando, la ficha
       crecía un renglón solo para ese jugador y la lista se descuadraba — el mismo problema que obligó a
       fijar el orden de las medallas. El nombre completo no se pierde: sigue entero en el marcado, así
       que un lector de pantalla lo lee y el `title` lo enseña.

       **Es una caja flexible y no un `nowrap` a secas**, y la diferencia importa: esta celda no siempre
       lleva solo el nombre. En la clasificación de un torneo lleva además distintivos —«abandonó en la
       5», «campeón», «2 bye»—, y recortando la celda entera **el distintivo se salía 170 px y quedaba
       fuera de la vista**, medido. Con `flex`, lo que encoge es el nombre y los distintivos conservan su
       tamaño: cede lo que puede ceder, no el dato. Es la misma regla que ya rige la ficha de una mesa. */
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
    overflow: hidden;
  }

  /* El nombre: lo único que encoge. `min-width: 0` es imprescindible —sin él, un hijo flexible no baja
     de su ancho de contenido y el `ellipsis` no llega a activarse nunca—. */
  .mtg-tabla-fichas tbody td[data-ficha-titulo] > .mtg-nombre,
  .mtg-tabla-fichas tbody td[data-ficha-titulo] > .mtg-abandonado {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Y los distintivos no se encogen ni se parten: o caben enteros o no dicen nada. */
  .mtg-tabla-fichas tbody td[data-ficha-titulo] > .badge {
    flex: none;
  }

  /* La segunda línea, más pequeña: son los datos de apoyo, no la identidad.

     **Y sin partir**: el rótulo y su valor caben en una línea o la caja se ensancha, nunca al revés. Sin
     esto, «% del meta» se partía en tres renglones y la ficha crecía por el rótulo y no por el dato — se
     vio con las columnas de tendencia y nivel. Los valores de estas celdas son cifras cortas, así que el
     `nowrap` no puede desbordar nada. */
  .mtg-tabla-fichas tbody td[data-etiqueta] {
    font-size: 0.85rem;
    white-space: nowrap;
  }

  /* Sin cabecera visible, un «52,0» suelto no dice nada. */
  .mtg-tabla-fichas tbody td[data-etiqueta]::before {
    content: attr(data-etiqueta) " ";
    color: var(--bs-secondary-color);
    font-size: 0.85em;
    font-weight: 400;
  }

  /* Los controles de la fila, a su propia línea y a todo el ancho: es lo que se
     pulsa, y en la ficha no tiene sentido que quede encajado en un hueco. */
  /* Los controles al final de la línea, **no a todo el ancho**. Esto estuvo mal y se vio
     en pantalla: la ficha de una mesa medía 108 px y más de la mitad se la llevaba un
     botón. El error fue dimensionar por «se toca con el dedo» en lugar de por **cuántas
     veces se toca**: el mínimo de 44 px habla del objetivo, no del bloque. */
  .mtg-tabla-fichas tbody td[data-ficha-acciones] {
    margin-left: auto;
  }

  /* La variante compacta ya no existe: los pareos dejaron de ser una tabla y pasaron a ser
     fichas de verdad (`.mtg-mesa`), iguales en móvil y en escritorio. Lo que queda de este
     patrón es para tablas que **sí** lo son, y hoy eso es la clasificación. */

  /* ---- Variante de celdas: los desempates en cuatro cajas iguales ----
     Las cifras sueltas se envolvían y parecían una lista de la compra. En celdas del
     mismo ancho se leen **en columna** al bajar por la tabla, que es como se compara a
     dos jugadores. La etiqueta va encima del valor, no delante. */
  .mtg-tabla-fichas-celdas tbody td[data-etiqueta] {
    flex: 1 1 0;
    min-width: 0;
    background: var(--mtg-celda-fondo);
    border-radius: var(--bs-border-radius-sm);
    padding: 0.15rem 0.2rem 0.25rem;
    text-align: center !important;
  }

  .mtg-tabla-fichas-celdas tbody td[data-etiqueta]::before {
    display: block;
    font-size: 0.7rem;
  }

  /* Una celda que en ficha no aporta. `Jugadas` es la suma de V-D-E, así que en el móvil
     V-D-E ya la lleva dentro: cuatro celdas es el máximo cómodo a 360 px, y de las cinco
     la que se puede recomponer con la vista es esa. En escritorio se queda la columna. */
  .mtg-tabla-fichas tbody td[data-ficha-solo-escritorio] {
    display: none;
  }

  /* El velo de «pide atención» pasa de las celdas a la ficha. Medido: las celdas suman
     331 px de los 366 de la fila, así que teñirlas una a una dejaba sin teñir los huecos
     del flex y la ficha salía a rayas. */
  .mtg-tabla-fichas tbody tr.mtg-fila-atencion {
    background-color: var(--mtg-atencion-fondo);
  }

  .mtg-tabla-fichas tbody tr.mtg-fila-atencion > * {
    --bs-table-bg: transparent;
  }

  /* La línea de corte, **exactamente el mismo fallo que el velo** y descubierto aparte: en
     escritorio va en cada celda y los trozos se alinean en una línea continua, pero en ficha cada
     celda es un bloque y salían seis rayas —una bajo el nombre y una bajo cada cifra— en vez de una
     línea bajo la ficha. Pasa a la fila y se quita de las celdas.

     La lección es la de siempre y ya está escrita para el fondo: **en modo ficha, lo que abarca la
     fila entera se declara en la fila.** */
  .mtg-tabla-fichas tbody tr.mtg-línea-de-corte > * {
    border-bottom: 0 !important;
  }

  .mtg-tabla-fichas tbody tr.mtg-línea-de-corte {
    border-bottom: 2px solid var(--mtg-acento);
  }
}

/* ---- Una fila que pide atención ----
   Sustituye a `table-warning`. Las clases contextuales de Bootstrap fijan un fondo
   CLARO y un texto oscuro, pero el texto de dentro —«sin jugar», el número de mesa,
   el «vs»— lleva `text-body-secondary`, que en tema oscuro es gris claro: el
   resultado era gris claro sobre amarillo claro, ilegible.

   Aquí solo se tiñe el fondo, con un velo translúcido del acento sobre el fondo del
   tema, así que el texto conserva el color del tema y el contraste con él. */
.mtg-fila-atencion > * {
  --bs-table-bg: var(--mtg-atencion-fondo);
}

/* El anillo de foco del acento, visible en los dos temas. El de la plantilla
   llevaba un halo blanco que sobre fondo claro parecía un defecto de pintado. */
.btn:focus-visible,
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
a:focus-visible,
summary:focus-visible {
  outline: none;
  border-color: var(--mtg-acento);
  box-shadow: 0 0 0 0.2rem var(--mtg-acento-halo);
}

/* ---- Acento en los elementos que lo llevan ---- */

.btn-primary {
  --bs-btn-bg: var(--mtg-acento);
  --bs-btn-border-color: var(--mtg-acento);
  --bs-btn-color: var(--mtg-acento-texto);
  --bs-btn-hover-bg: var(--mtg-acento-vivo);
  --bs-btn-hover-border-color: var(--mtg-acento-vivo);
  --bs-btn-hover-color: var(--mtg-acento-texto);
  --bs-btn-active-bg: var(--mtg-acento-vivo);
  --bs-btn-active-border-color: var(--mtg-acento-vivo);
  --bs-btn-active-color: var(--mtg-acento-texto);
  --bs-btn-disabled-bg: var(--mtg-acento);
  --bs-btn-disabled-border-color: var(--mtg-acento);
  --bs-btn-disabled-color: var(--mtg-acento-texto);
  font-weight: 600;
}

.btn-outline-primary {
  --bs-btn-color: var(--mtg-acento);
  --bs-btn-border-color: var(--mtg-acento);
  --bs-btn-hover-bg: var(--mtg-acento);
  --bs-btn-hover-border-color: var(--mtg-acento);
  --bs-btn-hover-color: var(--mtg-acento-texto);
  --bs-btn-active-bg: var(--mtg-acento);
  --bs-btn-active-border-color: var(--mtg-acento);
  --bs-btn-active-color: var(--mtg-acento-texto);
}

/* Los botones de contorno de Bootstrap usan **colores fijos** que no siguen al tema, y
   los dos temas los rompen por lados opuestos. Todo lo de aquí está medido:

   - `btn-outline-secondary` (#6c757d): 3,29:1 sobre el fondo oscuro y 4,68:1 sobre
     blanco. Por debajo o al filo del mínimo en los dos.
   - `btn-outline-warning` (#ffc107): sobre blanco daba **1,63:1**, ilegible — eran los
     ocho botones «Dropear» del plantel.
   - `btn-outline-dark`: su color ES el fondo del tema oscuro, contraste 1,0. Ese no se
     arregla, se deja de usar.

   El borde puede ser más flojo que el texto a propósito: como componente le basta 3:1. */
[data-bs-theme="light"] .btn-outline-warning {
  --bs-btn-color: #7a5200;
  --bs-btn-border-color: #b58100;
  --bs-btn-hover-bg: #b58100;
  --bs-btn-hover-border-color: #b58100;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: #b58100;
  --bs-btn-active-border-color: #b58100;
  --bs-btn-active-color: #fff;
}

[data-bs-theme="light"] .btn-outline-secondary {
  --bs-btn-color: #565e64;
}

/* El mismo rojo fijo de Bootstrap, roto por el otro lado: #dc3545 da 3,82:1 sobre blanco.
   Medido en el botón «Eliminar ronda». */
[data-bs-theme="light"] .btn-outline-danger {
  --bs-btn-color: #a5232f;
  --bs-btn-border-color: #dc3545;
  --bs-btn-hover-bg: #a5232f;
  --bs-btn-hover-border-color: #a5232f;
}

/* El rojo de Bootstrap (#dc3545) da 2,94:1 sobre el fondo del diálogo y 3,41:1 sobre el de
   la página: por debajo del mínimo en los dos. Con #ea868f son 5,27 y 6,10. Afecta al
   botón de doble incomparecencia y al de dar por perdidas. */
[data-bs-theme="dark"] .btn-outline-danger {
  --bs-btn-color: #ea868f;
  --bs-btn-border-color: #b02a37;
  --bs-btn-hover-bg: #b02a37;
  --bs-btn-hover-border-color: #b02a37;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: #b02a37;
  --bs-btn-active-border-color: #b02a37;
  --bs-btn-active-color: #fff;
}

[data-bs-theme="dark"] .btn-outline-secondary {
  --bs-btn-color: #adb5bd;
  --bs-btn-border-color: #6c757d;
  --bs-btn-hover-bg: #6c757d;
  --bs-btn-hover-border-color: #6c757d;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: #6c757d;
  --bs-btn-active-border-color: #6c757d;
  --bs-btn-active-color: #fff;
  --bs-btn-disabled-color: #6c757d;
  --bs-btn-disabled-border-color: #495057;
}

.navbar-brand {
  font-weight: 700;
  letter-spacing: 0.01em;
}

/* La página en la que estás, marcada con el acento. Sin esto la barra no dice
   dónde estás, que en cinco secciones ya se nota.

   Se pisan **las variables de Bootstrap**, no la propiedad `color`: es la forma
   idiomática en 5.3 y evita un `!important`.

   Nota de depuración, que costó un rato: al cambiar de tema, `getComputedStyle`
   puede devolver el color del tema ANTERIOR y parecer un fallo de invalidación. No
   lo es. `.nav-link` tiene `transition: color .15s`, y el reloj de las transiciones
   **se congela cuando la pestaña no se está pintando** —panel oculto, otra pestaña—,
   así que la transición se queda en `currentTime: 0`. Se comprueba con
   `elemento.getAnimations()` y con `document.visibilityState`: con `transition: none`
   el valor correcto aparece al instante. */
.navbar {
  --bs-navbar-active-color: var(--mtg-acento);
  --bs-navbar-hover-color: var(--mtg-acento-vivo);
}

.navbar .nav-link.active {
  box-shadow: inset 0 -2px 0 var(--mtg-acento);
}

/* ---- Ojo con el tema: los símbolos de edición ----
   Los SVG de Scryfall vienen SIN atributo `fill`, así que se pintan siempre en
   negro y no hay forma de recolorearlos desde CSS. Sobre fondo oscuro eso los
   volvía invisibles —y de forma silenciosa, porque el `<img>` carga bien—. Se
   invierten con un filtro, que sí funciona sobre un monocromo. */
[data-bs-theme="dark"] .mtg-simbolo-set {
  filter: invert(1);
}

/* ---- Táctil ----
   Solo con puntero grueso. Un desplegable de 27px de alto es imposible de acertar
   con el pulgar, y era la altura real del control de resultado del juez; con ratón
   esa misma altura está bien y las tablas densas se agradecen. */
@media (pointer: coarse) {
  .btn,
  .form-control,
  .form-select,
  .nav-link,
  summary {
    min-height: var(--mtg-toque);
  }

  .btn-sm,
  .form-control-sm,
  .form-select-sm {
    /* `btn-sm` se usa a propósito en las tablas para que quepan; en táctil lo que
       no cabe es el dedo, así que se le devuelve el alto y se conserva el ancho. */
    min-height: var(--mtg-toque);
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
  }

  .form-check-input {
    width: 1.35rem;
    height: 1.35rem;
  }

  /* Un botón que solo lleva icono no gana ancho con el relleno del texto, así que la regla de arriba
     le da alto y lo deja en **36 px de ancho** — medido en el de imprimir. Para los demás botones el
     texto ya se encarga; para estos hay que decirlo.

     Y con el ancho hay que dar el **centrado**, que es la otra mitad del mismo problema: al estirar la
     caja a 44 × 44, el relleno del botón (5,6 px arriba y abajo, 8 a los lados) deja de repartirse y el
     icono se queda arriba a la izquierda — medido, **4,2 px de desvío horizontal y 6,6 de vertical**.
     Un `d-inline-flex` a secas no centra nada: `align-items` y `justify-content` valen `normal`.

     El tamaño del icono se sube aparte, **junto a su regla base y no aquí**: con la misma especificidad
     manda el orden de fuente, y la base está más abajo en este fichero. */
  .btn:has(> .mtg-icono-boton) {
    min-width: var(--mtg-toque);
    align-items: center;
    justify-content: center;
  }
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

/* ---- Cartas ---- */

/* Proporción real de una carta de Magic: 63 x 88 mm. */
.mtg-carta-imagen {
  width: 100%;
  max-width: 244px;
}

.mtg-carta-imagen img {
  width: 100%;
}

/* Sustituto cuando no hay ilustración: mantiene el hueco para que la maqueta no salte. */
.mtg-carta-sin-imagen {
  aspect-ratio: 63 / 88;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
  overflow: hidden;
}

/* ---- Grid del editor de barajas ---- */

/* 145 px es el ancho al que se pinta cada carta del grid. La ilustración que se pide es la
   «normal» de Scryfall (488 px), así que se ve nítida también en pantallas de alta densidad. */
.mtg-miniatura {
  position: relative;
  width: 145px;
  /* Lo leen las marcas de puntos, restringida, prohibida y no legal para escalar con la carta. */
  --mtg-carta-ancho: 145px;
}

/* **En móvil estrecho, tres cartas por fila en vez de dos**, a petición del organizador. El umbral
   está medido y no es uno de los de Bootstrap: con el relleno de la página en 24 px, tres cartas de
   145 más sus dos huecos de 8 piden **451 px de contenedor**, o sea 475 de ventana. Por encima de ahí
   ya caben tres al tamaño grande y encogerlas sería perder nitidez a cambio de nada — comprobado a
   479, donde entran tres sin tocar nada.

   Que se pueda encoger **está medido, no supuesto**: a 111 px la ilustración se reconoce, los sellos
   se leen y —el peor caso— el dado del 6 baja a 27,8 px con puntos de 5,1 y sus seis puntos se siguen
   contando. Era la duda razonable, porque a 96 px el dado ya solo mide 24 y los puntos 4,4.

   **La caja va en porcentaje y la variable en `vw`, y esa asimetría es deliberada.** Un `%` en
   `flex-basis` se resuelve contra el contenedor, así que la cuenta de cuántas caben por fila no puede
   fallar; pero un `%` dentro del `calc()` de un `font-size` se resolvería contra el font-size del
   padre y no contra el ancho, así que la variable necesita una longitud absoluta. Si algún navegador
   mete la barra de scroll en `100vw`, lo único que pasa es que las marcas salen un pelín pequeñas —
   nunca que la tercera carta se caiga de la fila. */
@media (max-width: 474.98px) {
  .mtg-miniatura {
    flex: 0 0 calc((100% - 1rem) / 3);
    width: auto;
    --mtg-carta-ancho: calc((100vw - 40px) / 3);
  }
}

.mtg-miniatura img,
.mtg-miniatura .mtg-carta-sin-imagen {
  width: 100%;
  display: block;
}

.mtg-miniatura-nombre {
  font-size: 0.8rem;
  line-height: 1.15;
  word-break: break-word;
}

/* ---- Ancho de la página ---- */

.mtg-contenedor {
  max-width: 1800px;
}

/* ---- Columna de marcas de aviso del editor ---- */

.mtg-editor {
  display: flex;
  align-items: stretch;
}

/* Pegada al campo y con su mismo borde, para que las dos se lean como una sola pieza. */
.mtg-marcas {
  position: relative;
  flex: 0 0 1.6rem;
  overflow: hidden;
  border: 1px solid var(--bs-border-color);
  border-right: 0;
  border-radius: 0.375rem 0 0 0.375rem;
  background: var(--bs-secondary-bg);
}

.mtg-editor textarea {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

/* La altura la pone site.js: es la del renglón al que apunta la marca. */
.mtg-marca {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 0.75rem;
  line-height: 1.5;
  cursor: default;
}

/* ---- Desplegables flotantes del editor ---- */

/* Por defecto cuelgan del pie de su bloque, a todo su ancho. Vacíos no ocupan nada: así el
   JavaScript «cierra» un desplegable limpiando su contenido, sin tocar estilos ni clases. */
.mtg-flotante {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1000;
  max-height: 16rem;
  overflow-y: auto;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

.mtg-flotante:empty {
  display: none;
}

/* El autocompletado no cuelga de ningún bloque: es uno solo para toda la página, lo crea
   site.js y lo cuelga del body. Por eso va `fixed` y con las coordenadas de la línea que se
   está escribiendo — así funciona en cualquier pantalla sin que su marcado prepare nada.

   Nace escondido: sin `display: none` se vería un recuadro vacío en la esquina hasta la
   primera consulta. */
.mtg-autocompletar {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1080;
  width: min(26rem, calc(100vw - 1rem));
  max-height: 16rem;
  overflow-y: auto;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* ---- Gráficos de tarta ---- */

.mtg-tarta {
  width: 100%;
  max-width: 180px;
  display: block;
}

/* Un filete entre porciones, para que dos colores contiguos no se fundan. */
.mtg-tarta path,
.mtg-tarta circle {
  stroke: var(--bs-body-bg);
  stroke-width: 1.5;
}

/* La leyenda de una tarta: muestra de color, nombre y «valor · %».
   Con **dos tartas por fila en móvil** el renglón se queda en 164 px y «Encantamientos 8 · 13%»
   pide 169 —medido: 10 de muestra, 98 de nombre, 45 de cifra y dos huecos de 8—, así que la
   cifra se caía a una segunda línea y esa fila medía 42 px contra los 21 de las demás. Se cierra
   por los tres lados: hueco de 4 px, la **cifra sin partir nunca** —es el dato— y el **nombre
   cediendo con puntos suspensivos**, que es lo que puede ceder y por eso lleva su `title`.
   Con 4 px de hueco el peor caso pasa a 161 y entra sin recortar nada. */
.mtg-tarta-leyenda li {
  gap: 0.25rem;
}

.mtg-tarta-leyenda li > .text-body-secondary {
  white-space: nowrap;
}

/* Paleta neutra para tipos de carta y curva, donde el color no significa nada por sí mismo. */
.mtg-tarta-1 { fill: #2c7cb8; background: #2c7cb8; }
.mtg-tarta-2 { fill: #4aa3a2; background: #4aa3a2; }
.mtg-tarta-3 { fill: #7ab648; background: #7ab648; }
.mtg-tarta-4 { fill: #d9a441; background: #d9a441; }
.mtg-tarta-5 { fill: #d3702c; background: #d3702c; }
.mtg-tarta-6 { fill: #c9312c; background: #c9312c; }
.mtg-tarta-7 { fill: #7d5ba6; background: #7d5ba6; }

/* ---- Ficha de formato ---- */

/* Los símbolos de edición de Scryfall son SVG de un solo trazo y **sin atributo `fill`**: el
   navegador los pinta en negro y no hay forma de recolorearlos desde fuera.

   Se dibujan tal cual, sin fondo. Ponerles uno «para que contrasten» fue justo lo que los hizo
   invisibles: el color del texto es casi negro y quedaba negro sobre negro.

   Se intentó la vía elegante —usarlos como máscara de CSS rellenada con currentColor, que los
   haría tomar el color del texto— y no llegó a pintar nada. Como un <img> o carga o no carga,
   y eso se puede comprobar, se prefiere lo que se puede verificar a lo que es más bonito. */
.mtg-simbolo-set {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  object-fit: contain;
}

/* En tema oscuro el símbolo negro sí desaparecería. Invertirlo es suficiente porque son
   monocromos. */
@media (prefers-color-scheme: dark) {
  .mtg-simbolo-set {
    filter: invert(1);
  }
}

/* Lo que pinta <mtg-edicion>: símbolo, código opcional y nombre en una fila que no se parte.
   Clase propia y no `d-inline-flex` de Bootstrap para que una página pueda añadir `d-flex`
   sin que las dos reglas se peleen por cuál gana. */
.mtg-edicion {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  /* Sin esto, un hijo con text-overflow dentro de un flex no llega a encogerse nunca. */
  min-width: 0;
}

.mtg-edicion-nombre {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La ilustración al pasar el ratón por encima del nombre de una carta. Puro CSS: la imagen
   está en el HTML pero oculta, y como está oculta el navegador ni la descarga hasta que hace
   falta. */
.mtg-carta-al-vuelo {
  position: relative;
}

.mtg-carta-al-vuelo-nombre {
  border-bottom: 1px dotted var(--bs-border-color);
  cursor: help;
}

.mtg-carta-al-vuelo-imagen {
  display: none;
  position: absolute;
  bottom: 1.4em;
  left: 0;
  z-index: 1000;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.35);
  /* Sin esto, el propio recuadro capta el ratón al aparecer bajo el cursor y parpadea. */
  pointer-events: none;
}

.mtg-carta-al-vuelo:hover .mtg-carta-al-vuelo-imagen,
.mtg-carta-al-vuelo:focus-within .mtg-carta-al-vuelo-imagen {
  display: block;
}

/* En táctil no hay hover que valga. El navegador simula uno al tocar y lo deja pegado hasta
   que se toca otra cosa, así que la regla de arriba dejaría la imagen abierta sin control:
   aquí se anula y manda la clase que pone site.js.

   Y se coloca con `fixed`, no `absolute`: anclada al nombre se saldría de una pantalla
   estrecha, y el JS necesita poder acotarla al viewport. */
@media (hover: none) {
  .mtg-carta-al-vuelo:hover .mtg-carta-al-vuelo-imagen,
  .mtg-carta-al-vuelo:focus-within .mtg-carta-al-vuelo-imagen {
    display: none;
  }

  .mtg-carta-al-vuelo.mtg-abierta .mtg-carta-al-vuelo-imagen {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    bottom: auto;
    width: 60vw;
    max-width: 280px;
    height: auto;
  }
}

/* La columna de casillas del comparador: lo justo para la casilla, que si no la tabla le da
   un ancho de columna entera. */
.mtg-columna-check {
  width: 2rem;
}

/* ---- Marcas sobre la ilustración de una carta ---- */
/*
   Puntos, restringida y prohibida. Las medidas van en fracción de `--mtg-carta-ancho`, que
   declara cada contenedor: así las mismas reglas sirven para la carta de 145 px del editor y
   para la de 96 px de la ficha de formato, sin escribir dos veces nada.

   Es la misma técnica que el cuadro impreso con `--mtg-columna-papel`. En `rem` no valdría: el
   adorno mediría lo mismo en una carta grande que en una pequeña.

   Ninguna va en color de acento — el amarillo significa «esto se pulsa» — y todas llevan su
   letra o cifra, porque el color no puede ser el único canal.
*/

/* **El fondo de las tres marcas es translúcido, y el valor está medido, no elegido a ojo.** Es una
   petición del organizador —opacas quedaban «pegote», tapando ilustración que se ha venido a ver— y
   es la **única excepción** a la regla de que un velo no puede sostener un contraste. Lo que la
   justifica es que aquí el peor caso **está acotado**: la marca cae sobre la ilustración de una
   carta, y lo más claro que puede haber debajo de un texto blanco es el borde blanco del marco.
   Nada puede ser más claro que blanco, así que basta medir contra blanco — mientras que la regla
   general se escribió para un velo sobre otro velo, donde el fondo depende de la pila entera y no
   se puede razonar.

   Medido componiendo cada marca sobre blanco, que es su peor caso:

   | Alfa | «R» y sello (rojo #b3241d) | Dado (#23282d) |
   |---|---|---|
   | 1,00 (opaco) | 6,59 | 13,84 |
   | 0,85 | **5,11** | 9,22 |
   | 0,80 | 4,63 | — |
   | 0,75 | 4,17 ❌ | — |

   De ahí el 0,85: es donde se ve la ilustración por debajo y el rojo **sigue pasando el 4,5:1** con
   margen. A 0,75 el rojo baja de 4,5 y la letra deja de cumplir, así que **el tope no es una
   opinión**. El que manda es el rojo; el dado es oscuro y translucirlo sobre blanco lo *aclara*
   hasta 9,22, o sea que le sobra.

   El **filo blanco se queda opaco a propósito**: es lo que mantiene el canto neto de la marca, que
   es lo que se perdió en el intento de la «R» con contorno de sombras. Un fondo suave con canto
   duro se lee; un fondo suave con canto suave, no. */
:root {
  --mtg-marca-alfa: 0.85;
}

.mtg-marca-carta {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  line-height: 1;
}

/* Los puntos, arriba a la izquierda **dentro de la ventana de la ilustración**, no pegados al
   borde de la carta: ahí arriba está la barra del nombre y el dado la tapaba, así que de una carta
   marcada no se podía leer cuál era. El 11 % es donde empieza el dibujo en el marco antiguo, el
   mismo valor que usa el sello de prohibida.

   Dado clásico: cuadrado redondeado. El filo blanco es lo que lo separa de una ilustración oscura,
   y los colores son fijos y no del tema porque van sobre un dibujo, no sobre el fondo de la página.

   El 25 % está medido contra los 145 px del editor, que es **el único tamaño en que se pinta**: la
   ficha de formato pasa los puntos en nulo, porque ahí la fila ya dice el valor. Da un dado de 36
   px con puntos de 6,7, que se cuentan de un vistazo. Si algún día se pinta a 96 px hay que volver
   a medirlo: ahí el dado baja a 24 px y los puntos del 6 a 4,4. */
.mtg-marca-puntos {
  top: 11%;
  left: 5%;
  width: 25%;
  aspect-ratio: 1;
  /* Un dado real tiene las esquinas redondeadas, no es un cuadrado perfecto. */
  border-radius: 22%;
  /* Translúcido, ver `--mtg-marca-alfa`. */
  background: rgb(35 40 45 / var(--mtg-marca-alfa));
  color: #fff;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.92);
  font-size: calc(var(--mtg-carta-ancho) * 0.145);
}

/* La cara del dado: rejilla de tres por tres, con punto en las casillas que toquen.

   Las casillas vacías se pintan igual y quedan invisibles, y eso es lo que hace que cada punto
   caiga en su sitio sin una regla de posición por cara: la rejilla las coloca. */
.mtg-dado {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  /* Deja el margen del canto del dado, que es donde el filo blanco tiene que verse. */
  width: 74%;
  height: 74%;
  place-items: center;
}

.mtg-dado-punto {
  width: 74%;
  aspect-ratio: 1;
  border-radius: 50%;
  /* Del `color` del dado, así que el punto y la cifra del spindown no se pueden desparejar. */
  background: currentColor;
}

/* Por encima de 6 el dado deja de poder representarlo y se pasa a un spindown con la cifra.
   Aquí la forma la da el polígono del SVG, así que la caja apaga lo suyo: sin fondo, sin
   redondeo y sin filo, o se vería el cuadrado por detrás del hexágono. */
.mtg-marca-puntos-spindown {
  background: none;
  border-radius: 0;
  box-shadow: none;
}

.mtg-marca-puntos-spindown > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* El canto relleno con el filo blanco por fuera: el mismo papel que el `box-shadow` del dado
   normal, que aquí no serviría porque seguiría la caja cuadrada y no el hexágono. */
.mtg-spindown-canto {
  fill: #23282d;
  stroke: rgba(255, 255, 255, 0.92);
  stroke-width: 5;
}

/* Las aristas de dentro, más flojas que el canto: a este tamaño son lo que hace reconocible la
   forma, no un dato, y la cifra se lee justo encima. */
.mtg-spindown-cara {
  fill: none;
  stroke: rgba(255, 255, 255, 0.45);
  stroke-width: 3.5;
}

/* La cifra va sobre las aristas, y de ahí el `position: relative`: el SVG está en absoluto y
   sin esto se pintaría encima por ser posterior en el marcado. */
.mtg-dado-cifra {
  position: relative;
}

/* La «R» de restringida, abajo a la derecha y pegada al borde, justo encima de la fuerza y
   resistencia. Es la convención de los carteles de X-Point y 7 Points, y quien juega estos formatos
   ya la reconoce.

   **Rectángulo rojo apretado a la letra**, y las tres formas que se descartaron cuentan por qué.
   Un **círculo** es la peor: para que la letra quepa necesita tanto alto como ancho, y ese alto sale
   de un dato — pegado a la esquina tapaba la caja de fuerza y resistencia y de una criatura no se
   podía leer el 4/4. Un **rectángulo holgado** (relleno de 0,42 em a los lados) seguía siendo el
   doble de ancho de lo necesario y en cartas como `Balance` se comía el final del texto de reglas.
   Y la **letra sola con contorno de sombras blancas**, sin caja, es la más estrecha de todas y se
   descartó en pantalla: **no se ve definida**. Tiene explicación y conviene recordarla — un contorno
   de sombras no tiene borde neto, así que a 17 px de letra el rojo y el blanco se mezclan en el
   antialias y la marca queda algodonosa; un fondo opaco sí tiene borde, y ese canto es lo que la
   hace legible de un vistazo.

   Así que la caja vuelve, y lo que se conserva del intento sin caja es **el ancho ganado**: el
   relleno lateral baja de 0,42 em a 0,2 em y `letter-spacing` desaparece —en una sola letra solo
   añade hueco **detrás**, o sea que despega la R del borde justo lo que se le acaba de ganar—. Con
   eso la marca mide 15,4 px de ancho contra los 21 de la versión holgada, y ese ahorro se gasta en
   arrimarla al borde derecho, donde el marco de la carta ya no lleva datos.

   Ocupa del 79,3 % al 88,2 % del alto. **Las cifras de las zonas de la carta no se escriben aquí a
   propósito**: las que hubo estaban deducidas a ojo y no cuadraban. Medirlas no se puede por el
   camino corto, porque la ilustración viene de Scryfall y un `canvas` que la muestree sale
   contaminado por origen cruzado. Si se toca esta posición, **se comprueba en pantalla y sobre una
   criatura**, que es el único caso donde ese rincón lleva un dato.

   Anclada con `bottom` y no con `top` a propósito: así, si algún día crece la letra, la etiqueta se
   estira **hacia arriba** y no hacia abajo sobre el 4/4, que es justo el dato que estorbaba. */
.mtg-marca-restringida {
  right: 1.5%;
  bottom: 11.8%;
  padding: 0.1em 0.2em;
  border-radius: 0.18em;
  /* Translúcido, ver `--mtg-marca-alfa`. Esta es la marca que fija el tope: 5,11 sobre blanco. */
  background: rgb(179 36 29 / var(--mtg-marca-alfa));
  color: #fff;
  font-size: calc(var(--mtg-carta-ancho) * 0.105);
  /* **El filo va más flojo que en el dado, al 0,70, y esa es la palanca del «pegote» aquí.** El
     organizador vio la transparencia en el dado y no en la «R», y tenía razón en lo que veía: el
     alfa del fondo está puesto igual en las dos, pero esta marca mide 11×12 px contra los 24 del
     dado —menos superficie donde ver lo de debajo— y cae en la esquina de abajo a la derecha, que
     en el marco antiguo es borde negro o cuadro de texto, así que rojo mezclado con casi negro
     sigue siendo rojo. El dado cae dentro del dibujo, donde hay color variado, y ahí sí se nota.

     Lo que a 11 px hacía que pareciera una pegatina no era el fondo sino el filo: al 0,90 es buena
     parte de la marca. Probadas cuatro variantes en pantalla sobre marco blanco y marco negro
     —0,90, 0,70, 0,55 y sin filo— y **sin filo se cae**: sobre el marco negro la letra pierde el
     canto y queda una mancha roja. El 0,70 conserva el borde. */
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, 0.7);
}

/* El sello de la carta, cruzando **el recuadro de la ilustración** y no la carta entera. Cruzando la
   carta tapaba el nombre y el texto de reglas; encajado en el dibujo se lee igual de bien y deja la
   carta reconocible. Los porcentajes son la ventana de arte del marco antiguo, medida sobre la carta.

   **Sirve para dos estados y por eso ya no se llama «prohibida»**: rojo `[BANNED]` y gris
   `[NOT LEGAL]`. Son excluyentes —lo garantiza `CardMarks`— porque dos sellos cruzando el mismo
   dibujo serían ilegibles.

   Va por encima de todo lo demás porque una carta que no se puede jugar no se puede jugar, así que
   sus puntos y su restricción son secundarios. */
.mtg-sello-carta {
  position: absolute;
  top: 11%;
  left: 7%;
  width: 86%;
  height: 37%;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Para que la banda, más ancha que su hueco, no se salga del recuadro del dibujo. */
  overflow: hidden;
}

/* **Letras rojas con corchetes y sin banda.** Es el sello que eligió el organizador con la referencia
   delante, y el motivo es el mismo que le hizo pedir transparencia en las otras dos: la banda opaca
   cruzaba el dibujo entero y no dejaba ver la carta, que es justo lo que la sección viene a enseñar.
   Sin banda, la ilustración se ve **entre** las letras. Lo que **no** se copió de la referencia es su
   sitio —la ponía sobre el texto de reglas— porque el organizador prefiere el nuestro: cruzando la
   ventana del dibujo.

   Dice **«BANNED» y no «PROHIBIDA»**, también decisión suya: es el término que se reconoce en
   cualquier idioma y son seis caracteres en vez de nueve, o sea que la letra puede crecer un 30 % en
   el mismo hueco. El texto para el lector de pantalla y el `title` siguen en español.

   **El halo blanco no es adorno: es el fondo de la letra.** Sin banda, el contraste dependería de la
   ilustración, y ahí el peor caso *no* está acotado como en las otras dos marcas: rojo sobre blanco
   da 6,59 y sobre negro 3,19, pero sobre una ilustración de tono medio —la misma luminancia que el
   rojo— se iría a **1,0** y la palabra desaparecería. Con el halo, la letra se lee siempre contra su
   propio halo y no contra el dibujo, así que el contraste vuelve a ser **6,59 fijo**, sea lo que haya
   debajo. Va en `em` para que escale con la carta, y por eso es la excepción a que un velo no
   sostiene un contraste: aquí no hay velo debajo de la letra, hay blanco opaco.

   Sin `background` ni `box-shadow`: el filo de la banda era lo que se estaba quitando. */
.mtg-sello-carta-texto {
  /* Más ancha que su hueco a propósito: girada, tiene que cruzarlo de lado a lado. */
  width: 125%;
  text-align: center;
  transform: rotate(-15deg);
  color: #c9201a;
  font-weight: 800;
  letter-spacing: 0.08em;
  font-size: calc(var(--mtg-carta-ancho) * 0.125);
  text-shadow:
    -0.06em 0 0 #fff,
    0.06em 0 0 #fff,
    0 -0.06em 0 #fff,
    0 0.06em 0 #fff,
    -0.045em -0.045em 0 #fff,
    0.045em -0.045em 0 #fff,
    -0.045em 0.045em 0 #fff,
    0.045em 0.045em 0 #fff;
}

/* Los corchetes del sello. Van en pseudo-elementos porque son **adorno**: el texto de la marca es
   la palabra, y un lector de pantalla no tiene que leer «corchete BANNED corchete». */
.mtg-sello-carta-texto::before {
  content: "[";
  margin-right: 0.12em;
}

.mtg-sello-carta-texto::after {
  content: "]";
  margin-left: 0.12em;
}

/* **`[NOT LEGAL]`: el mismo sello en gris.** La carta existe pero no se imprimió en ninguna edición
   del formato, y eso **no es estar prohibida** — no está en su banlist, es que nunca estuvo en el
   formato. `Black Lotus` en Premodern es el caso, y lo señaló el organizador en pantalla.

   **El rótulo y el color son los de Scryfall**, no una invención: leído de su propio CSS, allí
   `legal` va verde `#75986e`, `banned` rojo `rgba(167,31,42,.58)`, `restricted` azul
   `rgba(36,103,130,.58)` y `not-legal` gris `#aeaeae`. O sea que la distinción que hacía falta ya
   existe y se hace **por color**, con «not legal» en gris: no es rojo, así que no es un castigo.

   Dos cosas de esa lectura que conviene tener escritas:

   - **El gris no puede ser el suyo.** Scryfall lo usa de *fondo* con texto blanco; aquí es el color
     de la letra sobre un halo blanco, y `#aeaeae` daría **1,95** de contraste. Medidas las tres
     variantes en pantalla sobre marco blanco y marco negro: `#aeaeae` se desvanece, `#6b7178` baja a
     **4,90** —justo por encima del mínimo— y `#3d4147` da **10,37**. Se eligió el último.
   - Y la separación entre los dos sellos: gris `#3d4147` contra rojo `#c9201a` son **1,83** de
     luminancia, contra el 1,27 de un gris medio. Sigue siendo poca, así que **la palabra es el canal
     principal** y el color el secundario — que es la regla del proyecto, no una concesión.

   La letra baja a 0,10 del ancho: «NOT LEGAL» son nueve caracteres contra los seis de «BANNED», y al
   tamaño del rojo se sale del recuadro del dibujo. */
.mtg-sello-no-legal .mtg-sello-carta-texto {
  color: #3d4147;
  font-size: calc(var(--mtg-carta-ancho) * 0.1);
}

/* ---- La ilustración pulsable y el diálogo de la carta ---- */

/* El botón que envuelve la ilustración. **Un botón de verdad y despojado**: sin fondo, sin borde y
   sin relleno, para que la caja mida exactamente lo que la imagen y no descuadre la rejilla ni
   desplace las marcas, que se posicionan contra la miniatura.

   `display: block` porque un botón es `inline-block` y dejaría el hueco de la línea base debajo de
   la imagen — tres o cuatro píxeles que se notan en una fila de cartas.

   No lleva ninguna señal de que se pulsa, y es deliberado: **la carta entera es el objetivo**, así
   que un adorno solo taparía dibujo. Lo que sí lleva es el foco visible, que es lo que necesita
   quien llega con el teclado, y en puntero fino un realce al pasar por encima. */
.mtg-carta-pulsable {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.mtg-carta-pulsable:focus-visible {
  outline: 2px solid var(--mtg-acento);
  outline-offset: 2px;
}

/* Solo con puntero fino. En táctil no hay «pasar por encima», y un `:hover` pegajoso en móvil deja
   la última carta tocada resaltada para siempre. */
@media (hover: hover) and (pointer: fine) {
  .mtg-carta-pulsable:hover {
    filter: brightness(1.08);
  }
}

/* El texto de reglas conserva sus saltos de línea: en una carta separan habilidades, no son adorno.
   `pre-line` y no `pre`, porque el texto viene con líneas ya formadas y no hay que respetar sus
   espacios de sangrado. */
.mtg-carta-texto {
  white-space: pre-line;
}

/* El texto impreso va atenuado y en cursiva: es el que **no** se aplica. */
.mtg-carta-texto-impreso {
  color: var(--bs-secondary-color);
  font-style: italic;
}

.mtg-carta-detalle-cuerpo {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

/* La ilustración a tamaño de lectura, y **no se encoge**: es lo primero que se ha venido a ver. El
   ancho está atado al de la caja para que en móvil pase a ocupar la fila entera. */
.mtg-carta-detalle-imagen {
  flex: 0 0 auto;
  width: min(100%, 15rem);
}

/* Los datos sí encogen, y necesitan `min-width: 0` o un texto largo no deja encoger la columna y la
   rejilla se sale del diálogo. `flex-basis` en una medida mínima legible: por debajo de eso, el
   texto se va debajo de la imagen en vez de quedarse en una columna de cuatro palabras. */
.mtg-carta-detalle-datos {
  flex: 1 1 16rem;
  min-width: 0;
}

.mtg-carta-detalle-bloque + .mtg-carta-detalle-bloque {
  margin-top: 1.1rem;
}

.mtg-carta-detalle-titulo {
  margin-bottom: 0.35rem;
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--bs-secondary-color);
}

.mtg-carta-detalle-separador {
  margin-inline: 0.35rem;
}

.mtg-carta-aclaraciones {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.875rem;
}

.mtg-carta-aclaraciones > li + li {
  margin-top: 0.5rem;
}

/* El año de la aclaración, delante. Solo el año y no la fecha entera: lo que informa es si es de
   los noventa o de anteayer, y una fecha completa por línea llenaría el bloque de cifras. */
.mtg-carta-aclaracion-fecha {
  margin-right: 0.4rem;
  color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
}

.mtg-carta-legalidad {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
}

.mtg-carta-legalidad > li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-block: 0.25rem;
  border-bottom: 1px solid var(--bs-border-color);
}

.mtg-carta-legalidad > li:last-child {
  border-bottom: 0;
}

.mtg-carta-legalidad-puntos {
  margin-left: auto;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}

/* **Cuatro estados y cuatro tonos, que es lo contrario de lo que hacen las marcas sobre la carta.**
   No es una incoherencia y conviene tener escrito el porqué: encima de una ilustración solo hay dos
   sellos y una letra, nunca dos a la vez, así que el rojo puede significar «prohibida» y también
   «restringida» sin que se comparen. Aquí las siete filas están **una debajo de otra y se comparan**,
   que es la misma lección que las columnas del medallero de la liga: dos filas del mismo color en una
   tabla de comparación se leen como el mismo estado. El azul de restringida es además el que usa
   Scryfall.

   El rótulo va escrito en cada fila, así que **el color no es el único canal** — la regla del
   proyecto se cumple igual. */
.mtg-estado {
  flex: 0 0 auto;
  min-width: 6.5rem;
  padding: 0.1rem 0.4rem;
  border-radius: 0.25rem;
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.mtg-estado-legal {
  background: #3f7a44;
}

.mtg-estado-restringida {
  background: #246782;
}

.mtg-estado-prohibida {
  background: #b3241d;
}

.mtg-estado-no-legal {
  background: #55595f;
}

/* ---- La leyenda de las marcas ---- */

/* Va al final de la pantalla, como nota al pie, con el mismo peso que la leyenda del medallero de
   la clasificación de liga: separada por una línea y en texto secundario. */
.mtg-leyenda-marcas {
  margin-top: 1.5rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
  font-size: 0.875rem;
}

.mtg-leyenda-marcas-titulo {
  margin-bottom: 0.6rem;
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Cada entrada es una fila de muestra + explicación, y las filas se reparten en columnas mientras
   quepan. `minmax(0, …)` es obligatorio: sin él una explicación larga no deja encoger su columna y
   la rejilla se sale del contenedor. */
.mtg-leyenda-marcas-lista {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 0.75rem 1.5rem;
  margin: 0;
}

.mtg-leyenda-marcas-lista > div {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}

/* **Ancho fijo, y por eso mismo el sello se encoge.** Con la columna en `auto` cada muestra medía lo
   suyo —16 px la «R», 36 el dado, 88,8 el sello— y las tres explicaciones empezaban en una `x`
   distinta: la lista se leía descuadrada. Lo vio el organizador en pantalla.

   El ancho lo manda la muestra más larga, que es el sello `[NOT LEGAL]` con 85,1 px. La muestra va
   **centrada** en el canal para que las cuatro se lean como una columna. */
.mtg-leyenda-marcas-lista dt {
  flex: 0 0 5.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mtg-leyenda-marcas-lista dd {
  margin: 0;
  min-width: 0;
}

/* La muestra es el componente de verdad, así que hay que **quitarle el posicionamiento absoluto**:
   fuera de una carta, `top`/`left` lo colgarían del primer ancestro posicionado que hubiera, y las
   medidas en porcentaje se resolverían contra él.

   `--mtg-carta-ancho` se declara aquí a propósito, y con los 145 px del editor y no con un valor
   pequeño «de leyenda»: la marca tiene que salir del tamaño **al que se ve en la carta**, porque una
   R de 6 px no se reconocería. */
.mtg-marca-en-leyenda {
  position: static;
  --mtg-carta-ancho: 145px;
}

/* El ancho del dado es el 25 % de la carta, y en absoluto ese porcentaje se resolvía contra ella.
   Suelto hay que escribirlo, o mediría el 25 % de su fila. */
.mtg-marca-puntos.mtg-marca-en-leyenda {
  width: calc(var(--mtg-carta-ancho) * 0.25);
}

/* El sello suelto pierde el hueco de la ventana del dibujo, así que también su `overflow: hidden`,
   que le recortaría lo que sobresale por estar girado.

   Es la muestra que se aparta del tamaño de la carta, y es porque **es una palabra**: lo que se
   reconoce de él es el texto, no su cuerpo, así que encogerlo no le quita señal — mientras que una
   «R» de 6 px sí deja de leerse.

   **En la leyenda los dos sellos llevan la misma letra**, escrita aquí en vez de heredada de
   `--mtg-carta-ancho`, y eso arregla un defecto medido: sobre la carta el gris va más pequeño que el
   rojo a propósito —«NOT LEGAL» son nueve caracteres contra seis y al tamaño del rojo se sale del
   dibujo—, pero al heredar esa proporción la muestra de la leyenda salía con letra de **9 px frente
   a los 11,25** del rojo. En una leyenda eso no vale: es el único sitio donde la marca se lee en vez
   de reconocerse, así que las dos tienen que pesar igual. Con la letra fija, lo único que las
   diferencia es el número de caracteres — 68,6 px el rojo y 85,1 el gris — y el canal se dimensiona
   por la más larga. **Si cambia alguna de las dos palabras, hay que volver a medir el canal**: ya
   pasó al cambiar «PROHIBIDA» por «[BANNED]», que se fue a 80 px en un canal de 76 y se salía por la
   izquierda, porque `justify-content: center` no tiene dónde centrar lo que no cabe. */
.mtg-sello-carta.mtg-marca-en-leyenda {
  width: auto;
  height: auto;
  overflow: visible;
}

.mtg-sello-carta.mtg-marca-en-leyenda .mtg-sello-carta-texto {
  width: auto;
  font-size: 0.7rem;
}

/* ---- Las galerías de la ficha de un formato ---- */

/* El número a la izquierda de cada fila, como en los carteles que publican estos formatos. */
.mtg-puntos-valor {
  flex: 0 0 2.5rem;
  text-align: center;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.4;
  color: var(--bs-secondary-color);
}

/* Cada galería —puntos, restringidas, prohibidas— con su línea de separación y su rótulo. Tres
   secciones seguidas de cartas se confunden en una sola si no se separan: la línea de arriba y el
   subtítulo son lo que dice dónde acaba una y empieza la siguiente. */
.mtg-galeria-cartas {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--bs-border-color);
}

.mtg-galeria-cartas-subtitulo {
  margin-bottom: 1rem;
  color: var(--bs-secondary-color);
  font-size: 0.875rem;
}

/* Más pequeñas que las del editor: aquí se trata de ver la sección entera de golpe, no de leer
   la carta. La proporción real de una carta es 63 x 88 mm.

   La clase se llamaba `.mtg-puntos-carta` y se renombró al usarla las tres galerías: un nombre que
   dice «puntos» en la galería de prohibidas es la pista falsa que encuentra el siguiente. */
.mtg-carta-galeria {
  /* position: relative porque las marcas se pintan en absoluto sobre la carta. */
  position: relative;
  width: 96px;
  --mtg-carta-ancho: 96px;
}

.mtg-carta-galeria img,
.mtg-carta-galeria .mtg-carta-sin-imagen {
  width: 100%;
  display: block;
}

/* Los sets legales de la ficha: rejilla de símbolo y nombre, en orden de publicación.

   `auto-fill` con un mínimo y no un número de columnas fijo: la columna de la ficha mide 398 px en
   escritorio y el ancho entero en móvil, así que el número de sets por fila lo decide el sitio.

   La edición se apila —símbolo arriba, nombre debajo y centrado— y ahí hay que **deshacer dos cosas
   de `.mtg-edicion`**, que está pensada para ir en una línea de texto: su `flex-direction` en fila y
   el recorte del nombre con puntos suspensivos, que en una celda estrecha se comería «Limited Edition
   Alpha» hasta dejarlo en dos palabras. Aquí el nombre parte en varias líneas, que es lo que permite
   celdas estrechas sin perder el nombre. */
.mtg-sets-legales {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
  gap: 0.9rem 0.5rem;
}

.mtg-sets-legales .mtg-edicion {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  text-align: center;
  line-height: 1.2;
}

.mtg-sets-legales .mtg-edicion-nombre {
  overflow: visible;
  white-space: normal;
}

/* El símbolo, más grande que en una línea de texto: aquí es lo que se reconoce de un vistazo, y a
   1,1 rem los de las ediciones viejas no se distinguen entre sí. */
.mtg-sets-legales .mtg-simbolo-set {
  width: 1.7rem;
  height: 1.7rem;
}

/* La tabla de puntos en texto: una línea por valor con sus cartas seguidas.

   Aquí **sí hay viñeta** —al contrario que las otras listas de la ficha, que van sin marcador—:
   con las cartas en prosa, una línea de tres renglones necesita algo que diga dónde empieza, y el
   valor en negrita solo no basta cuando el anterior acabó a media línea. El sangrado es el mínimo
   que deja la viñeta fuera del texto.

   Se fue con esto la clase `.columns-2`, que repartía en dos columnas las listas de prohibidas y
   restringidas: en prosa no hace falta, porque la línea se llena sola. */
.mtg-lista-por-puntos {
  margin-bottom: 1rem;
  padding-left: 1.1rem;
}

.mtg-lista-por-puntos > li + li {
  margin-top: 0.35rem;
}

/* ---- Curva de maná ---- */

.mtg-curva {
  display: flex;
  align-items: flex-end;
  gap: 0.25rem;
}

.mtg-curva-tramo {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
}

/* Altura fija: es lo que hace que las barras sean comparables entre sí. */
.mtg-curva-hueco {
  height: 8rem;
  display: flex;
  align-items: flex-end;
}

.mtg-curva-barra {
  width: 100%;
  /* Un tramo con una sola carta debe verse aunque su altura relativa sea mínima. */
  min-height: 3px;
  border-radius: 0.25rem 0.25rem 0 0;
  background: var(--bs-primary);
}

.mtg-curva-valor {
  font-size: 0.75rem;
  border-top: 1px solid var(--bs-border-color);
  padding-top: 0.15rem;
}

.mtg-curva-cuenta {
  font-size: 0.7rem;
  color: var(--bs-secondary-color);
}

/* ---- Estadísticas del maindeck ---- */

.mtg-pip-muestra {
  /* No encoge: es un cuadrado de color, y encogido deja de ser el color de nadie. En el
     renglón estrecho de la leyenda, quien cede es el nombre. */
  flex: 0 0 auto;
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 0.2rem;
  border: 1px solid var(--bs-border-color);
}

/* Los cinco colores de Magic. Aproximaciones a los de las cartas, oscurecidas lo suficiente
   para que el texto en blanco de las etiquetas contraste. Se declaran las dos propiedades
   porque los mismos colores pintan cuadraditos de leyenda (background) y sectores de tarta
   (fill, que es lo que entiende el SVG). */
.mtg-color-w { background: #e4d9a8; fill: #e4d9a8; }
.mtg-color-u { background: #2c7cb8; fill: #2c7cb8; }
.mtg-color-b { background: #4a4642; fill: #4a4642; }
.mtg-color-r { background: #c9312c; fill: #c9312c; }
.mtg-color-g { background: #237a4c; fill: #237a4c; }

/* La cantidad va encima de la esquina de la carta, como en los visores de mazos. */
.mtg-miniatura-cantidad {
  position: absolute;
  bottom: 4px;
  left: 4px;
  margin: 0;
  padding: 0 0.4rem;
  border-radius: 0.25rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: #fff;
  background: rgba(0, 0, 0, 0.78);
}

/* ============================================================================
   EL LISTADO DE TORNEOS
   ============================================================================
   **Fichas, no tabla**, y la prueba es la del propio proyecto: ¿se comparan las celdas de una fila con
   las de la de al lado? En la clasificación sí; en una lista de torneos **no** — nadie compara los
   jugadores de un torneo con los del de al lado, se busca el que se quiere abrir. Es una lista de
   unidades, como los emparejamientos.

   Eso simplifica de verdad: una sola forma arriba y abajo, sin `mtg-tabla-fichas` que mantener ni
   `data-ficha-*` en las celdas.

   Antes eran **tres listas apiladas** con el estado como encabezado de cada una. Medido a 375 px con
   25 torneos: 3.264 px de documento y **3,4 pantallas de scroll** hasta «Terminados». */
.mtg-listado-controles {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 1rem;
  margin-bottom: 1rem;
}

.mtg-listado-controles .mtg-pestanas {
  flex: 1 1 16rem;
  margin-bottom: 0;
}

.mtg-listado-filtro {
  flex: 0 1 auto;
  padding-bottom: 0.35rem;
}

/* Aquí **ya no hace falta una regla para la pestaña activa**: la de arriba se marca por
   `aria-selected` y vale para todas. Este bloque decía «podrían unificarse; no se ha hecho para no
   tocar una pantalla que funciona», y unificarlas es justo lo que arregló que las cuatro vistas de la
   baraja no señalaran la suya. */

.mtg-torneos {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
}

/* `position: relative` no es decoración: es lo que sostiene el `stretched-link` del nombre, y con él
   **la ficha entera es el objetivo**. Antes la única forma de abrir un torneo era un enlace de 22 px
   —lo sacó la pasada de QA— y aquí pasa a 72. */
.mtg-torneo {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
}

/* ---- La cinta de esquina de una jornada de liga ----
   Idea del organizador, con un mockup delante: una **cinta diagonal encima de la imagen**, no una imagen
   nueva. Se probaron cuatro variantes en pantalla —cinta oscura, cinta azul, esquina doblada con el icono
   y píldora plana— y eligió esta. Con ella **se quitó el tinte de fondo de la caja** que había antes: la
   cinta se ve antes y desde más lejos, así que el matiz de fondo solo aportaba ruido y un color más.

   **Casi negra en los dos temas**, no una variable por tema: no se apoya en el fondo de la página sino
   sobre la imagen del torneo, que puede ser cualquier cosa.

   El **filo blanco** lo pidió él y resuelve justo el caso que la cinta sola no cubre: sobre un tapete
   oscuro la banda se funde con la imagen. Sobre uno claro el filo no se ve y no hace falta, porque ahí
   destaca lo negro. Va en `box-shadow` y no en `border`: un borde sumaría 2 px de alto a la banda, y
   además cambiar el estilo de un lado sin anchura declarada resucita la anchura `medium` —3 px—, que es
   una trampa que este proyecto ya ha pagado dos veces.

   `z-index` porque la imagen y el velo son hermanos suyos y se pintan después.

   **El fondo va al 0,68**, bajado del 0,88 a petición del organizador para que se vea el tapete por
   debajo — el mismo criterio que las marcas de las cartas. El valor está medido y no elegido a ojo:
   componiendo la cinta sobre blanco, que es el peor caso para su texto blanco porque nada puede ser
   más claro,

   | Alfa | «LIGA» sobre tapete blanco | sobre tapete negro |
   |---|---|---|
   | 0,88 (el de antes) | 13,52 | 19,06 |
   | **0,68** | **5,84** | 19,61 |
   | 0,58 | 4,58 | 19,76 |
   | 0,50 | 3,52 ❌ | 19,92 |

   El suelo está en 0,58 y a 0,50 la letra se cae, así que 0,68 deja margen. Se descartó bajar más
   viéndolo ampliado: a 0,58 el «LIGA» empieza a competir con el dibujo y la cinta pierde presencia,
   que es justo su trabajo — se ve recorriendo la cuadrícula con la vista.

   Y una cosa que la comparación enseñó y conviene saber antes de volver a tocar esto: **sobre un
   tapete oscuro el cambio no se aprecia**, porque casi negro mezclado con marrón oscuro sigue siendo
   casi negro. Es la misma trampa que con la «R» de restringida. Para juzgar este valor hay que
   mirarlo sobre un tapete **claro** —el de Premodern— y ampliado. */
/* **La geometría se declara una vez** (`.mtg-cinta`) porque la usan dos: la de liga y la de «cambia tu
   lista» de una caja de baraja. Con las medidas escritas dos veces, la segunda cinta se separaría de la
   primera en cuanto se tocara el ángulo o el filo. */
.mtg-cinta,
.mtg-cinta-liga {
  position: absolute;
  top: 0.9rem;
  right: -2.4rem;
  z-index: 3;
  width: 9rem;
  padding: 0.18rem 0;
  transform: rotate(45deg);
  background: rgba(16, 18, 22, 0.68);
  box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.9), 0 1px 0 rgba(255, 255, 255, 0.9);
  color: #fff;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  pointer-events: none;
}

/* **El gris del distintivo y no el casi negro de la cinta de liga**, y lo pidió el organizador viéndolo:
   con el mismo color, una caja de baraja parecía una jornada de liga. La cinta es un mecanismo compartido
   y el color es lo que dice de qué habla cada una — mismo par que `.badge.text-bg-secondary`, que es de
   donde viene este distintivo.

   Sin el filo blanco, además: aquel existe porque la cinta de liga se apoya sobre un tapete que puede ser
   cualquier cosa, y este gris ya es opaco. */
.mtg-cinta-aviso {
  background: var(--bs-secondary);
  box-shadow: none;
  letter-spacing: 0.04em;
}

/* En papel no se pinta: los navegadores descartan los fondos al imprimir, así que quedaría un «LIGA»
   blanco sobre blanco. Lo que identifica una jornada en una hoja es el icono y el nombre de la liga, que
   sí se imprimen. */
@media print {
  .mtg-cinta,
  .mtg-cinta-liga {
    display: none;
  }
}

/* ============================================================================
   LA FASE DE INSCRIPCIÓN: DOS LISTAS
   ============================================================================
   La cola y el plantel, una al lado de la otra en escritorio y en dos pestañas en móvil. La cola va a la
   **izquierda** porque el movimiento va en esa dirección —se confirma hacia la derecha— y porque es donde
   se escribe.

   Por defecto —móvil— es una columna con el panel elegido, así que **si el JavaScript fallara se verían
   las dos listas seguidas** y no una pantalla en blanco. Misma regla que la barra de juez y que el
   listado de torneos: el servidor lo pinta todo y el cliente estrecha. */
.mtg-inscripcion {
  display: grid;
  gap: 1.5rem;
}

/* ---- El umbral son 992 px y no los 768 de siempre ----
   Este es el único sitio del proyecto donde el corte no es el de las tablas en modo ficha, y hay una
   medida detrás. A 768 px la columna se queda en **337**, menos que los 319 de un móvil de 375 más el
   ancho que gana al no compartir: al nombre le tocan 188 px y «Maria del Carmen Villanueva» se parte en
   dos, con la fila en 60 px. O sea que a ese ancho las dos columnas dan *menos* sitio que una sola.

   Medido lo que le toca a cada columna: 768 → 341, 880 → 397, **992 → 453**, 1280 → 597. A 992 el nombre
   tiene sitio de sobra y es además el umbral que ya usa el interruptor de forma del cuadro, así que no se
   inventa una anchura nueva. Por debajo, pestañas. */
@media (max-width: 991.98px) {
  .mtg-inscripcion[data-panel="cola"] #mtg-panel-plantel,
  .mtg-inscripcion[data-panel="plantel"] #mtg-panel-cola {
    display: none;
  }
}

/* De 992 en adelante las pestañas no hacen nada: las dos listas caben. Se esconden con `display: none` y
   no con `clip-path` —al contrario que un rótulo— porque no son texto que un lector de pantalla necesite:
   son un control de navegación de una vista que ahí no existe. */
@media (min-width: 992px) {
  .mtg-inscripcion {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }

  .mtg-inscripcion-pestanas {
    display: none;
  }
}

/* ---- El formulario de creación cambia de forma con el tipo ----
   En eliminación directa no hay rondas que elegir, así que el campo **se esconde** en vez de apagarse: un
   campo deshabilitado invita a preguntarse qué habría que poner. Y el cuadro deja de ser opcional, así que
   su nota lo dice.

   Lo decide el CSS con `:has()` sobre el radio marcado — sin JavaScript y sin volver al servidor. Nace
   visible y se esconde, que es el orden correcto: si `:has()` no estuviera soportado se vería un campo de
   más, no faltaría uno. */
.mtg-solo-sin-rondas {
  display: none;
}

form:has(#tipo-eliminacion:checked) .mtg-solo-con-rondas {
  display: none;
}

form:has(#tipo-eliminacion:checked) .mtg-solo-sin-rondas {
  display: inline;
}

/* ---- Montar el cuadro ----
   Aquí vivían **dos listas con pestañas** —«dentro» y «fuera», con el patrón de la inscripción— y una
   previa de cruces en texto. Se fueron enteras: la pantalla es ahora el cuadro y nada más, y cada hueco
   se pulsa para cambiar de jugador. Con eso desaparecieron el segundo panel, sus pestañas, el aviso de
   «falta un jugador» y la fila de móvil a dos renglones que hizo falta para que el nombre no se quedara
   en 73 px. Si vuelven las dos listas, vuelve ese bloque con ellas.

   Lo que queda es poco a propósito: el esqueleto del cuadro ya está resuelto por las reglas de
   `.mtg-cuadro`, que se comparten con la fase de top. */

/* El cuadro previsto no tiene resultados, así que **nada va en acento**: aquí el amarillo diría «esto se
   pulsa» de una caja de marcador que no existe. Lo pulsable son los huecos, y lo dice su flecha. */
.mtg-corte-hueco {
  /* Un `<button>` no hereda la caja del lado, así que hay que devolvérsela: sin esto el hueco se pinta
     con el fondo y el borde del navegador y la ficha deja de medir lo que mide en la fase de top. */
  width: 100%;
  background: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
}

/* **El relleno no se declara aquí**, y no es un olvido: lo pone `.mtg-cruce-lado`, y escribirlo otra vez
   fue exactamente el fallo que hubo. Con `0.35rem` en vez de los `0.3rem` del lado, la ficha medía
   **97,16 px contra los 93,97 de la casilla vacía** — 0,8 px por lado y por jugador, cuatro veces. Y eso
   rompe el invariante del cuadro: el hueco cambia de forma al llenarse y el reparto de altura descuadra
   los conectores. */

.mtg-corte-hueco:hover,
.mtg-corte-hueco:focus-visible {
  background: var(--mtg-celda-fondo);
}

/* La flecha es lo único que dice que la caja se pulsa, así que va **al final del hueco y siempre
   visible**: enseñarla solo al pasar por encima la escondería en táctil, que es justo donde más falta
   hace. Se queda a la derecha con `margin-inline-start: auto`, no con un ancho reservado, para no
   quitarle sitio al nombre. */
.mtg-corte-cambiar {
  margin-inline-start: auto;
  padding-inline-start: 0.35rem;
  color: var(--bs-secondary-color);
}

/* ---- Con el dedo, el hueco crece a 44 px ----
   En esta pantalla **todo hueco se pulsa**, así que la regla de los 44 px aplica de lleno: medido, los
   lados se quedaban en 34-35. Y aquí no vale el truco de la píldora de resultado —estirar el área con un
   pseudo-elemento hacia el relleno—, porque los dos lados de una ficha son adyacentes y el área de uno se
   solaparía con la del otro, que es peor que un objetivo pequeño.

   Crecen **los dos tipos de caja a la vez**, la del jugador y la vacía, aunque la vacía no se pulse: si
   solo creciera la pulsable, la ficha dejaría de medir lo que la casilla vacía y el reparto de altura
   descuadraría los conectores. Cuesta unos 18 px por ficha. */
@media (pointer: coarse) {
  .mtg-cuadro-previsto .mtg-cruce-lado {
    min-height: 44px;
  }
}

/* ---- El diálogo del intercambio ---- */
.mtg-corte-opciones {
  display: grid;
  gap: 0.35rem;
}

/* Nombre a la izquierda y dónde está a la derecha, en una línea. El nombre es lo que se busca con la
   vista, así que es lo único que encoge. */
.mtg-corte-opcion {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.mtg-corte-opcion-nombre {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-corte-opcion-donde {
  flex: 0 0 auto;
  font-size: 0.8125rem;
  white-space: nowrap;
}

/* ---- El hueco de la ficha, apretado en móvil por la miniatura ----
   La imagen del torneo le quita ancho a la línea de datos, y esa línea es larga —el nombre de un formato
   puede llevarse 37 caracteres—, así que se parte una vez más y la ficha crece **41 px** (115 → 156) en
   cuanto hay imagen.

   Medido, y lo que cuesta la línea **no es el tamaño de la miniatura sino el hueco**: con la miniatura en
   48 px y el hueco en 0,6 rem la ficha se queda en 135, exactamente igual que bajándola a 40, a 32 o a
   24. Por debajo de 48 no se gana nada más. Así que la miniatura conserva su tamaño —que es justo para lo
   que está, distinguir un torneo de un vistazo— y lo que cede es el aire. Coste con imagen: 20 px en vez
   de 41.

   **Va aquí y no en el bloque de móvil de arriba**, que es la trampa que ya mordió con el tamaño del
   icono de imprimir: misma especificidad, y con la misma especificidad manda el orden de fuente. Desde
   arriba, el `gap: 1rem` de la regla base la pisaba y no hacía nada.

   **`screen`**, porque al imprimir las media queries miden la hoja y un A4 vertical son ~703 px: sin la
   guarda, el listado se imprimiría con la forma de móvil. En papel quedan las filas de siempre. */
@media screen and (max-width: 767.98px) {
  .mtg-torneo {
    gap: 0.6rem;
  }

  /* **El nombre del formato se queda también en móvil**, y esto revierte una decisión mía. Lo escondí
     porque era el trozo más largo de la línea y la partía en cuatro renglones —quitarlo bajaba la lista
     de 868 px a 641—, dando por hecho que el logo lo decía. El organizador lo vio con el logo puesto y
     pidió las dos cosas: un tapete a 112 px se reconoce, pero no se lee. La altura se paga a sabiendas. */
}

/* El acento al pasar por encima y al enfocar, que es lo que dice «esto se pulsa» sin rellenar nada de
   amarillo. `focus-within` y no `focus`: quien enfoca es el enlace estirado, no la ficha. */
.mtg-torneo:hover,
.mtg-torneo:focus-within {
  border-color: var(--mtg-acento);
}

.mtg-torneo-cuerpo {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---- La ficha tiene forma fija: tres renglones, siempre los mismos ----
   Lo pidió el organizador con el precedente delante: es lo mismo que se hizo en la ficha de la
   clasificación de liga, donde lo que cambiaba de tamaño entre filas descuadraba la lista entera.

   El defecto medido: la línea de datos se partía en **uno, dos o tres renglones** según lo largos que
   fueran el formato y el nombre de la liga, así que el cuerpo de la ficha medía **56,8 / 77,2 / 97,5 px**
   y las cajas del listado, 264,7 u 285,1. Con la cuadrícula de escritorio eso además se contagia: una
   ficha alta estira toda su fila.

   La salida es la de siempre en este proyecto — **lo que cede es el texto, no la forma**: cada renglón va
   en una línea que no se parte y lo que sobra se recorta con puntos suspensivos. El nombre lleva `title`
   por lo mismo que los de las tablas de ficha: si se recorta, el completo tiene que estar en alguna
   parte. */
.mtg-torneo-nombre {
  display: block;
  overflow: hidden;
  color: var(--bs-body-color);
  font-weight: 600;
  text-decoration: none;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-torneo-nombre:hover {
  color: var(--bs-body-color);
}

/* Los dos renglones de datos: **una fila que no se parte**, y cada dato se recorta por su cuenta.

   Se probó primero con `display: block` y un solo `text-overflow` para todo el renglón, y no vale: el
   distintivo de liga es una caja `inline-flex` —lleva icono— y `text-overflow` no recorta cajas, las
   clipa. El resultado era «Liga Premodern Alicante» cortado a hueso contra el borde, sin puntos
   suspensivos. Con flex, cada hijo lleva su propio recorte y el que sobra pierde letras con aviso. */
.mtg-torneo-meta,
.mtg-torneo-datos {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
  margin: 0.1rem 0 0;
  color: var(--bs-secondary-color);
  font-size: 0.85rem;
}

/* `min-width: 0` en todos: sin él, un hijo flexible no baja de su ancho de contenido y el recorte no se
   activa nunca. Es la misma trampa que ya está documentada para los nombres de las tablas de ficha.

   **Y `flex-shrink: 0` por defecto**, o sea: nadie encoge salvo quien se declare abajo. Sin esto, un
   renglón apretado reparte el recorte entre todos en proporción a su tamaño y rompe los datos cortos —
   medido en un móvil: «Suiz · 2 jugad… · Liga Premodern Alican…», con el tipo y el recuento destrozados
   para ganarle sitio a un nombre que se recorta igual. Lo que tiene que ceder es **uno solo**. */
.mtg-torneo-meta > *,
.mtg-torneo-datos > * {
  flex: 0 0 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El único que cede: el nombre de la liga. Es el dato más largo y el más prescindible de su renglón —la
   cinta de la esquina ya dice que es una jornada, y el nombre entero está en el torneo. */
.mtg-torneo-datos > .mtg-torneo-liga {
  flex-shrink: 1;
}

/* El punto medio va como separador generado y no en el marcado: así el primero de cada renglón nunca
   empieza por un punto suelto que parezca una viñeta, y añadir o quitar un dato no obliga a mover
   separadores a mano. Va **dentro del hijo que sigue**, así que cuando ese hijo se recorta el punto
   sobrevive —está al principio— y el renglón sigue leyéndose como una lista. */
.mtg-torneo-meta > * + *::before,
.mtg-torneo-datos > * + *::before {
  content: "·";
  margin: 0 0.5rem;
}

/* **El formato no encoge.** Es el único dato del primer renglón, así que ahí siempre cabe entero — y esa
   es justo la propiedad que se buscaba: el primer renglón se lee igual en una jornada que en un torneo
   suelto. Hubo una versión con el nombre de la liga al lado y se apretaban entre sí («Old Fra… · Liga
   Premodern Alic…», los dos rotos); la liga se mudó al segundo renglón por eso.

   En el segundo renglón, lo que cede es **el nombre de la liga**, que va el último: el tipo y los
   jugadores son lo que se busca. */
.mtg-torneo-formato {
  flex-shrink: 0;
}

/* Dentro del distintivo de liga, lo que cede es el nombre y nunca el icono. */
.mtg-torneo-liga-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El distintivo de «esto es una jornada de tal liga».

   Lleva **el nombre de la liga**, no la palabra «liga»: en un club con dos ligas a la vez, «Liga» no
   diría de cuál. Va en el color del cuerpo y en seminegrita, no en acento: el amarillo significa «esto se
   pulsa» y este distintivo no se pulsa —quien pulsa es la ficha entera—.

   `white-space: nowrap` porque un nombre de liga partido en dos dentro de una línea de datos separada por
   puntos medios se lee como dos datos distintos. */
.mtg-torneo-liga {
  color: var(--bs-body-color);
  font-weight: 600;
  white-space: nowrap;
  /* `inline-flex` y no un icono suelto en flujo: dentro de una línea de datos, un SVG en flujo se alinea
     por línea base y arrastra el alto de la caja. Ya mordió en la clasificación de liga, donde un icono de
     1,1 em subió la celda de 20,4 a 26,8 px y dejó el texto de al lado 4,8 px más abajo. */
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

/* A **1 em**, no a 1,1: el icono acompaña al nombre y tiene que medir lo que el nombre. `flex: none` para
   que no lo encoja el reparto cuando el nombre de la liga es largo — lo que cede es el texto, nunca el
   dibujo, que encogido no se lee. */
.mtg-torneo-icono-liga {
  width: 1em;
  height: 1em;
  flex: none;
}

/* Los miembros de la liga que se pueden apuntar de un clic. Píldoras que fluyen, no una lista vertical:
   con veinte miembros una columna se comería la pantalla, y aquí lo que se hace es **buscar un nombre
   conocido**, no leerlos en orden. Cada uno es su propio formulario, así que el `gap` los separa. */
.mtg-miembros-liga {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

/* ---- La clasificación de una liga, en modo tabla ----
   **Las celdas no se parten**, y esto es lo que hace que el scroll horizontal sirva de algo. Sin ello la
   tabla se comprimía para caber siempre: medido a 900 px con 12 jornadas, sus 17 columnas se apretaban en
   861 px —unos 50 px cada una— y nunca aparecía la barra. Con 24 jornadas serían 29 columnas a 30 px, o
   sea columnas ilegibles en lugar de una tabla que se desplaza.

   Con `nowrap` la tabla conserva su ancho natural, `table-responsive` le da el scroll **solo a ella** —la
   página no se mueve— y `data-mtg-arrastrable` permite recorrerla con el ratón.

   Solo en modo tabla: en ficha las celdas son bloques y esto no aplica. */
@media print, (min-width: 768px) {
  .mtg-tabla-liga th,
  .mtg-tabla-liga td {
    white-space: nowrap;
  }
}

/* ---- Una caja que se desplaza arrastrando con el ratón ----
   Lo usa la clasificación de una liga: con 24 jornadas la tabla se sale bastante del ancho, y con ratón
   la única forma de llegar al final era la barra de abajo o `shift` + rueda, que no todo el mundo conoce.

   Acotado a **puntero fino**: con el dedo el navegador ya desplaza al arrastrar y no hay cursor que
   enseñar. Y `.mtg-arrastrando` la pone el JavaScript solo mientras dura el gesto. */
@media (pointer: fine) {
  /* `.mtg-desplazable` la pone `site.js` cuando la caja de verdad se sale de su ancho: CSS no puede
     comparar `scrollWidth` con `clientWidth`, y un cursor de «arrástrame» sobre una tabla que cabe
     entera promete algo que no pasa. */
  [data-mtg-arrastrable].mtg-desplazable {
    cursor: grab;
  }

  [data-mtg-arrastrable].mtg-arrastrando {
    cursor: grabbing;
    /* Mientras se arrastra no se selecciona texto: sin esto el gesto pinta media tabla de azul. */
    user-select: none;
  }
}

/* ---- El podio de una jornada: oro, plata y bronce ----
   Marcan las tres cosas que **de verdad se comparan** en el desempate de la liga, así que contar los
   colores de una fila es auditarlo. El color nunca es el único canal: cada celda lleva su texto oculto
   («2.º de la jornada 5») y su `title`.

   El oro es el acento del proyecto, que ya está medido en los dos temas (7,34 oscuro / 5,94 claro). La
   plata y el bronce llevan **un tono por tema**, porque son colores claros: el bronce claro sobre fondo
   blanco se quedaba en 2,4. Los valores de abajo están medidos sobre `--bs-body-bg`. */
.mtg-podio-1 {
  color: var(--mtg-oro);
  font-weight: 700;
}

.mtg-podio-2 {
  color: var(--mtg-plata);
  font-weight: 700;
}

.mtg-podio-3 {
  color: var(--mtg-bronce);
  font-weight: 700;
}

/* El botón que abre el detalle de jornadas de un jugador, en la ficha de móvil. Discreto a propósito:
   es una consulta secundaria y no debe competir con el nombre. Sin `btn-outline-*` porque un contorno
   al lado de cada nombre convertiría la lista en una rejilla de botones. */
/* El botón que abre el detalle de jornadas de un jugador, en la ficha de móvil.

   Va **en absoluto, en la esquina de abajo a la derecha**, justo debajo del dato destacado. Antes iba en
   línea al final de los datos y se movía con ellos: como el medallero aparece o no según el jugador, el
   botón bailaba de sitio en cada fila. Con una posición fija se aprende dónde está y se pulsa sin mirar.

   Es la misma técnica que ya usan las dos esquinas de la ficha —el ordinal y el destacado—, y funciona
   por lo mismo: la fila es `position: relative` en modo ficha. */
.mtg-ver-jornadas {
  position: absolute;
  right: 0.25rem;
  bottom: 0.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.2rem 0.3rem;
  border: 0;
  color: var(--bs-secondary-color);
  line-height: 1;
}

.mtg-ver-jornadas:hover,
.mtg-ver-jornadas:focus-visible {
  color: var(--bs-body-color);
}

/* La medalla y su cifra, pegadas: «🥇3». El icono va **antes** y sin hueco declarado —el espacio lo pone
   el margen de abajo— para que el par se lea como una unidad y no como dos datos. */
.mtg-medalla {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  white-space: nowrap;
  font-weight: 700;
}

/* El icono hereda el color de la clase de podio que lo envuelve, así que la medalla se declara **una
   sola vez** y sirve para los tres metales. `em` y no `rem`: así acompaña al tamaño del texto de donde
   esté —la leyenda es más pequeña que la tabla— sin declararlo dos veces. */
.mtg-medalla-icono {
  width: 1.1em;
  height: 1.1em;
  flex: none;
}

/* Lo que **solo existe en modo ficha**: la medalla de cada celda —en la tabla ya lo dice la cabecera de
   la columna, y repetirla en 62 filas eran 186 iconos de más— y el botón que abre el detalle por jornada.

   Se esconde declarando `display: none` **de 768 px en adelante**, y no al revés. La versión anterior
   ponía `none` en la base y `block` en el bloque de ficha, y eso **imponía el display a todo lo que
   llevara la clase**: al botón, que es `inline-flex`, le metía `block` y se iba a su propio renglón
   debajo de los datos. Así cada elemento conserva el suyo y la clase solo decide si se ve.

   Con `print` porque al imprimir las media queries miden la hoja y ahí la clasificación sale como tabla,
   no como fichas. */
@media print, (min-width: 768px) {
  .mtg-solo-ficha {
    display: none;
  }
}

/* La leyenda de los tres colores, encima de la tabla. Separada del texto de desempates con un punto
   medio generado, como la línea de datos de una ficha. */
.mtg-leyenda-podio {
  white-space: nowrap;
}

.mtg-leyenda-podio::before {
  content: "·";
  margin: 0 0.35rem;
}

.mtg-leyenda-podio > span + span {
  margin-left: 0.3rem;
}

/* Quién gana la liga. Va **en acento** al contrario que el distintivo de arriba, y aquí sí toca: no es
   que se pulse, es que es el único sitio de la pantalla donde el oro significa lo que significa en el
   cuadro de un torneo —el camino del campeón—. El icono hereda el color con `currentColor`, así que no
   hay que declararlo dos veces. */
.mtg-campeon-liga {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--mtg-acento);
  font-size: 1.05rem;
}

/* El icono **necesita su tamaño aquí**, y no es un detalle: `.mtg-accion-icono` no lo declara —lo hereda
   del contexto de la barra de acciones, donde vive—, así que fuera de ella un SVG sin ancho se estira a
   lo que le dé el contenedor. Salió a 110 px de alto ocupando media pantalla del móvil. */
.mtg-campeon-liga .mtg-accion-icono {
  flex: none;
  width: 1.375rem;
  height: 1.375rem;
}

/* El tipo de torneo: icono + rótulo, y el icono **acompaña, no sustituye**. `baseline` y no `center`
   porque va dentro de una línea de texto: centrado se despega del renglón. */
.mtg-tipo {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  white-space: nowrap;
}

.mtg-tipo-icono {
  width: 1em;
  height: 1em;
  /* Un `<svg>` se alinea por su borde inferior, así que sobre la línea base queda alto. Este empujón
     es el mismo truco que usa cualquier icono en línea, y va en `em` para que siga a la letra. */
  transform: translateY(0.13em);
  flex: none;
}

.mtg-torneo-lado {
  flex: 0 0 auto;
  text-align: end;
}

.mtg-torneo-estado {
  display: block;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.mtg-torneo-fecha {
  display: block;
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
  white-space: nowrap;
}

/* La miniatura de la ficha del listado: **a todo el alto de la ficha y pegada al borde**, antes del
   texto. `align-self: stretch` es lo que la estira; el `padding` de la ficha se cancela por ese lado con
   un margen negativo, para que la imagen llegue al borde y no quede flotando en un marco.

   `object-fit: cover` porque una imagen de torneo es un cartel o una foto y recortarla es lo que se
   espera. El logo de un formato va al revés, con `contain`: un logo se ve entero o no se ve. */
/* **7 rem y no 4,5**: los logos de formato son tiras de 1,7:1 y con la caja casi cuadrada `cover` se
   comía los lados —en el listado se veía el centro del tapete y poco más—. A 112 px sobre una ficha de
   70 la proporción queda en 1,6, casi la del tapete, así que apenas recorta. */
.mtg-torneo-miniatura {
  flex: none;
  align-self: stretch;
  width: 7rem;
  margin: -0.7rem 0 -0.7rem -0.9rem;
  border-radius: var(--bs-border-radius) 0 0 var(--bs-border-radius);
  overflow: hidden;
  /* Una URL externa que no cargue deja el hueco, y el hueco tiene que parecer un hueco y no un fallo
     de maquetación: el fondo lo delimita. */
  background: var(--bs-tertiary-bg);
}

/* En absoluto, por lo mismo que en el listado de formatos: así llena la ficha entera sin poder
   estirarla. Con el contenido en flujo, las fichas con imagen medían 70 px y las de iniciales 74. */
.mtg-torneo-miniatura {
  position: relative;
}

.mtg-torneo-miniatura > img,
.mtg-torneo-miniatura > .mtg-iniciales {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---- En móvil la imagen deja de estirarse ----
   `align-self: stretch` funciona en escritorio porque la ficha mide 70 px y la caja sale en 112×68, casi
   la proporción del tapete (1,71), así que `cover` apenas recorta. En móvil la ficha se va a 176 px y esa
   misma regla daba una caja de **112×194**: el tapete quedaba convertido en una tira vertical de la que
   se veía el centro y nada más.

   Con alto fijo y pegada arriba, la imagen conserva su forma y **deja de mandar en el alto de la ficha**,
   que vuelve a decidirlo el texto.

   Va en su propia media query y **después** de la regla base, no en el bloque de móvil de más arriba:
   misma especificidad, y con la misma especificidad manda el orden de fuente. Y con la guarda `screen`,
   por lo mismo que el bloque de arriba: en papel, filas. */
@media screen and (max-width: 767.98px) {
  /* ---- En móvil la imagen deja de ocupar sitio: pasa a ser el fondo de la ficha ----
     Como columna costaba mucho y encima descuadraba: `align-self: stretch` daba una caja de 112×194 —el
     tapete convertido en tira vertical— y quitarle ancho al texto subía la lista de 2029 px a 3100.

     De fondo cuesta **cero**: la ficha vuelve a medir lo que mide su texto y el tapete se sigue
     reconociendo. Va con un `<img>` en absoluto y no con `background-image` en un atributo `style`,
     porque la imagen de un torneo es **una URL que escribe el usuario** y no tiene por qué acabar dentro
     de un `url()` de CSS. */
  .mtg-torneo-miniatura {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    margin: 0;
    border-radius: inherit;
    background: none;
  }

  /* El velo que hace legible el texto: opaco donde va, y se abre hacia la derecha para dejar ver el
     tapete. El degradado usa el color del cuerpo, así que funciona en los dos temas sin declararlo dos
     veces. Y vive en `--mtg-velo-ficha` porque **la forma compacta se usa en dos sitios** —aquí para
     todos los listados en móvil, y en cualquier tamaño para las jornadas de una liga—: con dos copias del
     degradado, el día que se ajuste una quedaría la otra distinta sin que nadie lo decidiera. */
  .mtg-torneo-miniatura::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--mtg-velo-ficha);
  }

  /* Aquí vivía el tinte de fondo de una jornada, apilado delante del velo. **Se quitó al poner la cinta
     de esquina**: con las dos señales, el matiz de fondo no añadía nada que la cinta no dijera antes. La
     cinta funciona igual en móvil porque aquí la miniatura cubre la ficha entera, así que su esquina
     superior derecha *es* la de la caja.

     ---- Y por eso mismo, aquí la cinta **cuesta ancho** ----
     En escritorio la cinta cae sobre la cabecera de imagen, donde no hay texto. En móvil la imagen es el
     fondo de la ficha entera, así que la esquina que ocupa es la misma en la que acaban los dos primeros
     renglones: medido, el nombre y la línea de formato llegaban a x=348 con la cinta empezando en 270, o
     sea metiéndose debajo.

     Se les reserva el hueco. **Solo a esos dos** —el tercero queda por debajo de la cinta— y solo en las
     fichas de liga, que son las únicas que la llevan. El precio es que ahí el nombre se recorta antes, y
     es el correcto: lo que cede es el texto, que tiene su `title`, no la señal. */
  .mtg-torneo[data-liga] .mtg-torneo-nombre,
  .mtg-torneo[data-liga] .mtg-torneo-meta {
    padding-right: 3.4rem;
  }

  /* El texto, por encima del velo. Sin esto quedaría debajo y no se vería nada. */
  .mtg-torneo-cuerpo,
  .mtg-torneo-lado {
    position: relative;
  }

  /* ---- El estado y la fecha bajan a su propia línea ----
     Iban en una tercera columna, y una columna **reserva su ancho en toda la altura de la ficha**: el
     nombre no podía llegar al borde ni cuando a su derecha solo había hueco vacío. Con la imagen a
     112 px al nombre le quedaban 130 y «Prueba 12 rondas» se partía en dos. Lo vio el organizador.

     Con `flex-wrap` y una base del 100 %, el estado se va a su renglón y el nombre recupera todo el
     ancho. En escritorio no hace falta: ahí sobra sitio y la columna se lee mejor alineada a la derecha. */
  .mtg-torneo {
    flex-wrap: wrap;
  }

  .mtg-torneo-lado {
    flex: 0 0 100%;
    text-align: start;
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
  }
}

/* La imagen de la cabecera del torneo, junto al título. Misma decisión y mismo motivo. */
.mtg-torneo-imagen {
  flex: none;
  width: 3.5rem;
  height: 3.5rem;
  object-fit: cover;
  border-radius: var(--bs-border-radius);
  background: var(--bs-tertiary-bg);
}

/* Las reglas del torneo: texto plano, y **`pre-wrap` es toda la regla** — respeta los saltos de línea
   que escribió el organizador y sigue partiendo las líneas largas. Sin markdown no hay nada que sanear,
   porque lo escapa la propia plantilla. */
.mtg-reglas > summary {
  color: var(--bs-secondary-color);
  cursor: pointer;
}

.mtg-reglas-texto {
  white-space: pre-wrap;
  margin: 0.5rem 0 0;
  /* No más ancho que un párrafo legible: las reglas de un torneo son prosa, y a todo lo ancho de una
     pantalla de escritorio se leen mal. */
  max-width: 60ch;
}

/* ---- El nombre del formato, en color de cuerpo y no en azul de enlace ----
   Es una corrección de contraste con una cifra detrás, no una preferencia. El `--bs-link-color` de
   Bootstrap (`#0d6efd`) da **4,50 sobre el blanco del cuerpo** —justo en la raya del 4,5— y **3,78 sobre
   `--mtg-celda-fondo`**, que en tema claro se queda en `rgb(235,235,235)`. O sea que el día que la fila
   pasó a ser una caja con superficie propia, el nombre cayó por debajo del mínimo **sin que nada fallara**.
   Lo encontró el medidor de `tools/qa/medir.js` en su primera pasada de verdad.

   La salida no es oscurecer el azul sino la que ya usaba la ficha de torneo: **color de cuerpo y
   semibold**, con el subrayado como afordancia. Además de arreglar la cifra, deja los dos listados
   diciendo lo mismo con lo mismo, que era el objetivo de ponerlos los dos en cajas. */
.mtg-tabla-fichas:has(td.mtg-columna-logo) td[data-ficha-titulo] > a {
  color: var(--bs-body-color);
}

.mtg-tabla-fichas:has(td.mtg-columna-logo) td[data-ficha-titulo] > a:hover {
  color: var(--bs-body-color);
}

/* ---- El logo de un formato ----
   **`contain` y alto fijo**, al revés que la miniatura de un torneo. No es preferencia: los seis logos
   que publican los formatos son tiras de 2:1 a 3,8:1 —el más ancho, 1440×600—, y recortarlos a un
   cuadrado con `cover` se comería más de la mitad de lo que sirve para reconocerlos. Así se pintan
   enteros y lo que varía es el ancho, no el alto, que es lo que mantiene las filas iguales.

   `max-width` para que un logo casi cuadrado no se lleve media columna. */
/* ---- La columna del logo, a todo el alto de la fila ----
   En una tabla, la única forma de que algo llene la fila es que **sea la celda**: un hijo con
   `height: 100%` necesita que su padre tenga una altura definida, y la de un `<td>` la decide el
   contenido. El truco de siempre —y es un truco, no hay otra en tablas— es `height: 1px` en la celda:
   la fila la ignora y la estira a su alto real, pero pasa a contar como definida, así que el `100%` de
   dentro se resuelve contra ella. */
/* ---- El alto de la fila lo pone esta celda ----
   Aquí había `height: 1px`, que es el truco para que el hijo pueda medir `100%`. Servía para eso y para
   nada más: **la fila la seguía midiendo la celda del nombre** —62 px— y subir el relleno no cambiaba
   nada, porque el contenido de esta va en absoluto y no ocupa. Medido: con más relleno la fila seguía
   en 62 y al tapete le tocaban 72×42.

   Con una altura de verdad, esta celda pasa a ser la que manda: en una tabla el `height` de un `<td>` es
   un **mínimo** para la fila, así que tiene que ser mayor que los 62 px que mide la del nombre — con 60
   no pasaba nada, que fue el primer intento. Con `box-sizing: border-box` los 76 incluyen los 8+8 de
   relleno, así que a la caja le quedan 60 y el tapete pasa de 77×45 a 103×60.

   **El relleno no se toca desde aquí**: Bootstrap lo declara en `.table > :not(caption) > * > *`, que
   tiene más especificidad que una clase suelta. Un `padding` aquí no haría nada, y estuvo puesto sin
   hacerlo. */
.mtg-columna-logo {
  width: 1%;
  height: 76px;
}

/* El contenido va en **absoluto dentro de la caja**, y esa es la pieza que hace que esto funcione: así
   llena la fila entera sin poder empujarla. Con la imagen en flujo, un logo más alto que los demás
   estiraba su fila —medido: la de Premodern salía en 73 px y el resto en 62—, y una lista con filas
   desiguales es justo lo que se venía a arreglar. */
.mtg-logo-caja {
  position: relative;
  height: 100%;
  width: 6.5rem;
  border-radius: var(--bs-border-radius);
  overflow: hidden;
}

.mtg-logo-caja > .mtg-logo-formato,
.mtg-logo-caja > .mtg-iniciales {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* ---- En móvil el logo tampoco es una columna: es el fondo de la ficha ----
   Lo mismo que en el listado de torneos y por petición del organizador, que lo vio allí primero. Aquí
   gana **más**, porque lo que sustituye no es una columna estrecha sino una **tira de 44 px** encima de
   cada ficha: el logo pasa a costar cero. Medido con los siete formatos a 375 px: la tabla baja de
   **1136 px a 964** (−15 %) y la ficha de 149-196 a 118-165.

   Antes de esto la celda tenía `height: auto` y la caja `2.75rem`, que era el arreglo del `height: 1px`
   —el truco para que el hijo mida `100%` dentro de una tabla— al dejar de estar dentro de una tabla: por
   debajo de 768 px cada celda es un bloque y ese 1 px es una altura de verdad, así que el logo
   desaparecía. Ese problema ya no existe porque la caja va en absoluto contra la ficha.

   **Va aquí y no en el bloque de modo ficha de más arriba**: misma especificidad, y con la misma
   especificidad manda el orden de fuente. Desde allí, la regla base la pisaría.

   **`screen`, no `max-width` a secas**: al imprimir las media queries miden la hoja, y un A4 vertical
   son ~703 px — sin la guarda, el listado se imprimiría con la imagen de fondo y el velo. Es la misma
   corrección que ya llevan las tablas en modo ficha. En papel queda la tabla de siempre. */
@media screen and (max-width: 767.98px) {
  /* ---- La fila tiene que ser una caja antes de poder tener fondo ----
     Una ficha de tabla es hoy una **fila con una raya abajo**: sin fondo, sin borde y sin esquinas. Una
     imagen de fondo necesita un contorno que la recorte, así que esto es requisito y no adorno. Queda
     igual que la ficha del listado de torneos, que ya era una caja.

     **`:has()` y no una clase en el marcado**, por lo mismo que en la regla del ordinal de más arriba:
     quien sabe si hay logo es la propia tabla. `.mtg-tabla-fichas` la comparten la clasificación, la
     cola, el plantel y los formatos — sin acotar, esto convertiría en cajas las cuatro. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody tr {
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
    background: var(--mtg-celda-fondo);
    margin-bottom: 0.5rem;
    overflow: hidden;
    padding: 0.7rem 0.6rem;
  }

  .mtg-tabla-fichas tbody td.mtg-columna-logo {
    position: absolute;
    inset: 0;
    height: auto;
    padding: 0 !important;
  }

  .mtg-tabla-fichas .mtg-logo-caja {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    border-radius: inherit;
  }

  /* `cover` y **sin la plaquita blanca**, al revés que en escritorio: de fondo, la plaquita pintaría la
     ficha entera de blanco. Eso obliga a que los logos tengan color propio — ver la nota de la plaquita
     más abajo, que es la que explica por qué Old Frame Vintage pasó a ser un tapete. */
  .mtg-tabla-fichas .mtg-logo-caja > .mtg-logo-formato {
    object-fit: cover;
    background: none;
    padding: 0;
    border-radius: 0;
  }

  /* ---- El velo, opaco hasta el 68 % y no hasta el 52 % como en torneos ----
     Y la diferencia está medida, no copiada: en la ficha de un formato el texto llega **más a la
     derecha** —el identificador en monoespaciada acaba en el 72 % del ancho— y con el velo de torneos
     se quedaba en **4,31 de contraste en oscuro y 4,43 en claro**, por debajo del 4,5 de un texto
     normal. Con la zona opaca en el 68 % el peor caso sube a **6,39 / 4,50**, y lo que importa es que
     ese peor caso ya no depende de la imagen: es el azul del enlace sobre el fondo de siempre. */
  .mtg-tabla-fichas .mtg-logo-caja::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
      90deg,
      var(--bs-body-bg) 0%,
      var(--bs-body-bg) 68%,
      rgb(from var(--bs-body-bg) r g b / 0.75) 88%,
      rgb(from var(--bs-body-bg) r g b / 0.6) 100%);
  }

  /* El texto, por encima del velo. Sin esto quedaría debajo y no se vería nada. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td:not(.mtg-columna-logo) {
    position: relative;
  }
}

.mtg-logo-formato {
  display: block;
  object-fit: contain;
  object-position: center;

  /* ---- La plaquita blanca, y no es decoración ----
     **Hay logos que son negro puro sobre transparencia** —un SVG sin `fill` es el mismo caso que hizo
     invisibles los símbolos de edición— y sobre el fondo oscuro, que es el de por defecto, no se ven.
     Medido pintándolos en un canvas: color medio [0,0,0].

     La plaquita los salva **aquí, en escritorio**, donde el logo ocupa una caja suya. En móvil ya no
     puede: ahí el logo *es* el fondo de la ficha y una plaquita la pintaría entera de blanco. Así que
     por debajo de 768 px la plaquita se quita y **el logo tiene que traer color propio**. Eso es lo que
     obligó a convertir el de Old Frame Vintage en un tapete: medido en la banda que se ve, su PNG era
     **88 % transparente con la tinta en luminancia 0**, o sea invisible en cuanto se le quita el fondo.

     Se resuelve con un fondo claro y no con `filter: invert(1)` como los símbolos de edición: aquel vale
     porque son monocromos, y aquí invertir destrozaría los cuatro logos que sí llevan color.

     Va **en los dos temas** en lugar de solo en oscuro, y sale gratis: estos logos están hechos para las
     páginas claras de sus webs, y en tema claro la plaquita se confunde con el fondo. Una regla en vez
     de dos, y el mismo resultado. */
  background: #fff;
  padding: 0.15rem 0.3rem;
  border-radius: var(--bs-border-radius-sm);
}

.mtg-logo-formato-grande .mtg-logo-formato,
.mtg-logo-formato-grande .mtg-iniciales {
  width: auto;
  height: 3.5rem;
  max-height: none;
  max-width: 22rem;
  margin-bottom: 0.5rem;
}

.mtg-logo-formato-grande .mtg-iniciales {
  width: 3.5rem;
  border-radius: var(--bs-border-radius);
}

/* ============================================================================
   LOS DOS LISTADOS EN ESCRITORIO: CUADRÍCULA DE CAJAS
   ============================================================================
   Decisión del organizador del 7 de agosto de 2026, con las dos variantes capturadas delante y la
   referencia de la cuadrícula de tolaria.app: **imagen grande arriba, texto debajo**, y las columnas
   que quepan. Sustituye a las filas con la miniatura de 7 rem, que se quedaban flojas — la imagen a
   112×68 no enseñaba casi nada del tapete; aquí pasa a ~300×144, cinco veces el área.

   El precio está medido y se asume: por debajo de ~1100 px de ventana las cajas ocupan más alto que
   las filas (a 1000 px, 1511 contra 1324 con 17 torneos). A 1280 son cuatro columnas y gana incluso
   en alto. El responsive lo hace `auto-fill` solo: 4 columnas a 1280, 3 a 1000, 2 en tableta.

   **`screen`, no `min-width` a secas**: al imprimir, las media queries miden la hoja —un A4 horizontal
   son ~1047 px— y sin la guarda el listado se imprimiría en cuadrícula. En papel quedan las filas de
   siempre en torneos y la tabla completa en formatos, que es lo que se quiere en una hoja.

   El móvil no se toca: por debajo de 768 sigue el fondo en degradado, que es lo que el organizador
   dio por bueno («queda muy chula»). */
@media screen and (min-width: 768px) {
  .mtg-torneos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
    gap: 0.75rem;
  }

  .mtg-torneo {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0;
    /* Recorta las esquinas de la imagen contra el radio de la caja. */
    overflow: hidden;
  }

  /* La imagen pasa de columna lateral a cabecera: todo el ancho de la caja y proporción ~2:1, que es
     la de las cuadrículas de referencia y respeta casi entero un tapete de 1,71. El contenido sigue
     en absoluto (regla base), así que llena la cabecera sin poder estirarla. */
  .mtg-torneo-miniatura {
    width: auto;
    height: 9rem;
    align-self: auto;
    margin: 0;
    border-radius: 0;
  }

  .mtg-torneo-cuerpo {
    flex: 0 0 auto;
    padding: 0.6rem 0.8rem 0;
  }

  .mtg-torneo-nombre {
    font-size: 1.05rem;
  }

  /* El estado a la izquierda y la fecha a la derecha, en el pie de la caja. `margin-top: auto` lo
     ancla abajo cuando la línea de datos de arriba ocupa una línea menos que en la caja de al lado:
     sin él, los pies de una misma fila bailaban de altura. */
  .mtg-torneo-lado {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.4rem 0.8rem 0.7rem;
    margin-top: auto;
    text-align: start;
  }

  /* ---- Las jornadas de una liga NO van en cuadrícula: se quedan en la forma compacta ----

     La cuadrícula es lo correcto para *buscar* un torneo entre treinta, que es lo que se hace en
     `/Torneos`. Aquí el problema es otro: **una liga son 24 jornadas y se leen como un calendario**, y
     encima comparten pantalla con la clasificación y con el formulario de datos. En cajas de 9 rem de
     cabecera, llegar a la tabla eran varias pantallas de scroll. Lo pidió el organizador viéndolo.

     Se declara **después** del bloque de cuadrícula y con un selector más específico, así que gana sin
     tocar ninguna de las reglas de arriba: el listado de torneos no se entera de que esto existe. */
  .mtg-jornadas {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  .mtg-jornadas .mtg-torneo {
    flex-direction: row;
    align-items: center;
    gap: 0.9rem;
    padding: 0.7rem 0.9rem;
    overflow: hidden;
  }

  /* La imagen, de fondo y con su velo: la misma forma que en móvil, y el degradado sale de la variable
     compartida en lugar de repetirse aquí. */
  .mtg-jornadas .mtg-torneo-miniatura {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    align-self: auto;
    margin: 0;
    border-radius: inherit;
    background: none;
  }

  .mtg-jornadas .mtg-torneo-miniatura::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--mtg-velo-ficha);
  }

  /* El texto, por encima del velo. Sin esto quedaría debajo y no se vería nada — es el mismo par de
     reglas que en móvil, y olvidarlo es un fallo que se ve enseguida pero no da error. */
  .mtg-jornadas .mtg-torneo-cuerpo,
  .mtg-jornadas .mtg-torneo-lado {
    position: relative;
  }

  .mtg-jornadas .mtg-torneo-cuerpo {
    flex: 1 1 auto;
    padding: 0;
  }

  /* Aquí sí vuelve la columna de la derecha, al contrario que en móvil: en escritorio sobra ancho y el
     estado y la fecha se leen mejor alineados al borde. */
  .mtg-jornadas .mtg-torneo-lado {
    flex: none;
    display: block;
    padding: 0;
    margin-top: 0;
    text-align: end;
  }

  .mtg-jornadas .mtg-torneo-nombre {
    font-size: 1rem;
  }

  /* ---- El listado de formatos, misma cuadrícula sobre el marcado de tabla ----
     El HTML sigue siendo una `<table>` —la cabecera escondida con `clip-path` sigue existiendo para el
     lector de pantalla, igual que en el modo ficha de móvil— y la forma la pone el CSS, acotada con
     `:has(td.mtg-columna-logo)` para no convertir en cajas la clasificación ni las listas de
     inscripción, que comparten `mtg-tabla-fichas`.

     Nota honesta que conviene conservar: por la prueba del proyecto («¿se comparan las celdas de una
     fila con las de al lado?») este listado ES una tabla —Sets, Prohibidas y Restringidas alimentan el
     botón Comparar—. El organizador eligió cajas viendo las dos capturas, y son siete filas: la pérdida
     de comparabilidad está a la vista y asumida. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) {
    display: block;
    /* La caja pinta su propio fondo; el de tabla y el velo de hover de Bootstrap pintarían cada celda
       por su cuenta, que en bloques sueltos sale a parches. */
    --bs-table-bg: transparent;
    --bs-table-hover-bg: transparent;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
    gap: 0.75rem;
  }

  /* La cabecera de imagen se reserva con el relleno de arriba: 9rem de logo más el aire del texto. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody tr {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    align-content: flex-start;
    gap: 0.15rem 0.6rem;
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
    background: var(--mtg-celda-fondo);
    overflow: hidden;
    padding: calc(9rem + 0.6rem) 0.8rem 0.8rem;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody tr:hover {
    border-color: var(--mtg-acento);
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td {
    display: block;
    width: auto;
    border: 0;
    padding: 0;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td.mtg-columna-logo {
    position: absolute;
    inset: 0 0 auto;
    height: 9rem;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) .mtg-logo-caja {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    border-radius: 0;
  }

  /* De cabecera, el logo llena y sin plaquita — igual que en el fondo de móvil, y con la misma
     consecuencia: un logo de la semilla tiene que traer color propio. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) .mtg-logo-caja > .mtg-logo-formato {
    object-fit: cover;
    background: none;
    padding: 0;
    border-radius: 0;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td[data-ficha-titulo] {
    flex: 0 0 100%;
    margin-bottom: 0.2rem;
  }

  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td[data-ficha-titulo] a {
    font-size: 1.05rem;
  }

  /* Las cifras llevan su etiqueta delante, como en el modo ficha de móvil: sin cabecera de columna a
     la vista, un «11» suelto no dice nada. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td[data-etiqueta]::before {
    content: attr(data-etiqueta) " ";
    color: var(--bs-secondary-color);
    font-size: 0.8rem;
  }

  /* El marcador de comparar, flotando sobre la imagen. Su fondo ya es opaco —`form-check-input` pinta
     el del tema—, así que se ve sobre cualquier tapete. */
  .mtg-tabla-fichas:has(td.mtg-columna-logo) tbody td:first-child {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 2;
  }
}

.mtg-listado-vacio {
  padding: 1rem 0;
  color: var(--bs-secondary-color);
}

/* **`[hidden]` no gana a un `display` de autor.** La regla del navegador es `display: none` con
   especificidad de hoja de usuario-agente, así que el `display: flex` de estas dos clases la pisa y el
   elemento se sigue viendo. Hay que decirlo a mano, y es de los fallos que no dan error: se esconde
   con JavaScript, el atributo aparece en el DOM y en pantalla no cambia nada. */
.mtg-torneo[hidden],
.mtg-torneos[hidden] {
  display: none;
}

/* ============================================================================
   IMPRIMIR EL CUADRO
   ============================================================================
   Para dos cosas concretas del organizador: sacar el cuadro en papel y pegarlo en la pared, y
   tener un PDF (que lo da el propio diálogo de imprimir, sin generarlo nosotros).

   Tres decisiones que se toman aquí y **no** las decide quien imprime:

   · **Horizontal.** Un cuadro es ancho por definición; en vertical no cabe ni un top 8.
   · **A dos lados.** La forma en línea de un top 32 mide 1697 px de alto (medido) y en una hoja
     horizontal queda ilegible. A dos lados parte la altura por la mitad.
   · **Tema claro.** Imprimir el tema oscuro es una hoja negra: gasta tinta y se lee peor. El tema
     es un atributo del <html>, así que se cambia y se restaura en `beforeprint`/`afterprint`,
     igual que la forma del cuadro — sin duplicar una sola regla de las que ya existen.

   Lo que **sí** hace falta declarar aquí es que los colores salgan: por defecto los navegadores
   descartan fondos al imprimir, y con eso se irían el relleno de acento del ganador y el velo de
   las fichas. Sin `print-color-adjust: exact` el cuadro sale sin la mitad de su información. */
@media print {
  /* **Aquí NO va el `@page`**, y esa es la corrección del fallo que sacó dos PDF inservibles: un
     `@page` **anidado dentro de `@media print` no se aplica** en los navegadores basados en Chromium,
     así que la hoja salía vertical por mucho que dijera `size: A4 landscape`. La prueba estaba en el
     propio PDF —`/MediaBox [0 0 595.32 841.92]`, A4 en vertical— y la segunda prueba, más sutil, en
     que la forma a dos lados no aparecía: con la hoja en vertical el área mide ~700 px y no llegaba a
     los 992 de la forma de escritorio.

     Lo inyecta `site.js` **al nivel superior** de una hoja aparte, y de paso eso resuelve que haya
     tres impresiones con dos orientaciones distintas: horizontal para el cuadro, vertical para la
     clasificación y para los emparejamientos. Un documento solo puede declarar un `@page`, así que
     tiene que ser el que toque en cada impresión. */
  html,
  body {
    background: #fff !important;
  }

  /* Los colores con significado se imprimen tal cual. Es lo que salva el hilo del ganador, el
     relleno de acento y los conectores. */
  * {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }

  /* Fuera todo lo que no es el cuadro: navegación, pie, grafo de fases, franja de
     características, título de la página, avisos, barra de acciones, y los propios controles de
     vista — un botón «Imprimir» impreso en el papel no tiene ninguna gracia. */
  header,
  footer,
  .mtg-fases,
  .mtg-caracteristicas,
  .mtg-barra-acciones,
  .mtg-nota-de-estado,
  .alert,
  .modal,
  .mtg-cuadro-cabecera,
  .mtg-pestanas,
  .mtg-selector-rondas,
  .mtg-ir-a-ronda,
  [data-mtg-imprimir],
  [data-mtg-cuadro-forma] {
    display: none !important;
  }

  /* Los contenedores se quedan sin relleno ni márgenes, y **eso no es limpieza estética**: el zoom
     se calcula contra el ancho de la hoja, así que cualquier relleno por fuera del cuadro se suma a
     ese ancho y desborda. Lo destapó el emulador de impresión: sobraban 27 px y la hoja se partía
     en dos. El `container-fluid` de Bootstrap mete su `--bs-gutter-x` por los dos lados. */
  .mtg-contenedor,
  main,
  .mtg-fase-cuerpo {
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    background: none !important;
    max-width: none !important;
  }

  /* El `<h1>` con el nombre del torneo y el botón de volver: la cabecera del papel ya lleva el
     nombre, y un botón impreso no sirve para nada. */
  .mtg-fase-cuerpo > .py-3 > .d-flex,
  body > .py-3 > .d-flex:first-child {
    display: none !important;
  }

  /* La cabecera del papel, que en pantalla no existe. */
  .mtg-cabecera-impresion {
    display: flex !important;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 1rem;
    margin-bottom: 4mm;
    font-size: 11pt;
  }

  .mtg-cabecera-impresion strong {
    font-size: 14pt;
  }

  /* ---- El cuadro cabe por construcción, sin escalar nada ----
     Aquí hubo dos intentos fallidos y los dos por la misma razón: **suponer el tamaño de la hoja en
     píxeles**. El primero medía el cuadro con `getBoundingClientRect` (caja con scroll: 1209 en vez
     de 2496) y el segundo calculaba un factor de `zoom` contra 1047 px de hoja que no eran los
     reales — un top 32 salió con 6 de sus 9 columnas y el resto cortado.

     La forma que no puede fallar es dejar de contar en píxeles: **el ancho de columna se declara en
     milímetros de hoja**. Un A4 horizontal menos los márgenes de 10 mm da 277 mm útiles, y el
     servidor dice cuántas columnas hay (`--mtg-columnas`), así que cada una mide lo que le toca y la
     suma es exactamente el ancho de la hoja. No hay `zoom`, no hay medida, no hay nada que suponer.

     El precio es que en un top 32 la columna se queda en 29 mm y la letra en 6,5 pt: es pequeño, y
     es el tamaño real de meter nueve columnas en un A4. Con menos rondas se ensancha solo. */
  /* Las tres medidas de hoja se declaran **en el fragmento y no en la rejilla**: describen el papel, no
     el cuadro, y el partido por el tercer puesto —que vive fuera de la rejilla— necesita heredarlas para
     salir del mismo ancho y con la misma letra que una ficha de la llave. */
  #mtg-cuadro-fragmento {
    --mtg-hoja-util: 277mm;
    /* El hueco entre columnas **es el sitio del conector**, no aire: los dos brazos miden medio hueco
       cada uno. Estuvo en 1,5 mm, que dejaba el brazo en 0,75 y la llave casi sin tramo horizontal.
       Medido en el peor caso —un top 32, nueve columnas—, subirlo a 3 mm dobla el conector y cuesta
       0,3 pt de letra y un carácter de nombre: la columna pasa de 29,4 a 28,1 mm. De ahí en adelante ya
       solo se paga letra sin ganar nombre (4 mm → 5,9 pt y los mismos 14 caracteres), así que 3 es la
       rodilla de la curva. */
    --mtg-hueco-papel: 3mm;
    --mtg-columna-papel: calc(
      (var(--mtg-hoja-util) - (var(--mtg-columnas, 5) - 1) * var(--mtg-hueco-papel))
      / var(--mtg-columnas, 5));
  }

  .mtg-cuadro {
    /* ---- Los grises del tema claro no valen sobre papel ----
       El borde de la ficha es `--bs-border-color`, que en claro es `#dee2e6`: **1,30 de contraste** sobre
       el blanco de la hoja. O sea que el recuadro de la ficha prácticamente no existía, y el fondo de su
       franja (`#f8f9fa`) daba **1,05**, indistinguible del papel. Lo vio el organizador en el PDF.

       Se corrige **redefiniendo la variable en el cuadro** y no rescribiendo los tres bordes que la usan
       —el de la ficha, el de debajo de la franja y el que separa a los dos jugadores—, que es la forma de
       que no se quede uno atrás. `#6c757d` da **4,69**, muy por encima del 3:1 que se le pide a un
       gráfico con significado, y **se queda por debajo del 5,94 del hilo dorado**: así el camino del
       campeón sigue pesando más que el marco de las cajas. La casilla vacía no se ve afectada porque
       declara su color aparte (`--bs-secondary-color`, 5,76), y ahí la señal es el discontinuo. */
    --bs-border-color: #6c757d;

    overflow: visible !important;
    width: 100% !important;
    gap: var(--mtg-hueco-papel) !important;
    /* **La letra es una fracción del ancho de columna**, no una resta con un coeficiente ajustado a
       mano. Con eso entran los mismos caracteres por nombre en los tres tamaños, que es lo que de
       verdad se quiere: un top 32 no necesita «letra pequeña», necesita la letra que le corresponde a
       una columna de 29 mm. Sale 6,4 pt en un top 32, 8,4 en un top 16 y 11,8 en un top 8.

       Hubo antes una resta de 0,9 pt por columna, y lo que la delató fue medir: el alto de la ficha
       **no cambiaba** con la letra —53 px de 5,6 a 7,4 pt— porque la franja y la semilla estaban en
       `rem`, así que el número estaba ajustado contra una restricción que no existía. Lo que limita
       de verdad es el ancho, y por eso el ancho es lo que lo decide. El hueco sobra: 22 px de holgura
       en el caso más apretado, medido. */
    font-size: calc(var(--mtg-columna-papel) / 13);
  }

  .mtg-cuadro .mtg-cuadro-mitad {
    gap: var(--mtg-hueco-papel) !important;
  }

  .mtg-cuadro .mtg-cuadro-columna,
  .mtg-cuadro .mtg-cuadro-centro {
    flex: 0 0 var(--mtg-columna-papel) !important;
    min-width: 0 !important;
    width: var(--mtg-columna-papel) !important;
  }

  /* ---- Dentro de la ficha, el espaciado va en `em` y no en `rem` ----
     Es la misma lección que la franja y la semilla, y es la que de verdad decide si el cuadro se
     puede leer. **`rem` es relativo a la raíz**, así que todo el adorno interno de la ficha seguía
     midiendo lo mismo en un top 8 que en un top 32, donde la columna tiene la mitad de ancho. El
     desglose de los 111 px de una columna de top 32, medido: relleno de la ficha 8, **marcador 35**
     —`min-width: 2.2rem`—, relleno de los lados 16, hueco 5, semilla 14… y **17 px para el nombre**,
     o sea ocho caracteres. Con nombres de prueba de cuatro letras («J040») eso no se ve; con un
     «Alejandro Fernández» se ve enseguida, y no como un desborde sino como puntos suspensivos casi
     inmediatos, que es peor porque parece intencionado.

     En `em` el adorno encoge con la columna y el nombre se queda con lo que sobra, que es mucho más.
     La cuenta es la misma en los tres tamaños: proporción constante, ningún número ajustado a mano.

     Los puntos suspensivos ya los pone la regla de pantalla —`.mtg-cruce-nombre` los lleva sin
     condición de medio—, así que aquí no hacen falta. Hubo una regla mía para `.mtg-lado-nombre`, que
     es **la ficha de la fase de rondas**: no hacía nada. Tercera vez que confundo las dos fichas. */
  /* ---- El rótulo de ronda: escalado, y con el alto reservado igual para todos ----
     Otro `rem` que no encogía —12 px, **más grande que el texto de las fichas**, que en un top 32 está
     en 8,2— y esta vez no era solo cuestión de tamaño: en una columna de 28 mm «Cuartos de final» se
     parte en dos líneas mientras «Semifinales» cabe en una, así que **esa columna empezaba 14,4 px más
     abajo que sus vecinas** y con ella todos sus huecos. Los codos de la pareja seguían encontrándose
     entre sí, pero el punto de encuentro se iba 10,8 px del centro de la mesa a la que apuntan. En
     pantalla no se ve porque la columna mide 256 px y ningún rótulo se parte: es un fallo que **solo
     existe en papel**.

     Es el mismo defecto que ya obligó a sacar los rótulos a una fila propia de la rejilla en la forma
     «en línea»; en «a dos lados» seguía vivo. Aquí se cierra reservando **dos líneas para todos**, así
     que las columnas arrancan juntas por construcción y no porque el rótulo más largo quepa por los
     pelos — que es lo que se rompería en silencio el día que aparezca una «Ronda de 128». Y sale
     gratis: dos líneas a 0,9 em ocupan 17,8 px donde las dos grandes ocupaban 28,8. */
  .mtg-cuadro .mtg-cuadro-titulo {
    height: 2.4em;
    line-height: 1.2;
    font-size: 0.9em;
  }

  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-lado {
    gap: 0.25em;
    padding: 0.15em 0.35em;
  }

  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-marcador {
    min-width: 2.2em;
  }

  /* La corona lleva su tamaño en los atributos del `<svg>` —14 px—, que es la otra forma de no encoger.
     En un top 32 salía a 1,6 veces el cuerpo del texto y era lo que dejaba **la final 4 px más alta**
     que las demás fichas: 44,1 contra 39,9, medido. En `em` guarda la misma proporción que en pantalla,
     donde son 14 px junto a un cuerpo de 16. */
  .mtg-cuadro .mtg-corona {
    width: 1em;
    height: 1em;
  }

  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-marcador > span {
    padding: 0 0.35em;
  }

  /* ---- Y el alto, que costó tres intentos ----
     Arreglar solo el ancho dejó un top 32 en 813 px sobre 718 de hoja: cabía a lo ancho y se salía
     por abajo. Los dos intentos fallidos y por qué:

     · **`max-height` en los huecos.** Los huecos son `flex: 1 1 0` y reparten la altura de la
       columna, así que limitarlos no da altura a nadie: la columna se quedó sin nada que repartir y
       todo colapsó a 11 px. Y `overflow: hidden` empeoró la caída, porque le quita al hueco su
       **altura mínima automática** — sin ella ya nada lo sostenía.
     · **La altura en la columna.** También circular: la columna se estira al alto de sus hermanas
       (`align-items: stretch`), o sea que su altura depende del contenido, que es justo lo que se
       quiere limitar.

     Lo que funciona es dársela **al cuadro entero**: el estirado la propaga a las mitades, de ahí a
     las columnas y de ahí al reparto de huecos, que es el mecanismo del que ya dependen los
     conectores para ser exactos.

     Los 148 mm están **medidos a base de ajustar**, no deducidos: 190 de hoja útil menos la cabecera
     del papel (28 px) y el rótulo de ronda (14), y aun así con 172 el documento se iba a 790 px sobre
     718 de hoja, y con 155 se pasaba de 7. */
  .mtg-cuadro {
    height: 148mm !important;
  }

  /* ---- El partido por el tercer puesto también va en la hoja ----
     Está **fuera de la rejilla** —no forma parte de la llave—, así que su alto se suma al del cuadro y
     sin esto el cuadro se iba a una segunda hoja. Los 148 mm están ajustados a mano contra la hoja
     entera, o sea que aquí hay que devolverle a la llave lo que se lleva esta caja: se le quitan, no se
     estira la hoja.

     Se acota con `:has(~ …)` para no encoger el cuadro de los torneos que **no** llevan tercer puesto,
     que son casi todos: sin la guarda, cada cuadro impreso perdería 36 mm de alto sin motivo. */
  .mtg-cuadro:has(~ .mtg-cuadro-tercero) {
    height: 112mm !important;
  }

  /* La ficha del tercer puesto se compacta **con las mismas reglas que las del cuadro**, y por eso esas
     reglas están acotadas con `:is(.mtg-cuadro, .mtg-cuadro-tercero)` en vez de solo a `.mtg-cuadro`.
     Sin eso quedaba fuera de todas y se imprimía con el relleno de pantalla: **90 px de alto contra los
     62 de las demás**, medido, o sea un 45 % más alta al lado de la llave. Lo que **no** se comparte es
     la rejilla ni la altura de hoja, que son del cuadro y no de la ficha. */
  .mtg-cuadro-tercero {
    margin-top: 4mm;
    /* Ancho y letra **los mismos que una columna del cuadro**, con la misma fórmula y no con una cifra
       suelta: `--mtg-columna-papel` se hereda porque se declara en el fragmento y no en la rejilla. Con
       un `8pt` a ojo la ficha salía en 47 px contra los 62 de la llave — el error simétrico del de
       antes, y de los dos el peor es el que parece intencionado. */
    width: var(--mtg-columna-papel);
    font-size: calc(var(--mtg-columna-papel) / 13);
  }

  /* `min-height: 0` es lo que permite que el hueco se encoja por debajo de su contenido: sin él,
     flexbox se niega a bajar del alto natural de la ficha y la columna vuelve a desbordar.

     **Y aquí no puede ir un `overflow: hidden`.** Lo tuvo, arrastrado del intento fallido de limitar el
     alto por los huecos, y el precio fue que **el cuadro se imprimía sin una sola llave**: los
     conectores son pseudo-elementos del hueco que nacen en `left: 100%`, o sea justo fuera de su caja,
     así que recortar el hueco los borra enteros. Lo vio el organizador en el PDF, no yo midiendo — es
     un fallo que no da error y que ninguna de mis comprobaciones de alto podía detectar, porque el
     cuadro cabía perfectamente. Ya no hace falta: la ficha entra de sobra en su hueco (40 px en 66 en
     el caso más apretado), así que no hay nada que recortar. */
  .mtg-cuadro .mtg-cuadro-hueco {
    min-height: 0 !important;
    padding: 0.4mm 0 !important;
  }

  /* ---- Y el brazo del conector mide la mitad del hueco entre columnas ----
     En pantalla eso ya se cumple por casualidad de dos constantes que cuadran: el hueco es `1.5rem`
     (24 px) y los dos brazos —el codo que sale de una mesa y el tramo de entrada de la siguiente—
     miden `0.75rem` cada uno, así que se tocan justo en medio. En papel el hueco pasa a milímetros y
     los brazos seguían en `rem`, con lo que **los 24 px de brazo tenían 5,7 px de sitio**: aunque no
     los hubiera recortado el `overflow`, el codo habría entrado 18 px dentro de la ficha de la columna
     siguiente y el tramo de entrada habría salido por detrás de la anterior.

     Puestos en `calc(hueco / 2)` la relación deja de ser una casualidad y pasa a ser la definición: los
     dos brazos suman el hueco, midan lo que midan. */
  .mtg-cuadro .mtg-cuadro-mitad .mtg-cuadro-hueco::after,
  .mtg-cuadro .mtg-cuadro-columna:not(:first-child) .mtg-cuadro-hueco::before,
  .mtg-cuadro .mtg-cuadro-centro .mtg-cruce::before {
    width: calc(var(--mtg-hueco-papel) / 2);
  }

  /* Y la ficha se compacta —tres renglones, número de mesa y dos jugadores, sin el relleno de
     pantalla— pero **conserva su altura natural y se centra en su hueco**, exactamente igual que en
     pantalla. Aquí hubo un `height: 100%` y era un error de bulto: el hueco de una mesa **se dobla en
     cada ronda** (es lo que hace exactos los conectores), así que estirar la ficha a su hueco daba
     cajas cada vez más altas y una final del alto de la columna entera. Lo vio el usuario en el PDF.

     El alto de la hoja no lo sostiene la ficha: lo sostiene el `height` del cuadro de arriba, que se
     reparte por sí solo. La ficha solo tiene que caber en lo que le toque, y le sobra sitio —en un
     top 32, 40 px de ficha en 70 de hueco—. */
  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce {
    padding: 0.5mm 1mm !important;
    line-height: 1.15;
  }

  /* ---- Y lo que no encogía: la franja y el chip de semilla ----
     Las dos se declaran en `rem`, que es relativo **a la raíz** y no a la ficha, así que se quedaban
     en 12 px por mucho que bajara el cuerpo del cuadro. Dos consecuencias, y la primera es la mala:
     con el nombre del jugador en 7,5 px, **lo que más importa de la ficha era lo más pequeño de la
     ficha**. La segunda es que la altura de la ficha no dependía del cuerpo —medido: 53 px con
     cualquier tamaño entre 5,6 y 7,4 pt—, o sea que bajar la letra no ganaba ni un píxel de sitio.

     En papel pasan a `em`. Con eso la ficha vuelve a escalar con su letra y el cuerpo se puede subir
     hasta lo que de verdad la limita, que es el hueco más pequeño del cuadro. */
  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-franja {
    margin: 0 !important;
    padding: 0 !important;
    line-height: 1.1;
    font-size: 0.85em;
    /* Y el número de mesa **en el color del cuerpo**, no en el secundario: daba **6,59** de contraste,
       que en pantalla basta pero a 6 pt sobre papel no —lo leyó el organizador y le costaba—. Pasa a
       **14,63**. En papel no hay lujo de texto secundario: la jerarquía ya la marcan el tamaño (0,85 em)
       y la banda, y el número de mesa es justo lo que el juez busca con el dedo. */
    color: var(--bs-body-color);
  }

  /* El chip solo tiene que dar cabida a dos dígitos —la semilla más alta de un top 32 es 32—, y su
     `1.35rem` de ancho mínimo no encogía tampoco. */
  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-puesto-chip {
    min-width: 1.4em;
    padding: 0 0.15em;
    font-size: 0.85em;
  }

  /* **`.mtg-cruce-lado`, no `.mtg-lado`**: son dos fichas distintas —la del cuadro y la de la fase de
     rondas— y apuntar a la equivocada fue lo que hizo que esta regla no hiciera nada durante tres
     intentos. La del cuadro lleva `min-height: 32px` por jugador, o sea 64 px de mínimo por ficha, y
     eso es lo que la sacaba de su hueco: 82 px de contenido en 63 de sitio, con 19 recortados por
     abajo — justo la segunda línea, el nombre del segundo jugador. */
  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-lados,
  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-lado,
  :is(.mtg-cuadro, .mtg-cuadro-tercero) .mtg-cruce-marcador {
    min-height: 0 !important;
    padding-top: 0.2mm !important;
    padding-bottom: 0.2mm !important;
  }

  /* **En papel el chip vuelve a ser solo el puesto.** En pantalla dice también de qué grupo viene
     —«1 G4»—, que es lo que distingue a dos ganadores de grupo; aquí no cabe: la columna de un top 32
     mide 28 mm y el chip ya se lleva 14 px de los 111, así que doblarlo saldría del nombre, que es el
     dato. Y en papel el juez tiene la clasificación de grupos al lado. */
  .mtg-puesto-grupo {
    display: none;
  }

  /* ---- La caja de un grupo, en papel ----
     Se queda, y no es adorno: en una hoja de emparejamientos de ocho grupos, lo que dice dónde acaba uno
     es el recuadro. Los fondos sobreviven a la impresión porque más arriba se fuerza
     `print-color-adjust: exact`, así que la cabecera conserva su franja.

     Lo que **no** sobrevive es el gris del tema claro: `--bs-border-color` es `#dee2e6`, **1,30 de
     contraste** sobre el blanco de la hoja, o sea un recuadro que prácticamente no está. Misma corrección
     que el cuadro y por el mismo motivo: se redefine **la variable** dentro de la caja en lugar de
     rescribir sus dos bordes, que es lo que impide que se quede uno atrás. `#6c757d` da **4,69**, por
     encima del 3:1 de un gráfico con significado.

     Y el relleno del cuerpo baja a cero por los lados: en papel las mesas son líneas a todo el ancho, no
     fichas, y una sangría solo les quitaría sitio al nombre. */
  /* Sin `break-inside: avoid`: un grupo de veinte mesas no cabe en una hoja, así que pedir que no se
     parta lo empujaría entero a la siguiente y acabaría desbordándola igual. Lo que no se parte es **la
     mesa**, que ya lo declara por su cuenta. */
  .mtg-grupo-caja {
    --bs-border-color: #6c757d;
  }

  .mtg-grupo-cuerpo {
    padding: 0.5mm 1.5mm !important;
  }

  /* ---- Los emparejamientos: una mesa por línea, en orden de mesa ----
     En pantalla son fichas en rejilla porque un emparejamiento es una unidad, no una fila de celdas
     comparables. En papel se busca lo contrario: una lista que se recorre con el dedo buscando «mesa
     14». Así que la ficha se aplana a una fila con `display: contents` en el cuerpo, que asciende sus
     hijos —los dos lados y el marcador— a huecos de la rejilla de la ficha.

     El orden de mesa lo garantiza el servidor ordenando la lista; aquí solo se cambia la forma. */
  .mtg-mesas {
    display: block !important;
  }

  .mtg-mesa {
    display: grid !important;
    grid-template-columns: 22mm 1fr 16mm 1fr;
    align-items: baseline;
    gap: 0 3mm;
    padding: 1.6mm 0 !important;
    border: 0 !important;
    /* `#999` daba **2,85** sobre el papel, por debajo del 3:1 que se le pide a una línea con
       significado — y esta lo tiene: es lo que separa una mesa de la siguiente en una hoja de 49.
       `#6c757d` da 4,69, el mismo gris que el marco de las fichas del cuadro. */
    border-bottom: 0.2mm solid #6c757d !important;
    border-radius: 0 !important;
    background: none !important;
    font-size: 10pt;
    /* Una mesa no se parte entre dos hojas. */
    break-inside: avoid;
  }

  .mtg-mesa-cuerpo {
    display: contents !important;
  }

  /* El número de mesa, en el color del cuerpo por lo mismo que el del cuadro: en secundario daba 6,78
     y es justo el dato que se busca recorriendo la hoja. Pasa a 15,43. */
  .mtg-mesa-franja {
    margin: 0 !important;
    font-size: 9pt;
    color: var(--bs-body-color) !important;
  }

  /* **La hora no se imprime**, y no es un olvido. En papel la ficha es una rejilla de cuatro columnas y la
     primera —donde vive la franja— mide **22 mm**: «vie 21 ago · 19:00» no cabe ahí, así que partiría cada
     renglón en dos y una hoja de 49 mesas se iría a tres páginas. Y la hoja de pareos existe para una sala
     donde todo el mundo juega a la vez: quien agenda partidas las lee en la agenda, que es una pantalla.
     Si algún día hace falta en papel, necesita **columna propia** y eso cambia la rejilla.

     Vale también para la ficha del cuadro, que usa **la misma clase** porque es el mismo fragmento — y ahí
     hace más falta todavía: su columna mide 28 mm y el chip ya se lleva 14 px. */
  .mtg-mesa-hora {
    display: none !important;
  }

  .mtg-mesa-marcador {
    justify-self: center;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    box-shadow: none !important;
    color: inherit !important;
    font-weight: 700;
  }

  .mtg-mesa-explicacion {
    grid-column: 1 / -1;
    margin: 0 !important;
    font-size: 8pt;
  }

  /* ---- La clasificación: una fila por jugador, con todas las columnas ----
     El modo ficha es de pantalla —ya está acotado con `@media screen`— así que en papel la tabla es
     una tabla. Lo que sí hay que declarar es que la cabecera se repita en cada hoja: con 100
     jugadores son tres, y una tabla sin cabecera a partir de la segunda no se puede leer. */
  .mtg-tabla-fichas thead {
    display: table-header-group !important;
  }

  /* Las líneas entre filas daban **1,30** sobre el papel —`#dee2e6`, el mismo gris del tema claro que
     hacía invisible el marco de las fichas del cuadro—, o sea una tabla de 100 filas y ocho columnas sin
     una sola línea con la que seguir el renglón. `#6c757d` da 4,69. Va en las dos variables porque las
     celdas de una tabla de Bootstrap sacan su color de `--bs-table-border-color`, que a su vez cae en
     `--bs-border-color`: poner solo la segunda no basta si el tema ha resuelto ya la primera.

     **El texto de las celdas se deja como está**, y eso fue una corrección de rumbo: las cifras de
     desempate llevan `text-body-secondary` en el marcado y dan 6,78, que a 9 pt pasa de sobra el 4,5:1
     de un texto normal. Aclararlas todas habría aplanado la única jerarquía que hace escaneable una
     tabla de ocho columnas. Aquí hubo un `color: var(--bs-body-color)` que además no servía: la utilidad
     de Bootstrap lleva `!important` y le gana, así que a esas celdas no llegaba, y a la cabecera —que ya
     estaba en negro— la bajaba de 21 a 15,43. */
  .mtg-tabla-fichas {
    --bs-border-color: #6c757d;
    --bs-table-border-color: #6c757d;
  }

  .mtg-tabla-fichas th,
  .mtg-tabla-fichas td {
    padding: 1mm 1.5mm !important;
    font-size: 9pt;
  }

  .mtg-tabla-fichas tbody tr {
    break-inside: avoid;
  }

  /* El menú de tres puntos de cada fila no se imprime: es una acción. */
  .mtg-tabla-fichas [data-ficha-acciones] {
    display: none !important;
  }
}

/* En pantalla la cabecera del papel no existe. Va fuera del `@media print` a propósito: si
   estuviera dentro como `display: none`, la regla de imprimir tendría que pelearse consigo
   misma. */
.mtg-cabecera-impresion {
  display: none;
}

/* Un icono dentro de un botón normal, para los que van **sin rótulo**. Solo la impresora del cuadro
   lo usa hoy: es de los poquísimos dibujos que no necesitan explicación. Cualquier otro lleva
   rótulo, como los de la barra de acciones. */
.mtg-icono-boton {
  width: 1.1rem;
  height: 1.1rem;
}

/* ---- Un icono **al lado de su rótulo**, en un botón que no es de la barra de acciones ----
   Se distingue de `.mtg-icono-boton` en que allí el botón no lleva texto: aquí el icono acompaña y el
   rótulo sigue siendo quien lo nombra, así que va `aria-hidden`.

   **1 rem y no 1,125** como los de la barra: estos viven en botones `btn-sm`, cuya letra es más pequeña,
   y con el tamaño de los otros el dibujo pesaba más que la palabra.

   El `flex: 0 0 auto` no es adorno: sin él el icono es un hijo flexible y se estruja antes que el texto
   cuando el rótulo es largo, que es justo al revés de lo que se quiere. */
.btn:has(> .mtg-icono-junto) {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.mtg-icono-junto {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
}

/* En táctil crece al mismo tamaño que los iconos de la barra de acciones: dentro de una caja de 44 × 44
   —el mínimo del dedo— 17,6 px se ven perdidos, y eso es lo que se veía en el botón de imprimir.

   **Y va aquí, después de la regla base, no en el bloque de `pointer: coarse` de más arriba**: con la
   misma especificidad manda el orden de fuente, así que allí la base lo pisaba y el icono seguía en 18
   px. Es la misma trampa que ya obligó a sacar las reglas de escritorio de la barra a su propio medio. */
@media (pointer: coarse) {
  .mtg-icono-boton {
    width: 1.375rem;
    height: 1.375rem;
  }
}

/* ============================================================================
   LA AYUDA
   ============================================================================
   Una página de documentación, así que la primera decisión es de tipografía y no de color: **una medida
   de línea corta**. El resto de la aplicación usa todo el ancho porque son tablas y cuadros; aquí son
   párrafos, y una línea de 1200 px se lee mal — el ojo pierde el renglón al volver.

   65 caracteres es la medida clásica; `72ch` deja sitio para las tablas comparativas sin romperla. */
.mtg-ayuda {
  max-width: 72ch;
}

/* Las tablas y los diagramas **sí** pueden salirse de la medida de texto: son datos, no prosa, y
   apretarlos a 72ch los partiría en más renglones. */
.mtg-ayuda .table-responsive,
.mtg-ayuda .mtg-ayuda-figura,
.mtg-ayuda .mtg-ayuda-captura,
.mtg-ayuda .mtg-ayuda-flujo {
  max-width: none;
}

/* ---- Las capturas de pantalla de la ayuda ----
   Las pidió el organizador: «que la de ayuda la llenaras de capturas de la aplicación para ayudar en las
   explicaciones y para darle algo de color».

   **La leyenda no es un adorno, es la mitad del asunto.** Una captura es la documentación que envejece más
   rápido que hay, y a diferencia del texto nada puede comprobar que siga siendo verdad. Con la leyenda
   debajo, una imagen que envejezca —o que no cargue— deja dicho *qué se estaba enseñando*, que es lo que
   evita el peor caso: un hueco silencioso en medio de una explicación. Por eso el `alt` es descriptivo y
   la leyenda va siempre.

   Se generan con `tools/qa/capturas-de-ayuda.ps1`, así que rehacerlas todas es un comando. */
.mtg-ayuda-captura {
  margin-block: 1.25rem;
}

/* **La captura se sale de la medida de texto, y las tablas de esta página no.** Aquí `max-width: none` no
   basta para eso y conviene saber por qué: la medida la pone `.mtg-ayuda` con su `max-width: 72ch`, o sea
   **el padre**, así que quitarle el tope a la figura no la hace más ancha — hay que darle un `width` mayor
   que el padre. Medido a 1280 px: la columna de texto son **621** y la página **1265**, así que a la
   derecha sobraban 640 px de nada mientras la captura se pintaba a 621 desde un original de 1000, o sea al
   62 %.

   El tope es **64 rem acotado por la ventana**: a 1280 son 1024 px y la figura acaba en x=1036, dentro de
   los 1253 útiles del contenedor; a 992, 944 y acaba en 956. Sin el `calc(100vw …)` el desborde aparece
   solo, que es el defecto que este proyecto mide en cada pasada.

   Solo de 992 px en adelante: por debajo la columna ya ocupa casi todo y salirse no ganaría nada. */
@media (min-width: 992px) {
  .mtg-ayuda-captura {
    width: min(64rem, calc(100vw - 3rem));
  }
}

/* **Dentro de un diálogo, la figura no hereda el ancho de /Ayuda.** La regla de arriba existe para
   salirse de la columna de 72ch de aquella página, y un modal no tiene esa columna: heredada, la figura
   medía **1024 px en un cuerpo de 798** y el diálogo de ayuda del ID de Discord scrolleaba en horizontal.
   Dos clases le ganan a una, así que esto manda sobre la media query sin depender del orden. */
.modal .mtg-ayuda-captura {
  width: auto;
}

/* **`max-width` y no `width`**, y la diferencia importa: con `width: 100%` la captura se estiraría hasta el
   ancho del contenedor —1265 px a 1280 de ventana— y una imagen de 1000 px se vería aumentada un 26 %,
   borrosa. Así se pinta a su tamaño cuando cabe y encoge cuando no. Es la figura la que puede salirse de
   la medida de texto (72ch ≈ 700 px), que es lo que le da sitio para llegar a su tamaño real. */
.mtg-ayuda-captura > img {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  /* La captura es de la aplicación en tema oscuro. Sobre el tema claro necesita su propio fondo detrás o
     las esquinas redondeadas dejan ver el blanco por dentro del arco. */
  background: var(--bs-tertiary-bg);
}

.mtg-ayuda-captura > figcaption {
  margin-block-start: 0.4rem;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
}

/* **En papel no se imprimen.** La ayuda cabe en unas pocas hojas de texto; con doce capturas de 1000 px
   pasa a ser un folleto, y en una impresora en blanco y negro una captura de tema oscuro sale como un
   rectángulo gris. La leyenda **sí** se queda, que es lo que hace que el papel no pierda información. */
@media print {
  .mtg-ayuda-captura > img {
    display: none;
  }
}

.mtg-ayuda section {
  /* Aire entre secciones, que es lo que hace que un índice largo se pueda recorrer con la rueda sin
     perderse. Y `scroll-margin-top` para que al llegar desde el índice el título no quede pegado al
     borde de arriba. */
  margin-top: 2.5rem;
  scroll-margin-top: 1rem;
}

.mtg-ayuda h2 {
  border-bottom: 1px solid var(--bs-border-color);
  padding-bottom: 0.35rem;
  margin-bottom: 1rem;
}

.mtg-ayuda h3 {
  margin-top: 1.5rem;
  color: var(--bs-secondary-color);
}

/* ---- El índice ----
   Píldoras que fluyen y no una lista vertical: son trece secciones, y en columna se comerían la primera
   pantalla entera en un móvil. Aquí lo que se hace es **buscar un nombre**, no leerlas en orden. */
.mtg-ayuda-indice {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 0.5rem;
}

.mtg-ayuda-indice > a {
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 2rem;
  background: var(--mtg-celda-fondo);
  color: var(--bs-body-color);
  text-decoration: none;
  font-size: 0.875rem;
}

.mtg-ayuda-indice > a:hover,
.mtg-ayuda-indice > a:focus-visible {
  border-color: var(--mtg-acento);
}

/* En táctil, los 44 px de siempre. Un índice es justo lo que se pulsa con el pulgar. */
@media (pointer: coarse) {
  .mtg-ayuda-indice > a {
    min-height: var(--mtg-toque);
    display: flex;
    align-items: center;
  }
}

/* ---- Los diagramas de fases ----
   **HTML y no SVG**, a propósito: son cajas con texto dentro, así que se leen con un lector de pantalla,
   se encuentran con Ctrl+F y se reparten solas en móvil. Un SVG con texto no hace ninguna de las tres.

   La flecha va en un `::after` del paso, no en un elemento suyo: así no hay que pintar una flecha de más
   al final ni contar cuántos pasos hay. */
.mtg-ayuda-flujo {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.5rem;
  margin: 1rem 0;
}

.mtg-ayuda-paso {
  position: relative;
  flex: 1 1 9rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
}

.mtg-ayuda-paso > span {
  display: block;
  font-size: 0.8125rem;
  color: var(--bs-secondary-color);
}

/* La flecha entre pasos. `content` con `attr` no hace falta: es siempre la misma.

   Va **dentro del hueco** —`right: -0.5rem`, la mitad del `gap`— y con `pointer-events: none` para no
   comerse el clic de nada. Y no se pinta en el último de cada fila: como los pasos se reparten con
   `flex-wrap`, cuál es el último cambia con el ancho, así que se resuelve con `:last-child` para el
   final de verdad y aceptando que en un salto de línea quede una flecha apuntando al vacío — es lo que
   hace cualquier diagrama impreso y se lee sin problema. */
.mtg-ayuda-paso::after {
  content: "→";
  position: absolute;
  top: 50%;
  right: -0.6rem;
  transform: translateY(-50%);
  color: var(--bs-secondary-color);
  pointer-events: none;
}

.mtg-ayuda-paso:last-child::after {
  content: none;
}

/* ---- En un móvil el diagrama baja en columna ----
   Con `flex-wrap` a 375 px caben dos pasos por fila, y el segundo de cada fila se queda con una flecha
   apuntando al vacío: el siguiente paso no está a su derecha sino debajo. En columna la flecha señala
   adónde de verdad va, que es lo único que un diagrama de flujo tiene que hacer bien.

   El umbral son 576 px y no los 768 de las tablas: lo que decide aquí es si caben **dos cajas de 9 rem**
   en una línea, no si una tabla se convierte en fichas. */
@media (max-width: 575.98px) {
  .mtg-ayuda-flujo {
    flex-direction: column;
    /* Más aire que en fila, y por una razón medible: la flecha mide unos 16 px y el `gap` de 8 no da
       para meterla dentro, así que se quedaba encima del borde de la caja. Con 20 px cae en el hueco. */
    gap: 1.25rem;
  }

  /* **`flex: 0 0 auto` no es opcional aquí**, y falla de forma llamativa: en columna, la base de un
     elemento flexible es su *alto*, así que el `flex: 1 1 9rem` de la regla base dejaba cada caja en
     144 px de altura — cuatro cajas casi vacías ocupando una pantalla entera. Lo que se quiere es que
     cada una mida lo que mide su texto. */
  .mtg-ayuda-paso {
    flex: 0 0 auto;
  }

  .mtg-ayuda-paso::after {
    content: "↓";
    top: auto;
    right: auto;
    bottom: -1.15rem;
    left: 50%;
    transform: translateX(-50%);
  }
}

/* ---- Las tablas de la ayuda desbordan, no se comprimen ----
   Es la trampa que ya está documentada para la clasificación de liga: una tabla sin ancho mínimo **no
   desborda nunca**, aprieta sus columnas. Aquí eso deja «Cómo empareja» partido en dos líneas y una
   columna de texto de 40 px en un móvil, que es ilegible; con un mínimo, la tabla se sale y su
   contenedor le da barra —y arrastre con el ratón, por `data-mtg-arrastrable`—.

   30 rem es lo que necesita la más ancha de las cinco para que ninguna cabecera se parta. */
.mtg-ayuda-tabla {
  min-width: 30rem;
}

/* Un paso opcional se dibuja con el borde discontinuo. **Solo se toca el estilo del lado que ya tiene
   anchura declarada**: cambiar `border-style` de un lado que nunca la declaró le resucita la anchura
   `medium` —3 px— y la caja crece sin que nada avise. Ya mordió dos veces en el cuadro. */
.mtg-ayuda-paso-opcional {
  border-style: dashed;
}

/* ---- El cuadro de ejemplo ----
   Este sí es un dibujo, así que va en SVG. Con `viewBox` y sin ancho fijo se escala solo, y todo el
   trazo usa `currentColor`: sirve en los dos temas sin declarar un color. */
.mtg-ayuda-figura {
  margin: 1rem 0;
}

.mtg-ayuda-cuadro {
  width: 100%;
  max-width: 34rem;
  height: auto;
  color: var(--bs-body-color);
}

.mtg-ayuda-figura > figcaption {
  font-size: 0.875rem;
  color: var(--bs-secondary-color);
}

/* El icono de un tipo de torneo dentro de una tabla de la ayuda. A 1 em y con `vertical-align: middle`,
   que es lo que evita que la línea base lo empuje y agrande la fila — medido en la clasificación de liga:
   un icono de 1,1 em subía la celda de 20,4 a 26,8 px. */
.mtg-ayuda-icono {
  width: 1em;
  height: 1em;
  vertical-align: middle;
  margin-right: 0.15rem;
}

/* El glosario en dos columnas cuando cabe: un término y su definición se leen mejor juntos que en dos
   renglones. Por debajo de 480 px vuelve a apilarse solo. */
.mtg-ayuda-glosario {
  display: grid;
  grid-template-columns: minmax(8rem, auto) 1fr;
  gap: 0.35rem 1rem;
}

.mtg-ayuda-glosario > dt {
  font-weight: 600;
}

.mtg-ayuda-glosario > dd {
  margin: 0;
  color: var(--bs-secondary-color);
}

@media (max-width: 479.98px) {
  .mtg-ayuda-glosario {
    grid-template-columns: 1fr;
  }

  .mtg-ayuda-glosario > dd {
    margin-bottom: 0.5rem;
  }
}

/* El selector de rondas de la pantalla de reparto. Con el dedo, **el alto ya lo da la regla general de
   `.btn` pero el ancho no**: medido a 375 px daba 26 × 44, o sea un objetivo tan estrecho como un dígito.
   El `min-width` es el mismo recurso —y casi la misma cifra— que igualó los botones del selector de rondas
   de la fase, que también son números de una y dos cifras. */
@media (pointer: coarse) {
  .mtg-selector-rondas-grupo .btn {
    min-width: 2.75rem;
  }
}

/* ---- El reparto en grupos ----
   Cajas iguales en una rejilla que se llena sola. `auto-fill` con un mínimo y no un número de columnas
   por tamaño: los grupos van de 2 a 16 y sus tamaños de 2 a 10, así que un reparto de columnas fijo
   dejaría huecos en unos casos y apretaría en otros.

   El mínimo son 11 rem porque lo que manda es el **nombre**: por debajo de eso «Maria del Carmen
   Villanueva» se recorta en todas las cajas a la vez, y el reparto es justo la pantalla donde el
   organizador está buscando nombres concretos. */
.mtg-grupos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.75rem;
}

.mtg-grupo {
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
}

.mtg-grupo-titulo {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.35rem;
  font-size: 0.95rem;
  font-weight: 600;
}

/* La flecha que cambia el grupo entero de sitio. **Se empuja al final** con `margin-inline-start: auto`,
   igual que la de cada jugador dentro de su fila, para que todas las flechas de la pantalla caigan en la
   misma columna. Se dibuja como texto y no como botón por el mismo motivo que allí: en una caja de 11 rem
   un botón de Bootstrap por grupo la llenaría de marcos. */
.mtg-grupo-mover {
  margin-inline-start: auto;
  padding: 0 0.2rem;
  border: 0;
  border-radius: var(--bs-border-radius-sm);
  background: transparent;
  color: var(--bs-secondary-color);
  font: inherit;
  line-height: 1;
}

.mtg-grupo-mover:hover,
.mtg-grupo-mover:focus-visible {
  background: var(--mtg-celda-fondo);
  color: var(--bs-body-color);
}

/* 44 px con el dedo, como el hueco de un jugador. */
@media (pointer: coarse) {
  .mtg-grupo-mover {
    min-width: 44px;
    min-height: 44px;
  }
}

/* ---- Los pasos de la pantalla de reparto ----
   **No es un asistente** —no hay «siguiente» ni nada bloqueado—, pero las decisiones van en orden y la
   pantalla se leía como cuatro bloques sueltos. El número es la señal mínima que lo dice.

   La bola va en **contorno y no rellena**, y no es estética: rellena de acento diría «esto se pulsa», que
   es lo único que significa el amarillo aquí, y un número no se pulsa. Es el mismo tratamiento que
   `.mtg-fase-bola` le da a una fase que no es la actual.

   `flex: 0 0 auto` para que la bola no se estruje cuando el título es largo, que es la trampa de siempre
   con un hijo de flex. */
.mtg-paso {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.mtg-paso-numero {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border: 1px solid var(--bs-secondary-color);
  border-radius: 50%;
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
  font-weight: 600;
}

/* ---- El resumen de cruces ----
   Cada pareja es **una caja por grupo con un «vs» en medio**. Estuvo como «1 × 4» en texto plano y el
   organizador lo rechazó —«queda muy cutre»—: dos números sueltos no se leen como dos equipos
   enfrentados, y aquí lo que se está enseñando es precisamente un enfrentamiento.

   Las cajas de grupo repiten deliberadamente la forma de la cabecera de un grupo —el mismo velo de
   `--mtg-celda-fondo` y el mismo peso—, que es lo que hace que se reconozcan como grupos sin necesidad de
   decirlo en ninguna parte.

   Las parejas se reparten en una fila que se parte y no en columna: con 16 grupos son ocho, y en columna
   serían ocho renglones para algo que cabe en dos. */
.mtg-cruces-grupos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.mtg-cruce-pareja {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
}

.mtg-cruce-grupo {
  padding: 0.1rem 0.45rem;
  border-radius: var(--bs-border-radius-sm);
  background: var(--mtg-celda-fondo);
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
}

.mtg-cruce-vs {
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
  text-transform: uppercase;
}

/* La lista lleva su propio contador y no el del navegador: con `list-style` la cifra queda fuera de la
   caja de contenido y el nombre pierde el `min-width: 0` que necesita para recortarse. Es la misma
   trampa de la ficha de mesa, y falla igual de callada — el nombre no se recorta nunca. */
.mtg-grupo-lista {
  counter-reset: mtg-grupo;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mtg-grupo-lista > li {
  display: flex;
  gap: 0.4rem;
  min-width: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  counter-increment: mtg-grupo;
}

.mtg-grupo-lista > li::before {
  flex: 0 0 auto;
  content: counter(mtg-grupo);
  min-width: 1.1rem;
  color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Los cuadros a los que alimenta un reparto, en línea y separados por un punto medio que pone el CSS: en
   el marcado serían un carácter suelto entre elementos y se partiría solo al final de línea. El `gap`
   entre columnas es mayor que el de filas para que la separación se lea sin depender del punto. */
.mtg-tops-de-grupo {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.6rem;
}

.mtg-tops-de-grupo > span + span::before {
  content: "·";
  margin-inline-end: 0.6rem;
  color: var(--bs-secondary-color);
}

/* ---- La caja de un grupo ----
   Un grupo es **una caja con cabecera**, y la misma en las dos pestañas de la fase de rondas: en
   emparejamientos envuelve la rejilla de fichas de mesa, y en clasificación es el `<details>` que ya se
   plegaba. Antes era un encabezado suelto con el contenido debajo, y con 4 u 8 grupos no se veía dónde
   acababa uno y empezaba el siguiente — lo pidió el organizador.

   Tres cosas que la caja **no** hace, y las tres son deliberadas:

     · **No lleva `overflow: hidden`**, que es la forma cómoda de redondear una cabecera pegada al borde.
       El menú de acciones de la clasificación es un desplegable, y `_TablaDeClasificacion` renuncia a
       `table-responsive` justo para no recortarlo: un `overflow` aquí lo recortaría igual, y por el mismo
       sitio. Las esquinas de la cabecera se redondean a mano, descontando el borde.
     · **El cuerpo va sin relleno de color.** Una mesa sin resultado lleva su velo de atención
       (`--mtg-atencion-fondo`), así que rellenar la caja dejaría un velo debajo de otro velo — lo que este
       proyecto ya sabe que no se puede razonar, y que obligaría a volver a medir cada mesa pendiente. El
       color va **solo en la cabecera**, donde no hay nada translúcido encima.
     · **En móvil apenas gasta relleno lateral.** Ahí el lado de una ficha de mesa mide 109 px y el nombre
       ya se recorta: el sitio que se llevara la caja se lo estaría quitando al dato.

   Y una que sí hace y no se ve hasta imprimir: en papel los navegadores descartan los fondos, así que de
   la cabecera solo queda el **borde** — que es justo por lo que una caja separa mejor que una franja de
   color, y el motivo de que el borde no sea opcional aquí. */
/* **El borde va en `--bs-secondary-color`, no en `--bs-border-color`**, y es la misma corrección que
   necesitaron los conectores del cuadro — con la misma cifra: `--bs-border-color` da **1,41 en oscuro** y
   **1,10 en claro** contra el cuerpo de la fase, o sea que la caja no se veía justo en el tema donde más
   falta hacía. Un recuadro que agrupa es un gráfico con significado y se le piden 3:1.

   Medido contra el panel: **5,76 en oscuro y 6,17 en claro**. Se descartó `#6c757d` —el gris que sirve en
   papel— porque el papel es blanco y aquí hay dos fondos en extremos opuestos: da 3,95 en claro pero
   **2,45 en oscuro**, por debajo del mínimo. Un gris fijo no puede pasar los dos; el token del tema sí,
   porque cambia con él. */
.mtg-grupo-caja {
  border: 1px solid var(--bs-secondary-color);
  border-radius: var(--bs-border-radius);
}

.mtg-grupo-caja + .mtg-grupo-caja {
  margin-top: 0.75rem;
}

/* La cabecera es lo que separa: una franja a todo el ancho de la caja. El fondo es `--mtg-celda-fondo` y
   no un `--bs-*-bg`, que sobre el cuerpo de la fase (`--bs-secondary-bg`) son todos más oscuros y saldrían
   como un agujero en vez de como un escalón. */
.mtg-grupo-cabecera {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0.3rem 0.6rem;
  /* El mismo color que el borde de la caja y por el mismo motivo: es su continuación, y con
     `--bs-border-color` esta línea se quedaba en 1,41 / 1,10 mientras el marco de alrededor se veía. */
  border-bottom: 1px solid var(--bs-secondary-color);
  border-radius: calc(var(--bs-border-radius) - 1px) calc(var(--bs-border-radius) - 1px) 0 0;
  background: var(--mtg-celda-fondo);
  font-size: 1rem;
}

/* Plegada, la caja **es** su cabecera, y ahí el borde de abajo queda pegado al de la caja: dos líneas
   donde va una. Se quita la **anchura** y no el estilo, que resucitaría la `medium` de 3 px. */
details.mtg-grupo-caja:not([open]) > .mtg-grupo-cabecera {
  border-bottom-width: 0;
  border-radius: calc(var(--bs-border-radius) - 1px);
}

.mtg-grupo-cuerpo {
  padding: 0.5rem;
}

/* La lista de mesas trae su propio margen de abajo para separarse de lo que venga detrás; dentro de la
   caja el que separa es el relleno del cuerpo, y los dos juntos dejaban un escalón de aire muerto. */
.mtg-grupo-cuerpo > .mtg-mesas {
  margin-bottom: 0;
}

/* En móvil el ancho es el recurso escaso — ver arriba. El relleno se queda en lo justo para que las
   fichas no toquen el borde de la caja. */
@media (max-width: 767.98px) {
  .mtg-grupo-cuerpo {
    padding-inline: 0.25rem;
  }
}

/* El resumen es `flex` y no `display: list-item` para poder alinear el nombre del líder; con eso se pierde
   el marcador nativo, así que el triángulo se dibuja aparte. La caja pone ya el `flex` y el relleno: aquí
   queda solo lo que es de un `<summary>`. */
.mtg-grupo-resumen {
  list-style: none;
  cursor: pointer;
}

.mtg-grupo-resumen::-webkit-details-marker {
  display: none;
}

/* El nombre del líder cede primero: es la ayuda, no el dato. */
.mtg-grupo-lider {
  min-width: 0;
  overflow: hidden;
  font-size: 0.85rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El triángulo va **en los dos tamaños**, y eso es una corrección: lo tuvo solo móvil, que es donde el
   plegado empieza plegado, y en escritorio quedaba un encabezado que se podía pulsar sin decirlo. Si se
   puede plegar, se señala. Va en un pseudo-elemento y no en el marcador nativo porque el resumen es
   `flex`, que se lo lleva por delante. */
.mtg-grupo-resumen::before {
  content: "▸";
  display: inline-block;
  color: var(--bs-secondary-color);
  transition: transform 0.15s ease;
}

details[data-mtg-grupo][open] > .mtg-grupo-resumen::before {
  transform: rotate(90deg);
}

/* 44 px de objetivo con el dedo: el resumen es lo que se pulsa para abrir el grupo. */
@media (pointer: coarse) {
  .mtg-grupo-resumen {
    min-height: 44px;
  }
}

/* El sitio de un jugador en el reparto **es un botón**, como cada hueco del cuadro previsto: se pulsa para
   cambiarlo por otro. Se dibuja como texto y no como botón porque en una caja de 11 rem un botón de
   Bootstrap por jugador la llenaría de marcos; lo que dice que se pulsa es la flecha, igual que allí. */
.mtg-grupo-hueco {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  width: 100%;
  min-width: 0;
  padding: 0.05rem 0.2rem;
  border: 0;
  border-radius: var(--bs-border-radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
}

.mtg-grupo-hueco:hover,
.mtg-grupo-hueco:focus-visible {
  background: var(--mtg-celda-fondo);
}

.mtg-grupo-cambiar {
  margin-inline-start: auto;
  color: var(--bs-secondary-color);
}

/* Con el dedo, 44 px. La caja de grupo crece con ellos, que es lo correcto: lo que se toca es cada
   nombre. */
@media (pointer: coarse) {
  .mtg-grupo-hueco {
    min-height: 44px;
  }
}

/* ============================================================================
   CUENTAS, AVISO LEGAL Y BIBLIOTECA DE BARAJAS
   ============================================================================ */

/* ---- Columna de lectura para formularios y texto legal ----
   Un formulario de cuatro campos a 1800 px de ancho es ilegible: el rótulo queda a un
   palmo de su campo. Aquí no hay tabla ni cuadro que aproveche el ancho, al contrario
   que en las pantallas de torneo. */
.mtg-columna-formulario {
  max-width: 32rem;
}

.mtg-texto-legal {
  max-width: 46rem;
}

.mtg-texto-legal h2 {
  margin-block-start: 1.5rem;
}

/* ---- El campo trampa ----
   Escondido con CSS y **no** con `type="hidden"` ni con `display: none`: un oculto de
   verdad lo rellenan también los gestores de contraseñas y algunos navegadores, y
   entonces la trampa cazaría a personas en vez de a guiones.

   Se saca de la vista fuera de flujo, que es el mismo patrón que usa el proyecto para
   el rótulo largo de la barra de acciones. Lleva además `aria-hidden` y `tabindex="-1"`
   en el marcado, así que para un lector de pantalla y para el tabulador no existe. */
.mtg-trampa {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* La casilla del consentimiento pesa más que una casilla normal: es la que bloquea. */
.mtg-consentimiento .form-check-label {
  line-height: 1.4;
}

/* ---- La biblioteca: rejilla de fichas con portada ----
   `auto-fill` con un mínimo, como los dos listados en cuadrícula: 2 columnas en un
   móvil, 4 en un escritorio, sin puntos de ruptura escritos a mano. */
/* **9,5 rem y no 11**, y la cifra está medida: a 375 px el contenido son 343, así que con un
   mínimo de 11 rem (176 px) dos fichas más el hueco piden 364 y **cae a una sola columna**.
   Con 9,5 rem son 316 y entran dos, que es como se lee una biblioteca en un móvil — y como
   la enseñan las aplicaciones que hacen esto bien. En escritorio no cambia nada: `auto-fill`
   sigue metiendo las que quepan. */
.mtg-biblioteca {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0.75rem;
}

/* Alto de la pestaña de una carpeta. Va aquí, en la rejilla, y no en la ficha de carpeta,
   porque **todas** las fichas reservan ese hueco: si solo lo reservaran las carpetas,
   quedarían más bajas que las barajas de su misma fila. Ceden 12 px de alto por fila a
   cambio de que las dos formas convivan alineadas. */
.mtg-biblioteca {
  --mtg-pestana-alto: 0.75rem;
}

/* La ficha. `isolation` crea contexto de apilamiento propio: sin él, el enlace estirado
   de una ficha se solaparía con el de la de al lado según el orden del documento.

   **Sin `overflow: hidden`**, que es lo que tenía: la pestaña de una carpeta nace fuera de
   la caja y ese recorte se la comía entera. El redondeo de la ilustración y del velo se
   consigue con `border-radius: inherit` en cada uno, que hace lo mismo sin recortar a los
   pseudo-elementos. */
.mtg-portada {
  position: relative;
  isolation: isolate;
  aspect-ratio: 16 / 10;
  margin-block-start: var(--mtg-pestana-alto);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  border: 1px solid var(--bs-secondary-color);
}

/* La ilustración llena la ficha. `cover` y no `contain` —al revés que el logo de un
   formato— y aquí sí es lo correcto: un recorte de ilustración ya viene apaisado, así
   que no se pierde nada al recortarlo, mientras que un logo de 3,8:1 sí se destroza. */
.mtg-portada-imagen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Detrás del contenido pero delante del fondo de la ficha. Puede porque `.mtg-portada`
     crea contexto de apilamiento con `isolation`: sin él, un z-index negativo se iría
     detrás del fondo de la caja y la imagen desaparecería. */
  z-index: -2;
  /* Sustituye al `overflow: hidden` que llevaba la ficha, que se comía la pestaña. */
  border-radius: inherit;
}

/* El velo. **Vertical y no el `--mtg-velo-ficha` horizontal**, porque aquí el texto va
   arriba y no a la izquierda: el degradado se abre hacia abajo para dejar ver el dibujo.
   Opaco donde va el nombre, que es lo que sostiene el contraste — y no un velo sobre
   otro velo, que en este proyecto ya ha dado cifras inventadas tres veces. */
.mtg-portada-velo {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(
    180deg,
    var(--bs-body-bg) 0%,
    rgb(from var(--bs-body-bg) r g b / 0.82) 34%,
    rgb(from var(--bs-body-bg) r g b / 0.35) 62%,
    rgb(from var(--bs-body-bg) r g b / 0.15) 100%);
}

/* **Sin `position: relative`, y no es un olvido.** Lo llevaba, y con él el `::after` que estira
   el enlace se resolvía contra *este* bloque en vez de contra la ficha: el área pulsable se
   quedaba en el texto y **pulsar la ficha no navegaba**. No daba ningún error — se veía
   perfecta y no hacía nada—, y lo destapó probarla en pantalla.

   Ahora la imagen y el velo van a capas negativas, así que el texto se pinta encima estando en
   flujo normal, y `inset: 0` del `::after` se resuelve contra `.mtg-portada`, que es lo que se
   quería. */
.mtg-portada-texto {
  padding: 0.5rem 0.6rem;
}

.mtg-portada-nombre {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  /* Dos líneas y a partir de ahí puntos suspensivos. La ficha tiene forma fija: un
     nombre largo cede, no descuadra la rejilla. Es la misma regla que la ficha de un
     torneo. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.mtg-portada-enlace {
  color: var(--bs-body-color);
  text-decoration: none;
}

/* El icono de carpeta, dentro del nombre. **`vertical-align` y no flex**: el nombre es una
   caja `-webkit-box` con `-webkit-line-clamp` para recortarlo a dos líneas, y volverla flex
   desactiva el recorte.

   Y hace falta porque un SVG en línea **se apoya en la línea base del texto**, no en su
   centro, así que sin esto queda montado sobre la palabra. Es la misma trampa que ya
   descuadró la celda de la medalla en la clasificación de liga, y allí se cerró igual. */
/* `-0.1em` está **medido, no elegido a ojo**: con `-0.15em` el centro del icono caía 0,89 px
   por debajo del centro de la palabra, y con esto queda en 0,09. */
.mtg-portada-enlace .mtg-icono-junto {
  display: inline-block;
  vertical-align: -0.1em;
  margin-inline-end: 0.25rem;
}

.mtg-portada-enlace:hover,
.mtg-portada-enlace:focus-visible {
  text-decoration: underline;
}

/* El área pulsable es la ficha entera. Se hace con un `::after` y no con la clase
   `stretched-link` de Bootstrap por lo mismo que en la ficha de mesa: aquella cuelga del
   ancestro posicionado más cercano, que aquí podría ser cualquiera. */
.mtg-portada-enlace::after {
  content: "";
  position: absolute;
  inset: 0;
}

.mtg-portada-dato {
  margin: 0.1rem 0 0;
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* El menú de acciones, en la esquina. `z-index` por encima del enlace estirado, o sería
   inalcanzable: el `::after` de arriba lo taparía entero. */
.mtg-portada-accion {
  position: absolute;
  inset-block-end: 0.4rem;
  inset-inline-end: 0.4rem;
  z-index: 1;
}

/* **La ficha con el menú abierto se sube por encima de sus hermanas.**
   Cada ficha crea contexto de apilamiento con `isolation`, así que las que van después en el
   documento se pintan encima: el desplegable de una carpeta salía **por debajo de la
   ilustración de la siguiente**, medio menú tapado. No se arregla subiendo el `z-index` del
   menú —está dentro del contexto de su ficha y de ahí no sale—, sino subiendo la ficha
   entera mientras está abierto. */
.mtg-portada:has(.dropdown-menu.show) {
  z-index: 3;
}

/* Con el dedo, 44 px: es un botón destructivo y el peor sitio para fallar el toque. */
@media (pointer: coarse) {
  .mtg-portada-accion .btn {
    min-width: 44px;
    min-height: 44px;
  }
}

/* ---- La pestaña que hace que una carpeta *parezca* una carpeta ----
   Una carpeta y una baraja no se pueden distinguir solo por un icono de 14 px: la
   biblioteca se recorre con la vista y lo que se reconoce a esa velocidad es **la
   silueta**, no un detalle dentro de la caja. Es el mismo argumento por el que una
   jornada de liga lleva cinta de esquina además del nombre de su liga.

   Sale de la caja hacia arriba, por eso la ficha no puede llevar `overflow: hidden` y por
   eso todas reservan `--mtg-pestana-alto` de margen.

   `border-bottom: 0` y **1 px de más de alto**: así la pestaña se solapa con el borde
   superior de la ficha y las dos se leen como una sola pieza, sin costura. Ojo con esto —
   cambiar un `border-*-style` resucita la anchura `medium` de 3 px, así que aquí se
   declara `0` y no `none`. */
.mtg-portada-carpeta::before {
  content: "";
  position: absolute;
  inset-block-start: calc(-1 * var(--mtg-pestana-alto));
  inset-inline-start: 0;
  width: 42%;
  height: calc(var(--mtg-pestana-alto) + 1px);
  background: var(--mtg-celda-fondo);
  border: 1px solid var(--bs-secondary-color);
  border-bottom: 0;
  border-start-start-radius: var(--bs-border-radius);
  border-start-end-radius: var(--bs-border-radius);
}

/* Las migas no se parten en varias líneas cuando el camino es largo: se desplazan, que
   es lo que ya hace cualquier tabla ancha del proyecto. Sin esto, cuatro niveles con
   nombres largos suben la cabecera tres renglones en un móvil. */
.mtg-migas {
  flex-wrap: nowrap;
  overflow-x: auto;
  white-space: nowrap;
  /* **Centrado vertical, y hace falta desde que los enlaces miden 44 px con el dedo.** El
     último tramo —la carpeta en la que estás— no es un enlace, así que conserva su alto
     natural; con el `stretch` por defecto de un contenedor flex se estiraba a 44 y su texto
     se quedaba pegado arriba, desalineado respecto a los demás. Se vio en pantalla. */
  align-items: center;
}

/* ---- El avatar de un usuario ----
   Es la ilustración de una carta recortada en redondo. `cover` porque un recorte de
   ilustración viene apaisado (~626×457) y aquí la caja es cuadrada: sin él saldría
   deformado. */
.mtg-avatar {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
  border: 1px solid var(--bs-secondary-color);
}

/* El de la barra de navegación. Más pequeño que el mínimo táctil a propósito: **no es un
   objetivo**, es un adorno dentro del botón del menú, y el botón entero sí lo cumple.

   **Subido de 1,5 a 2 rem** el 24 de agosto de 2026, a petición del organizador: «se ve un poco pequeña, se
   puede hacer algo para que se aprecie mejor». A 24 px un recorte de ilustración no se reconoce — es un
   dibujo, no un icono—, y a 32 sí. Lo que hay que saber es **lo que cuesta**, porque son las dos cosas que
   esta barra ya tiene medidas: el botón pasa de 34 a 40 px de alto y con él la barra de 57 a 62, y el
   contenido con sesión sube 8 px de ancho, o sea de 959 a **967** — sigue por debajo de los 992 en que
   pliega, que es el número que importa. Con un nombre largo el recorte de `.mtg-navbar-nombre` absorbe el
   resto.

   El filo se queda **quitado**: a 32 px sobre la barra oscura la ilustración ya se separa sola, y un anillo
   de 1 px alrededor de un dibujo pequeño lo que hace es comerse 2 px del propio dibujo. */
.mtg-avatar-mini {
  width: 2rem;
  height: 2rem;
  border: 0;
}

.mtg-avatar-vacio {
  display: inline-block;
  background: var(--mtg-celda-fondo);
}

/* Un icono dentro de una opción de menú desplegable. El `.btn:has(> .mtg-icono-junto)` de
   arriba no lo alcanza: una opción de menú es un `.dropdown-item`, no un `.btn`. */
.dropdown-item:has(> .mtg-icono-junto) {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* ---- Con el dedo, las migas, el enlace legal y las fuentes de un formato llegan a 44 px ----
   Todos son navegación de verdad —una sube por el árbol, otro abre el aviso legal, y las
   fuentes abren la página oficial del formato— y medidos daban **21, 24 y 19 px** (las
   fuentes, en la regresión del 26 de agosto de 2026). La regla del proyecto es 44 en todo lo
   que se toca, y solo con puntero grueso: con ratón una miga de 21 px se acierta sin
   problema y estirarla engordaría la cabecera para nada.

   `inline-flex` + `align-items` y no `padding` a secas: el relleno solo movería el texto
   hacia abajo dentro de una caja que sigue midiendo lo mismo. */
@media (pointer: coarse) {
  .mtg-migas .breadcrumb-item > a,
  .mtg-fuentes a,
  .footer a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* **El enlace del aviso de propiedad intelectual se queda fuera de esa regla**, y no es una excepción
     de conveniencia: la WCAG 2.5.8 exime a los enlaces que van *dentro de un bloque de texto*, porque
     agrandarlos rompería el renglón. Con `inline-flex` y 44 px este partía la línea del párrafo en dos. */
  .mtg-pie-legal a {
    display: inline;
    min-height: 0;
  }
}

/* ============================================================================
   IMPRIMIR PROXIES
   ============================================================================
   Las medidas de una carta son **63,5 × 88,9 mm** (2,5 × 3,5 pulgadas) y son lo único de
   toda esta pantalla que no admite «casi»: una proxy que no las cumpla no entra en la funda
   junto a una carta de verdad, que es exactamente para lo que se imprime.

   Van en milímetros y no en píxeles ni en rem por el mismo motivo que el cuadro impreso
   declara su ancho de columna en milímetros: en papel el píxel no significa nada. */
.mtg-proxy-hoja {
  --mtg-carta-ancho-mm: 63.5mm;
  --mtg-carta-alto-mm: 88.9mm;

  /* El hueco entre cartas. Cero las deja pegadas y se cortan de un tijeretazo por fila, que
     es lo que se eligió; la línea de corte la pone el borde. */
  --mtg-corte-hueco: 0mm;

  display: grid;
  grid-template-columns: repeat(3, var(--mtg-carta-ancho-mm));
  gap: var(--mtg-corte-hueco);
  justify-content: start;
}

.mtg-proxy-carta {
  width: var(--mtg-carta-ancho-mm);
  height: var(--mtg-carta-alto-mm);
  /* La línea de corte. Media línea por carta, así que dos cartas pegadas suman una raya de
     1 px entre las dos y no dos rayas juntas. */
  outline: 0.5pt solid var(--bs-secondary-color);
  outline-offset: -0.25pt;
  overflow: hidden;
}

/* La ilustración llena su carta exactamente. `cover` y no `contain`: la imagen de Scryfall ya
   viene en la proporción de una carta, así que no recorta nada, y con `contain` un redondeo
   de un cuarto de píxel dejaría una línea blanca en un borde. */
.mtg-proxy-carta img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Una carta desmarcada desaparece de la hoja **y de la vista previa**, que son la misma cosa:
   lo que se ve es lo que sale. */
.mtg-proxy-carta[hidden] {
  display: none;
}

/* En pantalla la hoja se enseña reducida y centrada, para que quepa sin desplazarse. En papel
   este `zoom` desaparece: allí las medidas son las de verdad. */
@media screen {
  .mtg-proxy-hoja {
    zoom: 0.55;
    margin-inline: auto;
    padding-block-end: 2rem;
  }
}

@media print {
  /* Los controles no se imprimen —ya llevan `d-print-none`— y la hoja pierde cualquier
     contenedor que le reste ancho. */
  .mtg-proxy-hoja {
    zoom: normal;
    margin: 0;
    padding: 0;
  }

  /* **Sin esto las ilustraciones no salen.** Los navegadores descartan los fondos y las
     imágenes de fondo al imprimir para ahorrar tinta; aquí la imagen *es* el contenido. Es la
     misma línea que hizo falta para el hilo dorado del cuadro. */
  .mtg-proxy-carta,
  .mtg-proxy-carta img {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  /* Una carta **no se parte entre dos hojas**. Sin esto, la fila que cae en el borde sale
     cortada por la mitad en una página y la otra mitad en la siguiente. */
  .mtg-proxy-carta {
    break-inside: avoid;
    page-break-inside: avoid;
  }
}

/* ---- Los controles ---- */
.mtg-proxy-lista {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.1rem 1rem;
}

.mtg-proxy-copias {
  display: inline-block;
  min-width: 2.2rem;
  color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
}

/* Con el dedo, la etiqueta entera es el objetivo: una casilla de 16 px no se acierta. */
@media (pointer: coarse) {
  .mtg-proxy-lista .form-check-label {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ---- Al imprimir solo queda la hoja ----
   Los dos diálogos que imprimen —proxies y hoja de lista— son **la excepción** a la regla de arriba
   que oculta `.modal` al imprimir: aquí lo que se quiere imprimir está justamente dentro de uno.

   Hay que deshacerle a Bootstrap las cuatro cosas que hacen que un modal sea un modal —fijo,
   con alto máximo, con scroll y con un telón encima—, porque todas ellas recortan el contenido
   a la altura de la ventana y en papel no existe tal cosa.

   **Los dos comparten estas reglas y no se escriben dos veces**: solo uno puede estar abierto a la
   vez, y el que esté cerrado sigue con el `display: none` de Bootstrap, así que no se estorban. */
@media print {
  /* Fuera el editor entero: en el papel no pinta nada. */
  .mtg-editor-pagina {
    display: none !important;
  }

  /* **Con uno de los dos abiertos, el papel es SOLO ese diálogo.** La regla de arriba bastaba cuando
     los botones vivían solo en el editor; desde que la vista de solo lectura los lleva también dentro
     del diálogo de una lista presentada —pantalla del torneo y «Mis eventos»— y en `/Torneos/Apuntarme`,
     lo que hay alrededor es otra página cualquiera (las mesas de una ronda, la clasificación) y sin esto
     se imprimía debajo de la hoja. Los armazones son **hijos directos de `<main>`** en las cuatro
     pantallas que los incluyen, y esta regla lo exige: anidados más adentro, se esconderían con su
     ancestro. */
  body:has(#mtg-dialogo-hoja.show) main > :not(#mtg-dialogo-hoja),
  body:has(#mtg-dialogo-proxies.show) main > :not(#mtg-dialogo-proxies) {
    display: none !important;
  }

  #mtg-dialogo-proxies.show,
  #mtg-dialogo-hoja.show {
    display: block !important;
    position: static !important;
    overflow: visible !important;
    /* Sin `opacity: 0` de la animación de Bootstrap: si se imprime con el diálogo a medio
       aparecer, salen hojas en blanco. */
    opacity: 1 !important;
  }

  /* **El ancho hay que forzarlo, no basta con quitar el `max-width`.** Con el editor oculto, la
     cadena `body > .mtg-contenedor > main > .modal` se queda sin nada que le dé anchura y encoge al
     contenido: la hoja salía en **329 px de los 703** de un A4, con los nombres partidos en dos. Se
     ve solo en la emulación de impresión, porque en pantalla el editor ya ensancha el contenedor. */
  .mtg-contenedor,
  main {
    width: 100% !important;
  }

  #mtg-dialogo-proxies .modal-dialog,
  #mtg-dialogo-hoja .modal-dialog {
    width: 100% !important;
    max-width: none;
    margin: 0;
    transform: none !important;
  }

  #mtg-dialogo-proxies .modal-content,
  #mtg-dialogo-hoja .modal-content {
    border: 0;
    background: transparent;
  }

  /* **`max-height` y `overflow` son los que recortan.** Sin quitarlos, el papel enseña solo la
     primera pantalla de cartas y el resto no existe: se imprime lo que cabía en el scroll. */
  #mtg-dialogo-proxies .modal-body,
  #mtg-dialogo-hoja .modal-body {
    max-height: none !important;
    overflow: visible !important;
    padding: 0;
  }

  /* La cabecera, el pie y los controles del diálogo no se imprimen: un botón «Imprimir»
     impreso en el papel no tiene ninguna gracia. */
  #mtg-dialogo-proxies .modal-header,
  #mtg-dialogo-proxies .modal-footer,
  #mtg-dialogo-hoja .modal-header,
  #mtg-dialogo-hoja .modal-footer,
  .mtg-proxy-controles,
  .mtg-hoja-controles {
    display: none !important;
  }

  .modal-backdrop {
    display: none !important;
  }
}

/* ============================================================================
   LA HOJA DE LISTA
   ============================================================================
   El papel que se entrega en la mesa de jueces —la *print sheet* de tcdecks—, ya escrito.

   **Va en negro sobre blanco siempre, también en tema oscuro**, y es una excepción deliberada a
   que todo se pinte con las variables del tema: esto no es una pantalla, es la previsualización
   de un documento. Con los colores del tema oscuro, lo que se ve arriba no sería lo que sale
   abajo — y de paso los navegadores descartan los fondos al imprimir, así que un papel oscuro
   saldría con el texto claro sobre blanco. */
.mtg-hoja {
  background: #fff;
  color: #111;
  padding: 1.2rem 1.4rem;
  border-radius: var(--bs-border-radius);
  font-size: 0.92rem;
  line-height: 1.35;
}

.mtg-hoja-titulo {
  font-size: 1.1rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 0.6rem;
}

.mtg-hoja-cabecera {
  border-block-end: 1.5pt solid #111;
  padding-block-end: 0.6rem;
  margin-block-end: 0.8rem;
}

/* Tres por fila: los seis datos entran en dos renglones y no en seis. */
.mtg-hoja-campos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem 1.2rem;
}

.mtg-hoja-campo {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.mtg-hoja-campo > span {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #555;
}

/* **Un campo vacío tiene que imprimirse como una raya para rellenar a boli**, y uno escrito como
   texto normal. Un `<input>` hace las dos cosas con una sola regla: se le quita todo el aspecto
   de control y se le deja la línea de abajo. */
.mtg-hoja-campo > input {
  border: 0;
  border-block-end: 0.75pt solid #111;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  padding: 0.1rem 0.1rem 0.15rem;
  min-width: 0;
}

.mtg-hoja-campo > input:focus {
  outline: 2px solid #666;
  outline-offset: 1px;
}

.mtg-hoja-cuerpo {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 1.5rem;
  align-items: start;
}

.mtg-hoja-seccion {
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-block-end: 0.75pt solid #111;
  padding-block-end: 0.15rem;
  margin: 0 0 0.4rem;
  display: flex;
  justify-content: space-between;
}

.mtg-hoja-tipo {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #555;
  margin: 0.5rem 0 0.1rem;
  display: flex;
  justify-content: space-between;
}

.mtg-hoja-líneas {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* **Sin línea entre cartas.** La hoja compacta no es un formulario que se rellene —para eso está la
   oficial, que sí lleva sus renglones—, así que la raya punteada no era sitio para escribir: solo
   ruido entre nombre y nombre. Lo quitó el organizador viéndolo. */
.mtg-hoja-líneas li {
  display: flex;
  gap: 0.5rem;
  padding-block: 0.08rem;
}

/* Cifras alineadas: una columna de cantidades que baila se cuenta mal, y contarla es lo que hace
   el juez con esta hoja en la mano. */
.mtg-hoja-cantidad {
  min-width: 1.4rem;
  text-align: end;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.mtg-hoja-carta {
  flex: 1 1 auto;
  min-width: 0;
}

.mtg-hoja-vacio {
  color: #555;
  font-style: italic;
}

/* Aquí estaba el renglón de firma de la hoja compacta. **Se quitó viéndolo**: la firma es de la hoja
   oficial, que es la que se entrega y trae su recuadro; en la compacta era una raya suelta a media
   columna. */

.mtg-hoja-pie {
  margin: 1.2rem 0 0;
  padding-block-start: 0.3rem;
  border-block-start: 0.4pt solid #999;
  font-size: 0.65rem;
  color: #555;
}

/* ============================================================================
   LA HOJA DE REGISTRO OFICIAL, COPIADA POR COORDENADAS
   ============================================================================
   La rejilla es la del PDF que pasó el organizador: **612 × 792 puntos**, con el origen abajo a la
   izquierda. El marcado coloca cada pieza con `--x` y `--y` en esos puntos y aquí solo se decide
   **cuánto mide un punto**:

   - en papel, el que le toca dentro de un A4 → 210 mm / 612 pt = **0,3431 mm**;
   - en pantalla, uno que quepa en el diálogo.

   Es el mismo mecanismo que `--mtg-columna-papel` en el cuadro impreso: en papel el píxel no
   significa nada, y una hoja que se declara en píxeles sale de un tamaño distinto en cada impresora.

   **Nada de `zoom`**, que ya dio problemas con el cuadro: se multiplica con la escala del diálogo de
   impresión, así que pelea con lo que elija el usuario. */
.mtg-oficial {
  --mtg-pt: 1.05px;

  position: relative;
  width: calc(612 * var(--mtg-pt));
  height: calc(792 * var(--mtg-pt));
  margin-inline: auto;
  background: #fff;
  color: #111;
  font-family: Helvetica, Arial, sans-serif;
}

.mtg-oficial > * {
  position: absolute;
  left: calc(var(--x) * var(--mtg-pt));
  top: calc(var(--y) * var(--mtg-pt));
}

.mtg-oficial-caja {
  width: calc(var(--w) * var(--mtg-pt));
  height: calc(var(--h) * var(--mtg-pt));
  border: 1pt solid #111;
}

/* El logotipo va a su tamaño en puntos, como todo lo demás. **`print-color-adjust` no le basta**:
   los navegadores descartan los fondos, pero una imagen en flujo sí se imprime — lo que hay que
   asegurar es que no la escale nadie. */
.mtg-oficial-logo {
  width: calc(var(--w) * var(--mtg-pt));
  height: calc(var(--h) * var(--mtg-pt));
  object-fit: contain;
}

.mtg-oficial-caja-fina {
  border-width: 0.5pt;
}

/* Los rótulos van anclados por su **línea base**, que es como los coloca un PDF: por eso se sube el
   texto su propio tamaño en vez de tirar la caja hacia abajo. Sin esto todo queda una línea más bajo
   que en el original. */
.mtg-oficial-rótulo,
.mtg-oficial-renglon,
.mtg-oficial-campo {
  font-size: calc(var(--fs) * var(--mtg-pt));
  line-height: 1;
  transform: translateY(-100%);
  white-space: nowrap;
}

.mtg-oficial-negrita {
  font-weight: 700;
}

.mtg-oficial-girado {
  transform: rotate(-90deg);
  transform-origin: 0 0;
}

/* El renglón: la línea se dibuja siempre y el texto se apoya en ella. */
.mtg-oficial-renglon {
  display: block;
  width: calc(var(--w) * var(--mtg-pt));
  border-block-end: 0.5pt solid #111;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mtg-oficial-cantidad {
  text-align: end;
  padding-inline-end: calc(4 * var(--mtg-pt));
}

.mtg-oficial-campo {
  width: calc(var(--w) * var(--mtg-pt));
  border: 0;
  background: none;
  color: inherit;
  font-family: inherit;
  padding: 0;
}

.mtg-oficial-campo:focus {
  outline: 1pt solid #666;
}

@media print {
  .mtg-oficial {
    /* 210 mm de A4 entre los 612 pt de ancho de la hoja original. La altura sale sola: 792 pt por
       0,3431 son 271,7 mm, que entran en los 297 de un A4 con sitio de sobra. */
    --mtg-pt: 0.3431mm;

    margin: 0;
  }

  /* Sin esto, los navegadores descartan las líneas y las cajas al imprimir para ahorrar tinta, y la
     hoja sale con los datos flotando sin su rejilla. */
  .mtg-oficial * {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}

/* En el diálogo, a 375 px la hoja de 612 pt no cabe: se encoge el punto hasta que quepa. Sigue
   siendo la misma hoja, solo que más pequeña — lo que se imprime no depende de esto. */
@media screen and (max-width: 767.98px) {
  .mtg-oficial {
    --mtg-pt: 0.55px;
  }
}

/* El modelo en flujo de la hoja oficial —`.mtg-wotc-*`— **vivía aquí y se ha ido entero**: lo
   sustituyó `.mtg-oficial`, que copia la hoja por coordenadas del PDF original. Se borra en lugar de
   dejarlo «por si acaso»: CSS muerto que se parece al vivo es la pista falsa que encuentra el
   siguiente. */
@media print {
  .mtg-hoja {
    padding: 0;
    border-radius: 0;
    /* En papel el tamaño lo manda el punto y no el `rem`, que arrastra el 16 px de la pantalla. */
    font-size: 9.5pt;
  }

  /* Los fondos se descartan al imprimir, así que el papel es blanco de todas formas; lo que hay
     que asegurar es que **el texto y las líneas salgan**, que es lo que se pierde si el navegador
     decide aclarar. */
  .mtg-hoja * {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  /* Una sección no se parte entre dos hojas si puede evitarse: un «Criaturas» al final de una
     página con sus cartas en la siguiente es justo lo que hace ilegible una lista. */
  .mtg-hoja-tipo {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .mtg-hoja-tipo {
    break-after: avoid;
    page-break-after: avoid;
  }
}

/* En móvil las dos columnas se apilan: a 375 px, el sideboard en una columna de 140 px parte
   «Nevinyrral's Disk» en tres. En papel siguen siendo dos, porque allí el ancho es el del A4. */
@media screen and (max-width: 575.98px) {
  .mtg-hoja-cuerpo {
    grid-template-columns: 1fr;
  }

  .mtg-hoja-campos {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ---- Compartir la baraja como PNG ----
   La fuente de la que el lienzo saca las ilustraciones. **No se ve, pero tiene que existir con tamaño**:
   con `display: none` el navegador puede no llegar a descargar las imágenes, y entonces el lienzo se
   compone con huecos. Se saca de la vista con `clip-path`, el mismo patrón que un rótulo accesible. */
.mtg-png-fuente {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  pointer-events: none;
}

/* La previa es la imagen de verdad, reducida al ancho del diálogo. */
.mtg-png-imagen {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--bs-border-radius);
}

/* ---- La pantalla de probabilidad ----
   El titular: la cifra grande con su pregunta encima y sus datos debajo. Es lo que se lee primero y lo
   que se dice en voz alta; antes había que buscarlo dentro de la tabla. */
.mtg-prob-titular {
  text-align: center;
  padding: 1rem;
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
}

.mtg-prob-pregunta,
.mtg-prob-detalle {
  margin: 0;
  font-size: 0.85rem;
  color: var(--bs-secondary-color);
}

/* La cifra **no va en acento**: el amarillo significa «esto se pulsa» y un número no se pulsa. Va en
   el color del cuerpo y grande, que es lo que la hace destacar sin inventar un significado. */
.mtg-prob-cifra {
  margin: 0.1rem 0;
  font-size: clamp(2rem, 9vw, 3rem);
  font-weight: 700;
  line-height: 1;
}

/* Los atajos de valor bajo cada campo. Se parten de línea si hace falta y **no crecen con el dedo**:
   son un accesorio del campo, no el control principal — el campo sigue estando ahí para teclear. */
.mtg-prob-atajos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-block-start: 0.35rem;
}

.mtg-prob-atajos .btn {
  padding: 0.1rem 0.45rem;
  font-size: 0.8rem;
}

/* Los cuatro números de cierre: rótulo y cifra por línea, en rejilla para que las cifras se alineen. */
.mtg-prob-resumen li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  padding-block: 0.15rem;
  color: var(--bs-secondary-color);
}

.mtg-prob-resumen strong {
  color: var(--bs-body-color);
}

/* La tabla por turno lleva once filas y cinco columnas: sin `nowrap` se comprime en vez de desbordar,
   que es la trampa ya anotada para las tablas arrastrables. */
.mtg-tabla-turnos {
  white-space: nowrap;
}

/* ---- La tabla de probabilidades ----
   La barra es el canal que se lee de un vistazo; el porcentaje va al lado, así que el color
   nunca es la única forma de saber la cifra — la misma regla que el medallero de la liga. */
.mtg-barra-probabilidad {
  height: 0.6rem;
  border-radius: 0.3rem;
  background: var(--mtg-celda-fondo);
  overflow: hidden;
}

.mtg-barra-probabilidad > span {
  display: block;
  height: 100%;
  background: var(--mtg-acento);
}

/* En móvil la columna de la barra sobra antes que ninguna: el número ya lo dice todo y el
   ancho es lo que escasea. */
@media (max-width: 575.98px) {
  .mtg-tabla-probabilidad th:last-child,
  .mtg-tabla-probabilidad td:last-child {
    display: none;
  }
}

/* ---- El editor: las cuatro vistas de la baraja ----
   Mismo mecanismo que ronda/clasificación en un torneo: el panel visible lo dice `data-panel`
   en el contenedor y lo pinta el CSS. Aquí son cuatro en vez de dos, y por eso el selector va
   por «lo que NO es el panel activo» en lugar de enumerar las combinaciones: con cuatro
   paneles serían doce reglas. */
#mtg-vistas-baraja > [role="tabpanel"] {
  display: none;
}

#mtg-vistas-baraja[data-panel="cartas"] .mtg-vista-cartas,
#mtg-vistas-baraja[data-panel="estadisticas"] .mtg-vista-estadisticas,
#mtg-vistas-baraja[data-panel="probabilidad"] .mtg-vista-probabilidad,
#mtg-vistas-baraja[data-panel="mano"] .mtg-vista-mano {
  display: block;
}

#mtg-vistas-baraja .mtg-pestanas {
  margin-block-end: 1rem;
}

/* ---- Los datos de la baraja, plegados ----
   Un `<details>` y no un acordeón de Bootstrap: no hace falta JavaScript y el navegador ya
   recuerda su estado. Ojo con la trampa ya documentada — **Chrome restaura el abierto/cerrado
   al recargar**, así que el `open` del servidor no manda tras un F5. */
.mtg-datos-baraja > summary {
  cursor: pointer;
  padding-block: 0.4rem;
}

/* Con el dedo, el resumen es lo que se toca para desplegar. */
@media (pointer: coarse) {
  .mtg-datos-baraja > summary {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}

/* ---- La mano repartida ----
   Las siete cartas a un tamaño en el que se lee el nombre y el coste, que es lo que se mira
   para decidir si se queda uno con la mano. */
.mtg-mano {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
  gap: 0.5rem;
}

.mtg-mano img {
  width: 100%;
  border-radius: var(--bs-border-radius);
}

/* Cuatro pestañas no caben en una fila de móvil: medido, suman **395 px** y «Mano» quedaba
   cortada contra el borde. Saltan de línea en lugar de comprimirse o de acortar el rótulo —un
   botón lleva un rótulo y el mismo en todas partes, que es regla del proyecto—. Con `flex-fill`
   de Bootstrap quedan dos y dos, repartidas. */
@media (max-width: 575.98px) {
  #mtg-vistas-baraja .mtg-pestanas {
    flex-wrap: wrap;
  }

  /* **La mitad exacta, no un 45 %.** Con 45 % las tres primeras cabían en una fila y «Mano»
     se quedaba sola ocupando los 351 px de la segunda, que se lee como un error de
     maquetación. `calc(50% - el hueco)` fuerza dos y dos.

     **Y por eso estas pestañas no llevan `flex-fill`** sino `mtg-pestana-baraja`: la clase de
     Bootstrap declara `flex: 1 1 auto` **con `!important`** y le gana a cualquier regla de
     aquí, así que con ella puesta este `calc` no hacía absolutamente nada. Es la misma trampa
     que ya está anotada para el reparto de anchos de las pestañas del torneo. */
  #mtg-vistas-baraja .mtg-pestana-baraja {
    flex: 1 1 calc(50% - 0.5rem);
  }
}

/* De 576 px en adelante las cuatro caben en una fila y se reparten el ancho, que es lo que
   hacía `flex-fill` antes de quitárselo. */
@media (min-width: 576px) {
  #mtg-vistas-baraja .mtg-pestana-baraja {
    flex: 1 1 auto;
  }
}

/* ---- La cabecera de datos del editor ----
   Nombre, formato y —si el formato clasifica— arquetipo, en una fila. La portada es una
   miniatura con su lápiz, como las carpetas de la biblioteca: se ve lo que tienes en vez de
   leer su nombre en un desplegable. */
/* **Es un `<button>`, no una caja**: la imagen entera abre el diálogo de la portada. De ahí que
   haya que deshacerle el relleno y el borde de botón — el contorno lo pone la propia imagen. */
.mtg-portada-mini {
  position: relative;
  flex: 0 0 auto;
  width: 3.5rem;
  height: 2.6rem;
  padding: 0;
  border: 0;
  background: none;
}

.mtg-portada-mini img,
.mtg-portada-mini-vacia {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--bs-border-radius);
  border: 1px solid var(--bs-secondary-color);
  background: var(--mtg-celda-fondo);
}

/* El lápiz: **la señal de que la imagen se pulsa, no el objetivo**. Va dentro de la esquina y no
   colgando fuera, en una plaquita oscura con el lápiz en blanco — el fondo de una carta puede ser
   cualquier cosa, así que el icono necesita su propio fondo opaco para leerse siempre igual.
   Es la regla de que un velo no sostiene un contraste, aplicada a un icono. */
.mtg-portada-editar {
  position: absolute;
  inset-block-end: 0.15rem;
  inset-inline-end: 0.15rem;
  display: inline-flex;
  padding: 0.15rem;
  border-radius: 0.25rem;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  line-height: 0;
  pointer-events: none;
}

.mtg-portada-editar svg {
  width: 0.75rem;
  height: 0.75rem;
}

/* Con el dedo, la miniatura crece hasta pasar de 44 px de alto: **ahora el objetivo es ella**,
   así que ya no hace falta que el lápiz mida 44 por su cuenta. */
@media (pointer: coarse) {
  .mtg-portada-mini {
    width: 4.4rem;
    height: 3.2rem;
  }

  .mtg-portada-editar svg {
    width: 0.9rem;
    height: 0.9rem;
  }
}

/* En móvil la fila se parte: tres campos en 375 px dejarían el nombre en cuatro caracteres. */
@media (max-width: 575.98px) {
  .mtg-datos-baraja {
    flex-wrap: wrap;
  }

  .mtg-datos-baraja > .flex-grow-1 {
    flex: 1 1 100%;
  }

  /* **El nombre es la excepción y se queda al lado de la miniatura.** Bajándolo de línea, la
     miniatura se quedaba sola en la primera con **270 px vacíos a su derecha** — un renglón
     entero de pantalla gastado en no decir nada. Y cabe de sobra porque la miniatura solo se
     lleva 70 px: al campo le quedan 265, más de lo que necesita un nombre de baraja.

     La pieza que lo hace encajar es el `align-items: end` de la fila: la miniatura mide menos
     que el rótulo más el campo, así que su alto se come el hueco que el rótulo «Nombre» deja
     libre a su izquierda en vez de pedir sitio propio. Idea del organizador, con la captura
     delante.

     `min-width: 0` no es opcional: sin él un hijo flexible no baja de su ancho de contenido y
     el campo empujaría a la miniatura fuera de la línea. */
  .mtg-datos-baraja > .mtg-campo-nombre {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* **El lápiz sobresale de la miniatura y ahora tiene un vecino.** Con el dedo mide 44 px y se
   sale 0,8 rem por la derecha, así que su esquina se metía **5 px dentro del campo del nombre**
   —medido: el botón acaba en 95 y el campo empezaba en 90—: tocar el borde izquierdo del campo
   abría el diálogo de la portada. No pasaba antes porque el nombre estaba en otra línea, y no
   pasa con ratón, donde el lápiz es pequeño y se queda dentro de los 8 px de hueco. */
@media (max-width: 575.98px) and (pointer: coarse) {
  .mtg-datos-baraja > .mtg-campo-nombre {
    margin-inline-start: 0.5rem;
  }
}

/* «Validando…» en la esquina del rótulo de la lista, **fuera de flujo**: es un indicador de HTMX
   —invisible casi siempre— y en flujo reservaba su renglón, que eran 40 px de hueco muerto entre
   los avisos y las pestañas. En la esquina no cuesta nada y se lee al lado de lo que cuenta. */
#validando {
  position: absolute;
  inset-block-start: 0;
  inset-inline-end: 0;
  z-index: 1;
}

/* `mtg-recuentos` es **el destino del intercambio de HTMX, no una caja**: con `display: contents`
   sus distintivos son elementos de la fila del rótulo y se parten **uno a uno**. Como caja, los
   tres viajaban juntos a la segunda línea en móvil y «Lista» se quedaba solo con 300 px vacíos al
   lado, que se lee como un fallo de maquetación. */
.mtg-recuentos {
  display: contents;
}

/* ---- Elegir portada: las cartas de la lista ----
   Con ilustración y no con una lista de nombres, por lo mismo que la miniatura del editor sustituyó a
   un desplegable: una portada se elige mirándola. */
.mtg-portadas-posibles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  gap: 0.5rem;
}

.mtg-portada-opcion {
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  overflow: hidden;
  text-align: start;
  /* El borde de 2 px es la marca de elegida y va **siempre declarado**, transparente cuando no lo
     está: declararlo solo en la elegida le sumaría 4 px y movería la rejilla al elegir. */
}

.mtg-portada-opcion img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.mtg-portada-opcion-nombre {
  display: block;
  padding: 0.2rem 0.35rem;
  font-size: 0.75rem;
  line-height: 1.2;
  /* Un nombre largo recorta, nunca descuadra la caja: la regla general del proyecto. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-portada-opcion-elegida {
  border-color: var(--mtg-acento);
}

/* ---- El marcador de puntos ----
   Verde mientras quepan y rojo al pasarse, al lado de «Maindeck» y «Sideboard».

   **No usa `text-bg-success` ni `text-bg-danger`**, que es lo que parecía obvio: son colores
   fijos de Bootstrap y el rojo da **3,87 contra el blanco**, por debajo del 4,5 de un texto
   normal —y un distintivo se lee en 12,6 px—. Con los tonos oscuros de la misma paleta salen
   6,18 y 6,68, medidos, y valen igual en los dos temas porque el distintivo trae su propio
   fondo opaco: su contraste no depende de lo que tenga debajo. */
.mtg-puntos-ok,
.mtg-puntos-pasado {
  color: #fff;
}

.mtg-puntos-ok {
  background-color: #146c43;
}

.mtg-puntos-pasado {
  background-color: #b02a37;
}

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

   Ojo con el nombre: en este proyecto **«portada» es la carta de una baraja o de una carpeta**, y
   `.mtg-portada-*` ya es eso. Esta página usa `mtg-inicio-*` para que las dos cosas no compartan
   prefijo — un `.mtg-portada-seccion` habría sido la pista falsa que encuentra el siguiente.

   Hasta el 14 de agosto de 2026 esta pantalla era el andamiaje del primer día, y además decía que el
   almacenamiento era «XML en disco», un adaptador que ADR-0011 descartó y que nunca existió. */

/* El bloque de actividad y el de secciones, separados entre sí. No llevan caja: la que hay ya la
   ponen las fichas y las tarjetas de dentro, y una caja alrededor de otra caja solo añade bordes. */
.mtg-inicio-bloque {
  margin-block-start: 2rem;
}

/* El rótulo del bloque y su «ver todos» en la misma línea, alineados por la **línea base** y no por el
   centro: son dos textos de tamaños distintos y centrarlos deja el pequeño flotando. */
.mtg-inicio-titulo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-block-end: 0.6rem;
}

.mtg-inicio-titulo-solo {
  margin-block-end: 0.6rem;
}

.mtg-inicio-todos {
  flex: 0 0 auto;
  font-size: 0.9rem;
}

/* ---- La actividad del club: dos columnas cuando están las dos secciones ----
   Lo pidió el organizador el 24 de agosto de 2026 viéndolo —«¿no estaría mejor en dos columnas en lugar de
   uno bajo del otro? Si alguno no está, que coja toda la línea»—, y con un torneo abierto y dos ligas se veía
   por qué: cada sección se llevaba una fila entera de la pantalla para una ficha, con el 75 % del renglón
   vacío a la derecha.

   **Las dos mitades de la petición las resuelve `auto-fit`**, así que no hace falta que Razor cuente, ni una
   clase «soy la única», ni un `:has()`: con una sola sección la pista vacía se colapsa y la que queda se
   lleva el ancho entero, o sea el bloque de siempre. «Solo hay una» es el caso por defecto y no una rama que
   haya que acordarse de escribir.

   **Y el umbral no es un ancho de pantalla, es cuántas fichas caben**, que es lo que se vio midiendo: con
   `min-width: 992px` y dos columnas al 50 %, a 1200 px cada columna se quedaba en **568,5** y una fila de dos
   fichas pide **588** (`minmax(18rem)` × 2 + 12 de hueco), así que la cuadrícula interna caía a una sola
   columna y la sección de dos ligas pasaba de 297 px de alto a **570**. El bloque entero medía 602 contra los
   ~618 de apilarlo: dos columnas que no ganaban nada y que además rompían la forma de la cuadrícula de
   fichas. Con **37 rem** (592 px) la rejilla solo se parte cuando cada mitad puede llevar sus dos fichas —a
   1400 px de ventana la columna da 660— y por debajo se apila a todo el ancho, que es lo correcto.

   **`min(37rem, 100%)` y no `37rem` a secas**, y esto falla en silencio: el mínimo de un `minmax` es un
   mínimo de verdad, así que la pista no encoge por debajo de él — en una ventana de 375 px la rejilla pedía
   una pista de **592** y el documento se iba a **604**, con la página entera desplazándose de lado. El
   medidor no señaló ningún elemento culpable y lo que lo delató fue la cifra del documento. Con `min()` el
   mínimo se rinde al ancho disponible cuando no cabe, que es justo lo que hace falta en móvil.

   `align-items: start` para que la sección corta **no se estire** a la altura de la larga: una caja de fichas
   estirada reparte su hueco entre menos filas y deja las fichas separadas sin motivo. */
.mtg-inicio-actividad {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(37rem, 100%), 1fr));
  column-gap: 1.5rem;
  align-items: start;
}

/* ---- Mis cifras de la cabecera ----
   Tres enlaces-píldora a «Mis eventos» en el sitio de los botones que se fueron. **No van en acento**:
   son datos que se pulsan, no la acción principal de la página — mismo tratamiento que el chip de baraja
   de una ficha, relieve y no color. */
.mtg-inicio-cifra {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  color: var(--bs-secondary-color);
  text-decoration: none;
}

.mtg-inicio-cifra strong {
  color: var(--bs-body-color);
}

.mtg-inicio-cifra:hover,
.mtg-inicio-cifra:focus-visible {
  border-color: var(--mtg-acento);
  color: var(--bs-body-color);
}

@media (pointer: coarse) {
  .mtg-inicio-cifra {
    min-height: var(--mtg-toque);
  }
}

/* ---- Las dos mitades de «lo mío», lado a lado en escritorio ----
   Partidas por jugar y barajas por preparar, **una al lado de la otra** desde 992 px —el umbral que ya
   usan la inscripción y el interruptor del cuadro, no uno nuevo— y apiladas por debajo. Las partidas se
   llevan más sitio porque su línea tiene más datos (hora + rival + torneo contra nombre + destino).
   `minmax(0, …)` y no `1fr` a secas: sin él una rejilla no deja encoger a sus hijos por debajo de su
   contenido, y los puntos suspensivos de los nombres no se activarían nunca — la trampa de siempre. */
@media (min-width: 992px) {
  .mtg-inicio-mio {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    column-gap: 1.5rem;
    /* **`stretch` y no `start`**, que es lo que permite que el panel de noticias llegue hasta el fondo de la
       fila: con `start`, la columna derecha medía lo que midiera su contenido y dejaba un hueco en blanco
       debajo cuando la izquierda tenía muchas partidas. Lo pidió el organizador viéndolo. Estirar la columna
       izquierda no cambia nada —es un flex en columna y su contenido se queda arriba—. */
    align-items: stretch;
  }

  /* ---- El panel de noticias llega hasta abajo ----
     Tiene **alto mínimo y no alto fijo**: si no hay barajas ni partidas se queda como estaba, y si la columna
     izquierda pasa de ese mínimo, crece con ella. Eso es exactamente lo que pidió el organizador.

     Son tres eslabones y **hacen falta los tres**, porque entre la sección y la lista está el `<div>` que
     HTMX reemplaza: la sección crece dentro de su lado, el `<div>` crece dentro de la sección, y la lista
     crece dentro del `<div>`. Si uno se queda sin crecer, la cadena se rompe y vuelve el hueco.

     Y el `min-height: 0` de la lista **no es redundante con el `flex: 1`**: un hijo flexible no baja de su
     alto de contenido, así que sin él la lista mediría sus 25 líneas enteras, la fila crecería hasta ahí y
     **el scroll del panel no aparecería nunca** — sería la página la que se alargara. Es la misma trampa que
     el `min-width: 0` de un nombre que se recorta con puntos suspensivos, en el otro eje. */
  .mtg-inicio-noticias {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }

  .mtg-inicio-noticias-panel {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }

  /* **`flex-basis: 0` y no `auto`, y esto es la pieza que lo hace funcionar.** Con `auto`, el alto que la
     lista aporta a la fila es el de sus 25 líneas —1.611 px medidos—, así que la columna derecha pasaba a ser
     la más alta y **arrastraba la fila hasta 1.678**: ni había hueco que rellenar ni scroll en el panel, era
     la página la que se alargaba. Con la base a cero la lista no aporta alto, la fila la decide la columna
     izquierda, y la lista crece después hasta llenarla.

     El `min-height` es **el alto mínimo que pidió el organizador**: era el `max-height` de siempre y aquí
     pasa a ser un suelo en vez de un techo, así que sin barajas ni partidas el panel se ve como estaba. */
  .mtg-inicio-noticias .mtg-noticias {
    flex: 1 1 0;
    min-height: 28rem;
    max-height: none;
  }

  /* **Una columna sola ocupa el ancho entero.** Desde que la derecha lleva dos cosas —barajas y noticias—
     los lados son envoltorios, y sin esto un jugador sin barajas por preparar y sin noticias vería sus
     partidas en tres quintos de la fila con dos quintos en blanco. */
  .mtg-inicio-mio-lado:only-child {
    grid-column: 1 / -1;
  }
}

/* Los envoltorios de cada lado. **Existen porque el panel de noticias tiene que caer en la columna derecha**
   y con auto-colocación la tercera sección se habría ido debajo de las partidas — o sea a la izquierda, que
   es justo donde el organizador no señaló el hueco. El hueco vertical entre las secciones de un mismo lado
   lo pone esto y no un margen de la sección, que tendría que valer también entre columnas. */
.mtg-inicio-mio-lado {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-width: 0;
}

/* ---- Mis partidas por jugar ----
   Una lista de líneas, no fichas ni tabla: **la prueba del proyecto** —¿se comparan las celdas de una
   fila con las de la de al lado?— dice que no. Nadie compara la hora de su partida del jueves con la
   del sábado; cada línea es una unidad que se lee sola.

   Dos columnas en escritorio —la hora, y el resto— y **apiladas en móvil**, que es la misma decisión y
   el mismo motivo que apila los dos lados de una ficha de mesa: a 375 px, con la hora («vie 21 ago ·
   19:30», 129 px medidos) en su columna, al nombre del rival le quedan siete caracteres. */
.mtg-inicio-partidas {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 0;
}

/* `position: relative` es lo que sostiene el `stretched-link` del nombre del torneo, y con él **la
   línea entera es el objetivo táctil** — un enlace de una línea mide 22 px, que es el peor punto que
   sacó la pasada de QA del 7 de agosto y el mismo que ya se arregló en «ver todos». */
.mtg-inicio-partida {
  position: relative;
  display: grid;
  /* La hora primero y **con ancho fijo**, no `max-content`. La hora es la clave de ordenación, así que las
     columnas tienen que alinearse entre líneas para que la lista se lea como una agenda — y con
     `max-content` no se alinean, porque **cada línea es su propia rejilla**: «vie 21 ago · 19:00» mide 123
     px y «Sin hora» 58, así que el rival empezaba en una `x` distinta en cada renglón. Es el mismo
     descuadre que ya se corrigió en la leyenda de marcas, y por el mismo motivo.

     8,5 rem son 136 px, medido contra el peor caso de verdad: «mié 30 sept · 19:00», 132,2 px. El mes en
     español abrevia a cuatro letras en septiembre, que es lo que no cabía en 8. */
  grid-template-columns: 8.5rem 1fr auto;
  grid-template-areas:
    'cuando rival baraja'
    'cuando donde baraja';
  align-items: baseline;
  column-gap: 0.75rem;
  padding: 0.45rem 0.6rem;
  /* **El borde, y hace falta**: lo pidió el organizador viéndolo en los dos temas. El fondo de estas cajas
     es un velo translúcido muy suave, así que **donde el degradado de la imagen se acaba, el canto de la
     caja desaparece** y la lista se lee como texto suelto en vez de como una lista de cajas. Es el mismo par
     —velo de fondo + borde— que usa la caja de un torneo, que es la referencia que él citó. Cuesta 2 px de
     alto por línea, iguales en todas, así que no rompe ninguna de las cifras medidas. */
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius-sm);
  /* **Fondo opaco y no el velo translúcido**, pedido por el organizador —«en lugar de un borde, o además del
     borde, un color de fondo diferente»— y es lo correcto por la regla de siempre: **lo que necesita
     contraste garantizado no se apoya en un velo**. Con `--mtg-celda-fondo` la caja se veía o no según lo
     que tuviera debajo, que aquí es una ilustración; con un fondo opaco se lee igual en los dos temas y en
     todo el ancho.
     La ilustración **no se pierde**: va en un hijo a `z-index: -1` dentro de un contexto aislado, o sea por
     delante del fondo de la caja y por detrás del texto.
     Ojo con la regla gemela que dice lo contrario —una caja *sobre un panel* usa el velo, porque ahí todos
     los `--bs-*-bg` son más oscuros y la caja sale como un agujero—: esto se apoya en el fondo de la página,
     no en un panel, así que `--bs-tertiary-bg` es un escalón hacia arriba en oscuro y hacia abajo en claro. */
  background: var(--bs-tertiary-bg);
  /* Las dos mitades del fondo de imagen: `overflow` recorta la imagen al redondeo de la caja, e
     `isolation` es lo que permite que el fondo vaya en **`z-index: -1` sin desaparecer** — dentro de un
     contexto propio, un hijo negativo pinta por encima del fondo de la caja y por debajo de todo su
     contenido, así que el texto no necesita `position: relative`... y eso importa: posicionar los `<p>`
     robaría el ancla del `stretched-link`, que es la trampa ya documentada de `.mtg-portada-texto`. */
  isolation: isolate;
  overflow: hidden;
}

/* ---- El fondo de imagen de una caja que habla de un torneo ----
   La imagen del torneo o el tapete de su formato, con **el mismo velo medido de las fichas**
   (`--mtg-velo-ficha`): opaco donde va el texto y abriéndose hacia la derecha. Sin imagen, la caja se
   queda con su velo de siempre y no hay rama que mantener.

   La clase **ya no lleva el prefijo de la portada**: la pintan las dos listas de `/` y el histórico de
   «Mis barajas», y el marcado sale de `_FondoDeEvento` — un solo sitio para los cuatro. */
.mtg-fondo-evento {
  position: absolute;
  inset: 0;
  z-index: -1;
  /* La misma línea que ya lleva la miniatura de una ficha, y por lo mismo: sin ella, el `overflow`
     recorta el rectángulo del fondo un pelín por dentro del arco del propio fondo de la caja, y en cada
     esquina quedaba un **anillo de un píxel más claro** — se vio en la captura como cuatro marquitas.
     **Y el recorte va aquí además de en la caja**: el `<img>` es un rectángulo y sin esto asomaba por las
     esquinas del arco, que es la mitad del artefacto que quedaba después de la primera corrección. */
  border-radius: inherit;
  overflow: hidden;
}

.mtg-fondo-evento img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mtg-fondo-evento::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--mtg-velo-ficha);
}

/* El chip de la baraja de la partida: el de la ficha de un torneo, colocado en su columna. `align-self`
   al centro de las dos filas — con `baseline` heredado se pegaba a la primera. */
.mtg-inicio-chip-baraja {
  grid-area: baraja;
  align-self: center;
  justify-self: end;
  /* **Fondo opaco y no el velo del chip de la ficha**: aquí debajo hay una ilustración, y un velo sobre
     una imagen es exactamente el contraste que no se puede razonar — la regla del chip de semilla. */
  background: var(--bs-tertiary-bg);
}

/* ---- Barajas por preparar ----
   Cajas y no líneas — «hazlo con cajas, que queda visualmente más bonito», dicho por el organizador — con
   el mismo fondo de imagen que las partidas. La caja entera es el objetivo (`stretched-link` anclado a la
   caja, que es la posicionada) y lleva a la pantalla de la baraja de ese torneo. */
/* ---- En rejilla y no en columna ----
   Estuvo en `flex-direction: column`, o sea **una caja por fila pase lo que pase**, y eso deja una caja de
   1050 px para un nombre de torneo y tres datos. Lo vio el organizador: «las cajas son muy largas, no se puede
   hacer que cuando hay tanto espacio se pongan a más columnas».

   El número de columnas **lo decide `auto-fill`** y no una media query, que es la misma decisión que ya rige
   las tarjetas de «Qué hay aquí» y las ocho de la portada pública: una anchura escrita a mano sería una
   segunda verdad sobre dónde rompe la rejilla.

   **El `min()` no es opcional.** El mínimo de un `minmax` es un mínimo de verdad, así que con el ancho a secas
   la rejilla pediría una pista de 608 px dentro de una ventana de 375 y el documento se desbordaría — es la
   trampa que ya costó una medida en el bloque de actividad de esta misma página, donde el medidor no señaló
   ningún elemento culpable y lo delató la anchura del documento. Con `min()`, en móvil es una columna. */
.mtg-inicio-barajas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--mtg-caja-lista-min), 100%), 1fr));
  gap: 0.5rem;
  margin: 0;
}

.mtg-inicio-baraja {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  min-height: 4.25rem;
  padding: 0.55rem 0.75rem;
  /* El borde, por lo mismo que en la línea de una partida: sin él, donde acaba el degradado de la imagen
     desaparece el canto de la caja. */
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius-sm);
  /* Fondo opaco, por lo mismo que la línea de una partida. */
  background: var(--bs-tertiary-bg);
  /* El mismo par que la línea de una partida, y por lo mismo. */
  isolation: isolate;
  overflow: hidden;
}

/* ---- El borde en acento al pasar por encima ----
   **La regla que había aquí no hacía nada**: ponía `background: var(--bs-tertiary-bg)`, que *ya es* el fondo
   base de la caja — el mismo fondo por el mismo fondo. Así que la caja no daba ninguna señal de ser pulsable,
   y lo es entera (`stretched-link`). Lo vio el organizador: «cuando te pones por encima no se marca que es
   clicable con el borde amarillo como el resto de cajas».

   Se hace con `border-color` y **es la misma regla que `.mtg-torneo`**, que es la convención de la aplicación
   para una caja que se pulsa. No suma alto porque el borde ya está declarado. */
.mtg-inicio-baraja:hover,
.mtg-inicio-baraja:focus-within {
  border-color: var(--mtg-acento);
}

/* Las dos líneas **reservan el hueco del distintivo**, que va en absoluto sobre la esquina y no encoge:
   sin la reserva, el nombre de un torneo largo se metía por debajo de «Cambia tu lista». Es la misma
   corrección —y el mismo motivo— que el hueco que la cinta de liga se cobra en una ficha de móvil: cede
   el texto, que tiene su `title`, no la señal. */
.mtg-inicio-baraja-nombre,
.mtg-inicio-baraja-para {
  padding-inline-end: 7.5rem;
}

.mtg-inicio-baraja-nombre {
  display: flex;
  min-width: 0;
  font-weight: 600;
}

/* El nombre en el color del cuerpo, no en el azul de Bootstrap: mismo motivo y misma cifra que el nombre
   del torneo en una partida — el enlace es la caja entera, y el azul daba 3,76 sobre el velo en claro. */
.mtg-inicio-baraja-nombre .mtg-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
}

.mtg-inicio-baraja:hover .mtg-inicio-baraja-nombre .mtg-nombre,
.mtg-inicio-baraja:focus-within .mtg-inicio-baraja-nombre .mtg-nombre {
  text-decoration: underline;
}

.mtg-inicio-baraja-para {
  display: flex;
  gap: 0.35rem;
  min-width: 0;
  font-size: 0.9rem;
}

.mtg-inicio-baraja-para .mtg-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--bs-secondary-color);
}

/* Los datos, agrupados y con el separador **puesto por el CSS**. En el marcado el «·» iba dentro del texto de
   cada dato, y así no se le puede quitar al primero — que es justo lo que hace falta cuando el grupo baja a su
   propio renglón en móvil. */
.mtg-inicio-baraja-meta {
  display: flex;
  gap: 0.35rem;
  white-space: nowrap;
}

.mtg-inicio-baraja-meta .mtg-inicio-de::before {
  content: "·";
  margin-inline-end: 0.35rem;
}

/* El borde en acento, igual que la caja de un torneo y que las dos cajas de baraja. **Aquí también la regla
   que había no hacía nada**: ponía `background: var(--bs-tertiary-bg)`, que *ya es* el fondo base de la línea
   —dos comentarios más arriba se explica por qué es opaco—, o sea el mismo fondo por el mismo fondo. Lo
   señaló el organizador: «en tus partidas por jugar no has dejado el borde de cuando te pones encima». */
.mtg-inicio-partida:hover,
.mtg-inicio-partida:focus-within {
  border-color: var(--mtg-acento);
}

.mtg-inicio-cuando {
  grid-area: cuando;
  align-self: center;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}

/* «Sin hora» **no va en el color del cuerpo**: es la ausencia de un dato, no el dato. Y no se apaga más
   que eso —`--bs-secondary-color` da 5,76 y 6,17 medidos— porque sigue siendo información. */
.mtg-inicio-sin-hora {
  color: var(--bs-secondary-color);
  font-weight: 400;
}

.mtg-inicio-rival {
  grid-area: rival;
  display: flex;
  gap: 0.3rem;
  /* Sin esto el `text-overflow` del nombre no se activa nunca: un hijo flexible no baja de su ancho de
     contenido. Es la trampa que ya está documentada para la celda de una tabla de fichas. */
  min-width: 0;
  font-weight: 600;
}

.mtg-inicio-rival .mtg-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-inicio-contra {
  flex: 0 0 auto;
  color: var(--bs-secondary-color);
  font-weight: 400;
}

.mtg-inicio-donde {
  grid-area: donde;
  display: flex;
  gap: 0.35rem;
  min-width: 0;
  font-size: 0.9rem;
}

/* El nombre del torneo es el enlace y va **en el color del cuerpo**, no en el azul de Bootstrap. No es
   estética: `#0d6efd` sobre el velo de la línea da **3,76** en tema claro, por debajo del 4,5 de un texto
   normal —medido—, y además aquí el enlace es la línea entera, así que pintarlo de azul prometería que lo
   pulsable es esa palabra. Con el color del cuerpo, 12,63 y 15,08. Es lo mismo que ya hace el título de una
   tarjeta de sección, dos bloques más abajo. */
.mtg-inicio-donde .mtg-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
}

.mtg-inicio-partida:hover .mtg-inicio-donde .mtg-nombre,
.mtg-inicio-partida:focus-within .mtg-inicio-donde .mtg-nombre {
  text-decoration: underline;
}

/* De qué es la partida **no encoge**: «Ronda 3 · mesa 4» son datos cortos, y con el reparto
   proporcional del flex el largo —el nombre del torneo— se los comería letra a letra. Misma corrección
   que en el segundo renglón de la ficha de un torneo. */
.mtg-inicio-de {
  flex: 0 0 auto;
  color: var(--bs-secondary-color);
  white-space: nowrap;
}

/* ---- Las tarjetas de sección ----
   Mismas reglas que la ficha de un torneo y por el mismo motivo: `position: relative` es lo que
   sostiene el `stretched-link` del título, y con él **la tarjeta entera es el objetivo táctil**. Un
   título de una línea mide 22 px de alto, que es exactamente el peor punto que sacó la pasada de QA
   del 7 de agosto.

   `minmax(20rem, …)` se midió **contra seis tarjetas**: con 15 rem salían cuatro columnas a 1280 px y
   la segunda fila se quedaba a medias. **Hoy son cinco** —al borrar `/Cartas` el 14 de agosto se fue la
   suya— así que a 1280 salen 3 + 2 y el hueco se ve abajo a la derecha, que es exactamente el defecto
   que aquella cifra venía a evitar. La cifra se queda: lo que se arregla es el hueco, estirando la
   última tarjeta hasta el final de su fila. A ~1000 px pasan a dos columnas y en móvil a una. */
.mtg-inicio-secciones {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: 0.75rem;
  margin: 0;
}

/* El icono ocupa su columna y **abarca las dos filas** —título y texto—, así que no hace falta un
   elemento que envuelva al título para ponerlo a su lado. Con `align-self: start` se queda arriba en
   vez de estirarse hasta el pie de la tarjeta. */
.mtg-inicio-seccion {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  /* Recorta la ilustración contra el radio de la caja, igual que la tarjeta de la portada pública y la
     caja de un torneo en cuadrícula. */
  overflow: hidden;
}

/* La rejilla de icono + título + texto se mudó al cuerpo cuando la caja pasó a llevar una cabecera de
   ilustración encima: es la misma división que ya tenía `.mtg-publica-cosa`. */
.mtg-inicio-seccion-cuerpo {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.6rem;
  row-gap: 0.15rem;
  padding: 0.9rem;
}

/* ---- La ilustración de cabecera de una tarjeta de sección ----
   Lo pidió el organizador el 24 de agosto de 2026: las mismas cartas y la misma forma que en la portada
   pública, «para que quede más bonito».

   **7,5 rem y no las 9 de la portada pública**, y la diferencia está medida: allí la tarjeta es lo único que
   hay en la página, y aquí va detrás de las partidas por jugar y las barajas por preparar, así que 9 rem por
   cinco cajas metían la última fila fuera de dos pantallas de escritorio.

   **Sin `position: relative`**, al contrario que `.mtg-publica-cabeza`, y eso no es una simplificación: la
   tarjeta lleva `stretched-link`, cuyo `::after` se resuelve contra el ancestro posicionado más cercano. Con
   la cabecera posicionada, el área pulsable de la tarjeta se habría encogido **a la ilustración** —el enlace
   del título dejaría de cubrir la caja— y eso no da ningún error: solo deja de funcionar el gesto. Por eso el
   hijo se dimensiona con `width`/`height` al 100 % en vez de con `inset: 0`. */
.mtg-inicio-seccion-arte {
  flex: none;
  height: 7.5rem;
  /* Si la ilustración no carga, el hueco tiene que parecer un hueco y no un fallo de maquetación. */
  background: var(--bs-tertiary-bg);
}

.mtg-inicio-seccion-arte > img,
.mtg-inicio-seccion-arte > .mtg-carta-sin-imagen {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* En móvil baja a 6 rem por lo mismo que la de la portada pública: a 375 px la caja mide 343 de ancho, así
   que la cabecera es lo que más scroll añade. */
@media (max-width: 767.98px) {
  .mtg-inicio-seccion-arte {
    height: 6rem;
  }
}

/* El acento al pasar por encima y al enfocar, igual que la ficha de un torneo. `focus-within` porque
   quien recibe el foco es el enlace estirado, no la tarjeta. */
.mtg-inicio-seccion:hover,
.mtg-inicio-seccion:focus-within {
  border-color: var(--mtg-acento);
}

/* El icono **no va en acento**, y eso es la regla y no un gusto: el amarillo significa «esto se
   pulsa», y con seis tarjetas encendidas dejaría de significarlo. Lo que dice que la tarjeta se pulsa
   es el borde al pasar por encima, que es lo mismo que hace un torneo. */
/* **1,2 rem no es un tamaño elegido, es la altura de la línea del título** (`h6` = 16 px × 1,2 = 19,2),
   y por eso el icono queda centrado con él **por construcción y sin margen de compensación**. Estuvo en
   1,4 rem con un `margin-block-start: 0.1rem` puesto a ojo, y `medir.js` lo cazó: el dibujo sobresalía
   3,2 px por debajo del centro del título, porque medía 22,4 contra los 19,2 de la línea. Compensarlo
   habría pedido un margen **negativo** de 1,59 px, que es la señal de que el tamaño era el problema.
   Medido después: desvío 0. */
.mtg-inicio-icono {
  grid-row: 1 / span 2;
  align-self: start;
  width: 1.2rem;
  height: 1.2rem;
  color: var(--bs-secondary-color);
}

/* El título es el enlace, así que **se pinta como texto y no como enlace**: en una tarjeta que se
   pulsa entera, subrayarlo prometería que solo esa línea lleva a algún sitio. */
.mtg-inicio-seccion h3 a {
  color: inherit;
  text-decoration: none;
}

/* El título de la tarjeta de noticias es un `<button>` y no un enlace —abre el diálogo, no navega—, así que
   hay que quitarle la cáscara que le pone el navegador: sin esto sale con su fondo gris, su borde y su
   tipografía de control, o sea una tarjeta que no se parece a las otras cinco. `text-align: start` porque un
   botón centra su texto por defecto. */
.mtg-inicio-seccion h3 .mtg-inicio-nolink {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
}

.mtg-inicio-seccion p {
  grid-column: 2;
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
}

/* El enlace «ver todos» mide **22 px de alto**, la mitad del mínimo del dedo — lo denunció `medir.js`
   en la primera pasada, y es exactamente el defecto que esa misma herramienta le sacó al título de una
   ficha del listado el 7 de agosto.

   Se resuelve con el patrón que ya usa la píldora de una mesa: **el área crece sin que el enlace
   crezca**, con un pseudo-elemento que se sale hacia el hueco de arriba y de abajo. 22 + 11 + 11 = 44.

   El margen de abajo del rótulo sube a 0,9 rem **solo con puntero grueso**, y no es cosmético: con los
   0,6 de base (9,6 px) el área se metería 1,4 px dentro de la primera ficha, y ahí el clic lo cogería
   este enlace en vez del `stretched-link` de la ficha. Con 14,4 px de hueco, el área crece contra
   espacio vacío. Cuesta 4,8 px por rótulo. */
/* En móvil la línea de una partida **se apila**: la hora arriba y el resto debajo. Es la misma decisión
   que apila los dos lados de una ficha de mesa, y por la misma medida — con la hora en su columna
   («vie 21 ago · 19:30», 129 px) al rival le quedaban siete caracteres de los 375 de la pantalla.

   Va en `@media screen` porque al imprimir las media queries miden **la hoja**: un A4 vertical son ~703
   px y esta lista saldría apilada sin necesidad. */
@media screen and (max-width: 575.98px) {
  /* ---- Tres filas, y el reparto lo eligió el organizador ----
     **La hora comparte fila con el rival, el torneo se queda una entera y la ronda y la mesa van en la
     tercera.** Antes eran hora / rival / (torneo + ronda·mesa), y ahí el torneo compartía renglón con
     «Ronda 1 · mesa 1» —que no encoge— así que se recortaba a «Premodern por int…» en la mayoría de las
     líneas. Con su fila propia se lee entero y **no cuesta ni un renglón**: la hora y el rival caben
     juntos.

     El chip ocupa la columna de la derecha **a lo alto de las tres filas**: apilado debajo costaría un
     renglón por línea, y a la derecha es donde el velo se abre — lleva su fondo propio, así que no
     depende de lo que tenga debajo. */
  .mtg-inicio-partida {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      'cuando rival baraja'
      'donde donde baraja';
  }

  .mtg-inicio-cuando {
    align-self: baseline;
    font-size: 0.9rem;
  }

  /* La tercera fila sale de aquí: el nombre del torneo ocupa el ancho entero de su párrafo, así que
     «Ronda 1 · mesa 1» baja solo. Un `<p>` que se parte en dos y no dos elementos, para que en
     escritorio sigan siendo la misma línea sin una segunda regla que mantener. */
  .mtg-inicio-donde {
    flex-wrap: wrap;
  }

  .mtg-inicio-donde .mtg-nombre {
    flex: 1 0 100%;
  }

  /* ---- «contra» se esconde, y el hueco se lo lleva el nombre ----
     Compartir fila con la hora le dejaba al rival **63 px de los 80 que pide** «Carla Mora» —medido—, así
     que el nombre más corto de los datos de prueba ya se recortaba. Esta palabra cuesta 45 px y en una
     lista con la hora delante se deduce: lo que va detrás de una hora es con quién juegas.

     Se esconde **fuera de flujo con `clip-path`** y no con `display: none`, que es el patrón del proyecto
     —el mismo que el distintivo «abandonó» de una ficha de mesa—: sigue siendo texto para un lector de
     pantalla, que sin él leería una hora y un nombre pegados. Solo cuando comparte fila: en escritorio la
     palabra se queda. */
  .mtg-inicio-rival .mtg-inicio-contra {
    position: absolute;
    clip-path: inset(50%);
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  /* ---- La caja de baraja también se apila, y son tres líneas como la partida ----
     Lo pidió el organizador viendo el móvil: «parece que hace falta añadir una línea más y que pase a como
     tus partidas, 3 líneas». Y el motivo es el mismo que ya apiló la partida: los datos comparten renglón
     con el nombre de la lista, **el nombre es el único que encoge**, y con el hueco del distintivo reservado
     le quedaba nada — medido en su captura, «La de Bruno» salía como **«L..»** y en la segunda caja el nombre
     había desaparecido del todo, dejando el renglón abierto con un «·» colgando.

     Queda: torneo / nombre de la lista / para qué vale · formato. Y **el separador del primer dato se quita**,
     porque al bajar el grupo a su renglón abriría la línea con él. Va en `@media screen` por lo mismo que la
     partida: al imprimir, las media queries miden la hoja. */
  .mtg-inicio-baraja-para {
    display: grid;
    gap: 0;
  }

  .mtg-inicio-baraja-meta .mtg-inicio-de:first-child::before {
    content: none;
    margin-inline-end: 0;
  }
}

@media (pointer: coarse) {
  .mtg-inicio-titulo {
    margin-block-end: 0.9rem;
  }

  .mtg-inicio-todos {
    position: relative;
  }

  .mtg-inicio-todos::after {
    content: "";
    position: absolute;
    inset: -11px 0;
  }
}

/* ---- El `− +` de la rejilla de cartas ----
   La píldora de la cantidad pasa a ser también el control de copias. **Va donde ya estaba** —en absoluto
   sobre la esquina de la carta— y eso es lo que hace que no cueste ni un píxel de alto: una rejilla de
   maindeck son sesenta cartas, así que un renglón de controles bajo cada una habría sido casi mil píxeles
   de scroll de más en móvil.

   El contraste de esta píldora **sí puede apoyarse en su velo**, al contrario que la regla general, y por
   el mismo motivo que las marcas de carta: el peor caso está acotado. Su fondo es negro al 78 %, así que
   sobre la zona más clara posible de una ilustración compone rgb(56,56,56) y el blanco da 10,4:1. */
.mtg-miniatura-cantidad {
  display: inline-flex;
  align-items: center;
  /* Sin relleno propio: lo traen los botones, y así el `4×` queda a la misma distancia de los dos. */
  padding: 0;
}

.mtg-copia {
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  line-height: 1;
  padding: 0.15rem 0.35rem;
  cursor: pointer;
}

.mtg-copia-cifra {
  /* Ancho mínimo para que la píldora no cambie de tamaño al pasar de 9 a 10 copias: con la caja en
     absoluto, un salto de ancho no descuadra nada, pero los dos botones se moverían bajo el dedo.
     1,2 em cabe dos cifras; tres las ensancha, que solo pasa a partir de 100 copias. */
  min-width: 1.2em;
  text-align: center;
}

/* Al pasar por encima y al enfocar **se aclara el fondo del botón, y no se pinta el texto de acento**.

   Lo primero que se escribió fue el acento, que parecía lo correcto —estos botones *son* lo que se pulsa—
   y **daba 1,97 de contraste en tema claro**: es la trampa de «un acento no es un color, son dos». Esta
   píldora es oscura en **los dos temas** —no se apoya en el fondo de la página sino en la ilustración de
   una carta, igual que la cinta de liga se apoya en el tapete de un torneo—, así que el `#855c0e` del tema
   claro, que es un marrón pensado para ir sobre blanco, aquí desaparece.

   Aclarar el fondo no necesita ningún color nuevo, funciona igual en los dos temas y deja el texto en el
   blanco que ya tenía. Medido: **11,71 sin el puntero encima y 5,93 con él**, los dos por encima del 4,5 —
   y el segundo es el **peor caso acotado**, porque nada bajo el velo del 78 % es más claro que el blanco:
   ahí compone rgb(100,100,100). */
.mtg-copia:hover,
.mtg-copia:focus-visible {
  background: rgb(255 255 255 / 0.22);
}

/* Con el dedo, **el área crece sin que la píldora crezca**: el mismo patrón que la píldora de una mesa.
   La caja mide 18 px, así que hacen falta 26 repartidos — y **el reparto está pensado, no es simétrico**.

   **12 px hacia abajo**, que es exactamente lo que hay libre: 4 desde la píldora hasta el borde de la carta
   más los 8 del hueco entre filas de la rejilla. Ahí no hay nada que pulsar, así que sale gratis y no llega
   a tocar la carta de la fila siguiente.

   **14 px hacia arriba**, sobre la ilustración, y ese trozo sí se paga: la ilustración es el botón que abre
   la carta en grande, así que en esa franja el dedo cambia copias en vez de abrir la carta. Se busca que
   sea lo más estrecha posible — creciendo los 26 hacia arriba serían 26 px de los 156 de alto de la carta
   en móvil. Medido después: 44 px de área efectiva con la píldora en 20. */
@media (pointer: coarse) {
  .mtg-copia {
    position: relative;
  }

  .mtg-copia::after {
    content: "";
    position: absolute;
    inset: -14px 0 -12px;
  }
}

/* ---- La lista agrupada de la vista de solo lectura -------------------------------------------
   Como la vista compacta de tcdecks: secciones por tipo repartidas en columnas y el sideboard
   aparte. Sustituye a un `<textarea>` con el texto pelado, que ocupaba doce renglones de scroll.

   El maindeck va en **rejilla y NO en columnas de CSS**, y eso no es una preferencia de maquetación:
   con `column-width` el listado **se desmontaba al pasar el ratón por encima de un nombre**. La previa
   de `<mtg-carta>` es un `position: absolute` que pasa de `display: none` a `block`, y dentro de un
   contenedor multicolumna eso obliga a Chromium a **rehacer el reparto**, así que las secciones
   saltaban de columna y el texto acababa detrás del recuadro. Lo vio el organizador en pantalla.

   Una rejilla no fragmenta nada, así que un absoluto dentro de una celda no puede reordenar a nadie.
   El precio es el que decía el comentario anterior —las alturas son muy distintas, 23 tierras contra
   2 conjuros, así que sobra hueco al final de algunas celdas— y se paga a gusto: un hueco es feo, una
   lista que se recompone bajo el cursor es inservible. `align-content: start` evita además que las
   filas se estiren para rellenar. `break-inside: avoid` se queda **por el papel**, donde sí hay
   fragmentación de verdad. */
.mtg-lista-agrupada {
    display: grid;
    gap: 1rem 1.5rem;
    grid-template-columns: 1fr;
}

/* El sideboard a su lado desde tableta. Por debajo va debajo, que es lo que cabe. */
@media (min-width: 768px) {
    .mtg-lista-agrupada:has(.mtg-lista-sideboard) {
        grid-template-columns: 2fr 1fr;
    }
}

.mtg-lista-maindeck {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 0 1.5rem;
    align-content: start;
}

.mtg-lista-seccion {
    break-inside: avoid;
    margin-bottom: 0.9rem;
}

.mtg-lista-tipo {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin-bottom: 0.15rem;
}

.mtg-lista-tipo span {
    color: var(--bs-secondary-color);
    font-weight: 400;
}

.mtg-lista-agrupada li {
    font-size: 0.9rem;
    line-height: 1.5;
}

/* El número de copias, alineado a la derecha en su propia columna para que los nombres empiecen
   todos en la misma `x`: con el número en flujo, «4 Bolt» y «12 Mountain» descuadraban la lista. */
.mtg-lista-copias {
    display: inline-block;
    width: 1.4rem;
    text-align: right;
    margin-right: 0.35rem;
    color: var(--bs-secondary-color);
    font-variant-numeric: tabular-nums;
}

/* ---- La vista de solo lectura: sus dos pestañas ----
   **Texto e Imágenes son dos formas de decir lo mismo**, así que se mira una. Apiladas —como estuvieron
   unas horas— obligaban a recorrer un mazo entero de ilustraciones para llegar a lo de abajo; lo cambió
   el organizador viéndolo.

   Mismo mecanismo que las cuatro vistas del editor y que ronda/clasificación: el panel visible lo dice
   `data-panel` en el contenedor y lo pinta el CSS, sin que el servidor sepa nada. Y por «lo que NO es el
   activo», no enumerando pares: es lo que hizo que las pestañas del editor se quedaran sin subrayado
   cuando aparecieron, porque nadie se acordó de añadir la combinación nueva.

   La activa se pinta por `aria-selected`, que ya vale para todos los juegos de pestañas, así que aquí no
   hay ni una regla de pestaña que escribir. */
.mtg-baraja-solo-lectura .mtg-vista-solo-lectura {
  display: none;
}

.mtg-baraja-solo-lectura[data-panel="texto"] .mtg-vista-texto,
.mtg-baraja-solo-lectura[data-panel="imagenes"] .mtg-vista-imagenes {
  display: block;
}

/* ---- «Nuevo torneo»: las casillas que solo valen con inscripción por internet ----
   **Un control que no hace nada no se pinta**, y aquí venía encima *marcado*: con «A mano» elegido
   salían «Abrir la inscripción ya» —activada— y «Listas abiertas», las dos diciendo de su puño «solo
   para por internet». Lo encontró una pasada de QA pulsando el radio, no la compilación.

   En el marcado estaba escrito que se pintaban siempre «porque el formulario no vuelve al servidor al
   cambiar de modo». No hace falta el servidor: `:has()` lee el radio hermano y esto se resuelve **sin
   una línea de JavaScript**, que es además lo que hace que no haya dos verdades —el marcado y un
   manejador— capaces de separarse. */
form:has(#mtg-modo-manual:checked) .mtg-solo-por-internet {
  display: none;
}

/* Los cuatro webhooks de Discord, solo con «Integrado con Discord» marcado. El mismo mecanismo que el
   bloque de arriba y por lo mismo: cuatro campos de URL que no aplican son cuatro invitaciones a rellenar
   algo que el servidor va a ignorar. Nace escondido —el defecto de la casilla es apagado— y `:has()` lo
   enseña sin servidor y sin JavaScript. */
.mtg-solo-discord {
  display: none;
}

form:has(#mtg-discord-integrado:checked) .mtg-solo-discord {
  display: block;
}

/* ---- El distintivo de esquina de una ficha de torneo o de liga ----
   Hoy solo lo usa «Mis eventos» para marcar los que co-organizas. **Antes no existía**: el rótulo se
   pintaba envolviendo la ficha en otro `<li>` con dos clases —`mtg-evento-mio` y
   `mtg-evento-compartido`— que no tenían ni una regla, y eso partía la rejilla en dos celdas por ficha.

   Va en absoluto sobre la ficha y **por encima del `stretched-link`** del nombre, que cubre la caja
   entera: sin el `z-index` el rótulo quedaría debajo del área pulsable y no se leería el mismo color al
   pasar por encima. No captura el ratón, porque no es un botón — pulsar ahí tiene que abrir el torneo
   igual que en el resto de la ficha. */
.mtg-ficha-distintivo {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 3;
  pointer-events: none;
}

/* En móvil la ficha usa la imagen como **fondo de la caja entera**, así que la esquina de arriba a la
   derecha es justo donde vive el nombre: medido, el distintivo caía sobre su caja de texto (x 257-342
   contra un nombre que llega a 335). Es la misma trampa que ya tenía anotada la cinta de liga. Abajo a
   la derecha está libre — la fecha del pie va a la izquierda, x 15-85. */
@media screen and (max-width: 767.98px) {
  .mtg-ficha-distintivo {
    top: auto;
    bottom: 0.5rem;
  }
}

/* ---- «Torneos en los que juego»: los dos enlaces de cada fila ----
   Medían **23 px** de objetivo táctil contra los 44 de la regla. Se crece el área sin mover nada, con el
   mismo patrón que la píldora de una mesa: un pseudo-elemento que se sale hacia el relleno de la celda,
   donde no hay nada que pulsar. Crecer el enlace en sí subiría el alto de las cuatro filas. */
@media (pointer: coarse) {
  #donde-juego td a {
    /* **`inline-block` hace falta y no es adorno**: un enlace puramente en línea mide su línea de texto
       —18 px—, y el pseudo se resolvía contra esa caja sin que el medidor viera nada. Con caja propia el
       área efectiva sale 18 + 2×13 = 44, que es la regla. */
    display: inline-block;
    position: relative;
  }

  #donde-juego td a::after {
    content: "";
    position: absolute;
    inset: -13px -0.25rem;
  }
}

/* ---- El nombre de la cuenta en la barra ----
   **Cede el texto, no la forma**, que es la regla general de esta aplicación. Hace falta aunque la barra ya
   plegue bajo 992: medido con la sesión abierta, «Maria del Carmen Villanueva» hacía que la barra pidiera
   **1033 px** y volviera a desbordar justo por encima del punto de plegado, y con el nombre entero de los
   datos de prueba, **1113**. El dato completo no se pierde — está en el `title` y dentro del desplegable.

   `max-width` en `ch` y no en `px` porque lo que se acota es texto, y `min-width: 0` porque sin él un hijo
   de un flex no baja de su ancho de contenido y el recorte no se activa nunca. */
.mtg-navbar-nombre {
  display: inline-block;
  max-width: 14ch;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* ---- Aquí hubo una regla que estiraba la quinta tarjeta, y se ha quitado ----
   Era `.mtg-inicio-seccion:nth-child(5):last-child { grid-column: span 2 }`, puesta para tapar el hueco de
   abajo a la derecha cuando la rejilla salía a tres columnas: quedaba 3 + 2 y la quinta ocupaba las dos
   últimas. **Estaba medida contra tres columnas y falla con cuatro**, que es lo que sale en una pantalla
   ancha: la quinta se va sola a su fila, ocupa 2 de 4 y el hueco sigue ahí — así que lo único que se
   consigue es una tarjeta del doble de ancho que las demás. Con la ilustración de cabecera se ve el triple,
   porque el dibujo se estira con ella.

   Lo vio el organizador: «Ayuda tiene un tamaño diferente y no una caja como las demás, queda raro». Y la
   lección es la de siempre en este proyecto — **lo que cambia de tamaño entre hermanos descuadra la lista**,
   igual que la ficha de la clasificación de liga y las dos fichas de listado. Un hueco al final de una
   rejilla se lee como una rejilla; una caja del doble de ancho se lee como un error.

   Si algún día vuelve a hacer falta cerrar la fila, la salida no es estirar una tarjeta: es que el número de
   secciones cuadre con las columnas, o dejar el hueco. */

/* ---- La casilla de comparar de `/Formatos` ----
   **Es la única casilla de la aplicación sin `<label>`**: flota sobre la miniatura y se anuncia con
   `aria-label`, así que su objetivo táctil es *ella misma* — 22 px medidos, la mitad de la regla. Las de
   los formularios no tienen este problema y no hay que tocarlas: su etiqueta va pegada a 2 px y el
   objetivo real sale de 48 a 129 px, que es lo que el medidor no veía.

   Se crece con el pseudo-elemento, como la píldora de una mesa: la casilla se queda en 22 y el área sube a
   44 saliéndose hacia la miniatura, donde no hay nada más que pulsar. Crecer la casilla en sí la
   convertiría en un cuadro enorme encima del logo. */
@media (pointer: coarse) {
  .mtg-comparar {
    position: relative;
  }

  .mtg-comparar::after {
    content: "";
    position: absolute;
    inset: -11px;
  }
}

/* El nombre del formato en `/Formatos`. **Los de dos palabras se salvan por casualidad**: parten en dos
   líneas y llegan a 45 px, mientras que «Premodern», que es una sola, se queda en **23**. Una regla que
   depende de cuántas palabras tenga el dato no es una regla, así que se crece el área igual para todos —
   con el pseudo-elemento, que no toca el alto de la fila. */
@media (pointer: coarse) {
  td[data-ficha-titulo] > a {
    display: inline-block;
    position: relative;
  }

  td[data-ficha-titulo] > a::after {
    content: "";
    position: absolute;
    inset: -11px -0.25rem;
  }
}

/* ---- Los dos de la barra de navegación ----
   Son el defecto que trae Bootstrap de fábrica y los últimos que quedaban de la lista de objetivos
   cortos: **40 px los dos**, cuatro por debajo de la regla. Aquí sí se crece la caja y no un
   pseudo-elemento, porque la barra tiene alto de sobra —56 px— y son dos controles sueltos, no una fila
   densa a la que subirle el alto. `align-items` hace falta con el `min-height`: sin él, el rótulo de la
   marca se queda pegado arriba. */
@media (pointer: coarse) {
  .navbar-brand,
  .navbar-toggler {
    min-height: var(--mtg-toque);
    display: inline-flex;
    align-items: center;
  }

  .navbar-toggler {
    justify-content: center;
  }
}

/* ---- La caja de búsqueda del listado ----
   Al lado del desplegable de formato y con su mismo comportamiento en la fila: no crece, y por debajo de
   576 px pasa a ocupar toda la línea porque compartirla con el `<select>` deja los dos inservibles —a 375
   px la fila tiene 351 y el desplegable ya pide 170—. */
.mtg-listado-buscador {
  flex: 1 1 12rem;
  min-width: 0;
  padding-bottom: 0.35rem;
}

@media (max-width: 575.98px) {
  .mtg-listado-buscador {
    flex: 1 1 100%;
  }
}

/* ---- La agenda de un torneo ----
   Dos vistas del mismo dato: un día en lista y una semana en siete columnas. La casilla es **la misma**
   en las dos —solo cambia el ancho de la columna—, así que no hay dos marcados que puedan separarse.

   El interruptor de vista **solo desde 992 px**, y es el mismo umbral que ya usan el cambio de forma del
   cuadro y las dos columnas de la inscripción: en móvil siete días son 53 px por columna y ahí no cabe
   ni una hora. Decisión del organizador. */
.mtg-agenda-titulo {
  font-weight: 600;
}

/* En español un día empieza en minúscula, y en la cabecera se lee como una errata. Se arregla con
   `::first-letter` y **no con `text-transform: capitalize`**, que pone mayúscula en *cada palabra*: se
   escribió así y salía «Viernes 21 De Agosto», visto en pantalla. El artículo y la preposición no
   llevan mayúscula, así que la única regla correcta es «la primera letra y nada más». */
.mtg-agenda-titulo::first-letter,
.mtg-agenda-dia-titulo::first-letter {
  text-transform: uppercase;
}

.mtg-agenda-vista {
  display: none;
}

@media (min-width: 992px) {
  .mtg-agenda-vista {
    display: inline-flex;
  }
}

.mtg-agenda-semana {
  display: grid;
  /* Siete columnas fijas: el ancho mínimo es lo que hace que la rejilla **desborde su caja y se
     desplace dentro** en vez de comprimir las columnas hasta ser ilegibles. Es la misma decisión que el
     `white-space: nowrap` de las tablas anchas: mejor una barra que 29 columnas de 30 px. */
  grid-template-columns: repeat(7, minmax(9rem, 1fr));
  gap: 0.5rem;
}

/* La vista de día **no se estira a los 1280 px**: son tres líneas por partida, y a todo el ancho la caja
   se lee como una banda vacía con un texto en la esquina —se vio en la captura de escritorio—. La de
   semana sí ocupa lo que puede: ahí el ancho es lo que reparte los siete días. */
.mtg-agenda-lista {
  max-width: 44rem;
}

.mtg-agenda-dia,
.mtg-agenda-lista {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem;
  /* En `--bs-secondary-color` y no en `--bs-border-color`, que da 1,41 y 1,10 sobre el fondo: es la misma
     corrección y la misma cifra que ya hicieron falta en los conectores del cuadro y en las cajas de
     grupo. Un borde que delimita es un gráfico con significado y se le piden 3:1. */
  border: 1px solid var(--bs-secondary-color);
  border-radius: var(--bs-border-radius);
}

/* Hoy se marca con el borde y con el título en el color del cuerpo, **no en acento**: el amarillo
   significa «esto se pulsa» y un día no se pulsa. */
.mtg-agenda-hoy {
  border-width: 2px;
}

.mtg-agenda-dia-titulo {
  margin: 0;
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
  font-weight: 600;
}

.mtg-agenda-hoy .mtg-agenda-dia-titulo {
  color: var(--bs-body-color);
}

.mtg-agenda-partida {
  padding: 0.4rem 0.5rem;
  border-radius: var(--bs-border-radius-sm);
  /* El velo translúcido que aclara en oscuro y oscurece en claro, nunca un `--bs-*-bg`: sobre el fondo
     de la página todos son más oscuros y la caja saldría como un agujero. */
  background: var(--mtg-celda-fondo);
}

.mtg-agenda-hora {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.mtg-agenda-hasta {
  color: var(--bs-secondary-color);
  font-weight: 400;
  white-space: nowrap;
}

.mtg-agenda-quien {
  display: flex;
  flex-direction: column;
  /* Los nombres **apilados y recortados**, no en una línea: en una columna de 9 rem, «Maria del Carmen
     Villanueva contra Alejandro Fernández» en una línea deja cuatro caracteres por lado. Es la misma
     decisión —y el mismo motivo— que apila los dos lados de una ficha de mesa en móvil. */
  min-width: 0;
}

.mtg-agenda-quien .mtg-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-agenda-contra {
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
}

.mtg-agenda-donde {
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
}

/* En la vista de día hay sitio de sobra, así que los dos nombres van en una línea con su «contra» en
   medio: es como se lee un emparejamiento. La semana se queda apilada. */
@media (min-width: 576px) {
  .mtg-agenda-lista .mtg-agenda-quien {
    flex-direction: row;
    align-items: baseline;
    gap: 0.35rem;
  }
}

/* ---- «Mis eventos»: las secciones ----
   Tres en torneos —Juego, Organizo, No entré— y dos en ligas. **Una caja por evento**, así que la sección
   dice el papel que tengo en él y no hay nada repetido entre secciones.

   El rótulo va pequeño y con su cifra: es el mismo peso que una pestaña del listado, porque hace el mismo
   trabajo —decir cuántos hay sin contar cajas—. Y **no lleva acento**: el amarillo significa «esto se
   pulsa» y un encabezado no se pulsa. */
.mtg-eventos-seccion + .mtg-eventos-seccion {
  margin-top: 1.5rem;
}

.mtg-eventos-titulo {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  color: var(--bs-secondary-color);
}

/* La línea que explica una sección, encima de sus fichas. Pegada al rótulo —de ahí el margen de arriba
   negativo del hueco que deja el título— porque lo está explicando, no introduciendo otra cosa. */
.mtg-eventos-nota {
  margin-block: -0.25rem 0.6rem;
  color: var(--bs-secondary-color);
  font-size: 0.9rem;
}


/* ---- El chip de mis barajas, en el segundo renglón de la ficha ----
   **Dice «Baraja» y no el nombre de la baraja**, y eso es lo que hace que el renglón siga teniendo sitio para
   el tipo y el recuento: un nombre es texto de ancho variable —«Stiflenought (sin Daze)»— y un chip mide
   siempre lo mismo. Decisión del organizador; el nombre está dentro del diálogo, con las de las demás rondas.

   **No va en acento** aunque se pulse, por lo mismo que la hora de una mesa: el amarillo tiene que poder
   significar una sola cosa en la ficha, y aquí la acción principal es abrir el torneo —la caja entera—. Este
   chip es la excepción a esa caja, así que se distingue con relieve y no con color. */
.mtg-torneo-lista {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  flex: 0 0 auto;
  /* **Relleno solo a los lados.** Con `0.05rem` arriba y abajo el chip medía 22 px contra los 20,4 del
     texto de al lado, y eso subía el renglón y con él la caja: **267,92 px en vez de 266,33** — medido—, o
     sea la misma ficha con dos alturas según la pantalla que la pinte. La forma fija de la ficha es lo
     primero que el organizador pidió de estos listados; el relieve no vale un píxel y medio. */
  padding: 0 0.4rem;
  border: 0;
  border-radius: var(--bs-border-radius-sm);
  line-height: inherit;
  /* El velo translúcido de siempre, no un `--bs-*-bg`: sobre la superficie de la ficha todos son más
     oscuros y el chip saldría como un agujero. */
  background: var(--mtg-celda-fondo);
  color: inherit;
  font: inherit;
  white-space: nowrap;
  /* **Por encima del `stretched-link` de la ficha y capturando el ratón**: es el único sitio de la caja que
     no abre el torneo. El distintivo hace lo contrario —va encima pero deja pasar el clic— porque él no es
     un control. */
  position: relative;
  z-index: 2;
}

.mtg-torneo-lista:hover,
.mtg-torneo-lista:focus-visible {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

.mtg-torneo-icono-lista {
  width: 1em;
  height: 1em;
  /* La línea base otra vez: un SVG se apoya en ella y sin esto queda montado sobre la palabra. Misma
     corrección y misma cifra que `.mtg-icono-junto` y que la celda de la medalla de la liga. */
  vertical-align: -0.1em;
  flex: none;
}

@media (pointer: coarse) {
  /* Los 44 px del dedo **sin agrandar el chip**, con el mismo pseudo-elemento que la píldora de una mesa: se
     sale hacia el relleno del renglón, que no es pulsable. Lo que hay debajo sí lo es —la caja abre el
     torneo—, así que el área se queda **en el ancho del chip** y no en el del renglón: una banda de 44 px a
     lo ancho de la ficha robaría el clic de abrir el torneo. */
  .mtg-torneo-lista::after {
    content: "";
    position: absolute;
    /* -12 y no -11: con -11 el objetivo daba **42,4 px** y el mínimo es 44 — lo cazó `medir.js`. */
    inset: -12px -0.25rem;
  }
}

/* ============================================================================
   LAS CAJAS DE UNA LISTA DE TORNEO
   ============================================================================
   Las usan **las dos pestañas** de «Mis barajas» que no son la biblioteca: «Histórico» —lo que se
   presentó, en solo lectura— y «Por preparar» —las que todavía se pueden cambiar—. El prefijo es neutro
   (`mtg-lista-torneo-*`) y no `mtg-historico-*`, que fue el primero: son la misma caja, y con dos juegos
   de reglas casi iguales acabarían viéndose distintas sin que nadie lo decidiera. La diferencia entre las
   dos pestañas es **qué hace la caja al pulsarla** —abrir un diálogo o ir al editor de la lista—, así que
   la regla vale para un `<button>` y para un `<a>`. Cajas y no
   fichas de cuadrícula, y es la prueba del proyecto la que lo decide — ¿se comparan las celdas de una
   fila con las de la de al lado? No: cada caja es una unidad («esta lista, en este torneo»), así que se
   lee sola y va en una columna que aguanta cualquier nombre.

   **Sin ilustración de portada, y no es un olvido**: la baraja de un torneo es un *snapshot* que guarda
   nombre, arquetipo y texto — no una carta de portada, que es cosa de la baraja de la biblioteca. Poner
   aquí la del mazo homónimo sería inventar un vínculo que no existe: la lista del torneo tiene vida
   propia desde el primer segundo. */
/* En rejilla por lo mismo que `.mtg-inicio-barajas` y **con el mismo mínimo**, que vive en una variable
   compartida: son la misma caja, así que el día que ese número cambie tiene que cambiar en las dos. Aquí la
   caja llegaba a **1265 px** a 1280 de ventana, que es la cifra que ya estaba escrita unas líneas más abajo al
   explicar por qué el fondo de imagen se acota a una banda. */
.mtg-listas-torneo {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(var(--mtg-caja-lista-min), 100%), 1fr));
  gap: 0.5rem;
  margin: 0;
}

.mtg-lista-torneo {
  position: relative;
  /* **Dónde se vuelve opaca la banda de imagen, en una sola variable.** La usan la máscara que la desvanece y
     el hueco que el texto le reserva, y por eso está aquí y no escrita dos veces: si divergieran, el texto
     volvería a caer encima de la ilustración sin que nada lo dijera — que es exactamente el defecto que hubo
     que arreglar al pasar la lista a varias columnas. */
  --mtg-banda-opaca: 0.65;
  /* **El borde, por el mismo motivo que lo lleva la caja de la portada**, que estaba escrito allí y no aquí:
     donde acaba el degradado de la imagen desaparece el canto de la caja. Y de paso es lo que permite marcar
     en acento al pasar por encima sin que la caja cambie de alto. */
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius-sm);
  /* El velo translúcido de siempre y nunca un `--bs-*-bg`: sobre el fondo de la página todos son más
     oscuros y la caja saldría como un agujero. */
  background: var(--mtg-celda-fondo);
  /* Las dos líneas que necesita el fondo de imagen, y las mismas que las cajas de la portada: el
     `overflow` lo recorta al redondeo y el `isolation` es lo que permite que vaya en `z-index: -1` sin
     desaparecer — así el texto no necesita `position`, que aquí además rompería el botón. */
  isolation: isolate;
  overflow: hidden;
}

/* ---- El fondo, **acotado a una banda de la derecha** ----
   El velo compartido (`--mtg-velo-ficha`) va de opaco a transparente **a lo ancho de su caja**, y está
   medido para la ficha de un listado en móvil: ~343 px. Aquí la caja mide **1265** a 1280, así que ese
   mismo degradado dejaba media caja con la ilustración a plena vista y el texto en la otra mitad — se
   veía como una banda cruda pegada al lado derecho, no como un fondo.

   La salida **no es un segundo degradado más opaco** —eso duplicaría lo que la variable existe para
   tener en un sitio— sino darle a la imagen el ancho para el que el velo está pensado. El corte de la
   izquierda no se ve: justo ahí el velo es opaco. */
.mtg-lista-torneo .mtg-fondo-evento {
  left: auto;
  width: min(22rem, 40%);
  /* **Se desvanece con una máscara y no con el velo de color.** El velo compartido pinta
     `--bs-body-bg` —el fondo de la *página*— y esta caja se apoya en `--mtg-celda-fondo`, que es más
     claro: la banda opaca salía como un rectángulo oscuro pegado al lado derecho, con un corte visible.
     Una máscara no pinta color, solo quita imagen, así que la banda se funde con lo que haya debajo sea
     lo que sea — que es lo que hace falta cuando la caja no tiene el fondo de la página. */
  mask-image: linear-gradient(90deg, transparent 0%, black calc(var(--mtg-banda-opaca) * 100%));
  opacity: 0.55;
}

/* Y con máscara **el velo de color estorba**: taparía justo lo que la máscara deja ver. */
.mtg-lista-torneo .mtg-fondo-evento::after {
  content: none;
}


/* **La caja entera es el botón**, así que el objetivo táctil sale de los 44 px sin regla aparte: es un
   `<button>` de verdad y no un `stretched-link`, porque esto no navega — abre un diálogo. Se le quita
   todo el aspecto de botón y se le da el del texto que lleva dentro.

   ---- Y **el texto le reserva su hueco a la banda de imagen** ----
   Lo pidió el organizador al pasar la caja a varias columnas: «igual hay que hacer algo con el contraste de
   las letras sobre el fondo». Y tenía razón, con estas cifras: en una columna de **467 px** la banda empieza
   en 280 y su máscara la vuelve **opaca a partir de 401**, mientras el texto llegaba a **405**. O sea que los
   últimos píxeles del nombre del formato caían encima de la ilustración.

   **El medidor no puede ver esto**: compone capas de *color*, y aquí debajo del texto hay una imagen. Se
   comprueba con geometría —dónde acaban los glifos contra dónde empieza la banda— y mirando la captura.

   No se arregla subiendo el velo ni estrechando la banda: es la regla del proyecto —*un velo no sostiene un
   contraste, y una imagen menos*— y estrechar la banda sería ajustar a este texto, así que el formato
   siguiente con nombre más largo la rompería otra vez. Se reserva **la banda entera**, que es la misma
   solución que `_FondoDeEvento` ya usa en móvil, y así es correcto a cualquier anchura sin depender de la
   parada de la máscara. El precio es que en una columna estrecha los datos se van a dos líneas. */
.mtg-lista-torneo-abrir {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  width: 100%;
  padding: 0.55rem 0.75rem;
  padding-inline-end: calc(min(22rem, 40%) * var(--mtg-banda-opaca) + 0.75rem);
  border: 0;
  border-radius: inherit;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
  /* **Hace falta porque en «Por preparar» la caja es un `<a>`** y no un `<button>`: allí el enlace
     subrayaba las dos líneas enteras, incluidos el formato y la ronda. Se ve en cuanto se pinta. El
     subrayado vuelve al pasar por encima y **solo en el nombre**, igual que en las cajas de la portada. */
  text-decoration: none;
}

.mtg-lista-torneo:hover .mtg-lista-torneo-nombre,
.mtg-lista-torneo:focus-within .mtg-lista-torneo-nombre {
  text-decoration: underline;
}

/* El borde en acento, igual que `.mtg-torneo` y que la caja de la portada. El cambio de fondo se queda: aquí
   sí hace algo —el fondo base es `--mtg-celda-fondo`, que es otro color— aunque solo se note de reojo. */
.mtg-lista-torneo:hover,
.mtg-lista-torneo:focus-within {
  border-color: var(--mtg-acento);
  background: var(--bs-tertiary-bg);
}

.mtg-lista-torneo-nombre {
  font-weight: 600;
}

/* Los datos, en una línea que **se parte** —son cuatro y el nombre de un torneo es largo— con el
   separador puesto por CSS: escrito en el marcado habría que decidir cuál es el último. */
.mtg-lista-torneo-datos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-width: 0;
  font-size: 0.9rem;
  color: var(--bs-secondary-color);
}

.mtg-lista-torneo-datos .mtg-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-lista-torneo-dato::before {
  content: "·";
  margin-inline-end: 0.35rem;
}

/* El distintivo, con el mismo sitio que el de una ficha: en absoluto sobre la esquina y **sin capturar
   el ratón**, porque pulsar ahí tiene que abrir el diálogo igual que en el resto de la caja. */
.mtg-lista-torneo-distintivo {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  pointer-events: none;
}

/* Con distintivo, el nombre le reserva su hueco: va en absoluto y no encoge, así que un nombre largo se
   le metía por debajo. Misma corrección que en las cajas de «Barajas por preparar» de la portada. */
.mtg-lista-torneo:has(.mtg-lista-torneo-distintivo) .mtg-lista-torneo-nombre {
  padding-inline-end: 5.5rem;
}

/* ---- En móvil la banda se estrecha y **el texto le reserva su hueco** ----
   A 375 px la caja mide 351 y la línea de datos **se parte y ocupa todo el ancho**, así que el texto se
   metía encima de la ilustración: «Premodern» quedaba sobre el logo.

   Se probó la alternativa —cubrir la caja entera con la imagen al 18 %— y **se descartó midiendo**: con
   el texto encima de una imagen el contraste deja de estar acotado, y el peor caso (una zona blanca del
   logo bajo el gris secundario de la línea de datos) cae por debajo del 4,5. Es la regla del proyecto:
   *un velo no sostiene un contraste*, y una imagen menos. Con el hueco reservado el texto nunca está
   sobre la ilustración, así que las cifras son las de siempre.

   **Y este bloque va aquí abajo y no junto a las reglas del fondo**, que es donde lo puse primero: la
   regla base usa la abreviada `padding`, así que con el mismo peso **manda el orden de fuente** y desde
   arriba el `padding-inline-end` no hacía nada — el texto seguía pisando la banda. Es la trampa que este
   proyecto ya tiene anotada para las reglas de la barra de juez. */
@media screen and (max-width: 575.98px) {
  .mtg-lista-torneo .mtg-fondo-evento {
    width: 6rem;
  }

  .mtg-lista-torneo-abrir {
    padding-inline-end: 6.5rem;
  }
}

/* ---- El diálogo de mis barajas ----
   Una fila por ronda: cuándo valió, con qué jugué y —solo en la que se puede tocar— el botón de cambiarla.
   Es el histórico que la ficha no puede llevar dentro. */
.mtg-mis-listas {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.mtg-mis-listas-fila {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.mtg-mis-listas-cuando {
  flex: none;
  /* Todas las etiquetas con el mismo ancho: si «En el top» y «Desde la ronda 3» miden distinto, los nombres
     de al lado no se alinean y la columna deja de leerse de un vistazo. */
  min-width: 8.5rem;
  text-align: left;
}

/* El nombre es lo único que cede, y necesita su `min-width: 0` o el recorte no se activa nunca — la trampa
   que este proyecto lleva documentada en todas sus listas. */
.mtg-mis-listas-nombre {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-mis-listas-accion {
  flex: none;
}

/* La que se puede cambiar, marcada con el velo de atención: es la única fila que pide algo. */
.mtg-mis-listas-abierta {
  padding: 0.35rem 0.5rem;
  margin: -0.35rem -0.5rem;
  border-radius: var(--bs-border-radius-sm);
  background: var(--mtg-atencion-fondo);
}

@media (max-width: 575.98px) {
  /* A 375 px la fila entera pide 300 px solo entre la etiqueta y el botón, así que se apila: etiqueta y
     nombre arriba, botón debajo a la derecha. Sin esto el nombre se queda en tres caracteres. */
  .mtg-mis-listas-fila {
    flex-wrap: wrap;
  }

  .mtg-mis-listas-nombre {
    flex-basis: 100%;
  }

  .mtg-mis-listas-accion {
    margin-left: auto;
  }
}

/* ---- La «✕» de cerrar un diálogo ----
   Es de Bootstrap y mide **32 px**, por debajo de los 44 del dedo. No es de ninguna pantalla en concreto: es
   la de **todos** los diálogos de la aplicación —resultado, horario, abandono, carta, mis barajas—, así que
   el defecto estaba en los ocho. Lo encontró `medir.js` midiendo el diálogo de mis barajas.

   Se arregla con el pseudo-elemento de siempre, **sin agrandar la cruz**: 32 + 12 = 44,4 de área. Agrandar
   el botón movería la cabecera de todos los diálogos, y la cruz a 44 px de dibujo se ve enorme — es la misma
   decisión que en la píldora de una mesa y en el chip de la baraja. */
@media (pointer: coarse) {
  .btn-close {
    position: relative;
  }

  .btn-close::after {
    content: "";
    position: absolute;
    inset: -6px;
  }
}

/* El nombre de la lista **es un botón** y abre la baraja en solo lectura dentro del mismo diálogo. Se pinta
   como texto y no como botón —relleno cero, borde cero— porque en una columna de tres o cuatro filas cuatro
   botones seguidos se leen como una botonera y no como una lista; lo que dice que se pulsa es el subrayado
   punteado, el mismo recurso que la hora de una mesa. */
.mtg-mis-listas-ver {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 0.2em;
}

.mtg-mis-listas-ver:hover,
.mtg-mis-listas-ver:focus-visible {
  text-decoration-style: solid;
}

/* El nombre es lo único que cede dentro del botón: el arquetipo va detrás y no encoge. */
.mtg-mis-listas-ver .mtg-nombre {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (pointer: coarse) {
  /* El nombre mide **24 px** de caja y el dedo pide 44, así que el área crece con el pseudo-elemento de
     siempre —sin mover el texto— hacia el aire que la fila ya tiene: la fila mide 52 px en móvil, o 115 la
     que lleva botón, así que ±10 se queda dentro y no invade la fila de al lado. Lo cazó `medir.js`. */
  .mtg-mis-listas-ver {
    position: relative;
  }

  .mtg-mis-listas-ver::after {
    content: "";
    position: absolute;
    inset: -10px -0.25rem;
  }
}

/* ---- Datos de contacto ------------------------------------------------------------------------
   Una dirección postal son tres o cuatro renglones escritos por su dueño, así que se pinta **tal como se
   escribió** y no unida en una línea: `pre-wrap` es lo mismo que hacen las reglas de un torneo, y por el
   mismo motivo —los saltos son el dato—. Razor escapa el texto; aquí no hay ningún atributo en el que
   pueda acabar. */
.mtg-dirección {
  white-space: pre-wrap;
}

/* Un enlace suelto en un renglón de prosa mide el alto de su línea —24 px— y el dedo pide 44. Crece con el
   pseudo-elemento de siempre, sin mover el texto ni pisar la línea de al lado: es el mismo patrón que la
   píldora de una mesa y el enlace «ver todos» de la portada. */
@media (pointer: coarse) {
  .mtg-enlace-tactil {
    position: relative;
  }

  .mtg-enlace-tactil::after {
    content: "";
    position: absolute;
    inset: -10px -0.25rem;
  }
}

/* La columna del nombre no cede: es por lo que se busca una fila. La que se parte es la dirección, que
   para eso lleva `pre-wrap`. */
.mtg-tabla-contactos th:first-child,
.mtg-tabla-contactos td:first-child {
  white-space: nowrap;
}

/* ---- Cómo se paga ----------------------------------------------------------------------------
   La caja de la forma de pago, encima de las dos listas de la inscripción. Se apoya en `--mtg-celda-fondo`
   —el velo que aclara en oscuro y oscurece en claro— y no en un `--bs-*-bg`: sobre el panel de la fase,
   todos los de Bootstrap son más oscuros y la caja saldría como un agujero. Es la regla que ya rige las
   cajas elevadas del proyecto. */
.mtg-forma-de-pago {
  background: var(--mtg-celda-fondo);
  border: 1px solid var(--bs-secondary-color);
  border-radius: var(--bs-border-radius);
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}

/* El borde en `--bs-secondary-color` y no en `--bs-border-color`, que da 1,41 y 1,10 contra el panel: es la
   misma corrección, y la misma cifra, que los conectores del cuadro y las cajas de grupo. */

/* **Los saltos de línea son el dato.** Una dirección de pago o un concepto se escriben en varias líneas,
   así que se pinta tal como se escribió — igual que las reglas del torneo. Razor lo escapa; aquí no hay
   ningún atributo en el que pueda acabar, y una URL **no** se convierte en enlace a propósito. */
.mtg-pago-texto {
  white-space: pre-wrap;
}

/* ---- La franja de administración, con cuatro pestañas ----------------------------------------
   **Medido**: a 375 px la franja pedía 446 px en una caja de 351 y la cuarta pestaña se salía por el borde.
   Lo que cede es el icono y no el rótulo, que es lo que identifica una pestaña; son ~26 px cada uno y justo
   los 95 que faltaban.

   Se esconde con `display: none` y no con `clip-path` —el patrón de lo que tiene que seguir existiendo para
   un lector de pantalla— porque un icono decorativo ya lleva `aria-hidden`: ahí no hay nada que conservar. */
@media (max-width: 575.98px) {
  .mtg-pestanas-admin .btn > svg {
    display: none;
  }

  /* Y el relleno lateral baja con él: sin esto siguen sobrando 4 x 0,6 rem. */
  .mtg-pestanas-admin .btn {
    padding-inline: 0.6rem;
  }
}

/* ---- La cabecera de una pantalla, con su ilustración -----------------------------------------
   El problema lo señaló el organizador: la banda del título de cada pantalla son 40 px de texto y un botón
   en 1265 px de ancho, o sea casi todo hueco.

   **Banda a la derecha con máscara, y no un fondo con velo**, elegido entre tres propuestas viéndolas. La
   restricción está medida y es de este proyecto: el velo que sirve en una ficha de 343 px **deja media
   imagen cruda en 1265** (la cifra está en `_FondoDeEvento`), así que el tratamiento de las cajas no se
   puede copiar tal cual al ancho de la página. Las dos descartadas y por qué, en `_ArteDeCabecera.cshtml`.

   `isolation` y el `z-index: -1` del arte: sin ellos el arte se pinta encima del título, porque es su
   primer hijo. Con el contexto de apilamiento aislado, el `-1` no se escapa al fondo de la página. */
/* **7 rem de alto y la banda al 50 %**, subido de 5,5 y 34 a petición del organizador viéndolo: «en inicio
   el título es más ancho y queda mejor la imagen». Tenía razón y la causa es geométrica — la cabecera de la
   portada es un bloque de tres líneas, así que su banda tenía **el doble de alto** que la de una pantalla
   con solo un título, y un recorte de ilustración apaisado en una tira baja no se reconoce. */
.mtg-cabecera {
  position: relative;
  isolation: isolate;
  min-height: 7rem;
  padding-inline: 0.9rem;
  border-radius: var(--bs-border-radius);
  overflow: hidden;
}

/* La de la portada con sesión es más alta —lleva el lema y las cifras, no solo un título— así que su
   ilustración necesita alto para no salir como una tira. Y **relleno vertical**, porque ahí la banda no es
   una fila de 40 px sino un bloque: sin él el arte llega hasta el borde del texto de arriba. */
.mtg-inicio-cabecera.mtg-cabecera {
  padding-block: 0.9rem;
  margin-block-end: 1.5rem;
}

/* **Y el texto le reserva su hueco, que es la mitad que no se ve hasta que se mira.** Aquí la cabecera no
   es un título corto sino un párrafo de dos líneas, así que sin esto la segunda línea se mete debajo de la
   ilustración: se vio en la primera captura, con «Premodern y Old School» encima del dibujo. Es la regla de
   siempre —un velo no sostiene un contraste y una imagen menos— y el mismo apaño que ya usa el fondo de una
   caja ancha en `_FondoDeEvento`.

   El 38 % son los 34 de la banda más el hueco del degradado: la máscara empieza a desvanecer a la mitad de
   su ancho, así que parar justo en el 34 dejaría la última palabra sobre el arranque de la imagen.

   Un **botón** sí puede entrar ahí y por eso las demás cabeceras no reservan nada: lleva su propio fondo
   opaco, así que su contraste no depende de la carta. Lo que no puede es el texto. */
@media (min-width: 576px) {
  .mtg-inicio-cabecera.mtg-cabecera {
    padding-inline-end: 52%;
  }
}

/* ---- La fuente de los títulos: un gótico, servido por nosotros ----
   La eligió el organizador el 24 de agosto de 2026 entre seis vistas en pantalla, con un título corto y con
   el más largo que hay. Pidió «algo más tipo libros antiguos de magia» y puso de ejemplo *Old English Text
   MT* y *Blackadder ITC*, que **no se pueden usar**: son de Microsoft y de ITC, vienen con Office, y
   nombrarlas en una pila significaría que solo las ven los Windows con Office mientras el resto ve otra letra
   — en el título de la página, que es lo que te dice dónde estás, eso es peor que no cambiar nada.

   **Grenze Gotisch** es SIL Open Font License y es un gótico *moderno*: conserva el aire de imprenta antigua
   sin la ilegibilidad de un fraktur de verdad, que es lo que se paga en «Torneos de Magic para tu club».

   **Se sirve desde `wwwroot/fonts` y no desde Google Fonts**, por la misma razón que las ocho ilustraciones
   de `wwwroot/img/arte`: cargarla de `fonts.googleapis.com` sería una conexión a un tercero desde **todas**
   las páginas, la portada pública incluida, o sea antes de que exista una cuenta — y el aviso legal afirma lo
   contrario. Detalle y cómo rehacer los ficheros en `wwwroot/fonts/README.md`.

   `font-display: swap` para que el título **nunca bloquee el pintado**; el parpadeo de la primera visita lo
   quita el `preload` del layout. Y los dos subconjuntos por separado con su `unicode-range`, que es lo que
   hace que el navegador baje 17 KB y no 31. */
@font-face {
  font-family: 'Grenze Gotisch';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/grenzegotisch-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Grenze Gotisch';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/grenzegotisch-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
                 U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
                 U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---- El título de la cabecera crece con la banda ----
   Lo pidió el organizador el 24 de agosto de 2026 viendo `/Formatos`: «ahora que los títulos con la imagen
   son más grandes, ¿no deberíamos subir el tamaño de la fuente del título?». Tenía razón y es aritmética —
   la banda mide **7 rem de alto** y el `h3` de Bootstrap 1,75 rem, o sea que el título ocupaba **una cuarta
   parte** de la caja que lo contiene y se leía como una etiqueta dentro de un cuadro, no como su título.

   Va **en la clase de la cabecera y no cambiando el `h3` de cada vista**: son seis pantallas, y con el
   tamaño escrito seis veces la séptima nace distinta. Las vistas siguen declarando `h3`, que es lo que
   fija el peso y el margen; aquí solo se pisa el tamaño.

   `clamp` porque en móvil la cabecera **no tiene banda** (`min-height: 0`) y ahí 2,25 rem sobre 375 px
   dejaría «Aviso legal y protección de datos» en cuatro renglones. El mínimo es el `h3` de siempre, así
   que por debajo de ~430 px de cabecera nada cambia. */
/* **La fuente va en todos los `h1` y el tamaño solo en los de la banda**, y ese reparto es la decisión: el
   título de una pantalla tiene que leerse igual en todas —también en `/Admin` y en el aviso legal, que no
   llevan ilustración—, mientras que crecer a 3 rem solo tiene sentido donde hay una banda de 7 rem que
   llenar. Con la letra grande en una pantalla sin banda, el título se comería su propio formulario.

   La pila lleva **respaldo de serif y no de la sans del cuerpo**: si la fuente no llegara, un gótico se
   sustituye mejor por Georgia que por Segoe UI. */
h1 {
  font-family: 'Grenze Gotisch', Georgia, 'Times New Roman', serif;
  font-weight: 600;
  /* Un gótico ya es apretado de por sí; el interletraje negativo de una sans grande aquí lo emborrona. */
  letter-spacing: 0;
}

.mtg-cabecera > h1 {
  /* Más grande que la sans para el mismo hueco: un gótico tiene la altura de x pequeña, así que a 2,35 rem
     se leía **más pequeño** que el `h3` que sustituye. Medido contra el título más largo, «Torneos de Magic
     para tu club», que a 3 rem sigue entrando en una línea a 1280 px. */
  font-size: clamp(1.9rem, 1.3rem + 2.2vw, 3rem);
  /* Con la letra a 3 rem el interlineado de Bootstrap (1,2) deja la caja en 57 px y la banda mide 112: cabe,
     pero el título se pega al borde de arriba. 1,1 lo centra sin tocar el alto de la cabecera. */
  line-height: 1.1;
}

/* ---- Un botón apagado dentro de la banda no puede llevar la transparencia de Bootstrap ----
   La regla del proyecto decía que **un botón sí puede entrar en la banda porque lleva fondo opaco**, y tenía
   un agujero: `.btn:disabled` de Bootstrap no cambia de color, le baja la **opacidad al 65 %**. Sobre el
   fondo de una página eso solo se ve apagado; sobre una ilustración de cinco colores, el botón se disuelve
   en el dibujo. Lo vio el organizador dos veces en `/Formatos` —«sigue sin verse bien, me da que tiene algo
   de transparencia»— y la primera vez lo diagnostiqué mal: cambié el `btn-outline-secondary` por relleno
   gris, que era necesario y no suficiente, porque el botón nace **deshabilitado** hasta que marcas dos
   formatos.

   Se arregla devolviéndole la opacidad y dando el apagado **con color**, que es lo que hay que hacer siempre
   que algo se apoye en una imagen: es la misma corrección que la etiqueta «top N» de la clasificación, la
   del chip de semilla del cuadro y la del chip «Baraja» de la portada. Cuatro veces la misma lección — *un
   velo no sostiene un contraste, y una imagen menos*.

   Medido después: la caja es **opaca** en los dos temas —`opacity: 1`, fondo `rgb(248,249,250)` en claro y
   `rgb(43,48,53)` en oscuro— así que el rótulo ya no se mide contra el dibujo sino contra su propia caja, y
   da **14,63 y 10,23**. Eso es el arreglo entero: no es que el contraste sea alto, es que **deja de depender
   de la carta que haya debajo**. Y se sigue distinguiendo del encendido, que es gris medio con texto claro. */
.mtg-cabecera .btn:disabled,
.mtg-cabecera .btn.disabled,
.mtg-cabecera fieldset:disabled .btn {
  opacity: 1;
  background-color: var(--bs-tertiary-bg);
  border-color: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

/* El arte ocupa su tercio de la derecha y **se desvanece hacia el texto**. El título va sobre el fondo de
   la página, así que su contraste es el de siempre y no depende de la carta. */
.mtg-cabecera > .mtg-cabecera-arte {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  z-index: -1;
  /* **La mitad del ancho**, subido del 34 % a petición del organizador: «la imagen podría cubrir un poco
     más del espacio del título, hasta la mitad más o menos». Con la máscara desvaneciendo la mitad
     izquierda de la banda, lo que de verdad se ve de la ilustración es el 25 % de la cabecera. */
  width: 50%;
  mask-image: linear-gradient(to left, rgb(0 0 0) 55%, transparent 100%);
}

.mtg-cabecera-arte > img,
.mtg-cabecera-arte > .mtg-carta-sin-imagen {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* **En móvil no se pinta.** A 375 px la cabecera son el título y poco más, y un tercio de esa anchura son
   117 px: ni se reconoce la ilustración ni queda sitio para el título. Es la misma decisión que esconde las
   tres ilustraciones del lema de la portada por debajo de 992. */
@media (max-width: 575.98px) {
  .mtg-cabecera > .mtg-cabecera-arte {
    display: none;
  }

  .mtg-cabecera {
    min-height: 0;
    padding-inline: 0;
  }
}

/* **En móvil el pie se apila.** Con `flex-wrap` y los 44 px de objetivo táctil que la regla de puntero
   grueso le da a cada enlace, la fila se partía por donde le cabía —«marca + Ayuda» arriba y «Aviso legal»
   debajo— y los 44 px de alto dejaban huecos desiguales entre las dos filas: se leía como tres cosas
   sueltas en vez de como un pie. Lo vio el organizador en una captura.

   `gap: 0` porque el alto ya lo pone la regla táctil de los enlaces: con el `gap-3` de Bootstrap encima,
   cada renglón se separaba 1 rem **además** de sus 44 px. */
@media (max-width: 575.98px) {
  .mtg-pie-enlaces {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }
}

/* El aviso de propiedad intelectual del pie. Más pequeño que la fila de enlaces de encima y en el color
   secundario: es una nota al pie de verdad, no una sección.

   **Sin medida de lectura, y eso es un cambio de criterio a la vista.** Llevaba `max-width: 100ch` con el
   argumento de que 322 caracteres en una línea no se leen, que es cierto para un párrafo — y no lo es para
   esto. Medido a 1900 px: el aviso ocupaba **673 px** dentro de un pie de **1776**, o sea el 38 %, con la
   fila de enlaces de encima llegando al borde. Lo vio el organizador y lo describió exacto: «está como
   cortado a posta». Se lee como un fallo de maquetación, que es peor que una línea larga en un texto que
   nadie recorre palabra por palabra. Ahora las dos filas del pie miden lo mismo. */
.mtg-pie-legal {
  margin-block: 0.5rem 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--bs-secondary-color);
}

/* La nota de «las cuentas son por invitación» de la pantalla de entrar. Caja elevada como la puerta de la
   portada pública y por lo mismo: es una instrucción, no una acción, así que **no va en acento** —el
   amarillo significa «esto se pulsa»— ni en `alert-warning`, que la leería como un problema. El icono va
   en su columna y el texto en la otra, con `align-items: start` para que no se centre contra dos líneas. */
.mtg-entrar-invitacion {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  column-gap: 0.6rem;
  margin-block-start: 1.25rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--bs-secondary-color);
}

/* El icono hereda `mtg-icono-junto`, que está pensado para ir dentro de un botón: aquí el `.btn:has()` no
   aplica, así que se le dan tamaño y alineación a mano. `margin-block-start` lo baja al centro de la
   primera línea — la misma corrección de línea base que ya costó el icono de carpeta. */
.mtg-entrar-invitacion > svg {
  width: 1.1rem;
  height: 1.1rem;
  margin-block-start: 0.15rem;
}

/* ---- La portada pública ---------------------------------------------------------------------
   Lo único que se ve sin cuenta. Prefijo propio y no `mtg-inicio-*` porque son dos páginas
   distintas y no dos estados de una: comparten el aire y nada más. */

/* El texto de presentación **con tope de ancho**, y no es la regla general del proyecto: el
   `mtg-contenedor` ya limita la página, pero eso está medido para tablas y para el editor. Un párrafo
   de presentación a 1265 px son ~150 caracteres por línea, y ahí la vista pierde el renglón al volver.
   Con 45 rem la línea se queda en ~80 caracteres, que es el máximo que se lee de corrido. */
.mtg-publica-cabecera {
  max-width: 45rem;
  margin-block-end: 1.5rem;
}

/* La misma rejilla que las tarjetas de la portada con sesión, **sin su regla de la última tarjeta**:
   allí son cinco y la quinta se estira para no dejar hueco (`:nth-child(5):last-child`), y aquí son
   **ocho** —las siete de la oferta más la puerta—, o sea 4 + 4 a 1400 px y 2 + 2 + 2 + 2 en tableta sin
   ningún hueco que rellenar. Reutilizar la clase habría dejado aquella regla apagada en silencio, que es
   peor que copiar cuatro líneas. */
.mtg-publica-oferta {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: 0.75rem;
  margin: 0;
}

/* Misma forma que `.mtg-inicio-seccion` —icono en su columna abarcando las dos filas— y desde el 28 de
   agosto de 2026 **también su `position: relative` y su `:hover` en acento**. Aquí ponía lo contrario, y
   con su motivo: «estas tarjetas no se pulsan, porque todo lo que describen pide cuenta. Encender el borde
   al pasar por encima prometería un enlace que no hay». La primera mitad era verdad y la segunda ya no lo
   es, porque **el destino cambió**: no es la pantalla que la tarjeta describe —esa pide cuenta— sino
   **la sección de `/Ayuda` que la explica**, que es pública. Con eso el amarillo vuelve a significar
   exactamente lo que significa en el resto de la aplicación, y lo hace en las ocho tarjetas. */
.mtg-publica-cosa {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  /* Recorta las esquinas de la ilustración contra el radio de la caja, igual que hace la caja de un
     torneo en cuadrícula. */
  overflow: hidden;
}

/* El acento al pasar por encima y al enfocar, calcado de `.mtg-inicio-seccion`. `focus-within` porque
   quien recibe el foco es el enlace estirado del título, no la tarjeta — sin él, recorrer la página con
   el tabulador no señalaría dónde estás. */
.mtg-publica-cosa:hover,
.mtg-publica-cosa:focus-within {
  border-color: var(--mtg-acento);
}

/* El título es el enlace, así que **se pinta como texto y no como enlace**: en una tarjeta que se pulsa
   entera, subrayarlo prometería que solo esa línea lleva a algún sitio. Misma regla y mismo motivo que
   `.mtg-inicio-seccion h3 a`. */
.mtg-publica-cosa h3 a {
  color: inherit;
  text-decoration: none;
}

/* El cuerpo es el que lleva la rejilla de icono + título + texto: la caja pasó a ser una columna para
   poder llevar una cabecera de ilustración encima. */
.mtg-publica-cuerpo {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.6rem;
  row-gap: 0.15rem;
  padding: 0.9rem;
}

.mtg-publica-cosa p {
  grid-column: 2;
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--bs-secondary-color);
}

/* ---- La ilustración de cabecera, como una caja de torneo ----
   La eligió el organizador entre tres propuestas —esta, el dibujo en banda a la derecha de cada tarjeta, y
   una tira de las diez cartas intercalada— viéndolas montadas. Las otras dos se midieron y se fueron: la
   banda dejaba al texto el 55 % del ancho y «Torneos» pasaba de 4 renglones a 7, y la tira era la más
   discreta (la página más corta en móvil, 1694 px contra 2262) pero no daba color a nada.

   La forma se **copia y no se reutiliza la clase**: `.mtg-torneo` lleva `stretched-link`, cinta de liga,
   tres renglones de datos y un pie con estado y fecha, y aquí no hay nada de eso.

   9 rem de alto y `object-fit: cover` son las cifras de la cuadrícula de `/Torneos`, que están medidas
   contra un tapete de proporción 1,71. Un recorte de ilustración de Scryfall es ~1,37, así que se recorta
   un poco más por los lados — que es lo correcto: lo que interesa de una ilustración es el centro. */
.mtg-publica-cabeza {
  position: relative;
  height: 9rem;
  flex: none;
  /* Si la ilustración no carga, el hueco tiene que parecer un hueco y no un fallo de maquetación. */
  background: var(--bs-tertiary-bg);
}

.mtg-publica-cabeza > img,
.mtg-publica-cabeza > .mtg-carta-sin-imagen {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* En móvil baja a 7 rem: a 375 px la caja mide 343 de ancho, así que 9 rem de cabecera por ocho cajas
   son más de dos pantallas de scroll solo de ilustración. Medido con seis: la lista pasa de 2478 px a
   2286. */
@media (max-width: 767.98px) {
  .mtg-publica-cabeza {
    height: 7rem;
  }
}

/* ---- La puerta: la octava tarjeta, no una caja aparte ----
   Estuvo debajo de todo y a lo ancho, con su ilustración en banda lateral, y **lo cambió el organizador
   viéndolo** el 24 de agosto de 2026: la página acababa en dos formas distintas —siete tarjetas en 4 + 3 y
   luego una caja que no era ninguna de ellas—, y la caja distinta se leía como venida de otra pantalla. Con
   la puerta dentro de la rejilla son ocho y **cuadra en dos filas de cuatro**.

   Con ello se fueron sesenta líneas: la banda con su máscara, sus dos media queries y su propio icono y
   párrafo. Todo eso hacía falta **porque la caja era de ancho completo** —un recorte de ilustración de
   Scryfall mide ~626 px y estirado a 1265 se veía al doble de su tamaño—; en una tarjeta de 20 rem la
   cabecera de las demás sirve tal cual.

   **La puerta ya no lleva borde propio** (28 de agosto de 2026). Lo tuvo en `--bs-secondary-color` como su
   única señal, y aquí estaba escrito que «no va en acento: el amarillo significa esto se pulsa y aquí no hay
   nada que pulsar». Las dos mitades han caducado. La primera, porque la cifra que se daba —6,16 en oscuro y
   6,13 en claro— **nunca se comparó con la de las otras siete**, que es la que decidía: sus bordes dan
   **1,53 y 1,09**, o sea invisibles. Así que aquello no era «un tono más fuerte para que se note que es
   distinta», era **el único borde visible de la rejilla**, y una caja con anillo entre siete sin él se lee
   como una caja *resaltada* — la misma señal que usa un `:hover`. Lo vio el organizador en pantalla y pidió
   igualarla. La segunda mitad, porque ahora las ocho **sí se pulsan**: van a su sección de `/Ayuda`, que es
   pública, así que el acento al pasar por encima es correcto en todas.

   Lo que la distingue ahora es **su texto** y la negrita del «pídeselo a quien organiza» de la regla de
   abajo, que es el canal que no depende de saber leer un tono de gris.

   Queda un hueco a **tres columnas** (3 + 3 + 2) y no se persigue con una media query: el número de columnas
   lo decide `auto-fill` contra el ancho del contenedor, así que una anchura escrita a mano sería una segunda
   verdad sobre dónde rompe la rejilla y envejecería el día que cambie el `minmax`. */

/* El «pídeselo a quien organiza» en el color del cuerpo y no en el secundario del párrafo: es la única
   acción de la página y la negrita sola, dentro de un texto ya atenuado, no se separa. Sigue habiendo dos
   canales —peso y color—, así que no depende de distinguir tonos. Medido: **9,59 en oscuro y 12,89 en
   claro**. */
.mtg-publica-puerta strong {
  color: var(--bs-body-color);
}

/* ---- Un `<code>` dentro de un aviso no puede llevar el rosa de Bootstrap ----
   `--bs-code-color` es `#d63384`, y sobre el fondo de un `alert-info` en tema claro da **3,86**: por debajo
   del 4,5 que se le pide a un texto normal. Lo encontró `medir.js` en la pasada del 24 de agosto de 2026 y
   era el único contraste corto de 3992 medidos — sale en `/Admin/Correo`, donde el aviso dice en qué carpeta
   se escriben los correos en modo fichero, o sea justo el dato que se viene a leer.

   Se arregla con `color: inherit` y no con un rosa más oscuro, y por un motivo: el color del texto de un
   `alert` ya cumple en los dos temas y en las cuatro variantes, así que heredarlo lo resuelve para todas de
   una vez en lugar de dejar cuatro cifras que volver a medir. **Lo monoespaciado se queda**, que es lo que
   de verdad distingue una ruta o un nombre de fichero del resto de la frase.

   **Y ha vuelto a morder el 25 de agosto de 2026, una clase más allá**: el mismo rosa sobre la caja elevada de
   la clave de YouTube da **3,76** en claro, con el `robots.txt` que la explica. O sea que no es cosa de los
   avisos: es que este rosa no aguanta ningún fondo que no sea el del cuerpo. La lista se amplía en vez de
   inventar una regla nueva, y si aparece un tercer sitio, se añade aquí. */
.alert code,
.mtg-clave-youtube code {
  color: inherit;
}

/* ---- El panel de noticias de la comunidad --------------------------------------------------------
   Un agregador de feeds con la forma del de Tolaria, que es la referencia que pasó el organizador: cada
   línea con miniatura, titular, fecha, un renglón de resumen y el nombre de la fuente con su distintivo.

   **Lista de líneas y no fichas ni tabla**, por la prueba del proyecto: nadie compara la fecha de una
   noticia con la de la de al lado, así que cada línea es una unidad que se lee sola. Es la misma decisión
   que «Tus partidas por jugar», dos bloques más arriba. */
.mtg-noticias {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin: 0;
  /* **El scroll es del panel y no de la página**, que es la mitad de por qué esto cabe en la columna: con
     veinticinco noticias en flujo, el bloque de secciones de abajo se iría a dos pantallas. El alto es el
     que deja el panel a la altura de las dos cajas de su izquierda en un caso normal. */
  max-height: 28rem;
  overflow-y: auto;
  /* Sin esto, la barra de scroll se pega al texto. */
  padding-inline-end: 0.25rem;
}

/* Tres columnas: miniatura, cuerpo y fecha. La de la fecha va **de ancho fijo**, y es la misma corrección
   —y el mismo motivo— que la hora de una partida: cada línea es su propia rejilla, así que con
   `max-content` el titular empezaría en una `x` distinta en cada renglón según lo larga que fuera la fecha
   («3 sep» mide 38 px y «21 ago» 46). */
.mtg-noticia {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) 4.4rem;
  align-items: start;
  column-gap: 0.6rem;
  padding: 0.5rem 0.35rem;
  border-radius: var(--bs-border-radius);
  /* Ancla del área pulsable de abajo. */
  position: relative;
}

.mtg-noticia:hover {
  background: var(--mtg-celda-fondo);
}

/* La miniatura en 16:9, que es lo que sirven los feeds de vídeo. `cover` porque un feed de podcast la manda
   cuadrada y sin él saldría deformada — el mismo caso que el avatar.

   **Este es el tamaño de móvil**; en escritorio crece más abajo. Ver ahí el porqué y las cifras. */
.mtg-noticia-miniatura {
  flex: 0 0 auto;
  width: 4.5rem;
  height: 2.6rem;
  overflow: hidden;
  border-radius: calc(var(--bs-border-radius) * 0.75);
  background: var(--bs-tertiary-bg);
  display: grid;
  place-items: center;
}

.mtg-noticia-miniatura > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---- En escritorio la miniatura es un tercio más grande, y todas las filas miden lo mismo ----
   Lo pidió el organizador el 25 de agosto de 2026 viendo el panel: «la miniatura la veo muy pequeña, apenas
   se aprecia». Tenía razón y la cifra lo dice — **72 × 41,6 px** para el fotograma de un vídeo.

   Pasa a **96 × 54**, y las cinco opciones se midieron en la pantalla de verdad antes de elegir:

   | Miniatura | Alto de fila | Scroll | Líneas visibles |
   |---|---|---|---|
   | 72 × 41,6 (la de antes) | 57,6 / 73,8 | 1676 | 6 |
   | 85 × 48                 | 64 / 73,8   | 1765 | 6 |
   | 96 × 54                 | 70 / 73,8   | 1857 | 5 |
   | **96 × 54 + título de dos líneas fijas** | **73,8 todas** | 1903 | **5** |
   | 112 × 63                | 79 todas    | 2032 | 5 |

   **El `min-height` del titular es lo que hace buena a esta opción y no es cosmético**: sin él la lista tiene
   dos alturas de fila —según si el titular parte en una línea o en dos—, que es exactamente lo que la regla de
   forma fija de las fichas prohíbe. Y sale **casi gratis**: 46 px de scroll sobre la opción de al lado y **la
   misma cifra de líneas visibles**, porque las filas de dos líneas ya medían 73,8.

   El precio real está en la tercera columna y hay que conocerlo: **de 6 líneas visibles se pasa a 5**. Es lo
   que cuesta que un fotograma se reconozca, y el panel lleva su propio scroll.

   **Solo en escritorio**, por encima del corte en el que el panel pasa a enseñar cinco líneas: en un móvil el
   ancho es lo que le falta al titular, así que ahí la miniatura se queda como estaba. */
@media (min-width: 768px) {
  .mtg-noticia-miniatura {
    width: 6rem;
    height: 3.375rem;
  }

  /* Dos líneas de titular **reservadas**, con la misma cuenta que el `line-clamp` de arriba: si cambia el
     tamaño de letra o el interlineado del titular, esta cifra cambia con ellos porque está escrita con las
     mismas variables y no con un número a ojo. */
  .mtg-noticia-titulo {
    min-height: calc(2 * 1.3 * 0.9rem);
  }
}

/* Sin miniatura, la inicial de la fuente. Mismo criterio que el logo de un formato que no tiene imagen: un
   respaldo que se genera y no se guarda. */
.mtg-noticia-inicial {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--bs-secondary-color);
}

.mtg-noticia-cuerpo {
  min-width: 0;
}

/* El titular a dos líneas como máximo. **Se recorta con `line-clamp` y no con `text-overflow`**, que solo
   sabe recortar una línea: aquí el titular de un vídeo pasa de los cien caracteres y con una sola línea se
   perdería de qué va. Dos es lo que deja la línea en 3,4 rem de alto. */
.mtg-noticia-titulo {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* El enlace **se pinta como texto**: es la línea entera lo que se lee, y un azul de enlace en cada titular
   convertiría el panel en una pared de color. Se subraya al pasar por encima, igual que el nombre de una
   baraja en el histórico. */
.mtg-noticia-titulo > a {
  color: var(--bs-body-color);
  text-decoration: none;
}

.mtg-noticia-titulo > a:hover,
.mtg-noticia-titulo > a:focus-visible {
  text-decoration: underline;
}

/* ---- La línea entera es el enlace ----
   **La fila ya prometía esto y no lo cumplía**: `.mtg-noticia:hover` le cambia el fondo a la línea completa,
   así que se lee como pulsable, y lo pulsable era solo el texto del titular.

   El defecto llevaba ahí desde el principio y **estaba escondido porque en móvil la lista no se pintaba**: al
   pintarla, el medidor sacó dos titulares con **20 px de objetivo táctil** contra los 44 de la regla. Son los
   de una sola línea; los que parten en dos llegaban a 40 y tampoco cumplían.

   Se estira el área del enlace en vez de darle relleno, que es el patrón de la píldora de una mesa, y **no con
   `.stretched-link` de Bootstrap**: esa clase se ancla al primer ancestro posicionado, y aquí el ancla tiene
   que ser la línea. Dentro no hay ningún otro control, así que cubrirla entera no tapa nada. */
.mtg-noticia-titulo > a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.mtg-noticia-pie {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.15rem 0 0;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

.mtg-noticia-fuente {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El distintivo por tipo. **Fondo opaco y no un velo**, que es la regla que este proyecto lleva aprendida
   cuatro veces: sobre el velo del `:hover` de la línea, un velo encima de otro velo deja el contraste
   dependiendo de la pila entera.

   Y **no va en acento**: el amarillo significa «esto se pulsa» y esto es una etiqueta. Los tres colores se
   distinguen además por la palabra, así que el color no es el único canal. */
.mtg-noticia-tipo {
  flex: 0 0 auto;
  padding: 0.05rem 0.35rem;
  border-radius: var(--bs-border-radius-sm);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #fff;
}

/* Los tres tonos son **oscuros de su paleta y no los `bg-*` de Bootstrap**, por lo mismo que el marcador de
   puntos del editor: el rojo de Bootstrap da 3,87 sobre blanco y hace falta 4,5. Aquí el texto es blanco
   sobre el distintivo, así que lo que se mide es el fondo contra el blanco. */
.mtg-noticia-tipo-podcast {
  background: #7c3a8d;
}

.mtg-noticia-tipo-video {
  background: #b3261e;
}

.mtg-noticia-tipo-blog {
  background: #1f6f4a;
}

/* La columna de la derecha: la fecha y debajo el distintivo, los dos alineados al final.
   **Sin `nowrap` a propósito.** Con el año, «22 ago 2026» no cabe en los 4,4 rem de la columna y **se parte
   en dos líneas**, que es justo lo que pidió el organizador —«que salga el año también, que cabe debajo»—.
   Con `nowrap` se saldría de su columna o forzaría a ensancharla, y ensancharla se lo quita al titular, que
   es lo único que de verdad necesita ancho aquí. */
.mtg-noticia-lado {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.25rem;
  font-size: 0.75rem;
  line-height: 1.25;
  color: var(--bs-secondary-color);
  text-align: end;
}

/* ---- «Ver todas», en la fila del título ----
   **Sale en los dos tamaños**, que es lo que faltaba: la primera versión lo escondía en escritorio con el
   argumento de que «la lista está justo debajo y el botón no haría nada», y era falso — la lista de la
   portada está acotada a 25 y el diálogo trae las 95. En la web el control no existía, mientras el comentario
   del marcado afirmaba que sí. Lo vio el organizador.

   Y **va donde van los otros tres «ver todos» de la portada**, al lado del título: hubo un intento de
   ponerlo debajo del panel y lo corrigió él. Eso obliga a que sea un `<button>` con el aspecto de aquellos
   —que son enlaces— en vez de un `.btn` con icono: la fila es la misma y un botón relleno ahí sería el único
   de los cuatro que no se lee igual. Es la excepción justificada a «todo botón lleva el estilo de botón del
   proyecto y su icono»: aquí lo que manda es la coherencia de la fila.

   El objetivo táctil sale gratis — la regla de `pointer: coarse` que crece `.mtg-inicio-todos` de 22 a 44 px
   apunta a la clase y no a `a.clase`, así que un `<button>` la hereda. Medido.

   En móvil la lista no se pinta y este control es el único acceso, o sea que ahí es la pantalla entera de
   noticias en un toque. */
button.mtg-inicio-todos {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.9rem;
  color: var(--bs-link-color);
  text-decoration: underline;
}

button.mtg-inicio-todos:hover {
  color: var(--bs-link-hover-color);
}

@media (max-width: 767.98px) {
  /* ---- En móvil, las cinco primeras ----
     Estuvo escondida **entera**, así que el teléfono enseñaba un título y un enlace y nada más: una sección
     cuyo contenido completo es un enlace a un diálogo es una sección que no enseña nada, y el teléfono es
     justo donde alguien del club lee esto.

     **Cinco y no las 25** por lo que se escondió en su día, que era una razón buena: el panel lleva su propio
     scroll (`max-height`), y dos barras anidadas en un móvil es lo que hace que no se sepa cuál se está
     arrastrando — está apuntado unas líneas más abajo para el diálogo. Con cinco en flujo no hace falta
     ninguna. Son ~280 px, menos de lo que ya ocupan las dos cajas de al lado.

     **Son las cinco primeras de la lista repartida, o sea las cinco más recientes del panel, y una fuente
     puede repetirse.** Estuvo escrito aquí que serían «cinco fuentes distintas» y **era falso**: el reparto
     decide *quién entra en las 25*, pero la lista se pinta por fecha, así que las cinco de arriba son
     simplemente las cinco más nuevas de esas 25. Medido en pantalla: OLD SCHOOL, Numsgil7, **Numsgil7**,
     Premodern MTGO y Full Tapped — idénticas a lo que daría cortar por fecha pura. En este panel el reparto
     no cambia nada en móvil; lo que cambia es el escritorio, donde el podcast pasa de no salir a salir.

     Es lo que pidió el organizador («las 4 o 5 últimas por fecha»), así que se queda. Si algún día se quiere
     *una por fuente* en el móvil, no basta con este `nth-child`: haría falta emitir el marcado en orden de
     elección y colocarlo por fecha con `order`, o marcar desde el servidor cuáles son las cinco cabeceras de
     fuente. **Un solo render para los dos tamaños** es lo que se conserva a cambio: con dos listas en el HTML
     volvería la trampa de `mtg-accion-larga`/`mtg-accion-corta` — lo mismo escrito dos veces, con solo una
     visible, libre de separarse sin que nadie lo vea.

     **Acotado al bloque de la portada** y no a `.mtg-noticias` a secas, porque lo que HTMX trae al diálogo es
     otro `.mtg-noticias` y sin acotar se recortaría también: el archivo se quedaría en cinco. */
  .mtg-inicio-noticias .mtg-noticias {
    max-height: none;
    overflow-y: visible;
  }

  .mtg-inicio-noticias .mtg-noticia:nth-child(n + 6) {
    display: none;
  }
}

/* Dentro del diálogo el scroll ya lo pone Bootstrap (`modal-dialog-scrollable`), así que el del panel
   sobraría: dos barras anidadas es lo que hace que en un móvil no se sepa cuál se está arrastrando. */
.mtg-noticias-en-dialogo .mtg-noticias {
  max-height: none;
  overflow-y: visible;
}

/* ---- Las fuentes de noticias, en `/Admin/Ajustes` ------------------------------------------------
   Una fila por fuente con su nombre, su dirección, su estado y dos botones. **Lista de líneas y no tabla**,
   otra vez por la prueba del proyecto: nadie compara la fecha de lectura de una fuente con la de la de al
   lado.

   **El ancho se declara una vez**, en la sección, y lo heredan las cuatro piezas —el alta, el veredicto, la
   cabecera de la lista y la lista—. Estuvo escrito cuatro veces y ya se vio el precio a la primera: la fila
   de «Refrescar ahora» era la única que no lo llevaba, así que su botón se iba a 1300 px con la lista
   acabando en 750. Con el número en un solo sitio ese olvido no se puede repetir.

   46 rem y no el ancho entero: la fila es nombre + dirección + dos botones, y a 1400 px estirada dejaba el
   nombre pegado a la izquierda con medio metro de vacío hasta los botones. */
.mtg-noticias-seccion {
  --mtg-noticias-ancho: 46rem;
}

.mtg-noticias-alta {
  max-width: var(--mtg-noticias-ancho);
}

/* La clave de la API de YouTube. Caja elevada con `--mtg-celda-fondo` —y nunca un `--bs-*-bg`, que sobre este
   panel sale como un agujero—, para que se lea como un bloque de configuración y no como parte del alta que
   viene debajo. */
.mtg-clave-youtube {
  max-width: var(--mtg-noticias-ancho);
  margin-block-end: 1.25rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--bs-secondary-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
}

/* El campo y los botones en fila, y **apilados en móvil** por lo mismo que el alta: a 375 px, con los dos
   botones al lado, al campo le quedan 120 px. Se repiten las reglas en vez de compartir la clase porque son
   dos formularios distintos y uno tiene dos botones y el otro puede tener uno. */
.mtg-clave-youtube-fila {
  display: flex;
  gap: 0.5rem;
}

.mtg-clave-youtube-fila > .form-control {
  min-width: 0;
}

.mtg-clave-youtube-fila > .btn {
  flex: 0 0 auto;
}

@media (max-width: 575.98px) {
  .mtg-clave-youtube-fila {
    flex-wrap: wrap;
  }

  .mtg-clave-youtube-fila > .form-control {
    flex: 1 0 100%;
  }
}

.mtg-fuentes-cabecera {
  max-width: var(--mtg-noticias-ancho);
}

/* El campo y los dos botones en una fila, y **apilados en móvil**: a 375 px, con los dos botones al lado, al
   campo le quedan 120 px para una URL. */
.mtg-noticias-alta-fila {
  display: flex;
  gap: 0.5rem;
}

.mtg-noticias-alta-fila > .form-control {
  min-width: 0;
}

.mtg-noticias-alta-fila > .btn {
  flex: 0 0 auto;
}

@media (max-width: 575.98px) {
  .mtg-noticias-alta-fila {
    flex-wrap: wrap;
  }

  .mtg-noticias-alta-fila > .form-control {
    flex: 1 0 100%;
  }
}

/* El veredicto de «Comprobar». **Caja elevada y no un `alert`**: un `alert-success` verde diría «hecho», y
   esto no ha hecho nada todavía — es una previa. El borde de color es la señal de si vale o no, con la frase
   escrita al lado, así que el color no es el único canal. */
.mtg-noticias-veredicto {
  margin-block: 1rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--bs-border-color);
  border-inline-start-width: 4px;
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
  max-width: var(--mtg-noticias-ancho);
}

.mtg-noticias-veredicto.es-bueno {
  border-inline-start-color: var(--bs-success);
}

.mtg-noticias-veredicto.es-malo {
  border-inline-start-color: var(--bs-danger);
}

.mtg-noticias-muestra {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin: 0;
  font-size: 0.85rem;
}

.mtg-noticias-muestra > li {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  color: var(--bs-secondary-color);
}

.mtg-noticias-muestra-titulo {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--bs-body-color);
}

.mtg-noticias-muestra time {
  flex: 0 0 auto;
  margin-inline-start: auto;
}

.mtg-fuentes {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  max-width: var(--mtg-noticias-ancho);
}

.mtg-fuente {
  display: flex;
  align-items: start;
  gap: 0.75rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: var(--mtg-celda-fondo);
}

/* Apagada se **atenúa la fila y no se esconde**: sigue estando, y su dirección es justo lo que hace falta
   para volver a encenderla. La opacidad no baja de 0,65 para que el nombre siga legible. */
.mtg-fuente.esta-apagada {
  opacity: 0.65;
}

.mtg-fuente-datos {
  min-width: 0;
  flex: 1 1 auto;
}

.mtg-fuente-nombre {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-weight: 500;
}

/* Cada hijo con `min-width: 0` o los puntos suspensivos no se activan nunca: la trampa de siempre. */
.mtg-fuente-nombre > * {
  min-width: 0;
}

.mtg-fuente-url,
.mtg-fuente-estado,
.mtg-fuente-motivo {
  margin: 0.1rem 0 0;
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
}

/* La URL y el «Leída el martes» **se recortan**: la primera puede ser larguísima y su entera está en el
   `title`, y el segundo cabe siempre en una línea. */
.mtg-fuente-url,
.mtg-fuente-estado {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El motivo del fallo **en el rojo del tema y no en el de Bootstrap**: `--bs-danger` es `#dc3545`, que da
   3,87 sobre blanco y no llega al 4,5 de un texto normal — la misma cifra que ya obligó a cambiar el
   marcador de puntos del editor. `--bs-danger-text-emphasis` es el tono oscuro de la misma paleta. */
.mtg-fuente-fallo {
  color: var(--bs-danger-text-emphasis);
}

.mtg-fuente-acciones {
  display: flex;
  gap: 0.35rem;
  flex: 0 0 auto;
}

/* En móvil los botones bajan a su renglón: con ellos al lado, al nombre de la fuente le quedan 150 px. */
@media (max-width: 575.98px) {
  .mtg-fuente {
    flex-direction: column;
  }

  .mtg-fuente-acciones {
    align-self: stretch;
  }

  .mtg-fuente-acciones > form,
  .mtg-fuente-acciones .btn {
    flex: 1 1 0;
    width: 100%;
  }
}

/* ---- El vacío de una sección de la portada -------------------------------------------------------
   «Que aparezca algo que indique que no hay, y que no se quede vacío», pedido por el organizador el 24 de
   agosto de 2026. **Una frase y no una caja ni un dibujo**, y no es pereza: una ilustración para decir «nada»
   pesa más que el contenido cuando sí hay algo, y una caja vacía se lee como algo que se ha roto. Es el mismo
   tratamiento que el motivo de una sección o el de un candado — se cuenta una vez, en prosa, en el color
   secundario.

   El alto mínimo es lo único que se le da: sin él, una sección con su título y una frase de una línea queda
   notablemente más baja que la de al lado, y en dos columnas eso se lee como un descuadre. */
.mtg-inicio-vacio {
  margin: 0;
  padding: 0.75rem 0.1rem;
  font-size: 0.9rem;
  color: var(--bs-secondary-color);
}

/* ---- Los ajustes del torneo, agrupados y plegables --------------------------------------------------
   Los seis bloques de ajustes de la fase de inscripción —rondas, top, plazas, la puerta de internet,
   fecha/reglas/pago y los webhooks— dentro de un solo `<details>`, para que dejen de competir con las dos
   listas, que son la razón de la pantalla. Lo pidió el organizador el 26 de agosto de 2026.

   El borde en `--bs-secondary-color` y no en `--bs-border-color`, que da 1,41 y 1,10 contra el panel: es la
   misma corrección, y la misma cifra, que los conectores del cuadro, las cajas de grupo y la forma de pago. */
.mtg-ajustes {
  border: 1px solid var(--bs-secondary-color);
  border-radius: var(--bs-border-radius);
}

/* **El fondo va solo en la cabecera y el cuerpo se queda transparente**, y eso no es estética: con
   `--mtg-celda-fondo` en la caja entera —que es más claro que el panel— los controles de dentro pierden
   contraste contra un fondo que antes no tenían. Medido al hacerlo: el enlace «Cómo se crea un webhook»
   cayó de 6,39 a **3,84**, y los cinco botones de contorno («Cambiar», «Guardar», «Comprobar y guardar»)
   a **4,41**, los seis por debajo del 4,5. Ninguno cambió de color: cambió lo que tenían debajo, que es
   la lección que este proyecto ya tenía escrita con el nombre de un formato. Con el cuerpo transparente
   vuelven a apoyarse en el panel y recuperan sus cifras.
   El relleno va en el `summary` y en el cuerpo, no en el `<details>`: así la zona pulsable del resumen
   llega hasta el borde de la caja en vez de dejar un marco muerto alrededor. */
.mtg-ajustes > summary {
  padding: 0.75rem 1rem;
  background: var(--mtg-celda-fondo);
  border-radius: calc(var(--bs-border-radius) - 1px);
  cursor: pointer;
  /* Sin `list-style: none`: el triangulito de apertura es la señal de que esto se pliega, y es la misma
     que ya llevan «Reglas del torneo» y «Pegar una lista de nombres» en esta pantalla. */
}

/* Abierto, el resumen se separa del contenido con una línea: sin ella, el título del primer ajuste
   («Rondas») se lee como si colgara del resumen en vez de ser su hermano. */
.mtg-ajustes[open] > summary {
  border-bottom: 1px solid var(--bs-secondary-color);
  /* Abierta, la cabecera deja de ser el final de la caja: solo redondea por arriba. */
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

.mtg-ajustes-cuerpo {
  padding: 0 1rem 1rem;
}

/* El primer encabezado de dentro no necesita su `mt-4`: ya lo separa el relleno del cuerpo, y con los dos
   la caja abre con un hueco de 40 px. */
.mtg-ajustes-cuerpo > h3:first-child,
.mtg-ajustes-cuerpo > *:first-child > h3:first-child {
  margin-top: 0.5rem !important;
}

/* El `display: block` va aquí y no con el `d-block` de Bootstrap, que lo declara con `!important` y le
   ganaría a la regla de abajo dejando la línea visible con la caja abierta. Misma trampa que el
   `flex-fill` de las pestañas de ronda. */
.mtg-ajustes-de-que {
  display: block;
}

/* La línea de «qué hay dentro» no se pinta cuando ya está abierto: ahí los encabezados lo dicen, y
   repetirlo son dos renglones de ruido justo encima de ellos. */
.mtg-ajustes[open] > summary .mtg-ajustes-de-que {
  display: none;
}

/* ---- El enlace de ayuda («Cómo se crea un webhook», «Cómo encontrar tu ID») --------------------------
   Va en el **color del cuerpo y no en el azul de enlace de Bootstrap**, con el subrayado y el icono como
   señal de que se pulsa. El azul (`#0d6efd`) da 4,50 sobre el blanco del cuerpo —justo en la raya— y cae
   por debajo en cuanto el enlace se apoya en algo que no sea blanco puro: medido **3,80** sobre el panel
   de la fase de inscripción, y **3,84** sobre el fondo de una caja elevada. Es el mismo fallo que ya se
   corrigió en el nombre del formato de `/Formatos`, en el del torneo de la portada y en el «Ir al
   sábado…» de la agenda: **lo introduce un cambio de fondo, no de color**, y no falla nada.
   Con el color del cuerpo la cifra deja de depender de dónde esté puesto. */
.mtg-enlace-ayuda {
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-hover-color: var(--bs-body-color);
  --bs-btn-active-color: var(--bs-body-color);
  text-decoration-line: underline;
}

/* ================================================================================================
   ESTADÍSTICAS
   Las tres pantallas —la global, la de un torneo y la de una cuenta— comparten estos bloques.
   ================================================================================================ */

/* ---- La barra de cuota del metajuego -------------------------------------------------------------
   Reutiliza `.mtg-barra-probabilidad` y solo le cambia el ancho: en una tabla la barra acompaña a la
   cifra, no la sustituye, así que ocupa poco y **la cifra va escrita al lado** — el color no es nunca
   el único canal. En móvil no se pinta (`d-none d-md-inline-flex` en el marcado): ahí la tabla pasa a
   fichas y el ancho es lo que escasea. */
.mtg-barra-meta {
  width: 4rem;
  vertical-align: middle;
}

/* ---- La matriz de enfrentamientos ----------------------------------------------------------------
   **`white-space: nowrap` no es cosmético**: sin él la tabla no desborda nunca —se comprime hasta que
   veinte columnas caben en 300 px, ilegibles— y por tanto su contenedor `table-responsive` no llega a
   dar scroll. Es la misma trampa ya documentada para la clasificación de liga. */
.mtg-matriz {
  white-space: nowrap;
}

/* La primera columna se queda fija al desplazar: sin ella, arrastrando tres columnas ya no se sabe de
   qué arquetipo es la fila que se está leyendo. `--bs-body-bg` opaco y no un velo, porque debajo pasan
   las celdas al desplazarse: *un velo no sostiene un contraste*. */
.mtg-matriz th.mtg-matriz-fila,
.mtg-matriz th.mtg-matriz-esquina {
  position: sticky;
  inset-inline-start: 0;
  z-index: 1;
  background-color: var(--bs-body-bg);
  max-width: 10rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Las cabeceras de columna se recortan: un arquetipo largo —«Survival Opposition»— haría una columna de
   180 px y la matriz de veinte no cabría en ninguna pantalla. El nombre entero está en su `title`. */
.mtg-matriz-rival {
  display: inline-block;
  max-width: 6rem;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

/* Cada casilla son tres renglones: el porcentaje grande, el récord y el intervalo. El récord es lo que
   hace que un 100 % se pueda juzgar, así que va a la vista y no en el `title`. */
.mtg-matriz td .mtg-matriz-cifra {
  display: block;
  font-weight: 600;
}

.mtg-matriz td .mtg-matriz-record,
.mtg-matriz td .mtg-matriz-intervalo {
  display: block;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}

/* El intervalo es el dato de contexto: se lee después del récord, así que pesa menos. */
.mtg-matriz td .mtg-matriz-intervalo {
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}

/* Los tres matices de casilla. **Velos del color y no colores planos**: el texto conserva el del tema y
   con él su contraste, que es la misma razón por la que existe `.mtg-fila-atencion` en lugar de las
   clases contextuales de Bootstrap. Y el color nunca es el único canal — el porcentaje va escrito. */
.mtg-matriz td.mtg-matriz-buena {
  background-color: color-mix(in srgb, var(--bs-success) 18%, transparent);
}

.mtg-matriz td.mtg-matriz-mala {
  background-color: color-mix(in srgb, var(--bs-danger) 18%, transparent);
}

/* Poca muestra: se atenúa **antes** de mirar el porcentaje, porque cinco rondas no son una tendencia y
   teñirlas de verde sería justo la mentira que el intervalo viene a evitar. */
.mtg-matriz td.mtg-matriz-poca {
  opacity: 0.6;
}

/* La diagonal del espejo: no tiene porcentaje que dar, así que se aparta visualmente de las casillas
   que sí lo tienen. */
.mtg-matriz td.mtg-matriz-espejo {
  background-color: var(--mtg-celda-fondo);
  color: var(--bs-secondary-color);
  font-size: 0.8rem;
}

/* ---- Las cartas más jugadas ----------------------------------------------------------------------
   Las tierras básicas se esconden por defecto: «20 Bosque en el 100 % de las listas» no dice nada de un
   metajuego y con cuatro básicas arriba la tabla empieza por lo que menos informa. El interruptor las
   devuelve **sin volver al servidor** —las filas ya vienen marcadas—, igual que la forma del cuadro. */
.mtg-cartas-jugadas tbody tr.mtg-fila-tierra {
  display: none;
}

.mtg-cartas-jugadas.mtg-con-tierras tbody tr.mtg-fila-tierra {
  display: table-row;
}

/* En modo ficha una fila es un bloque, no una fila de tabla: con `table-row` la ficha se desmonta. Es
   la misma lección de «lo que abarca la fila entera se declara en la fila». */
@media screen and (max-width: 767.98px) {
  .mtg-tabla-fichas.mtg-cartas-jugadas.mtg-con-tierras tbody tr.mtg-fila-tierra {
    display: block;
  }
}

/* La numeración de «cartas más jugadas» la lleva un contador de CSS y no el servidor: las tierras
   básicas se esconden en el cliente, así que un contador del servidor deja huecos —se veía «2, 4, 5…»,
   que se lee como un error—. Un contador solo cuenta lo que se pinta, así que la numeración es correcta
   con el interruptor puesto y quitado. */
.mtg-cartas-jugadas tbody {
  counter-reset: mtg-carta;
}

.mtg-cartas-jugadas tbody tr {
  counter-increment: mtg-carta;
}

/* **Una tierra básica nunca lleva número, ni siquiera con el interruptor puesto.** Es la misma regla
   dicha del derecho: el ranking de «cartas más jugadas» es de las que dibujan un formato, y por eso
   las básicas se esconden por defecto y por eso el podio no las incluye. Numerarlas al destaparlas
   diría que *Bosque* es la tercera carta del formato, que es justo lo que se decidió no decir; y con
   el podio delante, además, la cifra ya no cuadraría con nada. Así la numeración significa lo mismo
   en los cuatro estados: con podio y sin él, con tierras y sin ellas. */
.mtg-cartas-jugadas tbody tr.mtg-fila-tierra {
  counter-increment: none;
}

.mtg-cartas-jugadas td.mtg-num-carta::before {
  content: counter(mtg-carta);
}

.mtg-cartas-jugadas tbody tr.mtg-fila-tierra td.mtg-num-carta::before {
  content: "·";
}

/* ---- El interruptor de tierras de «cartas más jugadas» ----
   Mide **22 px de alto** —lo que Bootstrap le da a una `form-check-input` en táctil— y el medidor no lo
   une con su etiqueta porque el `form-switch` deja 8 px entre las dos, más de los 2 px que la excepción
   del medidor da por «pegada». La altura no la arregla unirlas: sigue siendo 22.

   Aquí sí se corrige, al contrario que la casilla «No cerrar la sesión» —que el organizador dio por
   buena—, porque este se pulsa a menudo mientras se lee la tabla y no una vez al entrar. Se crece **el
   área y no la casilla**, con el pseudo-elemento de siempre: hacia arriba y hacia abajo, donde solo hay
   el hueco del renglón. */
@media (pointer: coarse) {
  [data-mtg-ver-tierras] {
    position: relative;
  }

  /* Va en **la casilla y no en su contenedor**: el medidor mira el pseudo-elemento del elemento que
     mide, y puesto en el `.form-check` seguía dando 21,6. Funciona porque Bootstrap le da
     `appearance: none`, que es lo que permite pseudo-elementos en un `<input>` — la misma razón por la
     que funciona en `.mtg-comparar`. Se sale hacia el lado hasta cubrir su etiqueta, que activa la
     casilla igual. */
  [data-mtg-ver-tierras]::after {
    content: "";
    position: absolute;
    /* **-12 y no -11**: la casilla mide 21,6 px y no 22 —Bootstrap la declara en `rem`—, así que con 11
       el área se quedaba en 43,6 y el mínimo es 44. Medido. */
    inset-block: -12px;
    inset-inline-start: 0;
    inset-inline-end: -9rem;
  }
}

/* ================================================================================================
   ESTADÍSTICAS · LOS GRÁFICOS
   Elegidos por el organizador el 27 de agosto de 2026 entre variantes montadas con datos reales.
   ================================================================================================ */

/* ---- Los tres tonos del resultado ------------------------------------------------------------
   Se declaran **una vez y como variables**, porque los usan tres cosas que tienen que decir lo mismo: la
   barra de victoria, los puntos del cuadrante y las casillas de la matriz. Con el color escrito en cada
   sitio, el día que se toque uno los tres dejarían de coincidir.

   **No son los de Bootstrap**: su verde y su rojo están pensados para texto sobre fondo claro y aquí son
   rellenos de un gráfico, que pide 3:1 y no 4,5:1. Estos aguantan en los dos temas y **el color nunca es
   el único canal** — la cifra va escrita al lado y, en la barra, el lado ya lo dice. */
:root {
  --mtg-gana: #4c9a5a;
  --mtg-pierde: #b3474f;
  --mtg-medio: #b08a2e;
}

/* ---- Los cinco colores de maná, para las barras -----------------------------------------------
   Lo pidió el organizador el 27 de agosto de 2026 al ver las cinco barras del bloque de colores todas
   en oro: *«¿sería posible con los contrastes que tenemos elegir tonos que funcionen en ambos y se
   parezcan al rojo, blanco, azul, verde y negro?»*. Sí, **con una condición: el blanco y el negro no
   pueden ser el mismo tono en los dos temas**. Un blanco de verdad desaparece sobre el fondo claro y un
   negro de verdad sobre el oscuro, así que esos dos se invierten de tema a tema; los otros tres aguantan
   con un solo valor y aun así se afinan, porque el mismo azul no rinde igual sobre blanco que sobre
   #212529.

   Son **rellenos de un gráfico**, así que se les pide **3:1** contra el fondo y no 4,5 — y el color
   nunca es el único canal: cada barra lleva su nombre escrito y su cifra al final.

   **No reutilizan `.mtg-color-*`**, que son los sectores de la tarta del editor y están pensados para
   llevar texto blanco encima: tocarlos aquí cambiaría aquella pantalla sin que nadie lo mirase. */
:root {
  --mtg-mana-w: #e8dcae;
  --mtg-mana-u: #4a9fd8;
  --mtg-mana-b: #a9a2b8;
  --mtg-mana-r: #e05d55;
  --mtg-mana-g: #3fa76a;
}

[data-bs-theme="light"] {
  --mtg-mana-w: #a3894e;
  --mtg-mana-u: #1f6fb2;
  --mtg-mana-b: #4a4a55;
  --mtg-mana-r: #c0392b;
  --mtg-mana-g: #1f7a4d;
}

/* El `>` es lo que le gana al relleno de acento del carril, que se declara con la misma forma: sin él
   las cinco barras salían doradas — se vio en pantalla. */
.mtg-meta-carril > span.mtg-mana-w { background: var(--mtg-mana-w); }
.mtg-meta-carril > span.mtg-mana-u { background: var(--mtg-mana-u); }
.mtg-meta-carril > span.mtg-mana-b { background: var(--mtg-mana-b); }
.mtg-meta-carril > span.mtg-mana-r { background: var(--mtg-mana-r); }
.mtg-meta-carril > span.mtg-mana-g { background: var(--mtg-mana-g); }

/* ---- El anillo de victoria -------------------------------------------------------------------
   **Un anillo con el porcentaje dentro, y el mismo en escritorio y en ficha.** Lo eligió el organizador
   el 27 de agosto de 2026 viéndolo en el móvil: primero para la ficha, donde la barra divergente se
   quedaba en una raya de 49 px con la cifra encima del relleno verde —**3,46 de contraste**, medido—, y
   acto seguido para las dos («yo ese círculo lo pondría hasta en web»).

   Lo que se pierde y hay que saberlo: la barra divergente **comparaba filas de un vistazo** —longitudes
   alineadas saliendo de una misma raya del 50 %— y un anillo no hace eso. Lo que se gana es que el mismo
   control funciona en las dos formas de la tabla, sin dos representaciones que puedan separarse, y que
   la cifra deja de apoyarse en un relleno de color: va en el hueco del anillo, sobre el fondo de la
   página, así que su contraste ya no depende de si se gana o se pierde.

   El arco es un `conic-gradient` sobre `--mtg-wr`, que llega **entera** desde el servidor: un decimal
   con coma dentro de un atributo `style` lo descarta el navegador sin decir nada.

   El agujero se hace con `mask` y **no con un círculo del color del fondo**: así no hay que adivinar
   sobre qué se apoya la caja, que cambia según la pantalla (el cuerpo, el panel de una fase, una ficha).
   Y la cifra va en un hijo normal, fuera del pseudo-elemento, porque una máscara recorta también el
   contenido. */
.mtg-col-wr {
  /* 7rem y no 6: con 6 la cabecera «% victoria» se partía en dos líneas y descuadraba la fila. El
     `nowrap` es el cinturón: la columna se estrecha con la ventana y lo que no puede es partirse.
     Y va **centrada**, porque el anillo está centrado en su celda y una cabecera a la izquierda sobre
     una columna centrada se lee como si fuera de la columna de al lado. */
  width: 7rem;
  text-align: center;
  white-space: nowrap;
}

.mtg-col-wr .mtg-orden-boton {
  justify-content: center;
}

.mtg-wr {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  /* Centrado en su celda: la columna es más ancha que el anillo y sin esto se pegaba al lado. Lo pidió
     el organizador viéndolo. */
  margin-inline: auto;
}

.mtg-wr::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    var(--mtg-wr-tono) calc(var(--mtg-wr, 0) * 1%),
    var(--mtg-celda-fondo) 0
  );
  mask: radial-gradient(farthest-side, #0000 62%, #000 63%);
}

.mtg-wr.mtg-wr-gana {
  --mtg-wr-tono: var(--mtg-gana);
}

.mtg-wr.mtg-wr-pierde {
  --mtg-wr-tono: var(--mtg-pierde);
}

.mtg-wr-cifra {
  position: relative;
  /* Sube de 0,72 a 0,8 al quitarle el «%»: el hueco del anillo es el mismo y la cifra tiene sitio. */
  font-size: 0.8rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---- La conversión al top --------------------------------------------------------------------
   Barra simple: aquí no hay un 50 % con el que comparar. */
.mtg-conv {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.mtg-conv-carril {
  flex: 1;
  height: 0.9rem;
  min-width: 4rem;
  border-radius: 0.2rem;
  background: var(--mtg-celda-fondo);
  overflow: hidden;
}

.mtg-conv-carril > span {
  display: block;
  height: 100%;
  background: var(--mtg-acento);
}

.mtg-conv-cifra {
  min-width: 2.8rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---- Las barras del metajuego ----------------------------------------------------------------
   Elegidas frente a la tarta sola: el ojo compara longitudes mejor que ángulos, y con catorce
   arquetipos caben todos sin agrupar nada. La tarta se queda **al lado** —decisión del organizador—
   porque enseña la concentración de un vistazo. */
.mtg-meta-barras > li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.3rem;
  font-size: 0.87rem;
}

/* El nombre cede y se recorta; la cifra nunca. Es la regla de las fichas aplicada aquí. */
.mtg-meta-nombre {
  min-width: 8rem;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-meta-carril {
  flex: 1;
  height: 1rem;
  min-width: 4rem;
  border-radius: 0.2rem;
  background: var(--mtg-celda-fondo);
  overflow: hidden;
}

.mtg-meta-carril > span {
  display: block;
  height: 100%;
  background: var(--mtg-acento);
}

.mtg-meta-cifra {
  min-width: 6rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* La tarta del metajuego es más pequeña que la del editor: aquí acompaña a las barras, no manda. */
.mtg-meta-tarta {
  width: 9rem;
  flex: 0 0 auto;
}

/* ---- El cuadrante ----------------------------------------------------------------------------
   Presencia contra resultado. El marco y los ejes van en `--bs-secondary-color` y no en
   `--bs-border-color`: aquel da 1,41 sobre el fondo —la misma cifra que ya obligó a corregir los
   conectores del cuadro y los bordes de las cajas de grupo— y esto es un gráfico con significado. */
.mtg-cuadrante {
  width: 100%;
  /* 52rem y no 34: a 1280 px el cuadrante se quedaba en poco más de un tercio de la fila y los catorce
     arquetipos se apelotonaban con sus etiquetas encima —lo vio el organizador—. El `viewBox` es el
     mismo, así que crecer no descuadra nada: solo hay más sitio entre los puntos. */
  max-width: 52rem;
  color: var(--bs-body-color);
}

.mtg-cuadrante-marco {
  fill: none;
  stroke: var(--bs-secondary-color);
  stroke-width: 1;
  opacity: 0.5;
}

.mtg-cuadrante-media {
  stroke: var(--bs-secondary-color);
  stroke-dasharray: 4 3;
}

.mtg-cuadrante-eje,
.mtg-cuadrante-nota {
  font-size: 10px;
  fill: currentColor;
  opacity: 0.75;
}

.mtg-cuadrante-etiqueta {
  font-size: 9.5px;
  fill: currentColor;
}

.mtg-punto-gana { fill: var(--mtg-gana); opacity: 0.85; }
.mtg-punto-pierde { fill: var(--mtg-pierde); opacity: 0.85; }
.mtg-punto-medio { fill: var(--mtg-medio); opacity: 0.85; }

/* ---- El resto de las cartas más jugadas -------------------------------------------------------
   Se enseña el top 50 y lo demás se despliega **sin volver al servidor**: las filas ya vienen, con su
   clase. Misma idea que el interruptor de tierras y que la forma del cuadro. */
.mtg-cartas-jugadas tbody tr.mtg-fila-resto {
  display: none;
}

.mtg-cartas-jugadas.mtg-con-resto tbody tr.mtg-fila-resto {
  display: table-row;
}

/* Y en modo ficha una fila es un bloque, no una fila de tabla: con `table-row` la ficha se desmonta.
   Es la misma lección que ya costó el interruptor de tierras. */
@media screen and (max-width: 767.98px) {
  .mtg-tabla-fichas.mtg-cartas-jugadas.mtg-con-resto tbody tr.mtg-fila-resto {
    display: block;
  }
}

/* El contador de la numeración no cuenta lo que no se pinta, así que el resto tampoco incrementa
   mientras esté escondido. */
.mtg-cartas-jugadas tbody tr.mtg-fila-resto {
  counter-increment: none;
}

.mtg-cartas-jugadas.mtg-con-resto tbody tr.mtg-fila-resto {
  counter-increment: mtg-carta;
}

/* ---- Ordenar una tabla por sus columnas ------------------------------------------------------
   La cabecera pulsable se pinta como cabecera y no como botón: es una tabla, no una barra de
   acciones, y un `.btn` en cada `<th>` convertiría siete tablas en una parrilla de botones. Lo que
   señala que se puede pulsar es el cursor y el indicador de sentido.

   **El acento se queda fuera**: el amarillo significa «esto se pulsa» y aquí lo pulsable es toda la
   fila de cabecera, así que teñirla entera sería teñir la tabla. La señal es la flecha. */
.mtg-orden-boton {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

/* Las columnas numéricas van alineadas a la derecha y el botón ocupa el ancho entero, así que su
   contenido tiene que seguir la alineación de la celda o el rótulo se despegaría del número. */
th.text-end .mtg-orden-boton {
  justify-content: flex-end;
}

th.text-center .mtg-orden-boton {
  justify-content: center;
}

/* La flecha: reserva su hueco siempre —con `visibility` y no `display`— o la cabecera se movería un
   pelo al ordenar y la tabla entera daría un salto. */
.mtg-orden-boton::after {
  content: "▾";
  visibility: hidden;
  font-size: 0.7em;
  line-height: 1;
}

th[aria-sort="descending"] .mtg-orden-boton::after {
  visibility: visible;
}

th[aria-sort="ascending"] .mtg-orden-boton::after {
  content: "▴";
  visibility: visible;
}

.mtg-orden-boton:hover,
th[aria-sort="ascending"] .mtg-orden-boton,
th[aria-sort="descending"] .mtg-orden-boton {
  color: var(--bs-emphasis-color);
}

/* En papel no hay nada que ordenar: la flecha sería tinta que no dice nada. */
@media print {
  .mtg-orden-boton::after {
    display: none;
  }
}

/* ---- La escala de la matriz de cruces --------------------------------------------------------
   Cinco tramos y no tres, a petición del organizador el 27 de agosto de 2026 —«en los cruces ponle
   colores»—: con dos matices al 18 % la matriz se leía casi plana y había que ir casilla por casilla.

   **Los tonos son los mismos tres de la barra y el cuadrante** (`--mtg-gana`, `--mtg-pierde`), no el
   verde y el rojo de Bootstrap: las tres cosas dicen lo mismo y tienen que decirlo igual.

   **Velos y no colores planos**, que es lo que deja el texto con el color del tema y por tanto con su
   contraste — la misma razón por la que existe `.mtg-fila-atencion`. Y el color nunca es el único
   canal: el porcentaje, el récord y el intervalo van escritos en la casilla. */
.mtg-matriz-gana-mucho {
  --mtg-matriz-velo: color-mix(in srgb, var(--mtg-gana) 42%, transparent);
}

.mtg-matriz-gana {
  --mtg-matriz-velo: color-mix(in srgb, var(--mtg-gana) 22%, transparent);
}

.mtg-matriz-pierde {
  --mtg-matriz-velo: color-mix(in srgb, var(--mtg-pierde) 22%, transparent);
}

.mtg-matriz-pierde-mucho {
  --mtg-matriz-velo: color-mix(in srgb, var(--mtg-pierde) 42%, transparent);
}

/* **El velo se declara una vez y se aplica en dos sitios**, y el `td` del selector no es adorno: la
   celda de una `.table` la pinta Bootstrap con `.table > :not(caption) > * > *`, que le gana a una clase
   suelta. Al quitarlo para que la leyenda pudiera reutilizar la clase, **la leyenda salió en color y la
   tabla en gris** — lo vio el organizador. */
.mtg-matriz td.mtg-matriz-gana-mucho,
.mtg-matriz td.mtg-matriz-gana,
.mtg-matriz td.mtg-matriz-pierde,
.mtg-matriz td.mtg-matriz-pierde-mucho,
.mtg-matriz-muestra {
  background-color: var(--mtg-matriz-velo, transparent);
}

/* ---- El podio de las cartas más jugadas ------------------------------------------------------
   Las diez primeras con su ilustración, y de la once en adelante la tabla de siempre. Lo propuso el
   organizador el 27 de agosto de 2026: una tabla de doscientos nombres no dice qué se juega en un
   formato, y diez cartas a la vista sí.

   **Se reparte con `auto-fill` y no con un número de columnas escrito**: son cinco a lo ancho en
   escritorio y bajan solas a tres y a dos, sin una media query que haya que volver a medir. */
.mtg-podio-cartas {
  display: grid;
  /* `auto-fit` y no `auto-fill`: con diez cartas y sitio para doce, `auto-fill` deja las dos pistas
     vacías y la décima carta cae sola a una segunda fila —se vio en la captura—, mientras que `auto-fit`
     las colapsa y el podio se lee en una sola línea. En móvil, donde solo caben tres, las dos formas
     hacen lo mismo. */
  grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr));
  gap: 0.75rem;
  padding: 0;
  margin-bottom: 1rem;
  list-style: none;
}

.mtg-podio-carta {
  position: relative;
  text-align: center;
}

.mtg-podio-carta img,
.mtg-podio-carta .mtg-imagen-hueco {
  width: 100%;
  height: auto;
  border-radius: 0.4rem;
}

/* El puesto, en la esquina de la ilustración. **Fondo opaco y no un velo**: debajo pasa un dibujo, y
   un velo no sostiene un contraste. Misma regla que el chip de semilla del cuadro. */
.mtg-podio-puesto {
  position: absolute;
  inset-block-start: 0.25rem;
  inset-inline-start: 0.25rem;
  min-width: 1.5rem;
  padding: 0.05rem 0.3rem;
  border-radius: 0.35rem;
  background-color: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-size: 0.8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.mtg-podio-cifra {
  display: block;
  margin-top: 0.2rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.mtg-podio-nombre {
  display: block;
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La tabla empieza donde acaba el podio, así que su contador arranca en el puesto siguiente. El podio
   son diez siempre —con menos cartas no se pinta—, así que la cifra es una constante y no un dato que
   haya que emitir. Va en una clase propia porque la misma tabla se pinta sin podio. */
.mtg-cartas-jugadas.mtg-tras-podio tbody {
  counter-reset: mtg-carta 10;
}

/* La muestra de la leyenda: **el mismo velo que pinta la casilla**, no un color aparte. Lleva borde
   porque el tramo central no tiene fondo y sin él no se vería que hay una muestra. */
.mtg-matriz-muestra {
  display: inline-block;
  width: 1.6rem;
  height: 0.9rem;
  margin-inline-end: 0.35rem;
  border: 1px solid var(--bs-border-color);
  border-radius: 0.2rem;
  vertical-align: -0.05rem;
}

.mtg-matriz-leyenda li {
  display: flex;
  align-items: center;
  color: var(--bs-secondary-color);
}

/* ---- Dónde jugué contra este rival ------------------------------------------------------------
   Un segundo renglón bajo el nombre, en la tabla de rivales. Va **dentro de la celda del nombre y no
   en una columna suya**: con tres torneos sería la columna más ancha de la tabla, y lo que se busca
   al leer la fila es el récord.

   Se recorta con puntos suspensivos y el `title` lleva la lista entera: cede el texto, no la forma de
   la fila — la misma regla que el nombre largo de una ficha. */
.mtg-rival-torneos {
  display: block;
  min-width: 0;
  overflow: hidden;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--bs-secondary-color);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* En modo ficha la celda del nombre es una caja flexible sin salto: sin esto, los torneos se
   pintarían **al lado** del nombre y no debajo. Se acota con `:has()` a las celdas que lo llevan,
   porque dejar que envuelva a todas partiría los distintivos de la clasificación a otra línea. */
@media screen and (max-width: 767.98px) {
  .mtg-tabla-fichas tbody td[data-ficha-titulo]:has(> .mtg-rival-torneos) {
    flex-wrap: wrap;
  }

  .mtg-rival-torneos {
    flex-basis: 100%;
  }
}

/* ---- Ordenar en modo ficha -------------------------------------------------------------------
   En móvil la tabla se pinta como fichas y la cabecera se esconde, así que los botones de ordenar de
   arriba quedan **invisibles y aun así enfocables**: trece objetivos táctiles de 24 px que nadie ve,
   denunciados por `medir.js`. La salida es darle a la ficha su propio control —el mismo `ordenar()`,
   no un segundo mecanismo— y quitarle la caja a los de la cabecera.

   `display: contents` y no `visibility: hidden`: el rótulo de la columna vive **dentro** del botón, y
   escondiéndolo se iría del árbol de accesibilidad, que es justo lo que el `clip-path` de la cabecera
   está protegiendo. Sin caja no hay objetivo táctil que medir y el texto se queda. */
.mtg-orden-ficha {
  display: none;
}

@media screen and (max-width: 767.98px) {
  .mtg-tabla-fichas thead .mtg-orden-boton {
    display: contents;
  }

  .mtg-orden-ficha {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
  }

  .mtg-orden-ficha label {
    flex: none;
    color: var(--bs-secondary-color);
    font-size: 0.85rem;
  }

  /* Los dos controles llegan a los 44 px del dedo: Bootstrap deja el `form-select` en 38 y el botón en
     lo que ocupe su flecha. Se declara el alto y no se crece con un pseudo-elemento porque aquí sí hay
     sitio — es una fila propia, no una esquina de tabla. */
  .mtg-orden-ficha .form-select,
  .mtg-orden-ficha .btn {
    min-height: 44px;
  }

  .mtg-orden-ficha .btn {
    flex: none;
    min-width: 44px;
  }
}

/* Los datos del podio: los mismos que su fila de la tabla, en una línea fija bajo el nombre. Se recorta
   igual que el nombre — cede el texto, no la forma. */
.mtg-podio-datos {
  display: block;
  overflow: hidden;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* En una casilla teñida los dos renglones pequeños suben al color del cuerpo: `--bs-secondary-color`
   lleva alfa 0,75 y sobre el verde fuerte daba **4,36** contra el 4,5 que se le pide a un texto. Se
   sube el texto y no se baja el velo, que es justo lo que la escala vino a ganar. */
.mtg-matriz td.mtg-matriz-tenida .mtg-matriz-record,
.mtg-matriz td.mtg-matriz-tenida .mtg-matriz-intervalo {
  color: var(--bs-body-color);
}

/* ---- El reparto de copias de una carta ---------------------------------------------------------
   Cuatro tramos apilados: cuántas listas la llevan a 1, 2, 3 y 4 copias. Los cuatro comparten tono y se
   distinguen por **intensidad y no por color**, que es lo correcto para una escala ordenada — cuatro
   colores distintos dirían que son cuatro categorías sin orden entre sí. El detalle va en el `title`:
   cuatro cifras dentro de 60 px no se leen. */
/* El reparto es **texto**, no un gráfico: dos formas de barra se descartaron porque pedían descifrar dos
   canales a la vez —el ancho son listas, el número copias— y no se entendían. Aquí solo se lee. */
.mtg-reparto {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- La tendencia y el nivel del metajuego -----------------------------------------------------
   Dos columnas que pidió el organizador el 27 de agosto de 2026. La tendencia usa los mismos dos tonos
   del resultado —subir no es «bueno», pero sí es el mismo eje visual de toda la pantalla— y el nivel va
   en una píldora de fondo opaco, no un velo: se apoya en filas con y sin velo de tabla. */
.mtg-tendencia {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* **Los tonos del resultado son rellenos, no colores de texto**, y aquí se usan como texto: el verde
   `--mtg-gana` sobre el fondo claro da **3,46** y a un texto se le piden 4,5. Es la trampa que el propio
   comentario de esas variables anuncia, cazada por `medir.js`. Tienen su par oscurecido, uno por tema. */
:root {
  --mtg-gana-texto: #67b177;
  --mtg-pierde-texto: #e08d88;
}

[data-bs-theme="light"] {
  /* Un punto más oscuros de lo que pide el fondo del cuerpo: en modo ficha estos textos se apoyan en la
     **caja gris** de una celda (`#ebebeb`), no en el blanco, y allí el verde daba **4,24**. Medido. */
  --mtg-gana-texto: #256a3b;
  --mtg-pierde-texto: #97323a;
}

.mtg-tendencia-sube { color: var(--mtg-gana-texto); }
.mtg-tendencia-baja { color: var(--mtg-pierde-texto); }

/* **La letra sola, en su color, sin píldora.** Lo pidió el organizador viéndola en la esquina de la
   ficha: la píldora gris de la B sobre el fondo gris de la caja no se distinguía de un distintivo más, y
   lo que tiene que leerse es la letra. Sin fondo, además, el mismo elemento vale en la columna de
   escritorio, en la esquina de la ficha y en la leyenda — una sola regla y ninguna divergencia.

   Los tonos son **los de texto** (`--mtg-gana-texto`, `--mtg-pierde-texto`), no los de relleno: aquí es
   una letra y se le piden 4,5:1, no los 3:1 de un gráfico. Y el color **no es el único canal** — la letra
   se lee igual, y su leyenda está debajo de la tabla. */
.mtg-nivel {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.mtg-nivel-a { color: var(--mtg-gana-texto); }
.mtg-nivel-b { color: var(--bs-secondary-color); }
.mtg-nivel-c { color: var(--mtg-pierde-texto); }

/* La caja de una baraja por preparar recorta su esquina: la cinta nace fuera del borde y sin esto
   asomaría por el lado. La de liga vive dentro de la miniatura, que ya recorta. */
.mtg-inicio-baraja,
.mtg-lista-torneo {
  overflow: hidden;
}

/* ---- Los colores: un anillo con el símbolo dentro ---------------------------------------------
   El mismo lenguaje que el anillo de victoria —arco con `conic-gradient` y agujero con `mask`— para que
   la pantalla diga los porcentajes de una sola forma. Lo eligió el organizador el 27 de agosto de 2026.

   El disco del centro es **el color con su letra**, no el símbolo oficial de maná: ese es una marca de
   Wizards y este proyecto no recrea marcas. La tinta es `--bs-body-bg`, que funciona en los dos temas por
   construcción — los tonos de maná se invierten con el tema y el fondo también. */
.mtg-colores > li {
  width: 5rem;
}

.mtg-color-anillo {
  position: relative;
  display: grid;
  place-items: center;
  width: 3.4rem;
  height: 3.4rem;
  margin-inline: auto;
}

.mtg-color-anillo::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    var(--mtg-anillo-tono) calc(var(--mtg-anillo, 0) * 1%),
    var(--mtg-celda-fondo) 0
  );
  mask: radial-gradient(farthest-side, #0000 66%, #000 67%);
}

/* El tono del arco sale de la misma variable que la barra que había: un color de maná, no un color nuevo. */
.mtg-color-anillo.mtg-mana-w { --mtg-anillo-tono: var(--mtg-mana-w); }
.mtg-color-anillo.mtg-mana-u { --mtg-anillo-tono: var(--mtg-mana-u); }
.mtg-color-anillo.mtg-mana-b { --mtg-anillo-tono: var(--mtg-mana-b); }
.mtg-color-anillo.mtg-mana-r { --mtg-anillo-tono: var(--mtg-mana-r); }
.mtg-color-anillo.mtg-mana-g { --mtg-anillo-tono: var(--mtg-mana-g); }

/* El símbolo de maná, servido por nosotros desde `wwwroot/img/mana`. **Sin filtro**: al contrario que los
   de edición —negros sin `fill`, que hay que invertir en tema oscuro— estos traen su color dentro, así
   que invertirlos los estropearía. */
.mtg-color-simbolo {
  width: 1.75rem;
  height: 1.75rem;
}

.mtg-color-cifra {
  margin-top: 0.2rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---- Las cajas de una ficha con anillo, todas de la misma altura ------------------------------
   La fila de una ficha alinea **por línea base** —así los rótulos de las cajas quedan a la misma altura,
   que es lo correcto cuando todas llevan una cifra—, y con el anillo de victoria dentro deja de serlo: esa
   caja mide 67 px y las demás 44, y la fila se ve escalonada. Lo vio el organizador.

   Se acota con `:has()` a **las filas que llevan anillo** y no se toca la regla general: en una ficha de
   clasificación o de mesa, donde todas las cajas son texto, la línea base sigue siendo lo que las alinea.

   Y el contenido se centra en vertical, o las cortas quedarían pegadas arriba con el hueco debajo. */
@media screen and (max-width: 767.98px) {
  .mtg-tabla-fichas tbody tr:has(.mtg-wr) {
    align-items: stretch;
  }

  /* El `:not` **no es adorno**: sin él este selector es más específico que el que esconde las columnas de
     solo escritorio, así que un `display: flex` aquí las resucita en la ficha. Volvieron seis cajas donde
     había cuatro — medido. */
  .mtg-tabla-fichas tbody tr:has(.mtg-wr) td[data-etiqueta]:not([data-ficha-solo-escritorio]) {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* ---- Los cruces contra un rival ----------------------------------------------------------------
   **El prefijo es `mtg-duelo-` y no `mtg-cruce-`, y eso no es gusto**: aquel ya existe y es del cuadro
   del top —`.mtg-cruce-lado`, `.mtg-cruce-marcador`, `.mtg-cruce-gana`, que rellena la fila del ganador
   en acento—. Se escribio primero con ese prefijo y el resultado fue que el marcador y el resultado de
   cada linea salian **con un fondo dorado** heredado del cuadro. Falla en absoluto silencio: son clases
   validas, solo que de otra cosa. Se vio en la captura.

   Y el renombrado hay que hacerlo **acotado a este bloque**: un reemplazo a lo ancho del fichero se llevo
   por delante 21 reglas del cuadro en el primer intento.

   ---- Lo que era antes ----------------------------------------------------------------
   La fila de un rival abre un dialogo con una linea por cruce. Antes el desglose iba en un segundo
   renglon bajo el nombre y no funcionaba: en el movil sale recortado, asi que no se leia ninguno de los
   dos torneos que como mucho cabian. Lo cambio el organizador el 27 de agosto de 2026.

   El boton se pinta **como el nombre y no como un boton**: es la identidad de la fila, y una caja de
   `.btn` en cada una convertiria la tabla en una parrilla. Lo que dice que se pulsa es el subrayado al
   pasar por encima. */
.mtg-rival-abrir {
  display: flex;
  min-width: 0;
  max-width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

/* El recorte va **dentro** del boton y no en el boton, y esa es la pieza que hace posible lo de abajo:
   un elemento con `overflow: hidden` **recorta su propio pseudo-elemento**, asi que con el ellipsis en el
   boton el area estirada no salia de su texto. Medido: 22,7 px de objetivo donde tenia que haber 116. */
.mtg-rival-nombre {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-rival-abrir:hover,
.mtg-rival-abrir:focus-visible {
  text-decoration: underline;
}

/* En modo ficha se pulsa **la fila entera**, que es lo que pidio el organizador. Se estira el area del
   boton con un pseudo-elemento y **no con `.stretched-link`**: aquella clase se aplicaria tambien en
   escritorio, donde un `<tr>` no esta posicionado, y colgaria el area de un ancestro cualquiera. Es la
   misma leccion que ya rige el objetivo tactil de una ficha de mesa. */
@media screen and (max-width: 767.98px) {
  .mtg-rival-fila {
    position: relative;
  }

  /* Y la celda del nombre tampoco puede recortar, por lo mismo: es el **segundo** `overflow: hidden` que
     se come el area estirada. Se puede quitar sin perder nada porque quien recorta el nombre largo es el
     span de dentro, no ella.

     **El selector va con el prefijo entero del patron de fichas**: con `.mtg-rival-fila td[...]` a secas,
     la regla de `mtg-tabla-fichas` gana por un tipo de mas y el `hidden` se queda. Medido. */
  .mtg-tabla-fichas tbody tr.mtg-rival-fila td[data-ficha-titulo] {
    overflow: visible;
  }

  .mtg-rival-abrir::after {
    content: "";
    position: absolute;
    inset: 0;
  }
}

/* El desglose, dentro del dialogo: una linea por cruce. Rejilla y no flex, para que las cuatro columnas
   se alineen entre lineas — con el torneo de ancho variable, en flex cada resultado empezaria en una `x`
   distinta. Es la misma correccion que necesito la linea de una partida en la portada. */
.mtg-duelos > li {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--bs-border-color);
}

.mtg-duelos > li:last-child {
  border-bottom: 0;
}

.mtg-duelo-torneo {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mtg-duelo-ronda {
  color: var(--bs-secondary-color);
  font-size: 0.85rem;
  white-space: nowrap;
}

.mtg-duelo-marcador {
  font-family: var(--bs-font-monospace);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}

.mtg-duelo-resultado {
  min-width: 4.5rem;
  font-size: 0.85rem;
  text-align: end;
  white-space: nowrap;
}

/* Los mismos dos tonos **de texto** que la tendencia y el nivel: aqui son letras, no rellenos. */
.mtg-duelo-gana { color: var(--mtg-gana-texto); }
.mtg-duelo-pierde { color: var(--mtg-pierde-texto); }

/* En un movil estrecho, el nombre del torneo se lleva su propia linea: con cuatro columnas se quedaba en
   nada y el resultado, que es el dato, quedaba apretado contra el borde. */
@media screen and (max-width: 419.98px) {
  .mtg-duelos > li {
    grid-template-columns: 1fr auto auto;
  }

  .mtg-duelo-torneo {
    grid-column: 1 / -1;
  }
}
