/*
 * Panel de carga en vivo — identidad de marca (docs/07, paleta de docs/08 §5).
 *
 * No es Bootstrap repintado: la pantalla de carga se usa a un metro de distancia, con sol,
 * de pie y con una mano. Por eso el marcador es enorme, los botones son grandes y el color
 * de la calidad es el mismo en el boton que la carga y en la fila que la muestra.
 *
 * La tipografia de marca es Space Grotesk. No se enlaza desde ningun CDN: en la arena la
 * conexion es mala y una fuente que tarda no puede demorar la pantalla de carga. Si esta
 * instalada localmente se usa; si no, cae al stack del sistema sin que se note.
 */

.live {
    --night: #101418;
    --slate: #161D25;
    --line:  #28323B;
    --court: #2C3B49;
    --grid:  #5A6B79;
    --bone:  #EDEFEA;
    --muted: #8B97A0;
    --lime:  #C6FF3D;

    /*
     * Dos derivados del lima, porque el lima tiene dos trabajos y sobre blanco sobrevive solo
     * uno. Como RELLENO —el boton principal, la red, el badge de dupla propia— el lima brillante
     * funciona en los dos modos. Como TEXTO sobre blanco es ilegible: 1.3:1 de contraste.
     *
     * `--lime-ink` es el lima cuando es texto: se oscurece en claro y sigue siendo el verde de
     * marca, no el gris plano al que lo manda la impresion monocroma (§28).
     * `--on-lime` es el texto que va ENCIMA del relleno lima. No puede ser `--night`, que en
     * claro vale blanco: blanco sobre lima no se lee.
     */
    --lime-ink: #C6FF3D;
    --on-lime:  #101418;

    /* Escala de calidad. El orden de color es el orden de la escala: no es decorativo,
       es el mismo mapa que lee el analista en el reporte. */
    --q-dp: #57C86B;   /* #  doble positivo */
    --q-p:  #2FD3A8;   /* +  positivo      */
    --q-ex: #4FC3E8;   /* !  exclamativa   */
    --q-sl: #E8933E;   /* /  slash         */
    --q-n:  #EE6055;   /* -  negativo      */
    --q-dn: #B4574E;   /* =  doble negativo */
    --q-null: #8B97A0; /* pendiente        */

    /* Las bandas del semaforo, como variables: los mapas SVG las heredan igual que la paleta,
       y asi el modo de impresion las puede cambiar en un solo lugar. */
    --band-good: #57C86B;
    --band-fair: #E8D24E;
    --band-low:  #E8933E;
    --band-bad:  #EE6055;

    font-family: 'Space Grotesk', 'Segoe UI', system-ui, -apple-system, sans-serif;
    color: var(--bone);
}

body:has(.live) {
    background: var(--night, #101418);
}

/* ── Formularios (inicio de set, alta de partido) ─────────────────────────── */

.live-narrow { max-width: 34rem; }

.live-form-title {
    font-size: clamp(1.8rem, 2.4vw, 2.4rem);
    font-weight: 700;
    margin: 0 0 .2rem;
}

.live-form-sub {
    color: var(--muted);
    font-size: .9rem;
    margin: 0 0 1.25rem;
}

.live-field { margin-bottom: 1.1rem; }

.live-label {
    display: block;
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--muted);
    margin-bottom: .35rem;
}

.live-select,
.live-input {
    width: 100%;
    font-family: inherit;
    font-size: 1rem;
    padding: .6rem .7rem;
    border-radius: .5rem;
    border: 1px solid var(--line);
    background: var(--night);
    color: var(--bone);
}

.live-select:focus,
.live-input:focus {
    outline: none;
    border-color: var(--lime);
}

/* Los radios son objetivo tactil, no un punto de 13px al lado de un texto. */
.live-radio {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .6rem .7rem;
    margin-bottom: .4rem;
    border: 1px solid var(--line);
    border-radius: .5rem;
    cursor: pointer;
}

.live-radio:has(input:checked) {
    border-color: var(--lime);
    color: var(--lime-ink);
}

.live-radio input { accent-color: var(--lime); }

.live-inline {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: end;
}

/* 13rem y no 10: con el shell ancho, los campos arman menos filas y mas anchas en vez de una
   grilla picada de cajitas. */
.live-inline .live-field { margin-bottom: 0; flex: 1 1 13rem; }

/* ── Encabezado ───────────────────────────────────────────────────────────── */

.live-head {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: .75rem;
}

/*
 * Volver es un boton, no un link suelto: en la pantalla de carga se toca con el dedo, en
 * tablet, y un texto de 14px sin borde ni no se ve ni se acierta. Lleva el borde y la
 * tipografia mono de los controles de la marca; el lima queda para la accion principal.
 */
.live-back {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    border: 1px solid var(--line);
    border-radius: .45rem;
    padding: .45rem .85rem;
    color: var(--muted);
    text-decoration: none;
    font-family: 'Space Mono', ui-monospace, Consolas, monospace;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    white-space: nowrap;
}

.live-back:hover {
    color: var(--bone);
    border-color: var(--muted);
}

.live-set {
    font-size: .95rem;
    color: var(--muted);
    letter-spacing: .02em;
}

/* ── Layout de tablet: cuatro cuadrantes, sin scroll ──────────────────────── */

/*
 * Un rally completo tiene que entrar en pantalla. El unico elemento que scrollea por dentro
 * es la lista de acciones; todo lo demas tiene lugar fijo, porque la memoria muscular es lo
 * que hace rapida la carga y un boton que se mueve la rompe.
 */

.live-body {
    margin: 0;
    background: #101418;
    overflow: hidden;
}

.live-app {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    padding: .6rem .9rem .9rem;
    box-sizing: border-box;
    gap: .5rem;
}

.live-topbar {
    display: flex;
    align-items: baseline;
    gap: 1rem;
    flex: 0 0 auto;
}

.live-topbar .live-coverage { margin: 0 0 0 auto; }

.live-quadrants {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: minmax(0, auto) minmax(0, 1fr);
    gap: .75rem;
    flex: 1 1 auto;
    min-height: 0;
}

.live-q1 { grid-column: 1; grid-row: 1; }
.live-q2 { grid-column: 2; grid-row: 1; }
.live-q3 { grid-column: 1; grid-row: 2; min-height: 0; overflow-y: auto; }
.live-q4 { grid-column: 2; grid-row: 2; min-height: 0; overflow-y: auto; }

/* Carga por pasos: el paso en curso ocupa los dos cuadrantes de abajo. Con un solo grupo en
   pantalla los botones entran al doble de tamano, que es el beneficio real en tablet. */
.live-wide-step .live-q3 { grid-column: 1 / -1; }

/* Las acciones scrollean por dentro: es lo unico que puede crecer sin limite. */
.live-actions-panel {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: .6rem .75rem;
    display: flex;
    flex-direction: column;
    min-height: 0;

    /* En horizontal esta fila define cuanto le queda al paso en curso. Es material de
       CONSULTA —lo que se carga esta abajo—, asi que no puede llevarse un tercio del alto. */
    max-height: 26dvh;
}

.live-actions-scroll {
    overflow-y: auto;
    min-height: 0;
}

/* El detalle ocupa el cuadrante libre, en dos columnas. */
.live-detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .5rem 1rem;
    align-content: start;
}

.live-detail-wide { grid-column: 1 / -1; }

/*
 * TABLET PARADA. Es la orientacion de carga: se sostiene como una planilla.
 *
 * El criterio es la ORIENTACION y no un ancho fijo. Con `max-width: 900px` un iPad Pro parado
 * —1024 de ancho— se quedaba con los cuatro cuadrantes en una pantalla angosta y alta, que es
 * el peor de los dos mundos.
 *
 * El orden en pantalla es MARCADOR, PASO EN CURSO, ACCIONES, y se consigue con `order`, no
 * moviendo el HTML: el orden del documento sigue siendo el logico, asi que el tabulador y el
 * lector de pantalla no dependen de como se sostenga la tablet.
 *
 * Que el paso quede segundo y no ultimo es todo el punto: abajo de todo obligaba a scrollear
 * en cada rally, que es donde se paga la carga.
 */
@media (orientation: portrait), (max-width: 900px) {
    /* La pagina sigue sin scrollear —eso ya lo fija `.live-app`—: lo que scrollea por dentro
       es la lista de acciones y nada mas. */
    .live-quadrants {
        grid-template-columns: 1fr;
        grid-template-rows: auto minmax(0, 1fr) auto;
    }

    .live-q1, .live-q2, .live-q3, .live-q4 { grid-column: 1; grid-row: auto; }

    .live-q1 { order: 1; }
    .live-q3 { order: 2; overflow: visible; }
    .live-q2 { order: 3; }

    /* El detalle vive dentro del paso desde la carga por pasos: parado no tiene lugar propio. */
    .live-q4 { display: none; }

    /* Marcador compacto: nombres y numeros en una linea. Parado, el alto es del paso. */
    .live-score { padding: .5rem .75rem; }
    .live-score-rally { margin-bottom: .15rem; }
    .live-score-num { font-size: 2.4rem; }
    .live-score-team { min-width: 5rem; }
    .live-possession { margin-top: .2rem; min-height: 0; }

    /* Las acciones son consulta, no carga: abajo, chicas y con su propio scroll. */
    .live-actions-panel { max-height: 22dvh; }
    .live-actions-panel .live-table-title { display: none; }
}

/* ── Marcador ─────────────────────────────────────────────────────────────── */

.live-score {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: .75rem 1rem;
    text-align: center;
}

.live-score-rally {
    color: var(--muted);
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    margin-bottom: .5rem;
}

.live-score-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
}

.live-score-team {
    min-width: 6.5rem;
    border-bottom: 3px solid transparent;
    border-radius: .25rem;
    padding-bottom: .2rem;
}

/* Quien tiene la pelota, en lima. Es el unico elemento en lima del tanteador. */
.live-score-team-ball { border-bottom-color: var(--lime); }
.live-score-team-ball .live-score-name { color: var(--lime-ink); }

.live-possession {
    margin-top: .4rem;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--muted);
    min-height: 1rem;
}

.live-score-name {
    color: var(--muted);
    font-size: .8rem;
    margin-bottom: .15rem;
    overflow-wrap: anywhere;
}

.live-score-num {
    font-size: 3.6rem;
    font-weight: 700;
    line-height: 1;
    color: var(--bone);
    font-variant-numeric: tabular-nums;
}

.live-score-sep {
    font-size: 2.5rem;
    font-weight: 300;
    color: var(--grid);
}

.live-badge-row { margin-top: .75rem; }

.live-badge {
    display: inline-block;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    padding: .2rem .6rem;
    border-radius: 1rem;
    border: 1px solid var(--line);
    color: var(--muted);
}

/* Estado de un cliente en el panel. El suspendido lleva el ambar de "algo pasa"; el dado de
   baja va apagado, porque no es una alerta: es alguien que ya no esta. */
.live-badge-warn {
    color: var(--q-sl);
    border-color: var(--q-sl);
    margin-left: .5rem;
}

.live-badge-off {
    opacity: .6;
    margin-left: .5rem;
}

/* Estado de cobranza. Tres colores y no dos: "nunca se le cobro" se queda con el badge pelado
   —gris— porque no es lo mismo que vencido, igual que `NoData` no es 0% en el semaforo del
   reporte (§19). Pintar de rojo al que todavia no empezo manda a llamar a quien no hay que
   llamar. */
.live-badge-overdue {
    color: var(--night);
    background: var(--q-n);
    border-color: var(--q-n);
    font-weight: 600;
}

.live-badge-due {
    color: var(--q-sl);
    border-color: var(--q-sl);
}

.live-badge-paid {
    color: var(--q-dp);
    border-color: var(--q-dp);
}

.live-badge-live {
    color: var(--on-lime);
    background: var(--lime);
    border-color: var(--lime);
    font-weight: 600;
}

.live-coverage {
    margin-top: .6rem;
    font-size: .8rem;
    color: var(--muted);
}

.live-coverage-ok   { color: var(--q-dp); }
.live-coverage-warn { color: var(--q-sl); }
.live-coverage-bad  { color: var(--q-n); }

/* ── Paneles de estado ────────────────────────────────────────────────────── */

.live-state { margin-top: 1rem; }

.live-surface {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: 1rem;
}

.live-winner {
    font-size: 1.15rem;
    font-weight: 600;
    margin-bottom: .75rem;
}

.live-section {
    color: var(--muted);
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    margin: .9rem 0 .4rem;
}

.live-panel-title {
    font-size: 1.05rem;
    font-weight: 600;
    margin-bottom: .25rem;
}

.live-row {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}

.live-stack {
    display: grid;
    gap: .5rem;
    margin-top: 1rem;
}

.live-permanent {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--line);
}

.live-quick {
    display: flex;
    gap: .5rem;
    margin-top: .75rem;
}

.live-quick .btn-live { flex: 1 1 0; }

.live-undo { margin-top: .5rem; }

