  /* ====================================================================
     TEMA CLARO — Fase 1a, 2026-09-09.

     QUE CAMBIA Y QUE NO. Cambian los VALORES de los tokens; no cambia el
     nombre de ninguno, ni una sola clase, ni una linea de HTML. Eso es
     deliberado: `app.js` tiene 27 selectores CSS y 12 `classList`, y una
     docena de tests citan clases por su nombre. Renombrar tokens obligaba a
     tocar 443 referencias sin ganar nada visual, y mover clases rompe el JS
     EN SILENCIO (la pagina se ve bien y los filtros dejan de andar).

     Se pudo hacer asi porque el 89% del color ya pasaba por tokens: 443 usos
     de `var(--...)` contra 5 hex sueltos en todo el archivo.

     PUNTO DE RETORNO: `git checkout antes-light-mode -- web/app.css`
     y despues `py -3.11 regenerar.py`, que rehace la pagina sin gastar
     un solo request.

     LO QUE SE APRENDIO DEL TEMA OSCURO Y SE CONSERVA: el oro no era el
     problema (2026-08-29, probado lado a lado); lo que se leia "retro" era
     el verde botella DE FONDO. Por eso el oro sigue, y el verde vuelve
     recien ahora que el fondo es claro — donde nunca se probo.
     ==================================================================== */
  /* ====================================================================
     TIPOGRAFIA — Fase 1b, 2026-09-09.

     Manrope para titulos y navegacion; Inter para datos, tablas y numeros.
     Inter se eligio por sus cifras tabulares: el archivo usa
     `font-variant-numeric: tabular-nums` 35 veces, y con una fuente sin
     tabulares de verdad las columnas de cuotas bailan renglon a renglon.

     SERVIDAS DESDE ACA, NO DESDE GOOGLE. Dos motivos, ninguno estetico:
       1. La app abre sin conexion. El service worker corta lo que no sea del
          propio origen, asi que una fuente de fonts.gstatic.com no se
          cachearia nunca y offline caeria a la del sistema.
       2. Google Fonts recibe la IP de cada visitante. Sumar un tercero para
          todos, y por una decision de diseno, complicaria la politica de
          privacidad pendiente sin ganar nada.

     VARIABLES: un archivo por familia cubre TODOS los pesos (400 a 800), en
     vez de un archivo por peso. Son 169 KB las dos completas, y con el
     `unicode-range` de abajo quien escribe en castellano baja solo el
     subconjunto `latin`: 71 KB.

     `font-display: swap` a proposito: primero se ve el texto con la fuente
     del sistema y despues cambia. La alternativa es texto invisible mientras
     baja, y en una app de datos eso es peor que un salto tipografico.
     ==================================================================== */
  @font-face {
    font-family: 'Manrope';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('/fonts/manrope-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Manrope';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('/fonts/manrope-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }
  @font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/fonts/inter-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
  }
  @font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/fonts/inter-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }

  :root {
    /* Crema, no blanco puro: un blanco de #FFF a pantalla completa cansa, y
       deja sin contraste a las tarjetas, que SI son blancas. */
    --bg: #F4F3EF;
    --card-bg: #FFFFFF;
    --card-bg-2: #F7F6F2;
    --border: #DCDFDA;
    --border-soft: #E9EBE7;
    --text: #17211F;
    --text-2: #47514C;
    --muted: #6B746F;
    /* Oro = mejor precio. Sigue siendo el unico acento fuerte y sigue
       reservado a lo unico que la app demostro que sirve: el line shopping
       (+3,37%). Si algo brilla, es porque ahi pagan mas.
       PERO SE OSCURECIO, y no por gusto: el oro claro (#D4A544) sobre blanco
       da 2,1:1 de contraste y es ilegible como texto. Acá se usa como COLOR
       DE TEXTO 43 veces, asi que en claro tiene que ser un oro profundo:
       #8A6714 da 5,6:1. Se sigue leyendo dorado, pero se lee. */
    --accent: #8A6714;
    --accent-soft: rgba(214, 168, 61, 0.16);
    /* Se invirtio junto con el acento: antes el acento era claro y esto
       oscuro. Se usa 12 veces SIEMPRE como texto sobre un fondo de color
       (--accent, --muted, --danger, --blue), y los cuatro quedaron
       suficientemente oscuros como para llevar blanco encima. */
    --on-accent: #FFFFFF;
    /* Azul = local e informacion. Arcilla = visita y avisos. Los dos
       oscurecidos para que se lean sobre blanco, y los dos siguen apagados
       a proposito: no compiten con el oro. */
    --blue: #2C6491;
    --amber: #A05B3E;
    --danger: #B4483A;
    /* Verde Pizarra. Es lo unico nuevo de la paleta y entra por la puerta
       chica: el token "positivo", que ya existia. La identidad verde de la
       marca llega con el shell (Fase 1b), que es donde hay una barra lateral
       y una cabecera donde ponerla. Meterla antes seria pintar de verde
       cosas que no son la marca. */
    --up: #1F7A54;
    --down: #B4483A;
    /* Verde Pizarra (Fase 1b). Es la IDENTIDAD, no un semaforo: vive en la
       barra lateral, en la marca y en la pestaña activa. No compite con el
       oro porque no señala lo mismo — el oro dice "acá pagan mas", el verde
       dice "esto es Pizarra". */
    --verde: #0E5545;
    --verde-oscuro: #073E34;
    --verde-suave: #E8F1ED;
    /* La banda del hero es SIEMPRE verde profundo con texto blanco, en
       los dos temas. Estaba usando --verde-oscuro, que ademas hace de
       TEXTO sobre fondo suave: en tema oscuro ese tiene que volverse
       claro para leerse, y la banda habria quedado blanco sobre verde
       claro. Dos trabajos opuestos no entran en un token. */
    --verde-banda: #073E34;
    /* Dos roles, no dos gustos. Manrope tiene mas caracter y se usa donde el
       texto ESTRUCTURA (titulos, marca, navegacion). Inter hace el trabajo
       pesado: cuerpo, tablas y sobre todo NUMEROS, que es casi todo lo que
       esta app muestra.
       El fallback no es decorativo: si el woff2 no llega (offline la primera
       vez, red cortada), la pagina tiene que seguir legible con lo del
       sistema. */
    --fuente: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --fuente-tit: 'Manrope', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    /* Sombra. NO existia: en oscuro las tarjetas se separaban por su fondo
       mas claro que el fondo. En claro eso se invierte —la tarjeta es blanca
       sobre crema— y sin una sombra minima el borde solo deja todo plano. */
    --sombra: 0 1px 2px rgba(23, 33, 31, .04), 0 3px 10px rgba(23, 33, 31, .04);
  }
  * { box-sizing: border-box; }
  body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--fuente);
    margin: 0;
    padding: 24px 16px 60px;
  }
  .wrap { max-width: 720px; margin: 0 auto; }
  h1 {
    font-family: var(--fuente-tit);
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -.4px;
    margin-bottom: 4px;
  }

  /* Encabezado: nombre a la izquierda, lupa a la derecha. */
  .app-hd {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .app-hd h1 { margin: 0; flex: 1; min-width: 0; }
  /* Volver al inicio. Solo aparece en las páginas de liga. */
  .hd-volver {
    flex: none;
    display: grid;
    place-items: center;
    /* 44px: mínimo táctil cómodo. */
    width: 44px; height: 44px;
    margin-left: -10px;
    border-radius: 10px;
    color: var(--text-2);
    text-decoration: none;
  }
  .hd-volver svg {
    width: 24px; height: 24px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
  }
  .hd-volver:hover { color: var(--accent); background: var(--card-bg); }
  .hd-volver:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .hd-buscar {
    flex: none;
    background: none;
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-2);
    cursor: pointer;
    /* 44px es el mínimo táctil cómodo; abajo de eso se falla el toque. */
    width: 44px; height: 44px;
    display: grid; place-items: center;
  }
  .hd-buscar svg {
    width: 20px; height: 20px;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
  }
  .hd-buscar:hover { border-color: var(--accent); color: var(--accent); }
  .hd-buscar[aria-expanded="true"] {
    border-color: var(--accent); color: var(--accent); background: var(--accent-soft);
  }
  .hd-buscar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .search-box[hidden] { display: none; }

  /* Iconos de la barra en SVG y no emoji: cada sistema dibuja los emoji con
     su propia paleta, y en el teléfono salían de colores ajenos a la app. */
  .tab-ico svg {
    width: 20px; height: 20px;
    fill: none; stroke: currentColor; stroke-width: 1.9;
    stroke-linecap: round; stroke-linejoin: round;
    display: block;
  }
  /* "Guías" es un enlace a otra página, no una pestaña con panel. Se ve
     igual que las demás pero no se marca como activa. */
  .tab-enlace { text-decoration: none; }
  h2 {
    font-family: var(--fuente-tit);
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.2px;
    margin: 32px 0 12px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
  }
  /* Etiqueta discreta, no un renglon propio con jerarquia visual.
     2026-08-29: antes era 13px a todo lo ancho, debajo del titulo — pedido
     explicito de la usuaria, "roba atencion sin aportar valor inmediato". */
  .subtitle {
    color: var(--muted); font-size: 10px; margin: -6px 0 12px;
    opacity: .75;
  }
  .alert-card, .pred-card, .report-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 18px;
    margin-bottom: 12px;
    /* Ver la nota de --sombra: en claro la tarjeta es blanca sobre crema y
       el borde solo no alcanza para separarla. */
    box-shadow: var(--sombra);
  }
  .alert-card { border-left: 3px solid var(--accent); }
  .pred-card { border-left: 3px solid var(--blue); }
  .tennis-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 10px;
    padding: 14px 18px;
    margin-bottom: 12px;
  }
  .market-block {
    margin-top: 12px;
    padding: 10px 12px;
    border-radius: 8px;
    background: rgba(111, 168, 220, 0.08);
    border: 1px solid rgba(111, 168, 220, 0.25);
    font-size: 13px;
  }
  .market-title { font-weight: 700; margin-bottom: 6px; color: var(--blue); }
  .market-odds { display: flex; flex-wrap: wrap; gap: 12px; color: var(--text); }
  .market-line { display: block; margin-top: 4px; font-size: 12px; color: var(--muted); }
  .market-warning {
    margin-top: 8px;
    font-size: 12px;
    color: var(--danger);
    background: rgba(210, 112, 90, 0.1);
    border-radius: 6px;
    padding: 6px 10px;
  }
  .tennis-warning {
    margin-top: 10px;
    font-size: 12px;
    color: var(--amber);
    background: rgba(199, 123, 94, 0.1);
    border-radius: 8px;
    padding: 6px 10px;
  }
  .market-diverge-warning {
    margin-top: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--danger);
    background: rgba(210, 112, 90, 0.12);
    border: 1px solid rgba(210, 112, 90, 0.35);
    border-radius: 8px;
    padding: 8px 12px;
  }
  .market-agree {
    margin-top: 10px;
    font-size: 12px;
    color: var(--accent);
    background: rgba(212, 165, 68, 0.1);
    border-radius: 8px;
    padding: 6px 10px;
  }
  .report-card { border-left: 3px solid var(--amber); }
  details > summary { cursor: pointer; list-style: none; }
  details > summary::-webkit-details-marker { display: none; }
  details > summary::after {
    content: "▾ más detalle";
    display: block;
    font-size: 11px;
    color: var(--muted);
    margin-top: 6px;
    opacity: 0.7;
  }
  details[open] > summary::after { content: "▴ ocultar detalle"; }
  .card-detail { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
  .form-row { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 14px; }
  .form-block { flex: 1; min-width: 140px; }
  .form-team { font-size: 12px; color: var(--muted); margin-bottom: 6px; font-weight: 600; }
  /* Se permite que envuelva: con ventana de 10 partidos no entran todos en
     una línea en el teléfono, y es preferible que bajen de renglón a que
     queden escondidos detrás de un scroll que nadie descubre. */
  .form-strip { display: flex; flex-wrap: wrap; gap: 6px 5px; }
  .form-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    cursor: default;
  }
  .form-score {
    font-size: 10px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    line-height: 1;
  }
  /* La L/V tiene que leerse: con el color del borde quedaba invisible y
     entonces era ruido visual en vez de dato. Va más tenue que el marcador
     (que es lo que se pidió destacar) pero legible. */
  .form-venue {
    font-size: 9px;
    /* Era #6E7C72 fijo, elegido a ojo contra el fondo oscuro. Pasa al token
       para que siga el tema en vez de quedarse anclado a un solo fondo. */
    color: var(--muted);
    line-height: 1;
    font-weight: 700;
    letter-spacing: 0.5px;
  }
  .form-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    font-size: 11px;
    font-weight: 800;
    cursor: default;
  }
  .form-w { background: var(--accent); color: var(--on-accent); }
  .form-d { background: var(--muted); color: var(--on-accent); }
  .form-l { background: var(--danger); color: var(--on-accent); }
  .pred-teaser { font-size: 13px; color: var(--muted); margin-top: 4px; }
  /* Evolucion del ROI y el CLV. Dos graficos separados y no dos lineas en
     uno: se miden los dos en % pero no son la misma magnitud, y encimarlos
     invitaria a leer cruces que no significan nada. */
  .evo-grid { display: grid; gap: 12px; margin: 10px 0; }
  @media (min-width: 700px) {
    .evo-grid { grid-template-columns: 1fr 1fr; }
  }
  .evo-bloque {
    background: var(--card-bg-2);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    padding: 10px;
  }
  .evo-cab {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 4px;
  }
  .evo-titulo {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 700;
    flex: 1 1 auto;
  }
  .evo-val { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
  .evo-pos { color: var(--up); }
  .evo-neg { color: var(--down); }
  .evo-n { font-size: 10px; color: var(--muted); }
  /* width 100% con viewBox: el dibujo escala solo y nunca desborda. */
  .evo-svg { width: 100%; height: auto; display: block; }
  .evo-pie { font-size: 11px; color: var(--muted); line-height: 1.6; margin-bottom: 10px; }

  /* Lo que se dejo sobre la mesa. Es la unica ventaja demostrada del
     proyecto (+3,37%), asi que lleva tratamiento de dato principal: una
     cifra grande en unidades, no un chip mas entre otros. */
  .mesa {
    border: 1px solid var(--accent);
    background: var(--accent-soft);
    border-radius: 12px;
    padding: 12px;
    margin: 12px 0;
  }
  .mesa:empty { display: none; }
  .mesa-titulo {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--accent);
    font-weight: 700;
    margin-bottom: 6px;
  }
  .mesa-hero { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
  .mesa-val {
    font-size: 30px;
    font-weight: 800;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
  }
  .mesa-sub { flex: 1 1 180px; font-size: 12px; color: var(--text-2); line-height: 1.45; }
  .mesa-detalle {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    margin-top: 10px;
    font-size: 12px;
    color: var(--text-2);
  }
  .mesa-casas { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
  .mesa-casas-lbl {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 700;
  }
  .mesa-casa {
    font-size: 11px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px 8px;
    color: var(--text-2);
  }
  .mesa-pie { font-size: 11px; color: var(--muted); line-height: 1.6; margin-top: 10px; }

  /* Desglose por mercado. Barra DIVERGENTE alrededor del cero: el ROI tiene
     polaridad (se gana o se pierde) y esa es la unica lectura que importa.
     Escala compartida entre filas, a diferencia de las sparklines: aca el
     punto es justamente comparar mercados entre si. */
  .desglose { margin: 12px 0; }
  .dg-titulo {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 6px;
  }
  .dg-fila, .dg-cab {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    padding: 4px 0;
  }
  .dg-cab {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    border-bottom: 1px solid var(--border-soft);
  }
  .dg-nombre { flex: 1 1 0; min-width: 0; overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap; color: var(--text-2); }
  .dg-n { flex: 0 0 26px; text-align: right; color: var(--muted);
          font-variant-numeric: tabular-nums; }
  .dg-acierto { flex: 0 0 44px; text-align: right; color: var(--text-2);
                font-variant-numeric: tabular-nums; }
  /* La barra tiene el cero en el MEDIO: sin eso, un -20% y un +20% se
     dibujarian con el mismo largo desde el mismo borde y no se
     distinguirian de un vistazo. */
  .dg-barra {
    flex: 0 0 90px;
    position: relative;
    height: 10px;
    background: linear-gradient(var(--border-soft), var(--border-soft))
                no-repeat center / 1px 100%;
  }
  .dg-tramo { position: absolute; top: 1px; bottom: 1px; border-radius: 3px; }
  .dg-pos { background: var(--up); }
  .dg-neg { background: var(--down); }
  .dg-roi { flex: 0 0 56px; text-align: right; font-weight: 700;
            font-variant-numeric: tabular-nums; }
  .dg-pos-txt { color: var(--up); }
  .dg-neg-txt { color: var(--down); }
  /* Muestra insuficiente: se atenua la fila entera en vez de esconderla.
     Esconderla daria la impresion de que ese mercado no se jugo. */
  /* ATENUAR POR OPACIDAD NO SIGNIFICA LO MISMO EN CLARO QUE EN OSCURO, y
     este es el caso donde mas se nota. Medido sobre --card-bg-2:
         opacity 0.50 -> contraste 1,92:1  (invisible)
         opacity 0.72 -> contraste 2,72:1  (todavia por debajo del minimo)
         opacity 0.85 -> contraste 3,70:1  (legible, y sigue viendose tenue)
     En oscuro, 0.5 dejaba un gris perfectamente legible; en claro lo borra.
     Ademas, sobre fondo claro el propio --muted YA atenua respecto de --text
     (4,6:1 contra 13:1), asi que hace falta mucha menos opacidad para decir
     lo mismo. Lo que se protege es "se atenua, NO se esconde": eso sigue
     igual, solo cambia cuanta atenuacion hace falta para conseguirlo. */
  .dg-pocas { opacity: 0.85; }
  .dg-pie { font-size: 11px; color: var(--muted); line-height: 1.6; margin-top: 8px; }

  /* Aviso de muestra chica. Va arriba de los graficos a proposito: se lee
     ANTES de sacar conclusiones, no despues. */
  .muestra-aviso {
    background: var(--accent-soft);
    border: 1px solid var(--accent);
    border-radius: 10px;
    padding: 9px 11px;
    font-size: 12px;
    color: var(--text-2);
    margin: 10px 0;
    line-height: 1.5;
  }
  .muestra-aviso[hidden] { display: none; }

  /* Movimiento de cuota: pequenos multiplos, una linea por resultado.
     Cada linea tiene su propia escala (cada cuota vive en un rango distinto,
     un favorito a 1.80 y un empate a 3.40), asi que se mira la FORMA. La
     identidad va en la etiqueta de texto, nunca en el color. */
  .mov-serie { margin-top: 12px; }
  .ms-titulo {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 6px;
  }
  .ms-fila {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    margin-bottom: 2px;
  }
  /* El nombre se trunca en vez de empujar la sparkline: el ancho del dibujo
     tiene que ser el mismo en las tres filas o las formas no se comparan. */
  .ms-eq {
    flex: 1 1 0;
    min-width: 0;
    color: var(--text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* flex-shrink en 1 para que en pantallas angostas se achique en vez de
     desbordar; el viewBox hace que el dibujo escale solo. */
  .spark { flex: 0 1 132px; width: 132px; height: 30px; display: block; }
  /* ANCHO FIJO, y esto NO es cosmetico: medido, con ancho automatico las tres
     sparklines arrancaban en x=154, 167 y 161 porque "3.05->2.61 14.4%" y
     "3.4->3.62 6.5%" no miden lo mismo. Con las lineas empezando en distinta
     x no se pueden comparar las formas, que es justo para lo que estan. */
  .ms-num {
    flex: 0 0 112px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
  }
  .ms-sube { color: var(--accent); }
  .ms-baja { color: var(--amber); }
  .ms-pct { font-weight: 400; color: var(--muted); }
  .ms-pie { font-size: 11px; color: var(--muted); margin-top: 6px; line-height: 1.6; }

  /* Racha por mercado: un cuadrito por partido, del mas viejo al mas nuevo.
     RELLENO vs CONTORNO, no dos colores — medido: --accent y --muted se
     diferencian 0,106 de luminancia, asi que en escala de grises o para quien
     no distingue colores serian el mismo tono. La diferencia tiene que ser de
     forma. Y la celda hueca se ve igual (contorno 5,86:1 contra el fondo),
     porque si no no se puede contar el denominador. */
  .racha-mercado { margin-top: 10px; }
  .rm-bloque { margin-bottom: 10px; }
  .rm-titulo {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 5px;
  }
  .rm-equipo { margin-bottom: 6px; }
  .rm-cab {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    font-size: 12px;
    margin-bottom: 3px;
  }
  .rm-nombre { color: var(--text-2); }
  .rm-cuenta { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }
  /* gap de 2px entre celdas: separa los marcos sin que se lean como una barra */
  .rm-tira { display: flex; flex-wrap: wrap; gap: 2px; }
  .rm-celda {
    width: 14px;
    height: 14px;
    border-radius: 4px;
    border: 1px solid var(--muted);
    background: transparent;
    cursor: help;
    flex: 0 0 auto;
  }
  .rm-celda.rm-si { background: var(--accent); border-color: var(--accent); }
  .rm-pie { font-size: 11px; color: var(--muted); margin-top: 6px; line-height: 1.6; }
  .rm-leyenda { display: inline-flex; align-items: center; gap: 4px; margin: 0 4px; }
  .rm-leyenda .rm-celda { width: 11px; height: 11px; cursor: default; }

  /* Modo revision: bloques que solo mira la usuaria hasta que el sistema
     este bueno. El atributo hidden ya los oculta; esto le da un borde para
     que se note que lo que se esta viendo NO es lo que ve el usuario. */
  .solo-revision {
    border: 1px dashed var(--accent);
    border-radius: 10px;
    padding: 10px;
    margin: 12px 0;
  }
  /* El `hidden` del HTML lo oculta a traves de la hoja de estilos del
     navegador, que pierde contra CUALQUIER regla de clase que fije display.
     Hoy ninguna lo hace, pero si mañana alguien le pone `display:block` a
     .solo-revision, el bloque de revision aparece para todo el mundo sin que
     nada avise. Esta linea lo hace explicito. */
  .solo-revision[hidden] { display: none; }
  /* El interruptor del modo revision, en "Tu cuenta". Va a la vista porque
     no es seguridad: esconderlo detras de un parametro de URL solo hacia que
     fuera inalcanzable desde la app instalada en el telefono. */
  .revision-toggle {
    margin-top: 16px;
    padding: 12px;
    border: 1px dashed var(--border);
    border-radius: 10px;
  }
  .revision-lbl {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-2);
    cursor: pointer;
  }
  .revision-nota { font-size: 11px; color: var(--muted); margin-top: 6px; line-height: 1.55; }

  .revision-sello {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent);
    font-weight: 700;
    margin-bottom: 8px;
  }
  .aviso-estado { font-size: 13px; }
  .aviso-titulo { font-weight: 700; margin-bottom: 6px; }
  .aviso-lista { margin: 0 0 8px; padding-left: 18px; }
  .aviso-lista li { margin-bottom: 4px; }
  .aviso-pie { font-size: 12px; color: var(--muted); }

  /* Destacados: lo que YA PASO en los ultimos partidos de los dos equipos.
     Se distinguen de .signal-badge (que sale del modelo) con el color de
     acento, porque son de naturaleza distinta: un hecho observado contra una
     estimacion. Mezclarlos visualmente seria mezclarlos conceptualmente. */
  .destacados { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
  .destacado-chip {
    font-size: 11px;
    background: var(--accent-soft, rgba(200, 164, 92, 0.14));
    border: 1px solid var(--accent);
    border-radius: 999px;
    padding: 3px 9px;
    color: var(--text);
    cursor: help;
  }
  .destacado-chip b { font-weight: 700; }

  /* Texto solo para lectores de pantalla. El triangulo de aviso es
     aria-hidden porque leerlo como simbolo no dice nada; el mensaje real va
     acá. */
  .sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  /* Un esperado que sabemos que esta mal: el proveedor manda las tarjetas
     incompletas en algunas ligas (ver diagnostico_tarjetas.py). Se MUESTRA
     igual —esconderlo dejaria al usuario sin saber que hay un problema— pero
     no puede verse como los demas, o seria mentir por omision. El detalle
     con el numero va en el title. */
  .esp-chip.esp-dudoso {
    border-style: dashed;
    opacity: 0.85;
  }
  .esp-alerta {
    margin-left: 4px;
    font-size: 10px;
    /* Sin color propio: hereda el del chip. Pintarlo de rojo lo haria gritar
       mas que los destacados, y esto es una advertencia sobre el dato, no
       una alarma sobre el partido. */
  }

  /* La MISMA lectura cuando no llega al umbral: sigue siendo un hecho
     observado (mismo conteo crudo), pero no es notable, asi que no se pinta
     como si lo fuera. Sin borde de acento y en gris — la jerarquia visual
     tiene que decir "esto es informacion" y no "mira esto". Se muestra igual
     porque esconderla seria la app decidiendo por la persona: un "4 de 10"
     tambien dice algo del partido. */
  .lectura-chip {
    font-size: 11px;
    background: var(--chip-bg, rgba(127, 127, 127, 0.10));
    border: 1px solid var(--borde, rgba(127, 127, 127, 0.28));
    border-radius: 999px;
    padding: 3px 9px;
    color: var(--muted, var(--text));
    cursor: help;
  }
  .lectura-chip b { font-weight: 600; }

  /* "Esperados" NO son destacados y no se pintan como tales: los destacados
     son hechos ya ocurridos y esto es una ESTIMACION. Van sin el borde de
     acento, en gris, para que la diferencia se vea sin leer. */
  .esperados {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    font-size: 11px;
  }
  .esp-lbl {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 700;
  }
  .esp-chip {
    background: rgba(140, 154, 144, 0.12);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 3px 9px;
    color: var(--text-2);
    cursor: help;
    font-variant-numeric: tabular-nums;
  }
  .esp-chip b { color: var(--text); font-weight: 700; }
  .signal-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
  .signal-badge {
    font-size: 11px;
    font-weight: 600;
    background: rgba(140, 154, 144, 0.12);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 3px 9px;
    color: var(--text);
  }
  .best-bet-teaser {
    font-size: 15px;
    font-weight: 700;
    color: var(--amber);
    margin-top: 8px;
    padding: 6px 10px;
    background: rgba(199, 123, 94, 0.1);
    border-radius: 8px;
    display: inline-block;
  }
  .best-price {
    font-size: 13px;
    font-weight: 600;
    color: var(--accent);
    margin-top: 6px;
    padding: 5px 10px;
    background: var(--accent-soft);
    border-radius: 8px;
    display: inline-block;
  }
  .best-price b { font-size: 15px; }

  /* El precio como titular de la tarjeta. La cuota es el numero mas grande
     porque es lo unico con ventaja demostrada (+3,83%, 20 de 20). */
  .precio-destacado {
    margin-top: 8px;
    padding: 10px 12px;
    background: var(--accent-soft);
    border: 1px solid rgba(212, 165, 68, 0.35);
    border-radius: 10px;
  }
  .precio-fila {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
  }
  .precio-que { font-size: 13px; color: var(--text); font-weight: 600; line-height: 1.35; }
  .precio-valor {
    font-size: 26px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: -0.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  .precio-casa { font-size: 12px; color: var(--muted); margin-top: 3px; }
  .precio-ventaja {
    font-size: 12px;
    color: var(--accent);
    margin-top: 5px;
    padding-top: 5px;
    border-top: 1px solid rgba(212, 165, 68, 0.22);
    font-variant-numeric: tabular-nums;
  }
  /* Sin cuota no se puede saber si conviene: se muestra apagado. */
  .pick-sin-precio {
    margin-top: 8px;
    padding: 7px 10px;
    font-size: 13px;
    color: var(--muted);
    background: rgba(140, 154, 144, 0.08);
    border-radius: 8px;
  }
  .sin-precio-nota { display: block; font-size: 11px; margin-top: 2px; opacity: .8; }
  /* La proyeccion del modelo baja a pie de tarjeta, con su etiqueta. */
  .modelo-nota {
    font-size: 12px;
    color: var(--muted);
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
  }
  /* Pestañas dentro del detalle del partido. El detalle venía creciendo y
     era un scroll largo donde todo pesaba igual; quien mira córners no
     quiere pasar por la racha para llegar. */
  .fichas { margin-top: 12px; }
  .fichas-nav {
    display: flex;
    gap: 2px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 10px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .fichas-nav::-webkit-scrollbar { display: none; }
  .ficha-btn {
    flex: none;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    color: var(--muted);
    cursor: pointer;
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.05em;
    /* 40px de alto: abajo de eso se falla el toque en el teléfono. */
    padding: 11px 12px 9px;
    white-space: nowrap;
  }
  .ficha-btn:hover { color: var(--text-2); }
  .ficha-btn.activo { color: var(--accent); border-bottom-color: var(--accent); }
  .ficha-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
  .ficha-panel[hidden] { display: none; }
  /* Dentro de una pestaña, los bloques ya no necesitan su propio margen
     superior: la barra de pestañas ya los separa. */
  .ficha-panel > .stats-block,
  .ficha-panel > .h2h-bloque { margin-top: 0; }

  /* Partido de hoy que ya arrancó. Ocupa el lugar del precio, porque ya no
     se puede apostar — pero la tarjeta se queda, que es lo que pidió la
     usuaria: quiso revisar un partido que iba 15 córners en el minuto 92 y
     ya había desaparecido de la página. */
  .jugado {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 8px;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg-2);
  }
  .jugado-sello {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.09em;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 2px 7px;
  }
  .jugado-vivo .jugado-sello {
    color: var(--down);
    border-color: var(--down);
  }
  .jugado-marcador {
    font-size: 20px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
  }
  .jugado-nota { font-size: 11.5px; color: var(--muted); margin-left: auto; }

  /* Todos los mercados del partido. El usuario decide; el sistema solo
     marca cuál elegiría. */
  .mercados-bloque {
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg-2);
  }
  .mercados-titulo {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--muted);
    margin-bottom: 9px;
  }
  .mercados-tabla { width: 100%; border-collapse: collapse; font-size: 13px; }
  .mercados-tabla th {
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    text-align: right;
    padding-bottom: 7px;
    border-bottom: 1px solid var(--border);
  }
  .mercados-tabla th:first-child { text-align: left; }
  .mercados-tabla td {
    padding: 8px 0;
    text-align: right;
    border-bottom: 1px solid var(--border-soft);
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
  }
  .mercados-tabla td:first-child {
    text-align: left;
    color: var(--text);
    padding-right: 10px;
  }
  .mercados-tabla tr:last-child td { border-bottom: none; }
  /* El que el sistema elegiría. */
  .mk-elegido td { background: var(--accent-soft); }
  .mk-elegido td:first-child { color: var(--accent); font-weight: 600; }
  .mk-punta { color: var(--accent); font-size: 8px; margin-right: 6px;
              vertical-align: middle; }
  /* Los que no califican: se ven, pero apagados. */
  .mk-fuera td { color: var(--muted); }
  .mk-fuera td:first-child { color: var(--muted); }
  .mk-nota {
    font-size: 10px;
    color: var(--muted);
    font-style: italic;
    margin-top: 1px;
  }
  .mk-casa { display: block; font-size: 10px; color: var(--muted); }
  .mk-bien { color: var(--up); font-weight: 600; }
  .mk-neutro { color: var(--muted); }
  .mk-sin { color: var(--muted); }
  .mercados-pie {
    margin-top: 9px;
    padding-top: 8px;
    border-top: 1px solid var(--border-soft);
    font-size: 10.5px;
    line-height: 1.5;
    color: var(--muted);
  }
  .mercados-pie b { color: var(--text-2); }
  .mercados-pie .sin-validar { color: var(--amber); }

  /* Historial entre los dos equipos (H2H). */
  .h2h-bloque {
    margin-top: 12px;
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg-2);
  }
  .h2h-titulo {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--muted);
    margin-bottom: 10px;
    display: flex;
    justify-content: space-between;
    gap: 8px;
  }
  .h2h-n { font-weight: 500; letter-spacing: 0; text-transform: none; }

  /* Reparto 1 / X / 2 / AA, como en las apps que la gente ya usa. */
  .h2h-reparto {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
    margin-bottom: 10px;
  }
  .h2h-reparto span {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 6px 2px;
    border: 1px solid var(--border);
    border-radius: 6px;
  }
  .h2h-reparto b {
    font-size: 10px;
    font-weight: 700;
    color: var(--muted);
    letter-spacing: 0.06em;
  }
  .h2h-reparto i {
    font-style: normal;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
  }

  /* Promedios de esos cruces: local / total / visita. */
  .h2h-medias { margin-bottom: 9px; }
  .h2h-media {
    display: grid;
    grid-template-columns: 1fr 44px 52px 44px;
    align-items: center;
    gap: 6px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border-soft);
    font-size: 12.5px;
  }
  .h2h-media:last-child { border-bottom: none; }
  .h2h-cab {
    font-size: 9.5px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    border-bottom: 1px solid var(--border);
  }
  .h2h-cab .h2h-mv, .h2h-cab .h2h-mt {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .h2h-me { color: var(--text-2); }
  .h2h-mv, .h2h-mt {
    text-align: center;
    font-variant-numeric: tabular-nums;
    color: var(--text-2);
  }
  .h2h-mt { font-weight: 700; color: var(--text); }

  .h2h-muestra {
    display: block;
    margin-top: 6px;
    font-size: 10px;
    color: var(--muted);
    text-align: right;
  }
  .h2h-goles {
    font-size: 11.5px;
    color: var(--muted);
    margin-bottom: 9px;
    font-variant-numeric: tabular-nums;
  }

  .h2h-lista { display: flex; flex-direction: column; }
  .h2h-fila {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 5px 0 5px 8px;
    border-left: 3px solid var(--border);
    border-bottom: 1px solid var(--border-soft);
    font-size: 12.5px;
  }
  .h2h-fila:last-child { border-bottom: none; }
  .h2h-l { border-left-color: var(--blue); }
  .h2h-e { border-left-color: var(--muted); }
  .h2h-v { border-left-color: var(--amber); }
  .h2h-fecha {
    font-size: 10.5px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    flex: none;
  }
  .h2h-cruce { color: var(--text-2); flex: 1; min-width: 0; }
  .h2h-cruce b { color: var(--text); font-variant-numeric: tabular-nums; }
  /* Los córners y tarjetas de ESE partido, al final del renglón. */
  .h2h-num {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 11px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  .h2h-ico { font-style: normal; font-size: 9px; opacity: 0.75; }
  .h2h-nota {
    margin-top: 9px;
    padding-top: 8px;
    border-top: 1px solid var(--border-soft);
    font-size: 10.5px;
    line-height: 1.5;
    color: var(--muted);
  }

  /* Promedio de la liga bajo cada barra. Es lo que convierte el número en
     información: "5.8 córners" no dice nada, "5.8 contra 4.9 de media" sí. */
  .st-media {
    text-align: center;
    font-size: 10px;
    color: var(--muted);
    margin-top: 3px;
    font-variant-numeric: tabular-nums;
  }
  /* Flechas solo cuando la diferencia con la media supera el 15%: con
     muestras de 5 partidos, menos que eso es ruido. */
  .st-alto { color: var(--up); font-size: 9px; margin-left: 3px; }
  .st-bajo { color: var(--down); font-size: 9px; margin-right: 3px; }

  /* Franja de países: una fila que se desliza en horizontal, arriba de todo.
     La versión anterior apilaba bloques por país dentro de .league-menu, que
     es flex-wrap — cada bloque se volvió una columna y la pantalla quedó con
     dos columnas descoordinadas y huecos enormes. Una fila no tiene ese
     problema, y además es la forma que la gente ya conoce de otras apps. */
  .paises-strip {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 4px 0 10px;
    margin: 0 0 4px;
    /* La barra de scroll horizontal en el teléfono tapa los chips y no hace
       falta: el gesto ya se entiende porque el último queda cortado. */
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .paises-strip::-webkit-scrollbar { display: none; }

  /* Pestañas de día. Misma forma que los chips de país a propósito: son dos
     filas de filtro y ya hay un lenguaje visual para eso en la app, así que
     inventarle otro haría que se leyeran como cosas distintas cuando hacen
     lo mismo. El oro como "seleccionado" ya viene de .pais-chip.activo. */
  /* Confianza: qué tiene medición detrás y qué no.
     Misma forma que las pestañas de día y los chips de país a propósito: son
     tres filas de filtro y ya hay un lenguaje visual para eso en la app. */
  .confianza { margin: 0 0 10px; }
  .conf-pills {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 2px 0 6px;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .conf-pills::-webkit-scrollbar { display: none; }
  .conf-pill {
    flex: none;
    white-space: nowrap;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-2);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    padding: 8px 13px;
    cursor: pointer;
  }
  .conf-pill b {
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--muted);
    background: var(--card-bg-2);
    border-radius: 999px;
    padding: 1px 6px;
    margin-left: 5px;
  }
  .conf-pill:hover { border-color: var(--accent); }
  .conf-pill.activa {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
  }
  .conf-pill.activa b { color: var(--accent); }
  .conf-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  /* La nota explica QUÉ se midió. Una etiqueta que diga "medido" sin el número
     detrás es un sello vacío, que es justo lo que este filtro evita. */
  .conf-nota {
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--muted);
    padding: 0 2px;
  }

  .dias {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 2px 0 10px;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .dias::-webkit-scrollbar { display: none; }
  /* Mismo caso que .hd-auth: el `display: flex` de arriba le gana al `hidden`
     del navegador. La barra de días arranca oculta y solo se muestra si hay
     partidos de dos días o más — sin esto, en una liga de un solo día quedaba
     una franja vacía ocupando lugar. Lo encontró tests/test_oculto.py. */
  .dias[hidden] { display: none; }
  .dia-pill {
    flex: none;
    white-space: nowrap;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-2);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    padding: 8px 13px;
    cursor: pointer;
    /* La primera letra en mayúscula: toLocaleDateString devuelve "vie 28/08"
       en español y "Fri" en inglés. Sin esto la fila queda despareja según
       el idioma del teléfono. */
    text-transform: capitalize;
  }
  .dia-pill b {
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--muted);
    background: var(--card-bg-2);
    border-radius: 999px;
    padding: 1px 6px;
    margin-left: 5px;
  }
  .dia-pill:hover { border-color: var(--accent); }
  .dia-pill.activa {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
  }
  .dia-pill.activa b { color: var(--accent); }
  .dia-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  .pais-chip {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-2);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    padding: 8px 13px;
    cursor: pointer;
  }
  .pais-chip:hover { border-color: var(--accent); }
  .pais-chip.activo {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
  }
  .pais-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .pais-n {
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
    background: var(--card-bg-2);
    border-radius: 999px;
    padding: 1px 6px;
  }
  .pais-chip.activo .pais-n { color: var(--accent); }

  /* Lista de ligas: una por renglón. En pastillas sueltas, 26 ligas obligan
     a leerlas todas para encontrar una; en lista se recorre con la vista. */
  .ligas-caja {
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--card-bg);
    margin-bottom: 14px;
  }
  .ligas-resumen {
    cursor: pointer;
    list-style: none;
    padding: 11px 14px;
    font-size: 13px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .ligas-resumen::-webkit-details-marker { display: none; }
  .ligas-resumen::after { content: "▾"; color: var(--muted); font-size: 12px; }
  .ligas-caja[open] .ligas-resumen::after { content: "▴"; }
  .ligas-caja[open] .ligas-resumen { border-bottom: 1px solid var(--border-soft); }
  .league-lista { display: flex; flex-direction: column; }
  .league-lista .league-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border: none;
    border-bottom: 1px solid var(--border-soft);
    border-radius: 0;
    background: none;
    color: var(--text-2);
    font-size: 13.5px;
    font-weight: 600;
    text-decoration: none;
  }
  .league-lista .league-btn:last-child { border-bottom: none; }
  .league-lista .league-btn:hover { background: var(--card-bg-2); color: var(--text); }
  .league-lista .league-btn.activa { color: var(--accent); }
  .league-bandera { font-size: 15px; line-height: 1; flex: none; }
  .league-nombre { flex: 1; min-width: 0; }
  .league-lista .league-n {
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
    background: var(--card-bg-2);
    border-radius: 999px;
    padding: 2px 8px;
    flex: none;
  }
  /* Lo esconde la franja de países al filtrar. */
  .league-btn[hidden] { display: none; }
  .league-inicio {
    display: block;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border-soft);
    color: var(--muted);
    font-size: 12.5px;
    font-weight: 600;
    text-decoration: none;
  }
  .league-inicio:hover { color: var(--accent); }

  /* Barra de probabilidad 1X2 en el resumen de la tarjeta. */
  .prob-bloque { margin-top: 10px; }

  /* Los tres números etiquetados 1 / X / 2, en cajas del mismo ancho para
     que al bajar por una lista larga queden en columna y se puedan comparar
     entre partidos sin leerlos uno por uno. */
  .prob-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
    margin-bottom: 6px;
  }
  .pg-caja {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 5px;
    background: var(--card-bg-2);
    border: 1px solid var(--border-soft);
    border-radius: 6px;
    padding: 5px 4px;
  }
  /* Cada caja hereda el color de SU segmento en la barra de abajo, así el
     número y la barra dicen lo mismo. --c la define cada posición. */
  .pg-caja { --c: var(--muted); }
  .pg-1 { --c: var(--blue); }
  .pg-x { --c: var(--muted); }
  .pg-2 { --c: var(--amber); }
  .pg-caja i {
    font-style: normal;
    font-size: 9.5px;
    font-weight: 700;
    color: var(--muted);
  }
  .pg-caja b {
    font-size: 13px;
    font-weight: 700;
    color: var(--c);
    font-variant-numeric: tabular-nums;
  }
  /* El más probable se marca con el BORDE, no con un color propio: usar un
     tono para "el mayor" chocaría con que el azul ya significa "local" —
     en un partido que gana el visitante, la caja resaltada saldría azul y
     diría lo contrario de lo que muestra. El borde además se sigue viendo
     con daltonismo y en blanco y negro. */
  .pg-caja.pg-alta {
    border-color: var(--c);
    background: var(--card-bg);
  }
  .pg-caja.pg-alta i { color: var(--c); }
  .prob-barra {
    display: flex; height: 5px; border-radius: 3px; overflow: hidden;
    background: var(--card-bg-2);
  }
  .prob-barra i { display: block; height: 100%; }
  .pb-h { background: var(--blue); }
  .pb-e { background: var(--muted); }
  .pb-a { background: var(--amber); }

  /* Racha reciente, compacta: solo color y letra. El detalle lleva la
     versión completa con marcador y localía. */
  .forma-compacta {
    display: flex; align-items: center; gap: 8px; margin-top: 9px;
  }
  .fc-lado { display: flex; gap: 3px; }
  .fc-der { flex-direction: row-reverse; }
  .fc-sep { flex: 1; height: 1px; background: var(--border-soft); }
  .fc {
    width: 17px; height: 17px; border-radius: 50%;
    display: grid; place-items: center;
    font-size: 9.5px; font-weight: 700; font-style: normal;
    color: var(--on-accent);
  }
  .fc-g { background: var(--up); }
  .fc-e { background: var(--muted); }
  .fc-p { background: var(--down); }
  .fc-vacio { font-size: 10.5px; color: var(--muted); font-style: italic; }

  /* "Analizar": la tarjeta ya se abre al tocarla en cualquier lado (es un
     <details>), pero sin nada que lo diga nadie lo descubre. */
  .card-cta {
    display: block; margin-top: 11px; padding: 9px 0; text-align: center;
    border: 1px solid var(--border); border-radius: 8px;
    font-size: 11.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--text-2);
  }
  .report-card[open] .card-cta { color: var(--muted); }
  .report-card[open] .card-cta::after { content: " ▴"; }
  .report-card:not([open]) .card-cta::after { content: " ▾"; }
  /* Cuando hay precio, el botón lo acompaña en vez de competir con él. */
  .precio-destacado + .card-cta {
    border-color: var(--accent); color: var(--accent);
  }

  /* Cómo salieron las últimas alertas: aciertos Y fallos.
     Va cerrado por defecto — informa a quien lo busca sin desplazar a los
     partidos de hoy, que son el producto. */
  .resultados-bloque {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 16px;
    margin-bottom: 14px;
  }
  .resultados-bloque > summary {
    cursor: pointer;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    list-style: none;
  }
  .resultados-bloque > summary::-webkit-details-marker { display: none; }
  .resultados-bloque > summary::after {
    content: "▾"; color: var(--muted); font-size: 12px; margin-left: auto;
  }
  .resultados-bloque[open] > summary::after { content: "▴"; }
  .res-titulo { font-weight: 700; font-size: 14px; }
  .res-resumen { font-size: 12.5px; color: var(--muted); }
  .res-resumen b { color: var(--text); font-variant-numeric: tabular-nums; }
  .res-lista { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
  .res-fila {
    border-left: 3px solid var(--border);
    padding: 7px 0 7px 11px;
  }
  .res-fila.res-acierto { border-left-color: var(--up); }
  .res-fila.res-fallo { border-left-color: var(--down); }
  .res-cab {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  }
  .res-equipos { font-size: 13.5px; font-weight: 600; }
  .res-marcador {
    font-variant-numeric: tabular-nums; color: var(--muted);
    font-weight: 700; margin: 0 3px;
  }
  .res-sello {
    margin-left: auto; font-size: 10.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em; white-space: nowrap;
    color: var(--muted);
  }
  .res-acierto .res-sello { color: var(--up); }
  .res-fallo .res-sello { color: var(--down); }
  .res-det { font-size: 12px; color: var(--muted); margin-top: 3px; }
  .res-det b { color: var(--text-2); font-variant-numeric: tabular-nums; }
  .res-cuota {
    margin-left: 8px; color: var(--accent);
    font-variant-numeric: tabular-nums;
  }
  .res-nota {
    margin: 12px 0 0; font-size: 11px; line-height: 1.5; color: var(--muted);
    border-top: 1px solid var(--border-soft); padding-top: 9px;
  }

  /* Movimiento de línea. Va en el resumen, visible sin abrir la tarjeta:
     si la cuota se desplomó, el mercado ya tomó posición y eso conviene
     saberlo antes de decidir. */
  .mov-linea { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
  .mov-chip {
    font-size: 11px;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 20px;
    border: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  /* Sube = pagan más que antes: le conviene al que todavía no apostó. */
  .mov-sube { color: var(--accent); border-color: var(--accent-soft); background: var(--accent-soft); }
  /* Baja = se cargaron de ese lado y pagan menos. */
  .mov-baja { color: var(--amber); border-color: rgba(199, 123, 94, 0.3); }

  /* "Lo que ve el modelo": cuota justa vs. cuota de mercado. Se muestra
     SIEMPRE que haya predicción, aunque la tarjeta lidere con una alerta de
     corners — antes la alerta la tapaba por completo. */
  .modelo-bloque {
    margin-top: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg-2);
  }
  .modelo-titulo {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--muted);
    margin-bottom: 8px;
  }
  .modelo-tabla { width: 100%; border-collapse: collapse; font-size: 13px; }
  .modelo-tabla th {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    text-align: right;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
  }
  .modelo-tabla th:first-child { text-align: left; }
  .modelo-tabla td {
    padding: 7px 0;
    text-align: right;
    border-bottom: 1px solid var(--border-soft);
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
  }
  .modelo-tabla td:first-child { text-align: left; color: var(--text); }
  .modelo-tabla tr:last-child td { border-bottom: none; }
  .modelo-prob { color: var(--muted); }
  /* Único caso donde el modelo ve valor: el mercado paga más que la justa. */
  .modelo-valor { color: var(--accent); font-weight: 700; }
  .modelo-casa { display: block; font-size: 10px; color: var(--muted); font-weight: 400; }
  .modelo-sin { color: var(--muted); }
  .modelo-pie {
    margin-top: 8px;
    font-size: 11px;
    line-height: 1.45;
    color: var(--muted);
  }
  .modelo-pie .sin-validar { color: var(--amber); }
  /* De donde salio el porcentaje. Va DEBAJO de la nota al pie y mas
     apagado: es procedencia, no advertencia. La mayoria de las veces dice
     algo tranquilizador (datos de anteayer) y no tiene que competir con el
     contenido. */
  .modelo-origen {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--line);
    font-size: 10px;
    color: var(--muted);
  }
  /* Cuando el dato SI esta viejo se marca con borde punteado, igual que el
     chip de tarjetas dudosas: la misma idea (este numero tiene un problema)
     se senala de la misma forma en toda la app, y se distingue sin depender
     del color. */
  .modelo-origen.origen-viejo {
    border: 1px dashed var(--amber);
    border-radius: 6px;
    padding: 5px 7px;
    margin-top: 8px;
  }
  .modelo-origen .origen-aviso { color: var(--amber); font-weight: 600; }
  .modelo-nota .sin-validar { color: var(--amber); }
  .price-warn { color: var(--amber); }
  .price-good { color: var(--accent); }
  .pred-teaser b { color: var(--text); }
  .narrative { font-size: 14px; line-height: 1.5; color: var(--text); margin-bottom: 10px; }
  .best-bet {
    font-size: 13px;
    background: rgba(199, 123, 94, 0.1);
    border: 1px solid rgba(199, 123, 94, 0.3);
    border-radius: 8px;
    padding: 8px 12px;
    color: var(--amber);
  }
  .best-bet b { color: var(--text); }
  .alert-header { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); margin-bottom: 6px; }
  .match-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
  }
  .team-side {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 15px;
    font-weight: 600;
    min-width: 0;
  }
  .team-side span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .crest {
    width: 20px;
    height: 20px;
    object-fit: contain;
    flex-shrink: 0;
  }
  .vs-label { font-size: 11px; color: var(--muted); flex-shrink: 0; padding: 0 4px; }
  /* ------------------------------------------------------------------
     CELULAR
     Hasta el 2026-08-18 toda la hoja tenia UNA media query, que solo
     cambiaba el tamaño de la fuente y de los escudos: la pagina estaba
     diseñada para escritorio con un parche. Lo de aca abajo la adapta de
     verdad, con la barra de pestañas convertida en navegacion inferior
     (donde llega el pulgar) y los controles agrandados a 44px, que es el
     minimo tactil recomendado.
     ------------------------------------------------------------------ */
  @media (max-width: 720px) {
    body {
      padding: 16px 12px 84px;   /* el padding de abajo deja lugar a la barra */
    }
    h1 { font-size: 22px; }

    /* Las pestañas pasan a barra inferior fija. Es el mismo marcado y el
       mismo JS: solo cambia la presentacion. */
    .tabs {
      position: fixed;
      left: 0; right: 0; bottom: 0;
      z-index: 60;
      margin: 0;
      gap: 0;
      background: var(--card-bg);
      border-top: 1px solid var(--border);
      border-bottom: none;
      overflow-x: visible;
      /* env(safe-area-inset-bottom): la franja del gesto en iPhone y en los
         Android con navegacion por gestos. Sin esto, la barra queda debajo
         de la manito del sistema y no se puede tocar. */
      padding: 4px 2px calc(4px + env(safe-area-inset-bottom, 0px));
      /* Bajada de 0.35 a 0.10 con el tema claro: una sombra pensada para
         separar del negro se ve como una mancha sobre crema. */
      box-shadow: 0 -2px 12px rgba(23, 33, 31, 0.10);
    }
    .tab-btn {
      flex: 1;
      min-width: 0;
      min-height: 48px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 2px;
      padding: 4px 2px;
      font-size: 10px;
      border-bottom: none;
      border-top: 2px solid transparent;
    }
    .tab-btn.active { border-bottom-color: transparent; border-top-color: var(--verde); }
    .tab-ico { margin-right: 0; }
    /* Las etiquetas nuevas (Partidos, Análisis, Guías, Apuestas, Cuenta)
       entran enteras en un quinto de pantalla, así que ya no hace falta la
       versión corta que existía para "Detalle técnico". */
    .tab-txt { display: block; font-size: 9.5px; }

    /* Controles al minimo tactil de 44px. */
    .search-box { font-size: 16px; padding: 12px 14px; }  /* 16px evita el zoom de iOS */
    .league-btn { padding: 10px 14px; font-size: 13px; }
    .log-bet-btn, .instalar-btn { min-height: 44px; }

    /* La tarjeta gana ancho: en un telefono cada pixel lateral cuenta. */
    .alert-card, .pred-card, .report-card { padding: 12px; }
    .team-side { font-size: 13px; }
    .crest { width: 18px; height: 18px; }
    .precio-valor { font-size: 23px; }

    /* El top del dia en telefono: el nombre del partido se corta antes que
       aplastar la cuota, que es el dato por el que existe la seccion. */
    .top-pick-match { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .top-pick-price { text-align: right; }
  }

  /* Los filtros ocupan media pantalla de telefono. Se pliegan y el usuario
     los abre si los quiere (ver el JS que los cierra en pantallas chicas). */
  .screener > summary {
    cursor: pointer;
    list-style: none;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
  }
  .screener > summary::-webkit-details-marker { display: none; }
  .screener > summary::after { content: " ▾"; color: var(--muted); }
  .screener[open] > summary::after { content: " ▴"; }
  .market-tag {
    display: inline-block;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 12px;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 999px;
    margin-bottom: 10px;
  }
  .projected { font-size: 13px; margin-bottom: 8px; color: var(--muted); }
  .projected b { color: var(--text); }
  .signal { font-size: 13px; margin-bottom: 4px; color: var(--muted); }
  .signal .side { color: var(--accent); font-weight: 700; font-size: 11px; margin-right: 4px; }
  .signal b { color: var(--text); }
  .sample { font-size: 11px; color: var(--muted); margin-top: 8px; opacity: 0.7; }
  .expected-goals { font-size: 13px; color: var(--muted); margin-bottom: 12px; }
  .expected-goals b { color: var(--text); }
  .outcome-bar {
    display: flex;
    height: 28px;
    border-radius: 6px;
    overflow: hidden;
    margin-bottom: 14px;
    font-size: 11px;
    font-weight: 600;
  }
  .outcome-seg { display: flex; align-items: center; justify-content: center; min-width: 40px; }
  .outcome-seg.home { background: var(--accent); color: var(--on-accent); }
  .outcome-seg.draw { background: var(--muted); color: var(--on-accent); }
  .outcome-seg.away { background: var(--blue); color: var(--on-accent); }
  .scores-row { display: flex; gap: 8px; flex-wrap: wrap; }
  .goals-markets-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
  /* Mercado todavia SIN calibrar (Over 1.5 y Over 3.5: no entraron en la
     medicion del 2026-08-26). Se atenua y lleva un asterisco en la etiqueta:
     mostrarlo igual que uno calibrado seria darle la misma confianza a dos
     numeros que no la tienen. El asterisco ademas se ve sin color. */
  .gm-crudo { opacity: 0.78; }  /* misma razón que .dg-pocas */
  .gm-chip {
    background: rgba(111, 168, 220, 0.1);
    border: 1px solid rgba(111, 168, 220, 0.3);
    border-radius: 8px;
    padding: 5px 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 56px;
  }
  .gm-label { font-size: 10px; color: var(--muted); }
  .gm-val { font-size: 13px; font-weight: 700; color: var(--blue); }
  .score-chip {
    background: rgba(199, 123, 94, 0.12);
    border: 1px solid rgba(199, 123, 94, 0.3);
    border-radius: 8px;
    padding: 6px 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 56px;
  }
  .score-val { font-size: 13px; font-weight: 700; color: var(--amber); }
  .score-prob { font-size: 11px; color: var(--muted); }
  .empty { color: var(--muted); font-style: italic; padding: 16px 0; }
  .status-banner {
    background: rgba(199, 123, 94, 0.12);
    border: 1px solid rgba(199, 123, 94, 0.4);
    color: var(--amber);
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 13px;
    margin-bottom: 20px;
  }
  .how-to-read {
    background: rgba(111, 168, 220, 0.08);
    border: 1px solid rgba(111, 168, 220, 0.25);
    border-radius: 10px;
    padding: 12px 14px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--text);
    margin: 14px 0;
  }
  .how-to-read b { color: var(--blue); }
  .search-box {
    width: 100%;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px;
    color: var(--text);
    font-size: 14px;
    font-family: inherit;
    margin-top: 10px;
    box-sizing: border-box;
  }
  .stats-block {
    background: rgba(255,255,255,0.02);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    margin: 10px 0;
  }
  .stats-title { font-size: 13px; font-weight: 700; margin-bottom: 8px; }

  /* Barras comparativas en vez de la tabla de numeros que habia antes.
     Con dieciseis filas de cifras hay que leerlas una por una para saber
     quien domina cada rubro; con la barra se ve de un vistazo. Ademas
     resuelve mejor el celular, donde una tabla de tres columnas queda
     apretada. */
  .st-head {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 11px;
    color: var(--muted);
    font-weight: 600;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 4px;
  }
  .st-head span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .st-head span:last-child { text-align: right; }

  .st-fila { margin: 7px 0; }
  .st-cab {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: 12px;
    margin-bottom: 3px;
  }
  .st-val {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    flex-shrink: 0;
    min-width: 34px;
  }
  .st-cab .st-val:last-child { text-align: right; }
  .st-lbl {
    color: var(--muted);
    text-align: center;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .st-barra {
    display: flex;
    height: 4px;
    border-radius: 999px;
    overflow: hidden;
    background: rgba(140, 154, 144, 0.16);
  }
  /* Cada lado con su color: el local en verde y el visitante en ambar. No es
     decoracion — con un solo color no se distingue si la barra "llena" es la
     de uno o la del otro. */
  .st-izq { background: var(--accent); }
  .st-der { background: var(--amber); }

  .st-sec {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--accent);
    text-align: center;
    margin: 14px 0 6px;
  }
  .st-sec:first-of-type { margin-top: 6px; }
  .stats-note {
    font-size: 11px; color: var(--muted); line-height: 1.4;
    margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
  }
  /* Los partidos sin alerta NO se atenuan.
     Antes iban con opacity 0.72, que los hacia leer como de segunda. Pero
     mucha gente usa la app para su propio analisis y las estadisticas son
     el producto para ellos: un partido sin sugerencia nuestra puede ser
     justo el que le interesa. Solo se saca el hueco de la apuesta sugerida,
     que ahi no va ninguna. */
  .sin-analisis .best-bet-teaser { display: none; }
  /* Precio cerrado: se ve que HAY un dato, pero no cuál. La idea es que dé
     curiosidad, no que parezca un error o que falta información. */
  /* Fecha y cuenta regresiva en "Mejor precio del dia". */
  .top-pick-cuando {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: baseline;
    font-size: 11px;
    color: var(--muted);
    margin-top: 3px;
    font-variant-numeric: tabular-nums;
  }
  .top-pick-cuando .falta {
    padding: 1px 6px;
    border-radius: 999px;
    background: rgba(140, 154, 144, 0.14);
  }
  /* Menos de 2 horas: hay que decidir ya. */
  .top-pick-cuando .falta.urgente { color: var(--amber); background: rgba(199, 123, 94, 0.14); }
  /* La opacidad subio de .6 a .78 con el tema claro. Atenuar por opacidad
     castiga mucho mas sobre fondo claro: el mismo .6 que sobre negro dejaba
     un gris legible, sobre crema lo deja en ~2,5:1 y no se lee. El tachado
     ya dice "esto venció"; la opacidad solo acompaña. */
  .top-pick-cuando .falta.vencido { opacity: .78; text-decoration: line-through; }
  /* Ya no fuerza renglon propio: es la tercera columna de la fila. */
  .top-pick-accion { flex: 0 0 auto; }
  .top-pick-btn {
    font-size: 17px;
    line-height: 1;
    /* 44px es el minimo de area tactil (Apple y Google dicen lo mismo). El
       boton perdio el TEXTO, no el tamaño: achicarlo por debajo de esto haria
       que fallara el toque justo en la seccion pensada para actuar rapido. */
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .precio-cerrado .precio-tapado { color: var(--muted); }
  .precio-cerrado .precio-tapado b {
    color: var(--accent); letter-spacing: 2px; font-size: 13px;
  }
  .precio-cerrado .precio-tapado a {
    color: var(--accent); text-decoration: underline; margin-left: 4px;
  }
  .top-pick-tapado .top-pick-odds { color: var(--accent); letter-spacing: 2px; }
  .top-pick-tapado .top-pick-book { font-size: 10px; }
  .login-caja {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 16px;
  }
  .login-titulo { font-size: 15px; font-weight: 700; }
  .login-sub { font-size: 12px; color: var(--muted); margin: 4px 0 12px; line-height: 1.4; }
  .login-input {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    color: var(--text);
    font-size: 14px;
    margin-bottom: 8px;
  }
  .login-input:focus { outline: none; border-color: var(--accent); }
  .btn-google {
    width: 100%;
    background: #fff;
    color: #1f1f1f;
    border: none;
    border-radius: 8px;
    padding: 11px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
  }
  .btn-google:hover { background: #f1f1f1; }
  .login-sep {
    display: flex; align-items: center; gap: 10px;
    margin: 14px 0 12px; color: var(--muted); font-size: 11px;
  }
  .login-sep::before, .login-sep::after {
    content: ""; flex: 1; height: 1px; background: var(--border);
  }
  .login-acciones { display: flex; gap: 8px; }
  .btn-primario {
    flex: 1; background: var(--accent); color: var(--on-accent); border: none;
    border-radius: 8px; padding: 10px; font-size: 13px; font-weight: 700; cursor: pointer;
  }
  .btn-secundario {
    flex: 1; background: transparent; color: var(--text);
    border: 1px solid var(--border); border-radius: 8px;
    padding: 10px; font-size: 13px; font-weight: 600; cursor: pointer;
  }
  .btn-secundario:hover { border-color: var(--accent); color: var(--accent); }
  .login-msg { font-size: 12px; margin-top: 10px; line-height: 1.4; min-height: 1em; }

  /* "Olvidaste tu contrasena". Es un <button> y no un <a> porque no navega a
     ningun lado: dispara el envio del correo. Un <a href="#"> se veria igual
     pero mandaria al teclado y al lector de pantalla la senal equivocada.
     Se pinta como enlace para que no compita con Entrar / Crear cuenta. */
  .login-olvide {
    display: block;
    margin: 10px auto 0;
    padding: 4px;
    background: none;
    border: 0;
    color: var(--muted, inherit);
    font: inherit;
    font-size: 12px;
    text-decoration: underline;
    cursor: pointer;
  }
  .login-olvide:hover { color: var(--text); }

  /* Edad mínima y enlace a la política (2026-09-11). Chico y en tono de
     nota: es un aviso, no un paso del formulario. */
  .login-legal {
    margin-top: 10px;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--muted);
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
  }
  .login-legal a, .pie-priv { color: var(--muted); text-decoration: underline; }

  /* FICHA CERRADA (freemium, 2026-09-11). Ocupa el lugar de Estadísticas y
     Forma cuando van detrás del registro. Invita, no niega: dice qué hay
     adentro y que es gratis. Tono de panel, no de error. */
  .ficha-cerrada {
    padding: 16px 14px;
    border: 1px dashed var(--border);
    border-radius: 10px;
    text-align: center;
    background: var(--card-bg);
  }
  .fc-msg { font-size: 13px; line-height: 1.5; color: var(--muted); }
  .fc-msg b { color: var(--text); }
  .fc-btn { margin-top: 10px; }
  /* Cuando ya cargó, es la ficha de siempre: sin recuadro punteado. */
  .ficha-cerrada[data-estado="ok"] {
    padding: 0; border: none; text-align: left; background: none;
  }
  .login-legal a:hover, .pie-priv:hover { color: var(--text); }
  .pie-priv { font-size: 12px; }
  .login-olvide:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .login-msg.error { color: var(--danger); }
  .login-msg.ok { color: var(--accent); }
  .login-legacy {
    font-size: 11px; color: var(--muted); line-height: 1.45;
    margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);
  }
  /* Sin esto el enlace sale con el azul por defecto del navegador, que sobre
     el fondo oscuro queda ilegible. */
  .login-legacy a { color: var(--accent); text-decoration: underline; }
  .login-quien { font-size: 14px; margin-bottom: 10px; }
  .login-via {
    font-size: 11px; color: var(--muted); margin-left: 6px;
    border: 1px solid var(--border); border-radius: 5px; padding: 1px 6px;
  }
  .instalar-barra {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--card-bg);
    border: 1px solid rgba(212, 165, 68, 0.35);
    border-radius: 10px;
    padding: 10px 12px;
    margin-bottom: 14px;
  }
  .instalar-texto { flex: 1; min-width: 0; line-height: 1.35; }
  .instalar-texto b { display: block; font-size: 14px; }
  .instalar-texto span { font-size: 12px; color: var(--muted); }
  .instalar-btn {
    background: var(--accent); color: var(--on-accent); border: none;
    border-radius: 8px; padding: 8px 14px;
    font-size: 13px; font-weight: 700; cursor: pointer;
    flex-shrink: 0;
  }
  .instalar-x {
    background: none; border: none; color: var(--muted);
    font-size: 15px; cursor: pointer; padding: 4px 2px; flex-shrink: 0;
  }
  .guias-link {
    display: inline-block;
    color: var(--accent);
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 8px;
  }
  .guias-link:hover { text-decoration: underline; }
  .top-picks {
    background: linear-gradient(160deg, rgba(212, 165, 68, 0.10), rgba(212, 165, 68, 0.02));
    border: 1px solid rgba(212, 165, 68, 0.35);
    border-radius: 12px;
    padding: 14px 16px;
    margin-bottom: 18px;
  }
  .top-picks-title {
    font-size: 15px; font-weight: 800; color: var(--accent);
    display: flex; align-items: center; gap: 6px; margin-bottom: 10px;
  }

  /* El icono (i) que reemplaza los parrafos largos de explicacion.
     CSS-only (sin JS): hover para mouse, :focus para teclado, asi que sigue
     siendo accesible sin apuntador. */
  .info-i {
    width: 16px; height: 16px; border-radius: 999px;
    border: 1px solid var(--muted); color: var(--muted);
    font-size: 10px; font-weight: 700; font-style: normal;
    display: inline-grid; place-items: center;
    cursor: help; position: relative; flex: none;
  }
  .info-tip {
    display: none; position: absolute; top: 22px; left: 0;
    width: 220px; max-width: 70vw;
    background: var(--card-bg-2); border: 1px solid var(--border);
    border-radius: 8px; padding: 9px 11px;
    font-size: 11.5px; font-weight: 400; line-height: 1.45;
    color: var(--text-2); text-transform: none; letter-spacing: 0;
    z-index: 5;
  }
  .info-i:hover .info-tip, .info-i:focus .info-tip { display: block; }
  /* TRES COLUMNAS EN UN RENGLON: partido | cuota | boton.
     Antes el boton iba en una fila propia debajo (flex-wrap + flex-basis:100%)
     y cada fila medía 152px, de los cuales 52 eran solo el boton. Con cinco
     filas, el bloque ocupaba 947px — el 69% de todo lo que había antes del
     primer partido, que arrancaba a 1,7 pantallas del tope.
     El boton compacto (solo el icono) entra al lado de la cuota sin apretar
     nada, porque el nombre del partido ya se corta con ellipsis si no cabe. */
  .top-pick {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 0;
    border-top: 1px solid rgba(212, 165, 68, 0.15);
  }
  .top-pick-main { flex: 1; min-width: 0; }
  /* Es un <a> desde el 2026-09-11 (lleva al análisis del partido, en la
     página de su liga). Se ve como el texto que era, con el subrayado solo
     al pasar por encima: una fila de destacados con tres enlaces subrayados
     se lee como una lista de links y no como el dato que es. */
  .top-pick-match {
    display: block; font-size: 14px; font-weight: 700;
    color: var(--text); text-decoration: none;
  }
  .top-pick-match:hover { text-decoration: underline; }
  .top-pick-match:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .top-pick-bet { font-size: 12px; color: var(--muted); margin-top: 2px; }
  .top-pick-price { text-align: right; flex-shrink: 0; }
  .top-pick-odds { font-size: 17px; font-weight: 800; color: var(--accent); line-height: 1.1; }
  .top-pick-book { font-size: 11px; color: var(--muted); }
  .top-pick-edge { font-size: 12px; font-weight: 700; color: var(--accent); }
  .screener {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 12px;
  }
  .screener-title {
    font-size: 13px; font-weight: 700; margin-bottom: 8px;
    display: flex; align-items: center; gap: 6px;
  }
  .screener-opt {
    display: block;
    font-size: 13px;
    color: var(--muted);
    margin-bottom: 6px;
    cursor: pointer;
  }
  .screener-opt select {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 3px 6px;
    font-size: 13px;
    margin-left: 4px;
  }
  .screener-count {
    font-size: 12px;
    color: var(--accent);
    font-weight: 600;
    margin-top: 8px;
  }
  .search-box::placeholder { color: var(--muted); }
  .search-box:focus { outline: none; border-color: var(--accent); }
  .tabs {
    display: flex;
    gap: 6px;
    margin: 16px 0 18px;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab-btn {
    background: none;
    border: none;
    white-space: nowrap;
    flex-shrink: 0;
    color: var(--muted);
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    padding: 10px 14px;
    cursor: pointer;
    border-bottom: 2px solid transparent;
  }
  .tab-btn:hover { color: var(--text); }
  /* Activo = VERDE, no oro, en las dos presentaciones (barra lateral en
     escritorio, barra inferior en telefono). El oro significa "acá pagan
     mas"; usarlo tambien para "estas acá" le gasta el significado a lo unico
     que la app tiene medido. */
  .tab-btn.active { color: var(--verde-oscuro); border-bottom-color: var(--verde); }
  /* En escritorio el icono va al lado del texto. */
  .tab-ico { margin-right: 5px; }
  .league-menu {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin: 16px 0 8px;
  }
  .league-btn {
    background: var(--card-bg);
    border: 1px solid var(--border);
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
    padding: 6px 14px;
    border-radius: 999px;
    cursor: pointer;
    font-family: inherit;
  }
  .league-btn:hover { border-color: var(--accent); color: var(--text); }
  .league-btn.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
  .log-bet-btn {
    margin-top: 12px;
    background: rgba(111, 168, 220, 0.12);
    border: 1px solid rgba(111, 168, 220, 0.4);
    color: var(--blue);
    font-size: 12px;
    font-weight: 600;
    padding: 8px 14px;
    border-radius: 8px;
    cursor: pointer;
    font-family: inherit;
  }
  .log-bet-btn:hover { background: rgba(111, 168, 220, 0.22); }
  .bets-summary { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }
  .connected-as { font-size: 12px; color: var(--muted); margin-bottom: 10px; }
  .connected-as b { color: var(--accent); }
  .summary-chip {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 14px;
    display: flex;
    flex-direction: column;
    min-width: 90px;
  }
  .summary-chip .summary-label { font-size: 10px; color: var(--muted); }
  .summary-chip .summary-val { font-size: 16px; font-weight: 700; color: var(--text); }
  .summary-chip.positive .summary-val { color: var(--accent); }
  .summary-chip.negative .summary-val { color: var(--danger); }
  /* La ficha de banca es un botón (se edita tocándola): mismo aspecto que
     las demás, con la pista de que se puede tocar. */
  .summary-chip.banca-btn {
    font: inherit; line-height: inherit; color: inherit;
    text-align: left; cursor: pointer; margin: 0;
    border-style: dashed;
  }
  /* El ✎ y la → salen de otra tipografía, más alta: sin fijar la línea,
     esta ficha quedaba 3px más alta que las vecinas. */
  .summary-chip.banca-btn .summary-label { line-height: 12px; }
  .summary-chip.banca-btn .summary-val { line-height: 20px; }
  .summary-chip.banca-btn:hover { border-color: var(--accent); }
  .summary-chip.banca-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .summary-nota {
    flex-basis: 100%;
    font-size: 11px; line-height: 1.5; color: var(--muted);
  }
  .summary-nota b { color: var(--text); font-weight: 600; }
  .calibration-block {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 16px;
  }
  .calibration-title { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
  #calibration-canvas { width: 100%; max-width: 380px; height: 160px; }
  .bet-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px;
    margin-bottom: 8px;
  }
  .bet-match { font-size: 13px; font-weight: 600; }
  .bet-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
  .bet-actions { display: flex; gap: 4px; flex-shrink: 0; }
  .bet-btn {
    border: none;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 600;
    padding: 5px 8px;
    cursor: pointer;
    font-family: inherit;
    color: var(--on-accent);
  }
  .bet-win { background: var(--accent); }
  .bet-loss { background: var(--danger); }
  .bet-void { background: var(--muted); }
  .bet-del { background: transparent; color: var(--muted); border: 1px solid var(--border); }
  footer { text-align: center; color: var(--muted); font-size: 11px; margin-top: 40px; }

  /* ------------------------------------------------------------------
     MENU DE LIGAS (navegacion entre paginas)
     Desde el 2026-08-18 el inicio NO carga los 269 partidos: son enlaces
     a la pagina de cada liga. Eran 2,7 MB y ~69.000 elementos de DOM en un
     solo documento, y en un telefono de gama media se sentia al hacer
     scroll. Ahora el inicio pesa una fraccion y cada liga se descarga solo
     si el usuario entra.
     ------------------------------------------------------------------ */
  a.league-btn {
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
  }
  a.league-btn.activa {
    background: var(--accent);
    color: var(--on-accent);
    border-color: var(--accent);
  }
  .league-n {
    background: rgba(140, 154, 144, 0.22);
    border-radius: 999px;
    padding: 0 6px;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
  }
  a.league-btn.activa .league-n { background: rgba(0, 0, 0, 0.22); }

  .inicio-guia {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 16px;
    margin: 18px 0 12px;
  }
  .inicio-guia-titulo { font-size: 15px; font-weight: 700; margin-bottom: 4px; }
  .inicio-guia-sub { font-size: 13px; color: var(--muted); line-height: 1.5; }

  /* El menu del inicio es la navegacion principal: botones mas grandes y
     en cuadricula, para que se toquen bien con el pulgar. */
  .league-menu-grande {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 8px;
  }
  .league-menu-grande a.league-btn {
    justify-content: space-between;
    min-height: 44px;
    padding: 10px 14px;
    font-size: 13px;
  }

  /* Selector de idioma. Vive en "Tu cuenta" y no en la barra de arriba a
     proposito: se toca una vez y despues nunca mas, asi que ocupar un lugar
     permanente en la navegacion seria gastar el espacio mas caro de la app en
     algo que casi nadie vuelve a usar. */
  .idioma-caja {
    margin-top: 18px;
    padding: 12px 14px;
    border: 1px solid var(--borde, rgba(127, 127, 127, 0.28));
    border-radius: 10px;
  }
  .idioma-lbl {
    display: block;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted, inherit);
    margin-bottom: 6px;
  }
  .idioma-sel {
    width: 100%;
    padding: 8px 10px;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    background: var(--chip-bg, rgba(127, 127, 127, 0.10));
    border: 1px solid var(--borde, rgba(127, 127, 127, 0.28));
    border-radius: 8px;
  }
  .idioma-sel:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .idioma-nota {
    margin-top: 8px;
    font-size: 11px;
    line-height: 1.45;
    color: var(--muted, inherit);
  }

  /* Termino tecnico que se lee igual en todos los idiomas (BTTS, Over 2.5).
     Va en versalita ligera para que se reconozca como vocabulario de casa de
     apuestas y no como una palabra suelta en ingles. Sin color propio: no es
     mas importante que lo que lo rodea, solo distinto. */
  .term {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
    white-space: nowrap;
  }

  /* Borrar la cuenta. Separado de "Salir" por una linea y en tono de peligro
     contenido: tiene que encontrarse cuando se busca y NO invitar a tocarlo de
     paso. Por eso es un boton de borde y no un boton lleno de rojo — un rojo
     solido compite con el resto de la interfaz y termina siendo lo primero que
     mira el ojo. */
  .borrar-caja {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--borde, rgba(127, 127, 127, 0.28));
  }
  .btn-borrar {
    padding: 7px 12px;
    font: inherit;
    font-size: 13px;
    color: var(--down, #d9534f);
    background: none;
    border: 1px solid currentColor;
    border-radius: 8px;
    cursor: pointer;
  }
  .btn-borrar:hover { background: rgba(217, 83, 79, 0.10); }
  .btn-borrar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .borrar-nota {
    margin-top: 6px;
    font-size: 11px;
    line-height: 1.45;
    color: var(--muted, inherit);
  }

  /* Aviso sobre la sugerencia (ventaja afirmada sospechosa). Va debajo del
     precio y en tono contenido: informa sobre el NUMERO, no es una alarma
     sobre el partido. Sin rojo solido, que competiria con el titular — y el
     titular es el precio, que es lo unico con ventaja demostrada. */
  .precio-aviso {
    margin-top: 6px;
    font-size: 11px;
    line-height: 1.4;
    color: var(--muted, inherit);
    font-style: italic;
  }

  /* EL PUENTE A LA TABLA DE MERCADOS (2026-09-10).

     Desde que el titular sale del PRECIO y no del pick del modelo, hay
     tarjetas que antes no mostraban nada y ahora encabezan con una cuota. Esta
     linea dice que hay mas para comparar y que se abre ahi mismo: la tabla
     completa ya existe (`_mercados_html`, ficha "Mercados", que abre por
     defecto). No se duplica la tabla en la tarjeta cerrada a proposito — con
     hasta 30 tarjetas por pagina de liga, seis filas en cada una haria la
     pagina inescaneable. */
  .precio-mas {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid rgba(200, 164, 92, 0.3);
    font-size: 11px;
    color: var(--muted, inherit);
  }

  /* EL MODELO, EN SU LUGAR.

     Hasta hoy gobernaba la tarjeta: sin pick del modelo no habia precio, y eso
     dejaba 151 partidos con cuotas reales mostrando NADA. Ahora es una linea,
     fuera del recuadro dorado y en tono de nota — dice lo que estima y aclara
     que es una estimacion. Deliberadamente SIN color de acento: el acento esta
     reservado para el precio, que es lo unico con ventaja demostrada. */
  .modelo-nota {
    margin-top: 7px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--muted, inherit);
  }

  .modelo-nota b {
    color: var(--text);
    font-weight: 600;
  }

  /* Los reparos sobre la ESTIMACION del modelo viven acá, no colgados del
     precio: los tres textos posibles ("paga X y vale Y", "el modelo se aleja
     mucho del mercado", "afirma mucha ventaja +N%") hablan del pronostico, y
     ese +N% no aparece en el titular —que muestra line shopping— asi que
     arriba quedaba como un aviso sobre un numero invisible. */
  .modelo-reparo {
    margin-top: 5px;
    font-size: 11px;
    line-height: 1.4;
    font-style: italic;
  }

  /* ====================================================================
     FASE 1b — EL SHELL: barra lateral + ancho real.

     VA AL FINAL DEL ARCHIVO A PROPOSITO. Un `@media` no suma especificidad,
     asi que si este bloque estuviera arriba, las reglas de `.tabs` de la
     linea ~2080 lo pisarian. Al final gana por orden de cascada sin tener
     que inflar selectores.

     SOLO DE 1024px PARA ARRIBA. Debajo de eso la pagina queda EXACTAMENTE
     como estaba: la nav vuelve a ser la barra inferior fija y el `<aside>`
     se disuelve con `display: contents`. El movil no se toca en esta fase.

     No se renombro ninguna clase. La nav de la izquierda es el mismo
     `<nav class="tabs">` de siempre, con los mismos botones y el mismo JS:
     solo cambia donde se dibuja.
     ==================================================================== */

  /* Por defecto (telefono) el aside no existe visualmente: sus hijos pasan a
     ser hijos directos de .wrap y todo queda como antes. */
  .app-side { display: contents; }
  .side-marca { display: none; }

  @media (min-width: 1024px) {
    body { padding: 0; }

    .wrap {
      max-width: none;
      margin: 0;
      min-height: 100vh;
      display: grid;
      grid-template-columns: 236px minmax(0, 1fr);
      grid-template-areas:
        "banner banner"
        "lado   top"
        "lado   main"
        "lado   pie";
      align-content: start;
    }

    #instalar-app { grid-area: banner; margin: 0; border-radius: 0; }

    /* ---- La columna izquierda ---- */
    .app-side {
      grid-area: lado;
      display: flex;
      flex-direction: column;
      position: sticky;
      top: 0;
      height: 100vh;
      padding: 20px 12px 16px;
      background: var(--card-bg);
      border-right: 1px solid var(--border);
    }
    .side-marca {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 0 10px 22px;
    }
    .side-mk {
      width: 36px; height: 36px; flex: none;
      display: grid; place-items: center;
      background: var(--verde); color: #fff;
      border-radius: 9px;
      font-weight: 800; font-size: 17px; letter-spacing: -1px;
    }
    .side-nom b {
      display: block; font-size: 18px; font-weight: 800;
      letter-spacing: -.4px; line-height: 1.1;
    }
    .side-nom > span {
      display: block; font-size: 9.5px; font-weight: 600;
      letter-spacing: .16em; text-transform: uppercase;
      color: var(--muted); margin-top: 2px;
    }

    /* La misma nav, en vertical. */
    .tabs {
      flex-direction: column;
      gap: 2px;
      margin: 0;
      border-bottom: none;
      overflow: visible;
    }
    .tab-btn {
      display: flex;
      align-items: center;
      gap: 11px;
      width: 100%;
      min-height: 42px;
      padding: 0 12px;
      border-radius: 9px;
      border-bottom: none;
      font-size: 14.5px;
      font-weight: 500;
      text-align: left;
      text-decoration: none;
      position: relative;
    }
    .tab-btn:hover { background: var(--card-bg-2); color: var(--text); }
    /* El activo pasa a VERDE: es identidad de marca, no un precio. El oro
       se queda para lo unico que lo merece — donde pagan mas. */
    .tab-btn.active {
      background: var(--verde-suave);
      color: var(--verde-oscuro);
      border-bottom-color: transparent;
      font-weight: 700;
    }
    .tab-btn.active::before {
      content: "";
      position: absolute; left: -12px; top: 9px; bottom: 9px;
      width: 3px; border-radius: 0 3px 3px 0;
      background: var(--verde);
    }
    .tab-ico { margin-right: 0; display: grid; place-items: center; }
    .tab-ico svg { width: 18px; height: 18px; }

    /* ---- La barra de arriba ---- */
    .app-hd {
      grid-area: top;
      padding: 14px 28px;
      border-bottom: 1px solid var(--border);
      background: var(--card-bg);
    }
    .app-hd h1 { font-size: 21px; }

    /* ---- El contenido ---- */
    .app-main {
      grid-area: main;
      /* Tope generoso pero no infinito: mas de ~1400px y las filas de la
         tabla de estadisticas quedan tan anchas que el ojo pierde el
         renglon. */
      max-width: 1400px;
      width: 100%;
      padding: 20px 28px 48px;
    }
    .subtitle { margin-top: 0; }

    footer { grid-area: pie; padding: 0 28px 28px; }
  }

  /* Entre 1024 y 1300 la lateral se achica un poco: a esa altura, 236px de
     nav le sacan demasiado a las tablas de estadisticas. */
  @media (min-width: 1024px) and (max-width: 1300px) {
    .wrap { grid-template-columns: 208px minmax(0, 1fr); }
    .app-main { padding-left: 20px; padding-right: 20px; }
    .app-hd { padding-left: 20px; padding-right: 20px; }
  }

  /* ---- El detalle del partido, a dos columnas (Fase 1b) --------------
     Solo de 1024px para arriba, igual que el shell. Debajo de eso las dos
     columnas se apilan y el orden queda identico al de siempre, porque las
     secciones de `.cd-side` ya eran las ultimas del orden anterior.

     `min-width: 0` en las dos: sin eso, la tabla de estadisticas —que es
     ancha— estira su columna de grilla y desborda la tarjeta. Es el fallo
     clasico de CSS Grid y no se ve hasta que hay una tabla adentro. */
  @media (min-width: 1024px) {
    .card-detail {
      display: grid;
      grid-template-columns: minmax(0, 1fr) 340px;
      gap: 22px;
      align-items: start;
    }
    .cd-main, .cd-side { min-width: 0; }
    .cd-side {
      display: flex;
      flex-direction: column;
      gap: 12px;
      /* Separada por una linea en vez de por una caja: la tarjeta ya es una
         caja, y meter otra adentro genera el "card dentro de card" que
         aplana la jerarquia. */
      border-left: 1px solid var(--border-soft);
      padding-left: 22px;
    }
    /* Adentro de la columna angosta, la tabla del modelo respira mejor sin
       el margen que traia para el ancho completo. */
    .cd-side > *:first-child { margin-top: 0; }
  }

  /* ---- Manrope donde el texto ESTRUCTURA -----------------------------
     Navegacion, marca y titulos de ficha. El resto —numeros, tablas,
     cuerpo— se queda con Inter, que es lo que esta app muestra casi siempre.

     VA AL FINAL POR LA MISMA RAZON QUE EL SHELL: `.tab-btn` trae
     `font-family: inherit` desde la linea ~2100, y a igual especificidad
     gana la ultima. Puesta arriba, esta regla no hacia nada — se vio en el
     navegador, no en los tests. */
  .tab-btn,
  .side-nom b,
  .ficha-tit,
  .st-sec,
  .alert-header .league { font-family: var(--fuente-tit); }

  /* ---- La franja de la competición (Fase 1b) --------------------------
     Solo aparece en las paginas de liga. El fondo verde oscuro es el unico
     lugar de la app donde el verde ocupa superficie grande: en el resto es
     un acento. Aca se lo puede permitir porque es una franja corta y porque
     es justamente donde la marca tiene que hacerse ver.

     El campito de fondo va al 9% de opacidad. Es el detalle de "pizarra
     tactica" del que hablo la usuaria: tiene que reconocerse sin leerse. */
  .hero-liga {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 18px;
    background: var(--verde-banda);
    color: #fff;
    border-radius: 14px;
    padding: 22px 24px;
    margin: 0 0 14px;
  }
  .hero-campo {
    position: absolute;
    right: -28px; top: -38px;
    width: 300px; height: 230px;
    opacity: .09;
    color: #fff;
    pointer-events: none;
  }
  .hero-txt { position: relative; z-index: 1; min-width: 0; }
  /* El h1 dentro del hero no hereda el de la barra: va mas grande y sin el
     borde superior que llevan los h2. */
  .hero-liga h1 {
    font-family: var(--fuente-tit);
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -.7px;
    line-height: 1.1;
    margin: 0;
    color: #fff;
  }
  .hero-liga p {
    margin: 5px 0 0;
    font-size: 13.5px;
    /* Blanco al 72% en vez de un gris fijo: sobre el verde oscuro un gris
       del sistema de tokens (pensado para fondo claro) quedaria ilegible. */
    color: rgba(255, 255, 255, .72);
  }
  .hero-lema {
    position: relative; z-index: 1;
    margin: 0 0 0 auto;
    text-align: right;
    font-family: var(--fuente-tit);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    line-height: 1.55;
    color: rgba(255, 255, 255, .85);
  }
  /* La miga de pan de la barra: ocupa el lugar del h1 pero no es un
     encabezado. Mismas propiedades de caja para que el buscador siga a la
     derecha. */
  .app-hd .hd-migas {
    flex: 1;
    min-width: 0;
    font-family: var(--fuente-tit);
    font-size: 13.5px;
    font-weight: 600;
    color: var(--muted);
  }

  @media (max-width: 720px) {
    .hero-liga { padding: 16px 18px; gap: 12px; border-radius: 12px; }
    .hero-liga h1 { font-size: 22px; }
    /* El lema es lo primero que sobra en una pantalla angosta: es marca, no
       informacion. */
    .hero-lema { display: none; }
    .hero-campo { width: 210px; height: 165px; right: -34px; top: -26px; }
  }

  /* ====================================================================
     TEMA OSCURO — opcional, por eleccion explicita.
     
     El claro es el predeterminado y este se enciende con el interruptor de
     la barra de arriba. NO se sigue `prefers-color-scheme` a proposito: la
     app acaba de pasar a claro y quien la abre tiene que ver lo mismo que
     vio la ultima vez, no algo que depende de como tenga el telefono. Si
     algun dia se quiere auto-detectar, es una linea mas.

     SON LOS VALORES EXACTOS QUE TENIA LA APP hasta el 2026-09-09,
     recuperados del tag `antes-light-mode`. No es un oscuro nuevo inventado
     al reves del claro: es el que ya estaba probado y usado.

     OJO CON LOS NOMBRES: `--verde-oscuro` se llama asi por su papel en el
     tema CLARO (verde profundo sobre fondo suave). Aca tiene que volverse
     CLARO, porque el fondo suave pasa a ser oscuro y el token sigue siendo
     el color del TEXTO. El nombre describe el rol, no el tono.
     ==================================================================== */
  :root[data-theme="dark"] {
    --bg: #121316;
    --card-bg: #1B1D22;
    --card-bg-2: #242730;
    --border: #2E3138;
    --border-soft: #262933;
    --text: #F0EEE7;
    --text-2: #C7C4BA;
    --muted: #8D8A82;
    --accent: #D4A544;
    --accent-soft: rgba(212, 165, 68, 0.13);
    --on-accent: #14100A;
    --blue: #6FA8DC;
    --amber: #C77B5E;
    --danger: #D2705A;
    --up: #6FBF87;
    --down: #D2705A;
    /* Los verdes de marca, adaptados. El de la banda se queda profundo (el
       hero lleva texto blanco encima en los dos temas); el de texto se
       aclara para leerse sobre el tinte oscuro. */
    --verde: #3E8F76;
    --verde-oscuro: #7FC9AE;
    --verde-suave: #16261F;
    --verde-banda: #0C2C25;
    /* En oscuro la tarjeta se separa por tener el fondo mas claro que la
       pagina, asi que la sombra vuelve a ser casi nada. */
    --sombra: 0 1px 2px rgba(0, 0, 0, .28);
  }

  /* El interruptor de tema, en la barra de arriba. */
  .hd-tema {
    flex: none;
    display: grid;
    place-items: center;
    width: 44px; height: 44px;   /* minimo tactil */
    border-radius: 10px;
    color: var(--muted);
    cursor: pointer;
  }
  .hd-tema:hover { background: var(--card-bg-2); color: var(--text); }
  .hd-tema svg { width: 20px; height: 20px; fill: none;
                 stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
  /* Se muestra el icono de lo que vas a OBTENER al tocar, no el del tema
     actual: es lo que espera la mano. En claro se ve la luna (tocar = pasar
     a oscuro) y en oscuro el sol. */
  .hd-tema .ico-luna { display: block; }
  .hd-tema .ico-sol { display: none; }
  :root[data-theme="dark"] .hd-tema .ico-luna { display: none; }
  :root[data-theme="dark"] .hd-tema .ico-sol { display: block; }

  /* ---- La tarjeta de la lista, rediseñada (2026-09-09) ---------------
     NO se agregan renglones. El 2026-08-29 la usuaria pidio explicitamente
     que la tarjeta CERRADA fuera compacta (3-4 renglones) despues de
     comparar un prototipo contra la de produccion, que apilaba siete
     secciones antes del CTA. Esto reordena y jerarquiza lo que YA estaba;
     los indicadores del prototipo (Goles ↑ Alta) se dejaron afuera a
     proposito, porque volverian a apilar.

     Lo que cambia: la hora deja de ser un dato chico en la esquina y pasa
     a ser lo primero que se lee, como en cualquier app de resultados. Y
     los dos equipos quedan en columnas iguales, en vez de empujarse segun
     el largo del nombre. */
  .alert-header {
    align-items: baseline;
    font-size: 11.5px;
    margin-bottom: 10px;
  }
  .alert-header .league {
    font-family: var(--fuente-tit);
    font-weight: 600;
    letter-spacing: .02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
  }
  .alert-header .date {
    font-family: var(--fuente);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 13px;
    color: var(--text-2);
    flex: none;
    padding-left: 10px;
  }
  /* Columnas iguales: sin esto el equipo de nombre largo se come al otro y
     el "vs" queda descentrado de tarjeta en tarjeta. */
  .match-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 10px;
    margin-bottom: 10px;
  }
  .team-side { gap: 9px; font-size: 15.5px; font-weight: 600; }
  /* El visitante se dibuja espejado: escudo hacia afuera, como en la
     previa y como en cualquier marcador. */
  .match-row .team-side:last-child { flex-direction: row-reverse; text-align: right; }
  .crest { width: 26px; height: 26px; }
  .vs-label {
    align-self: center;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    opacity: .7;
  }

  /* ---- Entrar / crear cuenta, en la barra de arriba ------------------
     Arrancan ocultos y los muestra `pintarEstadoLogin()` solo si NO hay
     sesion. Al reves —mostrarlos y esconderlos despues— quien ya entro
     veria "Iniciar sesion" un instante en cada carga.
     No abren un formulario propio: llevan al que ya existe en la pestaña
     Cuenta. Dos formularios de login son dos cosas que mantener y una
     que se olvida. */
  .hd-auth { display: flex; gap: 8px; flex: none; }
  /* El `display: flex` de arriba le gana al `hidden` del navegador (que solo
     pone `display: none` desde la hoja del agente), así que sin esta línea
     los botones quedaban SIEMPRE visibles. La usuaria lo vio el 2026-09-11:
     entró con su cuenta, el panel decía "Conectada como..." y la barra de
     arriba le seguía ofreciendo "Iniciar sesión" y "Crear cuenta" — la app
     diciéndole dos cosas contrarias en la misma pantalla. Mismo patrón que
     .muestra-aviso[hidden] y los otros de este archivo. */
  .hd-auth[hidden] { display: none; }
  .hd-auth button {
    min-height: 38px;
    padding: 0 14px;
    border-radius: 9px;
    font-family: var(--fuente-tit);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
  }
  .hd-entrar {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-2);
  }
  .hd-entrar:hover { border-color: var(--muted); color: var(--text); }
  .hd-crear {
    background: var(--verde);
    border: 1px solid var(--verde);
    color: #fff;
  }
  .hd-crear:hover { background: var(--verde-banda); border-color: var(--verde-banda); }
  /* En el telefono no entran los dos al lado del titulo y la lupa: queda
     solo "Crear cuenta", que es la accion que gana algo. Entrar sigue a un
     toque, en la pestaña Cuenta. */
  @media (max-width: 720px) {
    .hd-entrar { display: none; }
    .hd-auth button { min-height: 36px; padding: 0 11px; font-size: 12.5px; }
  }

  /* Al llegar desde "Crear cuenta" se marca cual de los dos botones es el
     que buscabas. Sin esto la barra te deja en un formulario con dos
     botones iguales y tenes que releer para saber cual era. Se apaga solo
     a los 2 segundos: es una señal, no un estado. */
  .destacado-un-momento {
    outline: 2px solid var(--verde);
    outline-offset: 2px;
  }