/* ── Botones ──────────────────────────────────────────────────────────────── */
/*
 * Reglas tactiles del panel entero. Se carga de pie, con una mano, mirando la cancha y no la
 * pantalla, asi que:
 *
 * - `touch-action: manipulation` mata el retardo de 300ms y el zoom por doble toque. Tapeando
 *   rapido, dos taps seguidos se leen como doble toque y la pantalla hace zoom sola en medio
 *   del rally.
 * - `user-select: none` evita que iOS empiece a seleccionar texto y aparezca la lupa justo
 *   encima de lo que se quiere tocar.
 * El PISO de 44px (2.75rem, el minimo de Apple) se pone clase por clase y no con una regla
 * generica sobre `button`: una regla asi le gana por especificidad a los botones que miden
 * mas y los ACHICA hasta el piso, que es lo contrario de lo que se busca.
 */
.live button,
.live .btn-live {
    touch-action: manipulation;
    -webkit-user-select: none;
    user-select: none;
}

.btn-live {
    /*
     * `inline-flex` y no el default: la misma clase se usa en <a>, <button> y <span> —el acceso
     * deshabilitado es un <span>— y sin declarar `display` los dos primeros quedan inline, donde
     * el padding vertical NO empuja la caja. Resultado: dos tarjetas con el mismo contenido
     * midiendo distinto segun que etiqueta les toco.
     */
    display: inline-flex;
    align-items: center;
    justify-content: center;

    font-family: inherit;
    font-size: .95rem;
    font-weight: 500;
    line-height: 1.2;
    padding: .6rem .9rem;
    border-radius: .5rem;
    border: 1px solid var(--line);
    background: transparent;
    color: var(--bone);
    cursor: pointer;
    transition: border-color .12s, background .12s;
}

.btn-live:hover:not(:disabled) { border-color: var(--grid); }

.btn-live:disabled {
    opacity: .38;
    cursor: not-allowed;
}

.btn-live-block {
    display: block;
    width: 100%;
    text-align: center;
    text-decoration: none;
}

.btn-live-lg {
    font-size: 1.1rem;
    padding: .85rem 1rem;
}

/* Principal: el unico boton lima de la pantalla. Si hay dos, no hay principal. */
.btn-live-primary {
    background: var(--lime);
    border-color: var(--lime);
    color: var(--on-lime);
    font-weight: 600;
}

.btn-live-primary:hover:not(:disabled) { filter: brightness(1.08); }

.btn-live-ghost { color: var(--muted); }

/* Cierre rapido: deliberadamente distinto de un boton normal. Es un atajo que saltea
   la carga de acciones, y tiene que verse asi. */
.btn-live-warn {
    border-color: var(--q-sl);
    color: var(--q-sl);
}

.btn-live-danger {
    border-color: var(--q-n);
    color: var(--q-n);
}

.btn-live-ok {
    border-color: var(--q-dp);
    color: var(--q-dp);
}

.btn-live-link {
    border: none;
    background: none;
    color: var(--muted);
    text-decoration: underline;
    padding: .3rem 0;
    font-size: .8rem;
}

.btn-live-link:hover { color: var(--bone); }

/* Seleccionado dentro de un grupo exclusivo */
.btn-live-sel {
    border-color: var(--lime);
    box-shadow: inset 0 0 0 1px var(--lime);
    color: var(--lime-ink);
}

/* Botones de calidad: el color ES el dato */
.btn-q {
    min-width: 3rem;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--night);
    border: none;
}

.btn-q-dp { background: var(--q-dp); }
.btn-q-p  { background: var(--q-p); }
.btn-q-ex { background: var(--q-ex); }
.btn-q-sl { background: var(--q-sl); }
.btn-q-n  { background: var(--q-n); }
.btn-q-dn { background: var(--q-dn); color: var(--bone); }

/* Grilla de zona: es una cancha, no nueve botones numerados (docs/08 §1) */
.live-zone {
    display: inline-grid;
    grid-template-columns: repeat(3, 3.4rem);
    gap: .3rem;
    padding: .4rem;
    background: var(--court);
    border-radius: .4rem;
}

.live-zone .btn-live {
    padding: .55rem 0;
    text-align: center;
    background: rgba(16, 20, 24, .35);
}

/* La red mide lo que mide la grilla, no un ancho fijo: la cancha crece en el paso de zona y
   una constante en rem se despega apenas cambia el tamano de la celda. */
/* width:fit-content y no inline-block: sigue midiendo lo que mide la grilla, pero al ser
   bloque el margin auto la centra. Con inline-block quedaba pegada a la izquierda del
   cuadrante y el margen auto no hacia nada. */
.live-court {
    display: block;
    width: fit-content;
    margin-inline: auto;
}

.live-net {
    height: 3px;
    background: var(--lime);
    border-radius: 2px;
    margin-top: .3rem;
    width: 100%;
}

.live-net-label {
    font-size: .7rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .1em;
    margin-top: .2rem;
}

/* ── Avisos ───────────────────────────────────────────────────────────────── */

.live-alert {
    border-radius: .5rem;
    padding: .7rem .9rem;
    font-size: .9rem;
    margin-bottom: .75rem;
    border: 1px solid;
}

.live-alert-error { border-color: var(--q-n);  color: var(--q-n); }

.live-alert-link {
    color: inherit;
    margin-left: .4rem;
    white-space: nowrap;
}
.live-alert-warn  { border-color: var(--q-sl); color: var(--q-sl); }
.live-alert-ok    { border-color: var(--q-dp); color: var(--q-dp); }

/* La contrasena temporal, que se muestra una sola vez. Monoespaciada y con aire alrededor:
   se lee para dictarla o copiarla, y ahi 0/O y 1/l tienen que distinguirse. */
.live-code {
    font-family: var(--font-mono);
    font-size: 1rem;
    letter-spacing: .06em;
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .3rem;
    padding: .15rem .45rem;
    user-select: all;
}

.live-error-list {
    margin: .4rem 0 0;
    padding-left: 1.1rem;
    font-size: .8rem;
}

/* ── Tabla de acciones ────────────────────────────────────────────────────── */

.live-col-right {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: 1rem;
}

.live-table-title {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--muted);
    margin: 0 0 .75rem;
}

/*
 * Una tabla ancha SCROLLEA adentro de su caja; no colapsa las columnas hasta apilarse. Mismo
 * patron que .live-actions-scroll del panel. Sin esto, en cuanto la ventana se angosta el
 * navegador reparte el ancho que falta rompiendo las celdas en varias lineas y la tabla deja
 * de leerse como tabla.
 */
.live-table-scroll { overflow-x: auto; }

.live-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .9rem;
}

/* El piso a partir del cual scrollea en vez de estrujarse. */
.live-table-scroll .live-table { min-width: 44rem; }

.live-table th {
    text-align: left;
    font-weight: 500;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
    border-bottom: 1px solid var(--line);
    padding: .35rem .5rem;
}

.live-table td {
    padding: .45rem .5rem;
    border-bottom: 1px solid rgba(40, 50, 59, .55);
}

.live-table tr:last-child td { border-bottom: none; }

.live-col-quality { text-align: center; }

.live-q {
    display: inline-block;
    min-width: 1.6rem;
    text-align: center;
    font-weight: 700;
    font-size: 1.05rem;
}

.live-q-dp { color: var(--q-dp); }
.live-q-p  { color: var(--q-p); }
.live-q-ex { color: var(--q-ex); }
.live-q-sl { color: var(--q-sl); }
.live-q-n  { color: var(--q-n); }
.live-q-dn { color: var(--q-dn); }
.live-q-null { color: var(--q-null); }

.live-detail-cell {
    color: var(--muted);
    font-size: .8rem;
}

/* ── Resumen de partido ───────────────────────────────────────────────────── */

/* Tarjetas que se acomodan solas: en monitor entran dos por fila, en tablet una. */
.live-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: .75rem;
    align-items: start;
    margin-top: 1rem;
}

.live-summary .live-surface { margin: 0; }

.live-summary textarea.live-input { resize: vertical; min-height: 5rem; }

/* ── Paginacion ───────────────────────────────────────────────────────────── */

.live-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    margin-top: 1rem;
}

.live-pager .btn-live {
    min-width: 2.4rem;
    text-align: center;
    text-decoration: none;
}

/* Los extremos sin a donde ir: se ven apagados y no responden. Un enlace que parece activo y
   no hace nada se lee como un bug. */
.live-pager .btn-live-off { opacity: .35; pointer-events: none; }

.live-pager-total {
    margin-left: auto;
    color: var(--muted);
    font-size: .8rem;
}

/* Partido definido: donde estaba el boton de agregar set. Dato, no accion. */
.live-match-done {
    font-family: 'Space Mono', ui-monospace, Consolas, monospace;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
    padding: .45rem .85rem;
}

.live-empty {
    color: var(--muted);
    text-align: center;
    padding: 1.5rem 0;
}

/* ── Botones de jugador ───────────────────────────────────────────────────── */

/*
 * El ROL va grande, no en letra chica. El operador no conoce a los jugadores por el
 * apellido: se guia por el rol, y en el sacador inicial ese numero define la rotacion de
 * todo el set. Que sea lo primero que se lee no es estetica, es prevencion de error.
 */
.btn-player {
    display: flex;
    align-items: center;
    gap: .6rem;
    text-align: left;
    padding: .55rem .7rem;
    min-width: 0;
    flex: 1 1 0;
}

.btn-player-role {
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1;
    color: var(--lime-ink);
    min-width: 1.4rem;
    text-align: center;
}

.btn-player-text { min-width: 0; }

.btn-player-name {
    display: block;
    font-size: .95rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.btn-player-pos {
    display: block;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
}

.btn-live-sel .btn-player-pos { color: inherit; }

/* Fila de atacantes. El orden lo decide el JS (`playersOfTeam`): rol 4 a la izquierda con la
   dupla cercana, espejado con la de enfrente. */
.live-players-row {
    display: flex;
    gap: .5rem;
}

/* Caja con la red del lado que le toca: arriba si la dupla es la cercana, abajo si es la de
   enfrente. Mismo truco de column-reverse que la cancha, misma lectura. La usan la fila de la
   dupla, las zonas de saque y las cartas de bloqueo/defensa. */
.live-net-group {
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.live-net-group-top { flex-direction: column-reverse; }

.live-net-group .live-net { margin-top: 0; }

/* ── Cancha ───────────────────────────────────────────────────────────────── */

/* Hereda el width:fit-content de .live-court: rotada tiene que seguir midiendo lo que mide la
   grilla, o la red al 100% se estira al ancho del cuadrante y deja de marcar donde esta. */
.live-court-net-top { display: flex; flex-direction: column-reverse; }

.live-court-caption {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--muted);
    margin-top: .25rem;
}

/* ── Carga paso a paso ────────────────────────────────────────────────────── */
/*
 * Un solo grupo en pantalla por vez. El beneficio no es ahorrar taps —son los mismos— sino
 * que cada boton entra al doble de tamano: la carga se hace de pie, en tablet, con una mano
 * y mirando la cancha. Con los cinco grupos a la vez hay que buscar con la vista en cada
 * paso, y eso se paga en cada punto del partido.
 */

.live-crumbs {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    align-items: center;
    margin: .35rem 0 .6rem;
    min-height: 1.9rem;
}

/*
 * Cada item vuelve A ESE paso sin perder los demas. Sin esto, equivocarse en el paso 1
 * obliga a cancelar todo el rally, que es peor que el error que se quiso corregir.
 */
/* El unico tocable que queda bajo los 44px, y es deliberado: el breadcrumb se usa para
   corregir, no para cargar. A 44px se llevaria esa altura de TODAS las pantallas, todo el
   tiempo, para un control que se toca de vez en cuando. 36px con aire a los costados. */
.live-crumb {
    font-family: 'Space Mono', ui-monospace, Consolas, monospace;
    font-size: .8rem;
    padding: .3rem .7rem;
    min-height: 2.25rem;
    border-radius: 1rem;
    color: var(--bone);
    background: rgba(40, 50, 59, .5);
    border: 1px solid var(--line);
    white-space: nowrap;
}

/* El sacador no se elige: sale de la rotacion. Se muestra, no se toca. */
.live-crumb-fixed {
    display: inline-block;
    color: var(--muted);
    border-style: dashed;
}

.live-crumb-here { border-color: var(--muted); }

.live-crumb-reset { color: var(--muted); background: none; }

.live-step-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: .5rem;
}

.live-step-title {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--muted);
}

.live-step-skip { font-size: .8rem; }

/* Los botones del paso: grandes de verdad. auto-fit reparte el ancho completo entre los que
   haya, asi que dos opciones dan dos botones enormes y seis dan seis usables. */
.live-step-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: .6rem;
}

.btn-step {
    min-height: 5.5rem;
    font-size: 1.35rem;
    font-weight: 600;
    padding: .75rem;
}

.btn-step.btn-player {
    flex-direction: column;
    gap: .2rem;
    justify-content: center;
}

.btn-step .btn-player-role { font-size: 3rem; }

.btn-step.btn-q { font-size: 2.4rem; }

/* Celda = boton + ayuda. La ayuda es hermana del boton y no hija: adentro lo deformaba, y un
   boton que cambia de alto segun cuanto mida su palabra rompe la fila entera. */
.live-q-cell {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: .2rem;
    min-width: 0;
}

.live-q-cell .btn-q { width: 100%; }

/* Que es esa calidad EN ESE FUNDAMENTO. En bone y mayusculas, como la tabla de acciones:
   tiene que leerse de un vistazo, no ser una nota al pie. */
.live-q-hint {
    font-size: .62rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--bone);
    text-align: center;
    line-height: 1.15;
}

.live-step-qualities { grid-template-columns: repeat(auto-fit, minmax(5rem, 1fr)); }

/* ── Bloqueo / defensa: jugador y calidad en la misma carta ───────────────── */
/*
 * Un tap en vez de dos. La sugerencia ya dice quien bloquea y quien defiende, asi que lo
 * unico que falta es la calidad: va debajo de cada jugador y se registra al tocarla.
 */

/* Apiladas, no lado a lado: en la cancha el bloqueador esta contra la red y el defensor en el
   fondo, y esa distancia es informacion. El orden lo decide el JS a partir de que lado esta
   la dupla; aca solo se apilan. */
.live-pick {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.live-pick-card {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: .6rem;
}

/* Apiladas, la carta tiene todo el ancho: el jugador va al costado de sus calidades y no
   arriba. Apilar gasta alto, que es lo escaso en tablet horizontal, y esto lo devuelve. */
.live-pick-card {
    display: flex;
    align-items: center;
    gap: .75rem;
}

/* Encabezado: identifica, no se toca. Sin cursor ni hover, para que no se lea como boton. */
.live-pick-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    flex: 0 0 9rem;
    min-width: 0;
}

.live-pick-head .btn-player-role { font-size: 2.2rem; }
.live-pick-head .btn-player-name { overflow: hidden; text-overflow: ellipsis; }

/* Con la carta a lo ancho, sin tope los seis botones se estiran hasta quedar enormes y la
   escala deja de leerse como escala. */
.live-pick-card .live-step-qualities {
    flex: 1 1 auto;
    grid-template-columns: repeat(auto-fit, minmax(3.6rem, 5.5rem));
    justify-content: center;
    gap: .35rem;
}

.live-pick-card .btn-step.btn-q {
    min-height: 3.4rem;
    padding: .4rem .2rem;
    font-size: 1.8rem;
}

.live-step-extras { margin-top: .6rem; gap: .5rem; }

/* Lado x marca: cada lado es una columna con su encabezado tocable y sus dos marcas debajo.
   El encabezado ES el lado sin marca; el medio no lleva marcas y su columna termina ahi. */
.live-side-grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: .4rem;
    align-items: start;
}

.live-side-col { display: flex; flex-direction: column; gap: .3rem; }

.live-side-marks { display: flex; gap: .3rem; }

.live-side-marks .btn-side { flex: 1 1 0; min-width: 0; }

.btn-side { min-height: 3.2rem; font-size: .85rem; padding: .4rem .2rem; }

/* El titulo del lado es un ROTULO: nombra la columna, no se toca. Sin borde ni fondo, para
   que no se lea como un boton que no responde. */
.live-side-head {
    font-family: 'Space Mono', ui-monospace, Consolas, monospace;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
    text-align: center;
    padding: .15rem 0;
}

/* ── Ataque: atacante + lado + marca en una pantalla ──────────────────────── */

/* Los dos atacantes apilados, no lado a lado: se lee como la cancha, y cada uno se lleva el
   ancho completo para sus tres lados. El que no es de 2da va arriba (lo ordena el JS). */
.live-attack-cols {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.live-attack-col { min-width: 0; }

/* Separador entre atacantes: divide sin competir con la linea de red, que es la unica lima. */
.live-attack-col + .live-attack-col {
    border-top: 1px solid var(--line);
    padding-top: .5rem;
}

/* Rotulo, no boton: nombra al atacante. Lo tocable son las marcas y el CARGAR del medio. */
.live-attack-name {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-bottom: .35rem;
    min-width: 0;
}

.live-attack-name .btn-player-pos { flex: 0 0 auto; }

.live-attack-name .btn-player-role { font-size: 1.8rem; }
.live-attack-name .btn-player-name { overflow: hidden; text-overflow: ellipsis; }

/* "2DA" al lado del nombre: dice quien NO toco primero sin que haya que leer dos botones. */
.live-attack-ontwo {
    font-family: 'Space Mono', ui-monospace, Consolas, monospace;
    font-size: .65rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--lime-ink);
    border: 1px solid var(--line);
    border-radius: 1rem;
    padding: .1rem .45rem;
    flex: 0 0 auto;
}

/* Con las cuatro combinaciones el interruptor alterna las dos columnas a la vez, en vez de
   duplicarlas. El de rejuego lo acompana y va siempre: los dos en el mismo renglon y en el
   mismo orden, que es lo que permite tocarlos sin mirar. */
.live-attack-toggle { margin-bottom: .5rem; }

/* Con el rejuego encendido la columna del jugador colapsa a un solo blanco del ancho completo:
   el rejuego no lleva lado ni marca, asi que no hay nada mas que elegir de ese jugador. */
.btn-attack-replay { width: 100%; min-height: 3.2rem; font-size: 1rem; }

/* ── Elegir vs registrar ──────────────────────────────────────────────────── */
/*
 * La regla de toda la carga: ARRIBA SE ELIGE, ABAJO SE REGISTRA.
 *
 * Hasta que existio esta distincion, un boton que marcaba y uno que cerraba la carga se veian
 * identicos, y tocar una zona esperando elegirla mandaba la accion. Se aprende una vez y vale
 * para las cuatro pantallas: si esta relleno y abajo, cierra.
 *
 * LA CANCHA DE ATAQUE PASO A REGISTRAR, y la regla se sostiene igual. Sus dos mitades van
 * RELLENAS —lo relleno cierra— y lo que las distingue es el borde: entero el remate, punteado el
 * toque. El punteado dice el golpe, el relleno dice que cierra; son dos ejes y no uno
 * reinterpretado. Y en esa pantalla ya no queda un solo selector: la fila Remate/Toque se fue
 * adentro de la celda, asi que la confusion que esta regla protege ahi no puede darse.
 */

.live-pick-row {
    display: flex;
    gap: .5rem;
    margin-bottom: .4rem;
}

/* Selector: borde y fondo transparente. Marcado, pasa a lima (btn-live-sel, comun al sistema). */
.btn-pick {
    flex: 1 1 0;
    min-height: 2.75rem;
    font-size: 1rem;
    background: none;
}

/* La fila que REGISTRA: tres ranuras fijas, siempre abajo y siempre en el mismo orden —sigue,
   punto nuestro, punto de ellos—. El saque deja la primera vacia y por eso su ACE cae donde
   cae el PUNTO DIRECTO del ataque. */
.live-outcome-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .5rem;
    margin-top: .5rem;
}

.live-outcome-gap { visibility: hidden; }

.btn-commit { min-height: 3.2rem; font-size: 1rem; font-weight: 600; }

.live-hint {
    color: var(--muted);
    font-size: .75rem;
    margin-top: .5rem;
}

/* El sacador se corrige desde el breadcrumb; corregido, se marca para que no pase inadvertido. */
.live-crumb-fix { border-style: dashed; color: var(--bone); }

.live-crumb-fix-on {
    border-style: solid;
    border-color: var(--lime);
    color: var(--lime-ink);
}

/* La zona de destino es el detalle que mas se carga y el que peor se toca: nueve blancos
   chicos, de pie y con una mano. En el paso propio la cancha vale el doble de lado.

   El ANCHO subio de 6.5rem a 7.5rem porque ahora lo que se toca es LA MITAD de la celda: con la
   celda vieja cada mitad quedaba por debajo de los 44px de minimo tactil.

   Y el tope dejo de ser `dvh`. Estaba atado al ALTO de la ventana porque antes la celda no tenia
   alto propio —lo daba su padding— y nueve de 6.5rem no entraban acostado. Desde que cada mitad
   declara su `min-height`, el alto ya esta protegido por su cuenta, y seguir atando el ancho al
   alto solo lograba que la tablet ACOSTADA —que tiene ancho de sobra y es donde el dedo va mas
   apurado— cayera a 44px justos. Ahora el ancho se protege contra el ancho: `26vw` es lo que
   deja tres celdas mas su aire en la pantalla mas angosta. */
.live-step .live-zone {
    grid-template-columns: repeat(3, min(7.5rem, 26vw));
    gap: .4rem;
    padding: .5rem;
}

.live-step .live-zone .btn-live {
    padding: min(1.5rem, 2.4dvh) 0;
    font-size: 1.5rem;
    font-weight: 600;
}

/* Cada zona es UNA celda partida en dos mitades verticales: remate a la izquierda, toque a la
   derecha. SIN hueco entre ellas: un gap en el medio de la celda es una franja muerta justo
   donde apunta el dedo que busca el numero. La separacion que si importa —"son dos blancos, no
   una franja", la leccion que dejo el rejuego pegado a su marca— la da el gap entre celdas. */
.live-zone-cell {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
}

/* El numero, una vez por celda y encima de las dos mitades. `pointer-events: none` es lo que
   permite tocar A TRAVES de el: sin eso el centro de la celda —que es donde el ojo apunta— no
   registraria nada. */
.live-zone-num {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    pointer-events: none;
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--bone);
}

/* `min-height` explicito y no solo padding: las mitades no llevan texto adentro, y un boton
   vacio no genera caja de linea — con el padding solo, la cancha entera colapsa a tres rayas.
 *
 * Va calificado con `.live-zone` a proposito: `.live-zone .btn-live` es (0,2,0) y le pisaria el
 * fondo a una clase suelta sin un solo error a la vista. */
.live-zone .btn-zone-half {
    min-height: min(3.6rem, 6.6dvh);
    border-radius: 0;
}

/* Remate: relleno lima y borde entero. Toque: relleno oscuro y borde punteado.
 *
 * LAS DOS ESTAN RELLENAS, y es deliberado: por la regla de aca arriba lo relleno REGISTRA, y
 * estas dos registran. Una mitad con fondo transparente se leeria como selector —como
 * `.btn-pick`— y el operador esperaria un segundo tap que ya no existe. El punteado distingue el
 * golpe, el relleno dice que cierra: son dos ejes, no uno reinterpretado. */
.live-zone .btn-zone-spike {
    background: rgba(203, 255, 77, .14);
    border-color: rgba(203, 255, 77, .3);
    border-right: none;
    border-radius: .3rem 0 0 .3rem;
}

.live-zone .btn-zone-tip {
    background: rgba(16, 20, 24, .5);
    border-style: dashed;
    border-radius: 0 .3rem .3rem 0;
}

/* Que es cada mitad. Dos muestras y no una frase: es lo unico nuevo que hay que aprender de esta
   pantalla, y se tiene que poder mirar de reojo sin dejar de mirar la cancha. */
.live-zone-legend {
    display: flex;
    justify-content: center;
    gap: 1rem;
    margin-bottom: .4rem;
    font-size: .7rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .08em;
}

.live-zone-key { display: flex; align-items: center; gap: .35rem; }

.live-zone-key-box { width: .9rem; height: 1.2rem; border-radius: .2rem; }

.live-zone-key-spike {
    background: rgba(203, 255, 77, .14);
    border: 1px solid rgba(203, 255, 77, .3);
}

.live-zone-key-tip {
    background: rgba(16, 20, 24, .5);
    border: 1px dashed var(--line);
}

/* ── Muneco de recepcion ──────────────────────────────────────────────────── */
/*
 * Los 4 cuadrantes en el lugar donde pasan, no en una fila de cuatro botones con el nombre
 * escrito. Misma geometria que el mapa de recepcion del reporte (docs/08 §3).
 */

/* Los dos munecos de la dupla, uno por jugador. Cada uno ES su receptor, asi que elegir
   jugador y cuadrante es un solo tap. */
.live-figures {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .75rem;
    align-items: start;
}

.live-figure { text-align: center; }

/*
 * El tamano sale del ALTO de la ventana, no de un ancho fijo.
 *
 * Con `max-width: 18rem` a secas, dos munecos mas sus nombres miden ~300px de alto y en
 * horizontal el paso dispone de unos 470: el saque desbordaba y habia que scrollear. Como el
 * ancho manda el alto —el SVG conserva su proporcion—, limitarlo en `dvh` lo achica solo
 * cuando la pantalla es baja y lo deja grande cuando sobra alto. Sin breakpoint y sin salto.
 */
.live-figure-svg {
    width: 100%;
    max-width: min(18rem, 24dvh);
    height: auto;
    touch-action: manipulation;
}

/* El numero de rol, adelante del nombre. Comparte renglon con el —el rotulo tiene
   `white-space: nowrap` y no se puede partir— asi que va mas chico que el del boton de
   jugador (`.btn-player-role`), del que hereda el lima y el peso. */
.live-figure-role {
    display: inline-block;
    margin-right: .35rem;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1;
    color: var(--lime-ink);
}

/* El nombre identifica al muneco y ademas carga "este receptor, sin cuadrante". */
.live-figure-name {
    width: 100%;
    min-height: 2.75rem;
    margin-top: .2rem;
    font-size: .95rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
}

.live-figure-target {
    fill: rgba(198, 255, 61, .10);
    stroke: var(--line);
    stroke-width: 1;
    cursor: pointer;
}

.live-figure-target:hover, .live-figure-target:active {
    fill: rgba(198, 255, 61, .28);
    stroke: var(--lime);
}

/* La silueta es referencia visual, no un blanco mas: los taps la atraviesan y caen en el
   cuadrante que hay debajo. Sin esto, tocar "sobre el cuerpo" no registra nada. */
.live-figure-body {
    pointer-events: none;
    stroke: var(--lime);
    stroke-width: 2.6;
    stroke-linecap: round;
    fill: none;
}

.live-figure-head { fill: var(--lime); stroke: none; }

.live-figure-label {
    fill: var(--bone);
    font-size: 5px;
    text-anchor: middle;
    text-transform: uppercase;
    cursor: pointer;
}

/* ── Entre rallies ────────────────────────────────────────────────────────── */
/*
 * :not([hidden]) porque el display:flex de abajo le ganaria al atributo hidden y el cartel
 * quedaria visible en todos los demas estados de la maquina.
 *
 * Hoy la regla global de site.css (`[hidden] { display: none !important }`) ya lo cubre —se
 * agrego cuando el mismo problema aparecio en los botones—, asi que esto es cinturon y
 * tiradores. Se deja porque documenta el riesgo justo donde vuelve a aparecer.
 */
#live-state-closed:not([hidden]) {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: .75rem;
    min-height: 60%;
}

#live-state-closed > * { width: 100%; max-width: 26rem; margin: 0; }

.live-wide-step .live-winner { font-size: 2rem; }

/*
 * Pantalla baja: se achica la TIPOGRAFIA y el aire, nunca el blanco. El piso de 2.75rem del
 * bloque de botones sigue valiendo aca — antes este bloque lo bajaba hasta 1.9rem (30px), y un
 * blanco de 30px de pie y con una mano es un tap perdido cada tantos puntos.
 */
@media (max-height: 40rem) {
    .btn-step { min-height: 4rem; font-size: 1.1rem; }
    .btn-step .btn-player-role { font-size: 2.2rem; }
    .live-step .live-zone .btn-live { padding: .6rem 0; font-size: 1.2rem; }
    .live-zone-num { font-size: 1.2rem; }
    .live-zone-legend { font-size: .62rem; margin-bottom: .25rem; }
    .live-figure-name { font-size: .85rem; padding: .35rem .5rem; }
    .live-wide-step .live-winner { font-size: 1.4rem; }

    /* Las dos cartas con sus calidades y sus ayudas tienen que entrar sin scroll: es la
       pantalla mas cargada del panel. */
    .live-pick-card { padding: .45rem; gap: .5rem; }
    .live-pick-head { flex-basis: 7rem; }
    .live-pick-head .btn-player-role { font-size: 1.7rem; }
    .live-attack-col + .live-attack-col { padding-top: .35rem; }
    .btn-side { font-size: .75rem; }
    .btn-attack-replay { min-height: 2.9rem; font-size: .9rem; }
    .live-side-head { font-size: .68rem; }
    .live-attack-name .btn-player-role { font-size: 1.4rem; }
    .btn-pick { font-size: .82rem; }
    .live-pick-row { margin-bottom: .3rem; }
    .live-outcome-row { margin-top: .35rem; }
    .btn-commit { font-size: .88rem; }
    .live-pick-card .btn-step.btn-q { min-height: 2.8rem; font-size: 1.5rem; }
    .live-q-hint { font-size: .58rem; letter-spacing: .04em; }
}

/* ══════════════════════════════════════════════════════════════════════════════
 * LENGUAJE DE DATOS — grillas, tarjetas y filtros
 *
 * Todo lo que no es la carga en vivo comparte esta gramatica: resumen de partido,
 * multiselector de reportes y las cuatro grillas de entidades. Un solo lugar, para que no
 * pase lo de siempre: cada pantalla con su propio borde, su propio radio y su propio gris.
 * ══════════════════════════════════════════════════════════════════════════════ */

/* ── Tarjeta ──────────────────────────────────────────────────────────────── */

.live-card {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: 1rem 1.1rem;
}

.live-card + .live-card { margin-top: 1rem; }

.live-card-title {
    font-family: var(--font-mono, inherit);
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--muted);
    margin: 0 0 .75rem;
    font-weight: 500;
}

/* Rejilla de tarjetas que se acomoda sola: sin breakpoints a mano, que es de donde salen
   las pantallas que se rompen en un ancho que nadie probo. */
.live-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

/*
 * EL MARGEN DE APILADO NO VA ADENTRO DE LA REJILLA, y el sintoma era raro de leer.
 *
 * `.live-card + .live-card` existe para las tarjetas apiladas una debajo de otra. Adentro de
 * `.live-cards` la segunda sigue siendo hermana de la primera, asi que se comia el margen igual
 * —pero ahi el margen no separa nada: empuja la tarjeta 1rem hacia abajo DENTRO de su celda y,
 * como la rejilla estira los items, la deja 1rem mas baja. Resultado: dos duplas con el mismo
 * ancho, el mismo pie y distinto alto y arranque. Se leia como un problema de contenido —un
 * nombre mas largo, un boton apagado— y no lo era.
 *
 * Va con el selector COMPLETO, tres clases contra dos, porque si no pierde por especificidad
 * aunque venga despues (la misma leccion que el `min-width` del detallado, §26).
 */
.live-cards > .live-card + .live-card { margin-top: 0; }

/* ── Dato destacado ───────────────────────────────────────────────────────── */

.live-stat { display: flex; flex-direction: column; gap: .15rem; }

.live-stat-label {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--muted);
}

.live-stat-value {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
}

.live-stat-value-lg { font-size: clamp(2.2rem, 5vw, 3rem); }

.live-stats-row {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem 2.5rem;
}

/* ── Filtros ──────────────────────────────────────────────────────────────── */

/* Los filtros van en fila y se envuelven: apilados en columna, un formulario de seis campos
   empuja la tabla de resultados fuera de la pantalla y deja de verse sobre que se filtra. */
.live-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .75rem;
}

.live-filters .live-field {
    margin-bottom: 0;
    flex: 1 1 10rem;
    min-width: 8rem;
}

/* La base es el MINIMO antes de envolver, no el ancho: como es el unico que crece, en cuanto
   sobra lugar se lleva todo el sobrante igual. Con 18rem, siete campos no entraban en un
   renglon ni en 1920. */
.live-filters .live-field-wide { flex: 2 1 11rem; }

/*
 * El campo que NO crece. Los de la fila se reparten el sobrante con `flex-grow: 1`, asi que el
 * ultimo de un renglon con lugar libre se lo lleva todo: el desplegable de viento —que muestra
 * "Sin viento"— terminaba con el ancho de media pantalla.
 *
 * Para un contenido de largo conocido —una fecha, tres opciones de clima— el ancho tiene que
 * salir del contenido y no del hueco que quedo.
 */
.live-filters .live-field-fixed { flex: 0 1 12rem; }

/*
 * La escala corta, para que los siete filtros del reporte entren en UN renglon.
 *
 * `live-field-fixed` son 12rem, que es lo que pide un desplegable con texto largo; para una
 * fecha es hueco y para "Set" —cuyo contenido es un digito— es el triple. Sumados, esos anchos
 * de mas eran los que partian la fila en dos.
 *
 * El `min-width: 0` es necesario: `.live-filters .live-field` declara `min-width: 8rem` y sin
 * pisarlo el `xs` no puede bajar de ahi, que es justo lo que se le esta pidiendo.
 */
.live-filters .live-field-sm { flex: 0 1 8.5rem; min-width: 0; }
.live-filters .live-field-xs { flex: 0 1 6.5rem; min-width: 0; }

.live-filters .live-field-action { flex: 0 0 auto; }

/* ── Acciones de fila ─────────────────────────────────────────────────────── */

/* En una grilla los botones son secundarios: la fila es el dato. Con el tamaño de la carga en
   vivo —pensado para el dedo, a un metro y con sol— dos botones por fila empujan la tabla al
   scroll horizontal con tres registros cargados. */
.live-row-actions {
    display: flex;
    gap: .35rem;
    justify-content: flex-end;
    white-space: nowrap;
}

.btn-live-sm {
    font-size: .78rem;
    padding: .3rem .6rem;
    border-radius: .4rem;
}

.btn-live-danger { color: var(--q-n); }

.btn-live-danger:hover:not(:disabled) { border-color: var(--q-n); }

/* ── Grilla ───────────────────────────────────────────────────────────────── */

/* El piso baja de 44rem a 34rem. Con 44 una tabla de cinco columnas scrolleaba de costado en
   tablet vertical teniendo tres filas: el scroll aparecia por el minimo, no por el contenido.
   `overflow-x` sigue puesto como valvula para las tablas que de verdad no entran. */
.live-table-scroll .live-table { min-width: 34rem; }

.live-table tbody tr:hover { background: rgba(40, 50, 59, .35); }

/* La columna de acciones no se estira ni se parte en dos lineas. */
.live-table td.live-row-actions-cell {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

/* La fila que se esta editando queda marcada: sin esto el formulario de arriba se llena solo
   y no hay manera de saber cual de las filas es. */
.live-table tr.is-editing { background: rgba(198, 255, 61, .07); }

.live-table tr.is-editing td:first-child { box-shadow: inset .18rem 0 0 var(--lime); }

/* ── Marcador del resumen ─────────────────────────────────────────────────── */

/*
 * El resumen abre con el resultado, grande y a los dos lados. Antes abria con una linea de
 * texto donde el marcador era un `<strong>` mas: para saber quien gano habia que leer, y el
 * resumen de un partido es lo primero que se abre despues de cargarlo.
 */
.live-scoreboard {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: 1.25rem 1.1rem;
    margin-bottom: 1rem;
}

.live-score-team { min-width: 0; }

/* La dupla de la derecha se lee hacia adentro: las dos apuntan al marcador del medio. */
.live-score-team-right { text-align: right; }

.live-score-name {
    font-size: clamp(1.05rem, 2.2vw, 1.45rem);
    font-weight: 700;
    margin: 0 0 .2rem;
    overflow-wrap: anywhere;
}

.live-score-players {
    color: var(--muted);
    font-size: .85rem;
    margin: 0;
    overflow-wrap: anywhere;
}

/* El ganador se marca con el lima de la marca. Es el unico lugar del resumen donde aparece:
   si estuviera tambien en los botones, dejaria de significar "gano". */
.live-score-team-won .live-score-name { color: var(--lime-ink); }

.live-score-sets {
    font-size: clamp(2.4rem, 7vw, 3.6rem);
    font-weight: 700;
    line-height: 1;
    letter-spacing: .02em;
    white-space: nowrap;
}

/* Con un set en juego el numero grande son sus puntos y los sets ganados bajan aca. Es texto
   de apoyo: dice de que set son los puntos de arriba, no compite con ellos. */
.live-score-block { text-align: center; }

.live-score-sub {
    color: var(--muted);
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    margin: .25rem 0 0;
    white-space: nowrap;
}

/* Pantalla angosta: el marcador pasa arriba y las duplas quedan una debajo de la otra, las
   dos alineadas a la izquierda. En tres columnas de 1fr sobre 320px los nombres se parten
   letra por letra. */
@media (max-width: 34rem) {
    .live-scoreboard { grid-template-columns: 1fr; text-align: left; }
    .live-score-team-right { text-align: left; }

    /* El que sube es el bloque cuando existe, y el numero suelto cuando no: sin la regla del
       bloque, el marcador del set en juego se quedaba abajo de las dos duplas. */
    .live-score-sets, .live-score-block { order: -1; }
    .live-score-block { text-align: left; }
}

/* ── Sets como fichas ─────────────────────────────────────────────────────── */

.live-set-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.live-set-chip {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .1rem;
    border: 1px solid var(--line);
    border-radius: .5rem;
    padding: .5rem .8rem;
    text-decoration: none;
    color: var(--bone);
    min-width: 4.5rem;
}

.live-set-chip:hover { border-color: var(--grid); }

.live-set-chip-label {
    font-size: .62rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--muted);
}

.live-set-chip-score { font-size: 1.15rem; font-weight: 700; }

/* El set abierto es donde se sigue cargando: es la accion, no un dato mas. */
.live-set-chip-open {
    border-color: var(--lime);
    box-shadow: inset 0 0 0 1px var(--lime);
}

.live-set-chip-open .live-set-chip-score { color: var(--lime-ink); font-size: .95rem; }

/* ── Cambio de lado de recepcion ──────────────────────────────────────────── */

/*
 * El control va ARRIBA de los dos munecos y alineado a la derecha: es una excepcion, no un
 * paso. Puesto en el medio o a tamaño de blanco competiria con los cuadrantes, que son lo que
 * se toca en todos los puntos menos en estos.
 */
.live-reception-picker {
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.live-swap {
    align-self: flex-end;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);

    /* Piso de blanco: es chico en peso visual, no en superficie tocable. Se toca de pie, con
       una mano y apurado, igual que todo lo demas del panel. */
    min-height: 2.2rem;
}

.live-swap.btn-live-sel { color: var(--night); }

/* ── Bloque de jugador del reporte ────────────────────────────────────────── */

/*
 * Un reporte se lee jugador por jugador, asi que cada uno tiene que leerse como una UNIDAD y
 * no como una tabla mas de la lista. La separacion es una linea y aire: suficiente para que el
 * ojo sepa donde termina uno, sin encerrar media pagina en una caja.
 */
.live-player-block {
    padding-top: 1.75rem;
    margin-top: 1.75rem;
    border-top: 1px solid var(--line);
}

/* El primero arranca pegado al contexto de la dupla: ahi no hay nada de que separarlo. */
.live-player-block:first-of-type {
    padding-top: .5rem;
    margin-top: .5rem;
    border-top: none;
}

/*
 * El corte por jugador depende de LA VISTA.
 *
 * En el one-pager grafico la meta es una A4 por jugador (`docs/08` §6), asi que cada bloque
 * empieza en hoja nueva. En el detallado no: son ocho tablas por jugador y el corte forzado deja
 * la ultima hoja de cada uno a medio llenar, que es justo lo que se venia a arreglar. Ahi el
 * contenido corre y lo unico que se protege es que no se parta una fila.
 */
@media print {
    .live-view-general .live-player-block { break-before: page; }
    .live-view-general .live-player-block:first-of-type { break-before: auto; }
}

/* ── Semaforo del reporte ─────────────────────────────────────────────────── */

/*
 * Los cortes los decide EfficiencyScale, en el dominio y por fundamento. Aca solo vive el
 * color: si la banda se calculara en el CSS o en la vista, el mismo numero saldria de un color
 * en la tabla y de otro en el mapa.
 *
 * Se pinta el TEXTO y un fondo muy leve, no la celda entera: con la celda pintada, una tabla de
 * treinta filas se lee como un tablero de ajedrez y el numero deja de leerse.
 */
.live-eff { font-variant-numeric: tabular-nums; }

.eff-good { color: var(--q-dp); background: rgba(87, 200, 107, .10); }
.eff-fair { color: var(--band-fair); background: rgba(232, 210, 78, .10); }
.eff-low  { color: var(--q-sl); background: rgba(232, 147, 62, .10); }
.eff-bad  { color: var(--q-n);  background: rgba(238, 96, 85, .10); }

/* Sin acciones no hay banda: un 0% de cero pelotas pintado de rojo dice "anduvo pesimo" donde
   el dato es "no paso nunca". */
.eff-none { color: var(--muted); }

/* Las columnas de distribucion son angostas y numericas: alineadas y sin estirarse. */
.live-col-quality,
.live-col-count {
    text-align: center;
    width: 1%;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* El selector de calidad de la planilla de revision: angosto y del color de su calidad, para
   que la columna se pueda barrer con la vista igual que en el panel de carga. */
.live-q-select {
    min-width: 9rem;
    padding: .25rem .4rem;
    font-weight: 700;
}

/*
 * Un paso que todavia no se puede tocar: apagado y sin recibir clicks, pero A LA VISTA.
 * Esconderlo hace que la pantalla cambie de forma sola y el operador lea "desaparecio" en vez
 * de "me falta un tap".
 */
.live-disabled {
    opacity: .3;
    pointer-events: none;
    filter: grayscale(1);
}

/* ══════════════════════════════════════════════════════════════════════════════
 * REPORTE — esqueleto de columnas y bloques por fundamento
 * ══════════════════════════════════════════════════════════════════════════════ */

/*
 * Las ocho tablas del reporte comparten esqueleto: Concepto | Efic | Total | # + ! / - = |
 * extras. `table-layout: fixed` con anchos declarados es lo que hace que `Efic` arranque en el
 * MISMO pixel en todas — sin eso el navegador reparte el ancho segun el contenido y dos tablas
 * con las mismas columnas igual se desalinean.
 *
 * Por eso tambien las dimensiones van en UNA sola celda ("Bueno · Z1 · Remate"): con tres
 * columnas en una tabla y una en otra, ninguna regla de ancho las puede alinear.
 */
.live-report-table {
    table-layout: fixed;
    min-width: 42rem;
}

/*
 * Los anchos suman 41.2rem = 659px, y el ancho util de una A4 son 703px: el reparto de la
 * pantalla entra tal cual en el papel, que es lo que deja usar `table-layout: fixed` en los dos
 * lados — y por lo tanto tener `Efic` en el mismo lugar en las ocho tablas.
 *
 * Cuando entro `Eficacia` el reparto viejo sumaba 42.3rem y no daba. Se recorto del CONCEPTO y de
 * las calidades —que son anchos con aire— y no de la tipografia: §27 ya fijo que un desglose que
 * no se lee no se usa. Lo mismo al entrar `Eficacia ataque`, que lleva a las tablas de recepcion a
 * TRES columnas extra: 8.4 + 4.2 + 4.2 + 3.6 + 6x2.1 + 3x3.6 = 43.8rem = 701px, justo adentro.
 *
 * `live-col-count` es columna propia y no una de calidad: con 2.6rem la palabra "CANTIDAD" del
 * encabezado se partia en dos renglones, y ese renglon de mas en cada tabla costaba una hoja
 * entera en el PDF.
 */
.live-report-table .live-col-concept  { width: 8.4rem; }
.live-report-table .live-col-eff      { width: 4.2rem; }
.live-report-table .live-col-efficacy { width: 4.2rem; }
.live-report-table .live-col-count    { width: 3.6rem; }
.live-report-table .live-col-quality  { width: 2.1rem; }
.live-report-table .live-col-extra    { width: 3.6rem; }

/* El concepto puede ser largo ("Bueno · Z1 · Remate") y no puede empujar al resto. */
.live-report-table .live-col-concept {
    overflow-wrap: anywhere;
    white-space: normal;
}

/*
 * Los titulos de las columnas numericas van CENTRADOS sobre su numero. `.live-table th` los
 * alinea a la izquierda —bien para el concepto, que es texto— y eso dejaba el `#` pegado al
 * borde izquierdo de una columna de 2.6rem con el conteo centrado abajo: el ojo tiene que
 * decidir a que columna pertenece cada rotulo.
 */
.live-report-table th.live-col-eff,
.live-report-table th.live-col-efficacy,
.live-report-table th.live-col-quality,
.live-report-table th.live-col-count,
.live-report-table th.live-col-extra,
.live-report-table td.live-col-eff,
.live-report-table td.live-col-efficacy,
.live-report-table td.live-col-extra {
    text-align: center;
}

/* La fila que es una PORCION de la de arriba (K1 sin 2da, K2 solo de 2da). */
.live-report-table .live-concept-sub {
    padding-left: 1.25rem;
    color: var(--muted);
}

/* ── Bloques ──────────────────────────────────────────────────────────────── */

/*
 * Un contenedor por fundamento adentro de cada jugadora, como el legacy. Sin esto el general
 * queda en tarjeta y las tablas sueltas debajo, y las tres secciones se leen como una sola
 * lista larga: scrolleado a la mitad no hay forma de saber si lo que se esta mirando es
 * recepcion o ataque.
 *
 * El nombre lleva `report` a proposito: `.live-section` ya existe en el panel de carga
 * (`live-entry.js`, el aviso del bloqueo) y compartirlo le metia a ese aviso el borde y el
 * padding de una seccion de reporte, en una pantalla que no tiene nada que ver.
 */
.live-report-section {
    border: 1px solid var(--line);
    border-radius: .75rem;
    padding: 1rem;
    margin-bottom: 1rem;
}

/*
 * EL COMPLEJO: el contenedor de arriba de todo, adentro de cada jugadora.
 *
 * K1 —recibir y atacar esa pelota— y K2 —sacar, bloquear, defender y contraatacar— son dos juegos
 * distintos, y sus numeros no se suman. Antes las tablas de ataque mezclaban los dos: con 199
 * ataques de K1 y 39 de K2, "por donde ataca" estaba contestado sobre 238 sin decirlo.
 *
 * El rotulo es una linea, no una caja: encerrar el complejo en otro borde daria tres cajas
 * anidadas —complejo, seccion, grupo— y a la tercera nadie sabe cual es cual.
 */
.live-complex-title {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--lime-ink);
    margin: 1.6rem 0 .6rem;
    padding-bottom: .35rem;
    border-bottom: 2px solid var(--lime);
}

.live-report-complex:first-of-type .live-complex-title { margin-top: .6rem; }

.live-report-section-title {
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--lime-ink);
    font-weight: 700;
    margin: 0 0 .85rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--line);
}

/*
 * La tarjeta de la franja general SI lleva su caja: al lado del rotulo `GENERAL` es lo que la
 * empareja con los grupos del desglose, y sin ella el rotulo queda apoyado contra nada.
 */

/*
 * La franja general, con su rotulo al costado. El rotulo es lo que hace legible la estructura de
 * la seccion: sin el, la franja se lee como una tabla mas y no como "esto es lo general y lo de
 * abajo es el desglose". Va en recepcion Y en ataque — en una sola pasaria a significar "esto es
 * distinto" en vez de "esto es lo general".
 */
.live-report-general {
    display: flex;
    align-items: stretch;
    gap: .9rem;
    margin-bottom: 1.25rem;
}

.live-report-general > .live-card { flex: 1; min-width: 0; }

/*
 * La franja se reparte a lo ancho en vez de amontonarse a la izquierda. Con `flex` y `gap` los
 * items quedaban del ancho de su contenido y sobraba media tarjeta vacia a la derecha; con
 * `auto-fit` + `1fr` las celdas se estiran hasta llenar la fila y entran todas las que quepan,
 * asi que en pantalla ancha la franja de ataque —cinco metricas y seis calidades— cae en un
 * solo piso.
 */
.live-report-general .live-stats-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(5.5rem, 1fr));
    gap: 1rem .5rem;
}

/*
 * Rotulo, numero y eficiencia en el mismo eje, y los numeros TODOS A LA MISMA ALTURA.
 *
 * Con la celda en columna simple, un rotulo de una linea ("#") y uno de tres
 * ("K1 (recepcion + 2da)") empujaban su numero a alturas distintas y la franja se leia como un
 * gusano. La primera fila en `1fr` resuelve esa mitad: como todas las celdas de una fila del
 * grid miden igual, el rotulo crece hacia arriba y no mueve nada.
 *
 * La otra mitad —la que quedaba— es que las celdas NO TIENEN LA MISMA CANTIDAD DE RENGLONES:
 * `Recibidas (jugador)` lleva tres (rotulo, numero, "52% de la dupla") y las otras ocho llevan
 * dos. Con la tercera fila en `auto`, la celda que no la usa la colapsa a cero y su numero cae
 * al piso, una linea mas abajo que el de la celda de tres. Por eso la tercera fila tiene
 * **altura fija**: ocupa igual este vacia, y entonces el numero de la segunda cae siempre en la
 * misma linea. Alinear la primera fila no alcanzaba: lo que desalineaba era la ultima.
 */
.live-report-general .live-stat {
    display: grid;
    grid-template-rows: 1fr auto 1.15rem;
    align-items: end;
    justify-items: center;
    text-align: center;
}

.live-general-label {
    writing-mode: vertical-rl;
    rotate: 180deg;
    text-align: center;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .18em;
    color: var(--muted);
    padding-right: .9rem;
    border-right: 1px solid var(--line);
}

/*
 * Angosto: el rotulo se acuesta. Vertical al costado de una franja ya envuelta en tres lineas
 * queda un rotulo de tres renglones al lado de seis, y deja de leerse como rotulo.
 */
@media (max-width: 48rem) {
    .live-report-general { display: block; }

    .live-general-label {
        writing-mode: horizontal-tb;
        rotate: none;
        display: block;
        text-align: left;
        padding: 0 0 .4rem;
        border-right: none;
    }
}

/* La eficiencia debajo del conteo: chica, con el color del semaforo y su propio aire. */
.live-stat-eff {
    font-size: .8rem;
    font-weight: 600;
    padding: .05rem .35rem;
    border-radius: .25rem;
}

/*
 * El grupo: un escalon mas adentro que la seccion. La recepcion se lee tres veces —flotado +
 * potencia, solo flotado, solo potencia— con las MISMAS dos tablas cada vez, y sin caja las seis
 * quedan una atras de otra sin decir cual pertenece a cual corte.
 *
 * El titulo va AFUERA, al nivel de la seccion: adentro competiria con el titulo del fundamento y
 * habria dos rotulos del mismo peso en cajas anidadas.
 */
.live-report-group {
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .6rem;
    padding: .75rem;
    margin-bottom: 1.25rem;
}

.live-report-group:last-child { margin-bottom: 0; }

/* Dos tablas en el mismo grupo se separan; pegadas se leen como una sola con dos encabezados. */
.live-report-group .live-table-scroll + .live-table-scroll { margin-top: .9rem; }

/* ── Canchas del reporte general ──────────────────────────────────────────── */

/*
 * Tres por fila, SIEMPRE tres (docs/08 §6). Con `auto-fit` una cancha vacia se sacaria del
 * renglon y el lado bueno de una jugadora caeria donde esta el medio de la otra: comparar dos
 * hojas dejaria de funcionar. Por eso son tres columnas fijas.
 */
.live-court-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .6rem;
    margin-top: .75rem;
}

/*
 * `live-court-svg` y no `live-court`: ese nombre ya era del contenedor del cuadrante en el panel
 * de carga, y compartirlo le rompio DOS cosas de una, sin error a la vista.
 *
 * Con la misma especificidad gana la regla que va despues en el archivo, y esta va despues:
 * `width: 100%` le pisaba el `width: fit-content` —y ahi el `margin-inline: auto` deja de
 * centrar, el cuadrante se corria a la izquierda— y `display: block` le pisaba el
 * `display: flex` de `.live-court-net-top`, con lo cual el `column-reverse` que sube la red no
 * hacia nada y la red quedaba abajo tambien cuando ataca la dupla de enfrente.
 */
.live-court-svg {
    width: 100%;
    height: auto;
    display: block;
}

/*
 * EL POPUP DEL CHIP. Todo lo de esa trayectoria, sin salir del one-pager.
 *
 * Nace oculto y lo muestra el JS: por eso no sale en el PDF ni deja hueco. En papel esta misma
 * informacion vive en las tablas del detallado, abierta — el popup es lo que la pantalla puede
 * dar y el papel no.
 */
.live-chip { cursor: pointer; }

.live-chip:hover rect { fill-opacity: 1; }

.live-chip-panel {
    display: none;
    position: absolute;
    z-index: 40;
    min-width: 15rem;
    max-width: 22rem;
    padding: .6rem .7rem;
    background: var(--night);
    border: 1px solid var(--lime);
    border-radius: .5rem;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .55);
    pointer-events: none;
}

.live-chip-panel.live-chip-open { display: block; }

.live-chip-head {
    margin: 0 0 .35rem;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--lime-ink);
}

.live-chip-main {
    margin: 0 0 .35rem;
    font-size: .78rem;
}

.live-chip-main strong { font-size: 1.05rem; }

/* Las filas de datos: pares rotulo-numero que envuelven solos. */
.live-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: .15rem .7rem;
    margin: 0 0 .2rem;
    font-size: .68rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/*
 * COMO SE ARMA EL NUMERO DE ESTA SECCION, al pie y en chico.
 *
 * Va al final de la seccion y no en el encabezado para que absorba el aire que ya sobra ahi, en
 * vez de empujar el contenido y costar una hoja en el PDF. `break-inside: avoid` la mantiene
 * pegada a la ultima tabla de su seccion: sola al pie de una hoja no explica nada.
 */
.live-report-formula {
    margin: .5rem 0 0;
    font-size: .68rem;
    line-height: 1.4;
    color: var(--muted);
    break-inside: avoid;
}

/*
 * El globo explicativo: el mismo molde que el panel del chip, con el texto suelto.
 *
 * Es UNO SOLO para todo el documento —lo crea el JS y le cambia el texto—: uno por elemento
 * serian decenas de nodos ocultos por hoja para mostrar de a uno.
 *
 * `pointer-events: none` es lo que evita el parpadeo: sin eso el globo aparece bajo el mouse,
 * dispara `mouseout` sobre el elemento y se cierra solo, en un ciclo.
 */
.live-tip {
    max-width: 22rem;
    font-size: .72rem;
    line-height: 1.4;
    color: var(--bone);
    pointer-events: none;
}

/* El cursor avisa que hay algo que leer antes de que el globo aparezca. */
[data-tip] { cursor: help; }

/* El chip que ademas navega: el cursor lo dice antes de apretarlo. */
.live-chip[data-href] { cursor: pointer; }

.live-chip-link {
    color: var(--lime-ink);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid currentColor;
}

/*
 * DONDE CAISTE. El chip lleva a la seccion del detallado y `:target` la marca sola, sin una linea
 * de JS: sin la marca, el salto deja al lector en medio de ocho tablas sin saber cual es la suya.
 * Se apaga al imprimir — en papel no hay salto que explicar.
 */
.live-report-section:target {
    outline: 2px solid var(--lime);
    outline-offset: 3px;
    scroll-margin-top: 1rem;
}

@media print {
    .live-report-section:target { outline: none; }
}

/* En pantalla angosta tres canchas de 380px no se leen: pasan a una por fila. */
@media (max-width: 48rem) {
    .live-court-row { grid-template-columns: 1fr; }
}

/*
 * La fila que le falta el dato, en la planilla de revision. Marcarla es todo el punto de la
 * pantalla: con doscientos ataques, encontrar los diez sin zona scrolleando es el trabajo que la
 * pagina tiene que ahorrar. Van primero Y marcadas — el orden se pierde apenas se guarda y se
 * recarga con otro orden, el color no.
 */
.live-row-missing > td { background: rgba(238, 96, 85, .09); }

/*
 * La marca al pie de cada hoja. Va con `position: fixed`, que en impresion es lo que se repite
 * en todas las paginas —a diferencia del numero, que necesita las cajas de margen de `@page`
 * porque es lo unico que sabe en que hoja esta—.
 *
 * En pantalla no se muestra: ahi la marca ya esta en la barra de navegacion.
 */
.live-print-mark {
    display: none;
    position: fixed;

    /* `0` y no un valor negativo: con `-10mm` la marca caia DENTRO del margen de la hoja, o sea
       fuera del area de pagina, y Chrome la recorta. No se veia en ninguna. */
    bottom: 0;
    left: 0;
    right: 0;
    text-align: right;
    font-size: .52rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--muted);
}

/*
 * La hoja de lectura: primera del PDF y SOLO del PDF.
 *
 * En pantalla no va —el que carga ya sabe leerlo— y por eso arranca oculta. Al imprimir aparece
 * si el boton la dejo encendida, con su propio corte de pagina para que el reporte empiece
 * limpio en la hoja siguiente.
 */
.live-print-legend { display: none; }

/* El membrete. Es lo primero que ve el cliente, asi que lleva la marca con su tipografia. */
.live-legend-brand {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding-bottom: .5rem;
    margin-bottom: .9rem;
    border-bottom: 2px solid var(--lime);
}

/* El isotipo hereda el color del texto para el aro y las costuras, y la S lleva el acento. Con
   los hexadecimales escritos adentro del SVG, el membrete quedaba oscuro sobre la hoja blanca:
   el modo claro redefine las variables, no los literales (§28). */
.live-legend-logo {
    width: 2.1rem;
    height: 2.1rem;
    flex: 0 0 auto;
    color: var(--bone);
}

.live-legend-brand-text {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
}

.live-legend-brand-name {
    font-family: 'Unbounded', 'Space Grotesk', sans-serif;
    font-size: 1.15rem;
    font-weight: 800;
    letter-spacing: .02em;
    line-height: 1.1;
}

.live-legend-brand-accent { color: var(--lime-ink); }

.live-legend-brand-tag {
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .16em;
    color: var(--muted);
}

.live-legend-block { margin-bottom: 1.1rem; break-inside: avoid; }

/* El cuadro de ejemplo, con los mismos colores y bordes que el mapa real: si fuera un dibujo
   distinto, el lector tendria que traducir dos veces. */
.live-legend-chip {
    display: block;
    width: 100%;
    max-width: 20rem;
    height: auto;
    margin-top: .4rem;
}

.live-legend-block p {
    margin: .25rem 0 0;
    font-size: .8rem;
    line-height: 1.5;
}

/* El encabezado de cada hoja impresa. En pantalla no va: ahi el contexto esta arriba de todo. */
.live-print-head {
    display: none;
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--muted);
    margin: 0 0 .3rem;
}

/* ── Impresion en claro ───────────────────────────────────────────────────── */

/*
 * Fondo blanco y tinta oscura AL IMPRIMIR, sin tocar la pantalla.
 *
 * El reporte en pantalla es oscuro porque es la identidad de la marca y porque se mira en una
 * arena con sol. En papel eso es una hoja entera de tinta por pagina — seis hojas de un reporte
 * son un cartucho— y ademas se lee peor: el texto claro sobre fondo oscuro impreso se emborrona.
 *
 * Se resuelve REDEFINIENDO LAS VARIABLES, no reescribiendo cada regla: como todo el reporte
 * —incluidas las canchas SVG, que van inline— pinta con `var()`, cambiar la paleta en un solo
 * lugar da vuelta el documento entero. Las bandas del semaforo NO se tocan: el verde y el rojo
 * son informacion, no decoracion.
 *
 * La clase la pone el boton y vive en <html>, que es donde estan declaradas las variables.
 */
@media print {
    /*
     * La paleta se redefine EN `.live`, no solo en `<html>`.
     *
     * Las variables se heredan, y para un elemento gana el ancestro MAS CERCANO que las declare,
     * sin importar la especificidad del selector. `.live` declara la paleta oscura, asi que
     * declararla en `<html>` daba vuelta el fondo de la pagina y dejaba oscuro todo lo de
     * adentro: tarjetas, franjas y canchas. Medio reporte en blanco es peor que ninguno.
     */
    html.live-print-light,
    html.live-print-light .live {
        --night: #FFFFFF;
        --slate: #FFFFFF;
        --line:  #C7CDD4;
        --court: #EDF1F5;
        --grid:  #97A3AE;
        --bone:  #14181D;
        --muted: #5A646E;

        /* El lime de marca tambien se apaga: es el acento de la pantalla —red, silueta, titulos
           de seccion— y en una impresion en blanco y negro sale de un verde sucio. Van los dos:
           el relleno y el lima-como-texto, que es el que usan los 33 rotulos de acento. */
        --lime:  #2B3138;
        --lime-ink: #2B3138;

        color: #14181D;
    }

    /* Los valores de la franja, en tinta plana. El gris de `.live-detail-cell` SI se conserva:
       no es color, es jerarquia —numero principal contra numero de apoyo— y en gris se lee. */
    html.live-print-light .live-stat-value { color: #14181D; }

    html.live-print-light body,
    html.live-print-light body:has(.live) {
        background: #FFFFFF;
        color: #14181D;
    }

    /*
     * EL FONDO LLEGA AL BORDE en el modo oscuro.
     *
     * Lo pintaba `body`, y en impresion `body` cubre solo el area de contenido: el margen quedaba
     * blanco y la hoja se veia con un marco. El fondo del elemento RAIZ se propaga al lienzo
     * entero, margenes incluidos, asi que va en `html`.
     *
     * En claro no: ahi el margen blanco es exactamente lo que se quiere.
     */
    html:not(.live-print-light) { background: var(--night, #101418); }

    /*
     * Y esto es lo que lo lleva HASTA EL BORDE.
     *
     * El fondo de `html` cubre el area de contenido, no el margen: en oscuro la hoja quedaba con
     * un marco blanco alrededor. La caja de pagina es lo unico que pinta el margen, y resuelve
     * `var()` contra el documento — asi que la misma linea sirve para los dos modos, blanca en
     * claro y `--night` en oscuro. Verificado sobre el PDF: el relleno cubre 794x1123, la A4
     * entera.
     */
    @page { background: var(--night, #101418); }

    /*
     * BLANCO Y NEGRO, tambien el semaforo.
     *
     * El color de la banda es informacion, pero en papel el reporte se manda impreso y en
     * blanco y negro: un verde y un ambar salen del mismo gris y dejan de distinguirse igual.
     * Antes que un semaforo que miente, ninguno — el numero de eficiencia sigue ahi, que es de
     * donde salia el color.
     *
     * `NoData` si conserva su gris: "no paso nunca" contra "paso y anduvo mal" son dos lecturas
     * opuestas (§19), y esa distincion no se puede perder.
     */
    html.live-print-light .live {
        --band-good: #14181D;
        --band-fair: #14181D;
        --band-low:  #14181D;
        --band-bad:  #14181D;
    }

    html.live-print-light .eff-good,
    html.live-print-light .eff-fair,
    html.live-print-light .eff-low,
    html.live-print-light .eff-bad {
        background: none;
        color: #14181D;
    }

    html.live-print-light .eff-none { color: #7A828B; }

    /* Los colores de calidad del panel tampoco: en la planilla impresa son texto. */
    html.live-print-light .live-q-dp,
    html.live-print-light .live-q-p,
    html.live-print-light .live-q-ex,
    html.live-print-light .live-q-sl,
    html.live-print-light .live-q-n,
    html.live-print-light .live-q-dn { color: #14181D; }
}

/* ── Impresion del reporte ────────────────────────────────────────────────── */

/*
 * El PDF que recibe el cliente sale del print del navegador: la misma hoja de estilos que la
 * pantalla, sin una segunda maqueta que se desincronice. Lo que cambia aca es SOLO lo que no
 * tiene sentido en papel — la navegacion y los botones— y la geometria de la hoja.
 */
@media print {
    /*
     * NO se le pide a las cajas grandes que no se partan.
     *
     * `break-inside: avoid` sobre `.live-report-section` era la causa de las medias hojas en
     * blanco: una seccion de recepcion con tres grupos de dos tablas mide mas que una A4, el
     * navegador no puede cumplir "no la partas", y entonces la empuja entera a la hoja
     * siguiente dejando vacio el resto de la anterior. La regla que buscaba prolijidad era la
     * que producia los huecos.
     *
     * Lo que se protege ahora es chico —una fila, una celda de la franja—, que es lo unico que
     * un navegador puede respetar sin dejar aire.
     */
    tr,
    .live-stat { break-inside: avoid; }

    /*
     * Estos SI se protegen enteros, porque miden bastante menos que una hoja: la franja general
     * son dos renglones y el renglon de canchas es un tercio de A4. Cortar una franja al medio
     * —eficiencia arriba, calidades en la hoja siguiente— o partir una cancha por la mitad es
     * exactamente "cortar en partes claves".
     */
    .live-report-general,
    .live-court-row { break-inside: avoid; }

    /* El encabezado se repite cuando la tabla cruza de hoja: sin esto, media tabla queda sin
       decir que columna es cual. */
    thead { display: table-header-group; }

    /* Ningun titulo se queda solo al pie de una hoja. */
    h2, h3, h4 { break-after: avoid; }

    /*
     * Y ninguna tabla arranca o termina con una fila huerfana: el encabezado seguido de una sola
     * fila al pie de la hoja, o la ultima fila sola arriba de la siguiente, se leen como si
     * faltara algo.
     */
    thead { break-after: avoid; }
    tbody tr:first-child,
    tbody tr:last-child { break-before: avoid; }

    /* El titulo de la seccion no se separa de su franja general. */
    .live-report-section-title { break-after: avoid; }

    /* La leyenda y las notas al pie viajan con lo que explican. */
    .live-court-row + .live-form-sub,
    .live-table-scroll + .live-form-sub { break-before: avoid; }

    /*
     * NUMERO DE PAGINA arriba a la derecha, con las cajas de margen de `@page`.
     *
     * Es la unica forma de numerar: `counter(page)` solo existe dentro de esas cajas. Un div con
     * `position: fixed` se repite en todas las hojas pero no sabe en cual esta, asi que sirve
     * para la marca de agua y no para el numero.
     *
     * El margen crece arriba y se achica abajo: el numero necesita lugar y el alto util tiene
     * que quedar IGUAL que antes (273mm), porque el detallado esta calibrado contra el. Con
     * 16/14 se perdian 6mm y una seccion se derramaba a una hoja mas.
     */
    @page {
        size: A4;
        margin: 14mm 12mm 10mm;

        @top-right {
            content: counter(page) " / " counter(pages);
            font-family: 'Space Mono', ui-monospace, monospace;
            font-size: 8pt;
            color: #7A828B;
        }
    }

    /* Nada de cromo: el menu, el volver y los botones de vista no son parte del reporte. */
    .brand-nav,
    .live-head,
    .live-row-actions,
    .live-print { display: none !important; }

    .brand-container,
    .brand-main { padding: 0; margin: 0; max-width: none; }

    /*
     * Los fondos se imprimen. Sin esto el navegador descarta el color del semaforo "para ahorrar
     * tinta" y el reporte llega en gris: justo la informacion que el color transporta.
     */
    * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

    /*
     * Las tablas no scrollean en papel: se dibujan enteras o no se ven.
     *
     * El `min-width` va con el selector COMPLETO —`.live-table-scroll .live-table`— y no con la
     * clase sola. En pantalla el piso de 34rem esta puesto con esos dos selectores, y una regla
     * de una sola clase no lo pisa aunque venga despues: pierde por especificidad y se aplica
     * igual. Esa era la razon real por la que la tabla del detallado se salia de su columna y
     * perdia las dos ultimas: no era la tipografia ni los anchos, era un piso de 544px que
     * seguia vigente.
     */
    .live-table-scroll { overflow: visible; }
    .live-table-scroll .live-table,
    .live-report-table { min-width: 0; }

    /*
     * Mas compacto en papel que en pantalla. En pantalla el aire ayuda a leer; en una A4 el aire
     * son hojas de mas, y el objetivo declarado es que no sobre espacio.
     */
    .live-report-section { padding: .55rem; margin-bottom: .55rem; }
    .live-report-group   { padding: .45rem; margin-bottom: .7rem; }
    .live-report-general { margin-bottom: .7rem; }
    .live-table          { font-size: .74rem; }
    .live-stat-value     { font-size: 1.15rem; }

    /*
     * La franja entra en UN renglon. En pantalla el minimo de 5.5rem por celda esta bien; en una
     * A4 deja nueve celdas repartidas en dos renglones con dos solas abajo, que es medio bloque
     * de aire por franja y por jugadora.
     */
    .live-report-general .live-stats-row {
        grid-template-columns: repeat(auto-fit, minmax(3.8rem, 1fr));
        gap: .4rem .25rem;
    }

    /*
     * Y la tercera fila se hace mas alta: el "% de la dupla" ocupa dos renglones a esta
     * tipografia y con la altura de pantalla se montaba ENCIMA del numero. Fija, no `auto`, por
     * lo mismo de siempre: si la celda que no la usa la colapsa, los numeros se desalinean.
     */
    .live-report-general .live-stat { grid-template-rows: 1fr auto 1.7rem; }
    .live-player-block   { padding-top: .8rem; margin-top: .8rem; }

    /* Las canchas vuelven a tres por fila aunque la ventana sea angosta: la hoja es A4, no la
       pantalla, y una por fila no entraria nunca en una pagina. */
    .live-court-row { grid-template-columns: repeat(3, 1fr); gap: .35rem; margin-top: .4rem; }

    /* ── El one-pager: UNA hoja por jugadora, no "aproximadamente una" ────────
     *
     * Salia en 4 hojas para dos jugadoras. El corte por jugadora ya estaba; lo que fallaba es
     * que el contenido de cada una medía mas que una A4, asi que se derramaba a la segunda y el
     * corte siguiente empujaba a la tercera. La unica forma de que "una hoja por jugadora" sea
     * cierto es que el contenido ENTRE, y para eso las alturas se declaran en milimetros —la
     * unidad de la hoja— en vez de dejarlas depender del ancho de la ventana.
     *
     * Presupuesto de una A4 util (273mm): 3 renglones de cancha 3x42 = 126, tres franjas 3x18 =
     * 54, titulos y aire ~30, encabezado 12. Total ~222mm, con margen para nombres largos.
     */
    /*
     * Las canchas se llevan el espacio que le sobraba a los numeros.
     *
     * La franja general estaba dimensionada como en pantalla —valores de 1rem, tres renglones
     * por celda— y en una hoja eso son tres bloques grandes diciendo cuatro numeros, mientras el
     * dibujo, que es para lo que existe el one-pager, quedaba chico. Se invierte: la franja al
     * minimo legible y los mapas todo lo que entre.
     */
    /*
     * 39mm. Fue 43 hasta que los titulos de complejo —K1 y K2— sumaron ~20mm por jugadora y la
     * empujaron a una segunda hoja. Los titulos valen mas que 4mm de cancha: sin ellos los
     * numeros de los dos complejos se leen como si fueran del mismo.
     */
    /*
        38mm y no 39: el ACUMULADO mide 1046px contra los 1032 utiles —sus numeros son mas largos y
        la franja de ataque envuelve un renglon mas que en un partido suelto— asi que se derramaba
        a una segunda hoja por jugadora. Un milimetro de dibujo por tres renglones alcanza, y es lo
        que no se lee: los titulos de complejo ya costaron 4mm por el mismo criterio (§37).
    */
    .live-view-general .live-court-svg {
        height: 38mm;
        width: auto;
        margin: 0 auto;
    }

    /* El rotulo del complejo, compacto: en una A4 cada milimetro de titulo sale de una cancha. */
    .live-view-general .live-complex-title {
        font-size: .78rem;
        margin: .45rem 0 .2rem;
        padding-bottom: .12rem;
        border-bottom-width: 1px;
    }

    .live-view-general .live-stat-value { font-size: .78rem; }
    .live-view-general .live-stat-label { font-size: .44rem; }
    .live-view-general .live-stats-row { gap: .2rem .2rem; }
    .live-view-general .live-report-general .live-stat { grid-template-rows: 1fr auto 1.1rem; }
    .live-view-general .live-stat-eff { font-size: .58rem; padding: 0 .2rem; }
    /* El acumulado es el que manda el alto: sus franjas envuelven un renglon mas que las de un
       partido suelto, asi que el aire de las tres secciones es lo que lo mantiene en una hoja. */
    .live-view-general .live-report-section { padding: .22rem; margin-bottom: .15rem; }
    .live-view-general .live-report-general { margin-bottom: .25rem; }
    .live-view-general .live-report-section-title { margin-bottom: .25rem; padding-bottom: .15rem; }
    .live-view-general .live-court-row { gap: .25rem; margin-top: .25rem; }
    .live-view-general .live-form-sub { font-size: .52rem; margin: .15rem 0 0; }
    .live-view-general .live-card { padding: .3rem .4rem; }
    .live-view-general .live-player-block { padding-top: .3rem; margin-top: .3rem; }

    /*
     * En el one-pager la nota de formula va PEGADA a su seccion y en el cuerpo de una nota al
     * pie. Con el margen de la pantalla, las tres notas sumaban ~45px sobre un bloque que mide
     * 1031px de los 1032 utiles: la ultima se derramaba a una segunda hoja por jugadora.
     */
    .live-view-general .live-report-formula { margin-top: .1rem; font-size: .44rem; }

    /* Las dos metricas comparten renglon; el separador las despega sin gastar una fila. */
    .live-stat-eff .live-eff-sep { opacity: .55; }

    /*
     * El contexto compartido —que partidos entran, el selector de vista— se esconde: ocupaba
     * media hoja arriba de la primera jugadora y era lo que la empujaba a una segunda. En su
     * lugar cada bloque lleva su propio encabezado impreso, asi cada hoja se entiende sola
     * cuando se la manda suelta.
     */
    .live > .live-card,
    .live > .live-form-title { display: none !important; }

    .live-print-head { display: block !important; }
    .live-print-mark { display: block !important; }

    /* El popup es de pantalla: en papel su informacion vive en las tablas del detallado. */
    .live-chip-panel { display: none !important; }

    /* Solo si el boton la dejo encendida, y con la hoja para ella sola. */
    html.live-print-legend-on .live-print-legend {
        display: block;
        break-after: page;
    }

    /* El primer bloque de jugadora no fuerza corte —ya lo dio la hoja de lectura—, asi que se
       neutraliza el `break-before: auto` que tiene por ser el primero: no hace falta nada. */
    .live-print-legend .live-report-section-title {
        border-bottom: none;
        margin-bottom: .15rem;
        padding-bottom: 0;
    }

    /* Once bloques a una columna serian dos hojas. A dos columnas entran en una, que es lo que
       la hoja de lectura tiene que ser: una. */
    .live-legend-cols {
        columns: 2;
        column-gap: 7mm;
    }

    .live-legend-block { margin-bottom: .7rem; }
    .live-legend-block p { font-size: .62rem; line-height: 1.4; }

    /* ── El detallado: UNA HOJA POR FUNDAMENTO ───────────────────────────────
     *
     * Recepcion en una hoja, ataque en otra, K2 en otra. La estructura pasa a ser predecible
     * —cada hoja tiene un tema— y ninguna tabla puede caer partida entre dos, porque el corte ya
     * no depende de donde termine el contenido de la anterior.
     *
     * Y como cada fundamento tiene la hoja entera, las tablas vuelven a UNA COLUMNA con
     * tipografia legible. Las dos columnas a .48rem eran la respuesta a "esto no entra"; con una
     * hoja por fundamento la pregunta ya no existe, y la legibilidad vale mas que el ahorro de
     * papel: un desglose que no se lee no se usa.
     */
    .live-view-detailed .live-report-section {
        break-before: page;
        padding: .3rem;
    }

    /*
     * EL CORTE ES DEL BLOQUE DE LA JUGADORA, no solo de sus secciones.
     *
     * Con el corte unicamente en las secciones, el encabezado de la jugadora siguiente —su
     * nombre, su rol, la linea del partido— queda ANTES de su primera seccion y por lo tanto se
     * imprime al pie de la hoja anterior: la hoja de K2 de una terminaba con el nombre de la
     * otra. Es de manual y lo di por resuelto sin verificarlo.
     *
     * El bloque corta, y entonces su primera seccion NO corta: si cortaran las dos, quedaria una
     * hoja con el encabezado solo.
     */
    .live-view-detailed .live-player-block { break-before: page; }
    .live-view-detailed .live-player-block:first-of-type { break-before: auto; }

    /*
     * La primera seccion de la jugadora no corta: ya cortó el bloque. Con el complejo de por
     * medio la seccion dejo de ser hija directa del bloque, asi que se apunta al primer complejo
     * — si no, quedaba una hoja con el nombre de la jugadora solo.
     */
    .live-view-detailed .live-report-complex:first-of-type .live-report-section:first-of-type {
        break-before: auto;
    }

    /*
     * EL TITULO DEL COMPLEJO NO PUEDE QUEDAR SOLO EN UNA HOJA, y `break-after: avoid` no alcanza:
     * la seccion que le sigue trae `break-before: page`, y un corte FORZADO le gana siempre a un
     * "evitar". El titulo "K2" terminaba imprimiendose en una hoja entera para el solo — asi
     * salia la decima pagina de un detallado que tiene nueve.
     *
     * La solucion es mover el corte un nivel arriba: corta el COMPLEJO, y entonces su primera
     * seccion no corta. El titulo y la primera seccion arrancan juntos la hoja, que es lo que se
     * queria decir con "avoid".
     */
    .live-complex-title { break-after: avoid; }

    .live-view-detailed .live-report-complex { break-before: page; }
    .live-view-detailed .live-report-complex:first-of-type { break-before: auto; }

    .live-view-detailed .live-report-complex > .live-report-section:first-of-type {
        break-before: auto;
    }

    /*
     * La franja general va REDUCIDA A UNA LINEA DE NUMEROS.
     *
     * En pantalla es una tarjeta con su rotulo al costado y sus tres renglones por celda, y esta
     * bien ahi. En el PDF del desglose ocupaba un cuarto de hoja para decir seis numeros que
     * ademas estan, abiertos, en la tabla de abajo. Sin caja, sin rotulo vertical y con la
     * tipografia de una nota al pie: sigue estando, deja de gritar.
     */
    .live-view-detailed .live-report-general { margin-bottom: .4rem; }

    .live-view-detailed .live-report-general > .live-card {
        border: none;
        background: transparent;
        padding: 0;
    }

    .live-view-detailed .live-general-label { display: none; }

    .live-view-detailed .live-report-general .live-stats-row {
        grid-template-columns: repeat(auto-fit, minmax(3.2rem, 1fr));
        gap: .15rem;
    }

    .live-view-detailed .live-report-general .live-stat {
        grid-template-rows: 1fr auto .8rem;
    }

    .live-view-detailed .live-stat-value { font-size: .82rem; }
    .live-view-detailed .live-stat-label { font-size: .48rem; }
    .live-view-detailed .live-stat-eff   { font-size: .55rem; padding: 0 .2rem; }

    /*
     * El tamaño lo fija el partido MAS CARGADO, no el que estoy mirando.
     *
     * Es tentador agrandar la tipografia hasta llenar la hoja de recepcion de una jugadora, pero
     * esa hoja tiene pocas filas y otra del mismo reporte tiene el doble: lo que llena una parte
     * la otra en dos. Medido contra los cuatro partidos cargados, `.6rem` es el maximo con el que
     * ninguna seccion se derrama. El aire que sobra en las hojas cortas es exactamente el margen
     * que mantiene enteras a las largas.
     */
    /*
     * El aire entre grupos se achico cuando la seccion de ataque sumo las tres tablas de origen
     * —por recepcion, por cuadrante y por tipo de saque—: con siete grupos, la seccion medía
     * 1039px contra los 1032px utiles y se derramaba a una hoja mas. Se recorta el margen, que es
     * lo que no se lee, en vez de la tipografia, que es lo unico que se lee.
     */
    .live-view-detailed .live-report-group {
        break-inside: avoid;
        padding: .15rem;
        margin-bottom: .2rem;
    }

    /* Lo mismo con el aire de los titulos de tabla: son siete por seccion de ataque. */
    .live-view-detailed .live-table-title { margin-bottom: .1rem; }
    .live-view-detailed .live-report-formula { margin-top: .15rem; }

    .live-report-formula { margin-top: .3rem; font-size: .5rem; }

    .live-view-detailed .live-table { font-size: .6rem; }
    /* El relleno de la celda es aire, no contenido: se recorta antes que la tipografia (§27). */
    .live-view-detailed .live-table th,
    .live-view-detailed .live-table td { padding: .06rem .22rem; }
    .live-view-detailed .live-table th { font-size: .51rem; letter-spacing: .03em; }
    .live-view-detailed .live-table-title { margin-bottom: .25rem; font-size: .68rem; }
    .live-view-detailed .live-form-sub { font-size: .62rem; }

    /*
     * LA TABLA IMPRESA REPARTE COMO LA DE PANTALLA, o sea `table-layout: fixed` con los anchos
     * declarados. Es lo unico que hace que dos tablas apiladas tengan la columna `Efic` en el
     * mismo lugar.
     *
     * Hubo un `table-layout: auto` aca, y era de cuando el detallado se imprimia A DOS COLUMNAS:
     * con 337px por tabla el reparto de la pantalla no entraba. Pero `auto` mide cada tabla por
     * su propio contenido, asi que dos tablas del mismo grupo dejaban de coincidir — se veian
     * torcidas en el PDF y perfectas en pantalla.
     *
     * Desde que cada fundamento tiene su hoja, el ancho util es 703px y el reparto suma 674px:
     * entra, y no hay nada que recalcular.
     */

    /*
     * Los encabezados se parten por donde sea. Con `auto`, el ancho MINIMO de una tabla lo fija
     * su palabra mas larga sin cortar: "EFICIENCIA", "CANTIDAD", "CUADRANTE". Once columnas asi
     * dan mas que media hoja, y la tabla se salia por la derecha perdiendo las ultimas dos
     * columnas —las de ataque de la cadena— sin avisar. Partidos, cada uno ocupa lo que su
     * numero necesita.
     *
     * `white-space: normal` es la mitad que faltaba: las columnas de calidad son `nowrap` en
     * pantalla —para que el numero no se parta— y ese `nowrap` tambien le prohibia partirse a la
     * palabra "CANTIDAD" del encabezado, que es lo que sostenia el ancho de la tabla.
     */
    .live-view-detailed .live-report-table th {
        overflow-wrap: anywhere;
        white-space: normal;
        hyphens: none;
    }

    .live-view-detailed .live-report-table .live-col-concept {
        white-space: normal;
        overflow-wrap: anywhere;
    }

    /* Nada se sale de su columna: con `hidden` un desborde se recorta en vez de pisar la de al
       lado, que es como se veian los encabezados encimados. */
    .live-view-detailed .live-report-group { overflow: hidden; }
}

/* ── Portada ──────────────────────────────────────────────────────────────── */

/*
 * El bloque de marca queda arriba SIEMPRE. En el cliente nuevo crece y se centra: es lo unico
 * que sostiene la pantalla cuando todavia no hay un solo dato que mostrar.
 */
.live-home-hero {
    display: flex;
    align-items: center;
    gap: 1.6rem;
    margin: 1.5rem 0 2.4rem;
}

.live-home-art {
    width: 5.5rem;
    height: 5.5rem;
    flex: 0 0 auto;
}

.live-home-hero.is-big {
    flex-direction: column;
    text-align: center;
    gap: 1.1rem;
    margin: 2rem 0 2.6rem;
}

.live-home-hero.is-big .live-home-art { width: 9rem; height: 9rem; }

.live-home-title {
    font-family: var(--font-display, inherit);
    font-weight: 500;
    letter-spacing: -.02em;
    font-size: clamp(1.5rem, 2.6vw, 2.1rem);
    line-height: 1.15;
    margin: 0 0 .25rem;
}

.live-home-sub {
    margin: 0;
    font-family: var(--font-mono, inherit);
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--muted);
}

.live-home-label {
    font-family: var(--font-mono, inherit);
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--muted);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0 0 .7rem;
}

.live-home-counts { color: var(--muted); }
.live-home-counts b { color: var(--bone); font-variant-numeric: tabular-nums; }

/* Seguir cargando: la unica tarjeta con acento de la portada, y solo existe si hay un set
   abierto. Una tarjeta que esta siempre deja de querer decir algo. */
.live-resume {
    display: flex;
    align-items: center;
    gap: 1.2rem;
    flex-wrap: wrap;
    border-color: var(--lime);
    background:
        linear-gradient(90deg, rgba(198, 255, 61, .07), transparent 60%),
        var(--slate);
}

.live-resume-main { flex: 1 1 18rem; min-width: 0; }

.live-resume-title { font-size: 1.15rem; font-weight: 500; margin: 0 0 .25rem; }
.live-resume-title span { color: var(--muted); font-size: .85rem; }

.live-resume-meta {
    font-family: var(--font-mono, inherit);
    font-size: .74rem;
    color: var(--muted);
    letter-spacing: .06em;
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.live-resume-meta b { color: var(--q-sl); font-weight: 400; }

.live-home-match { display: flex; flex-direction: column; gap: .5rem; }
.live-home-match-teams { font-size: 1.02rem; font-weight: 500; margin: 0; }
.live-home-match-teams span { color: var(--muted); font-size: .85rem; }

.live-home-match-meta {
    font-family: var(--font-mono, inherit);
    font-size: .7rem;
    color: var(--muted);
    letter-spacing: .08em;
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.live-home-match .btn-live { align-self: flex-start; margin-top: auto; }

/*
 * Los pasos del arranque. Van numerados porque el orden ES informacion: sin jugadores no hay
 * duplas, sin duplas no hay partido.
 *
 * PREFIJO PROPIO, no `live-step`: esa familia ya existe en el panel de carga en vivo, y
 * `.live-step-title` viene de ahi en mayusculas y apagado. Reusar el nombre no da error: se
 * hereda el estilo del otro componente y el titulo sale como un rotulo. Es la cuarta colision
 * de este tipo en el proyecto (CLAUDE.md §32).
 */
.live-onboarding {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.live-onboarding-step {
    display: flex;
    align-items: center;
    gap: 1rem;
    background: var(--slate);
    border: 1px solid var(--line);
    border-radius: .6rem;
    padding: .85rem 1rem;
}

.live-onboarding-num {
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    border: 1px solid var(--line);
    font-family: var(--font-mono, inherit);
    font-size: .78rem;
    color: var(--muted);
}

.live-onboarding-text { flex: 1 1 auto; min-width: 0; }
.live-onboarding-name { display: block; }

.live-onboarding-text small {
    display: block;
    font-family: var(--font-mono, inherit);
    font-size: .68rem;
    color: var(--muted);
    letter-spacing: .08em;
    text-transform: uppercase;
    margin-top: .15rem;
}

.live-onboarding-step.is-done { border-color: rgba(87, 200, 107, .35); }
.live-onboarding-step.is-done .live-onboarding-num { border-color: var(--q-dp); color: var(--q-dp); }

.live-onboarding-step.is-done .live-onboarding-name {
    color: var(--muted);
    text-decoration: line-through;
    text-decoration-color: var(--grid);
}

.live-onboarding-step.is-next { border-color: var(--lime); }

/* El tablero del superadmin. `live-cards` ya reparte solo, asi que la variante solo aprieta el
   minimo: cuatro numeros cortos no necesitan 17rem cada uno. */
.live-home-kpis { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }
.live-home-kpis .live-stat-value { display: block; margin-top: .3rem; }

.live-stat-value.is-warn { color: var(--q-sl); }
.live-stat-value.is-quiet { color: var(--muted); }

.live-home-alert {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

.live-home-alert p { margin: 0; flex: 1 1 16rem; }

.live-home-month {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1rem;
}

.live-home-month-value { display: block; font-size: 1.15rem; font-weight: 500; margin-top: .3rem; }

/* La dupla propia. Lima y no un gris mas: es la unica de la lista que el operador busca, y las
   rivales se acumulan de a una por partido hasta enterrarla. */
.live-badge-own {
    color: var(--on-lime);
    background: var(--lime);
    border-color: var(--lime);
    font-weight: 600;
    margin-left: .6rem;
    font-size: .62rem;
    vertical-align: middle;
}

/* La tarjeta de la dupla propia en el resumen. Un borde, no un fondo: las dos tarjetas siguen
   pesando lo mismo —el reporte del rival se abre igual— y la marca solo dice cual es cual. */
.live-card.is-own { border-color: var(--lime); }

/* El cliente que se paso del tope de su plan. Ambar y no rojo: no es un error del sistema, es
   el pie para llamarlo y venderle el plan de arriba. */
.live-over-limit { color: var(--q-sl); font-weight: 600; }

/* El ofrecimiento del partido de ejemplo. Sin lima: el acento de esa pantalla es el primer paso
   pendiente, y el ejemplo es un desvio util, no lo que hay que hacer. */
.live-demo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
    border-style: dashed;
}

.live-demo-main { flex: 1 1 20rem; min-width: 0; }
.live-demo-title { margin: 0 0 .2rem; font-size: 1.02rem; font-weight: 500; }

/* El contacto de la pantalla de cuenta suspendida. Grande y en lima: es lo unico accionable de
   esa pantalla, y el que llega ahi llega buscando exactamente eso. */
.live-suspended-mail {
    display: block;
    margin-top: .4rem;
    font-size: 1.1rem;
    color: var(--lime-ink);
    text-decoration: none;
    word-break: break-all;
}

.live-suspended-mail:hover { text-decoration: underline; }
