/* ============================================================
   OLIMAR — ESTADIO v8 · sistema único de la regeneración total
   Broadcast de estadio + bento. Tipografía como gráfica, score
   como elemento visual, diagonales de banderín, líneas de cancha,
   datos en tiles. docs/olimar-v8-estadio.md
   Páginas v8 cargan SOLO este CSS (+ fuentes + bootstrap-icons).
   Mobile-first. Sidebar desktop ≥1024px, dock flotante mobile.
   ============================================================ */

:root {
    /* canvas noche de club */
    --bg: #060f28;
    --bg-2: #0a1838;
    --card: linear-gradient(168deg, #11244f 0%, #0b1a3e 100%);
    --card-flat: #0e2049;
    --raise: #16295c;
    --line: rgba(151,177,232,.14);
    --line-2: rgba(151,177,232,.28);

    --tx: #f3f6ff;
    --tx-2: #b7c5e8;
    --tx-3: #8093c0;

    --gold: #ffc233;
    --gold-2: #ffd45e;
    --gold-ink: #241a00;
    --blue: #3d7bff;
    --sky: #9cc3ff;

    --win: #34d97b;
    --draw: #93a4c8;
    --loss: #ff5d77;
    --win-t: #8ef5bd;
    --loss-t: #ffb3c0;

    --disp: 'Anton', 'Barlow', sans-serif;
    --body: 'Barlow', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

    --r: 16px; --r-lg: 22px;
    --sh: 0 18px 44px -20px rgba(2,6,23,.85);
    --sh-deep: 0 30px 70px -28px rgba(2,6,23,.95);
    --sh-gold: 0 10px 30px -10px rgba(255,194,51,.45);
    --inlight: inset 0 1px 0 rgba(255,255,255,.06);

    --rail: 86px;             /* sidebar colapsada */

    /* ============================================================
       ARENA — sistema de contenedor (OLA 3 · P3.1)
       Antes cada página elegía su propio número: `.arena__in` valía 1180 en la
       mayoría, 720 en Mi Olimar (47 % del arena vacío en desktop) y 880/560 en
       Mi Perfil. Tres anchos sin criterio compartido. Ahora hay TRES roles y
       nada más; una página elige un rol, no un número:
         --arena         base       · páginas de contenido (Inicio, Juegos, Partidos…)
         --arena-narrow  estrecho   · lectura y formularios (60-80 caracteres por línea)
         --arena-wide    amplio     · grillas densas que ganan con más columnas
       Los gutters también son del sistema (--gutter escala solo por breakpoint),
       no un padding re-tipeado en cada media query. */
    --arena: 1180px;
    --arena-narrow: 720px;
    --arena-wide: 1400px;
    --gutter: 16px;           /* mobile — sube a 24/32 más abajo */
    --maxw: var(--arena);     /* alias legacy: había consumidores fuera de .arena */
    /* altura real que ocupa el dock flotante desde el borde inferior:
       12px de bottom + ~60px de alto + safe-area (iPhone standalone).
       .netnotice8 depende de esta variable para no solaparse con el dock. */
    --dock-h: calc(72px + env(safe-area-inset-bottom, 0px));
    /* altura real del topstrip sticky: 10px de padding-top + 44px de contenido (lo fija
       .topstrip__sess con min-height:44px) + 10px de padding-bottom + 1px de borde = 65px,
       MÁS la safe-area del notch (que el propio .topstrip suma a su padding-top).
       Lo consumen los sticky de segundo nivel — hoy .pnav de Perfil — para engancharse
       justo debajo en vez de con un offset fijo que en iPhone queda tapado. */
    --topstrip-h: calc(65px + env(safe-area-inset-top, 0px));

    /* motion tokens (lenguaje comun de animacion)
       Ola 1: la escala existente (--mo-fast/--mo/--mo-slow + las 3 curvas) se
       mantiene TAL CUAL — tenía 88 consumidores y funcionaba. Se agregan 3
       tokens, solo aditivos, para los tres grupos que quedaban fuera y que
       sumaban 43 duraciones literales repartidas en 47 valores casi iguales:
         --mo-xfast  micro-feedback (color/opacidad de un chip)
         --mo-enter  entradas y reveals (rv8, poster-in, apertura de sheets)
         --mo-bar    barras, donuts y progreso (animan un dato, no un gesto) */
    --mo-fast: 140ms; --mo: 200ms; --mo-slow: 280ms;
    --mo-xfast: 120ms; --mo-enter: 500ms; --mo-bar: 700ms;
    --ease-out: cubic-bezier(.22,.61,.36,1);    /* entradas */
    --ease-in: cubic-bezier(.55,.08,.68,.53);   /* salidas */
    --ease-spring: cubic-bezier(.34,1.56,.64,1);/* tap/pop */
    --press: scale(.97);

    /* escala de espaciado 4/8px (ritmo unico del sistema) */
    --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;

    /* ============================================================
       ESCALA TIPOGRÁFICA (OLA 3 · P3.4)
       La tipografía era la única dimensión del sistema que nunca se tokenizó:
       114 tamaños distintos, y entre 8 y 25,6 px no había un hueco mayor a 1 px
       (`.82/.84/.85/.86rem` conviviendo con 0,64 px de diferencia). Diez pasos,
       con nombre de ROL y no de número, para que elegir un tamaño sea elegir qué
       es el texto y no cuánto mide.
       Razón entre pasos ~1.1–1.4; los cuatro primeros cubren el 80 % del corpus.  */
    --fs-caption:        .62rem;  /*  9,9px  micro-label denso, eyebrow, unidad     */
    --fs-label:          .70rem;  /* 11,2px  rótulo de sección, meta de fila        */
    --fs-body-sm:        .76rem;  /* 12,2px  texto de apoyo, subtítulo, hint corto  */
    --fs-body:           .86rem;  /* 13,8px  texto corrido, celda, control          */
    --fs-body-strong:    .95rem;  /* 15,2px  nombre de entidad, ítem de lista       */
    --fs-card-title:    1.15rem;  /* 18,4px  título de card / sheet                 */
    --fs-section-title: 1.45rem;  /* 23,2px  título de sección (display)            */
    --fs-page-title:     2.2rem;  /* 35,2px  título de página                       */
    --fs-kpi:            2.4rem;  /* 38,4px  número protagonista de tile            */
    --fs-display:        3.4rem;  /* 54,4px  marcador / hero numérico               */
    /* caption minima legible (~13px) para hints/ayudas de texto corrido.
       Se mantiene el nombre porque tenía consumidores; ahora apunta a la escala. */
    --cap: var(--fs-body);

    /* posicion deportiva (unificado con Fantasy) */
    --pos-gk: #ffc233; --pos-def: #3d7bff; --pos-med: #28c281; --pos-ata: #ff5a6a;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
/* fondo del canvas raíz: sin esto, el overscroll/rebote y cualquier gap de 100vh en
   mobile dejaban ver el blanco default del browser ("franja blanca al pie"). var(--bg)
   = base del gradiente del body, así el empalme es invisible. Global, una sola vez. */
html { -webkit-text-size-adjust: 100%; background: var(--bg); min-height: 100%; }

/* OLA 1 — `scroll-behavior: smooth` estaba acá sin guardia, y eso anulaba toda la
   política de motion del JS: `behavior:"auto"` NO significa "salto instantáneo", significa
   "hacé lo que diga el CSS", y el CSS decía smooth. Con reduced-motion activo los scrolls
   de página seguían animados en TODA la app, y cada consumidor tenía que parchear con
   `"instant"` por su cuenta. Se declara solo cuando el usuario no pidió lo contrario. */
@media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
}

body.est {
    font-family: var(--body);
    color: var(--tx);
    background:
        radial-gradient(110% 50% at 85% -8%, rgba(255,194,51,.07), transparent 55%),
        radial-gradient(120% 70% at 12% -12%, rgba(61,123,255,.2), transparent 58%),
        linear-gradient(180deg, #0a1838 0%, var(--bg) 38%, #04091c 100%);
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    font-feature-settings: "tnum";
    line-height: 1.5;
    /* 100dvh = alto visible real en mobile (descuenta la toolbar retráctil). 100vh queda
       arriba como fallback para browsers sin dvh. El padding-bottom despeja el dock flotante:
       se deriva de --dock-h (72px + safe-area) + 24px de aire, en vez de un número mágico, para
       que la holgura siga a la altura del dock si cambia. Equivale a 96px + safe-area. */
    min-height: 100vh;
    min-height: 100dvh;
    padding-bottom: calc(var(--dock-h) + 24px);
}
body.est a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; color: inherit; background: none; border: 0; }
::selection { background: rgba(255,194,51,.85); color: var(--gold-ink); }

.disp { font-family: var(--disp); font-weight: 400; line-height: .92; letter-spacing: .015em; }
.muted { color: var(--tx-3); }
.hide { display: none !important; }

/* ============================================================
   CHROME — mobile: top-strip + dock flotante · desktop: sidebar
   ============================================================ */
.topstrip {
    position: sticky; top: 0; z-index: 50;
    display: flex; align-items: center; gap: 10px;
    /* PWA standalone (iOS notch/status bar translúcida): la strip arranca
       debajo de la safe area, si no el ícono de sesión queda bajo el reloj */
    padding: calc(10px + env(safe-area-inset-top, 0px)) 16px 10px;
    background: rgba(5,12,32,.86);
    -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
}
.topstrip .crest8 { width: 32px; height: 32px; }
.topstrip__brand { font-family: var(--disp); font-size: 1.15rem; letter-spacing: .07em; }
.topstrip__brand em { font-style: normal; color: var(--gold); }
/* aux: puede achicarse con ellipsis — el texto cede antes que empujar el
   acceso a sesión fuera de pantalla (360px con chips largos) */
/* OLA 2 — un slot, un significado. `.topstrip__aux` es CONTEXTO NO DESTRUCTIVO y nada más:
   temporada, categoría, conteo, nombre de la entidad. No puede ser logout, no puede ser un
   Back disfrazado, no puede llevar navegación escondida en un chip. Antes significaba cuatro
   cosas distintas según la página (contexto, navegación, logout y etiqueta muerta), con la
   misma píldora dorada y sin ninguna affordance que las distinguiera.
   La navegación vive en `.topstrip__back` y las acciones en `.topstrip__act`. */
.topstrip__aux { margin-left: auto; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: .7rem; font-weight: 700; color: var(--gold-2); border: 1px solid rgba(255,194,51,.35); background: rgba(255,194,51,.08); padding: 5px 11px; border-radius: 999px; white-space: nowrap; }

/* Back real: se lee como control, no como etiqueta. Va pegado al escudo (a la izquierda,
   donde el usuario busca "volver") y cumple el mínimo táctil de 44px sin engordar el topstrip:
   el alto lo absorbe el propio header, que ya mide 65px. */
.topstrip__back {
    display: inline-flex; align-items: center; gap: 6px; flex: none;
    min-height: 44px; padding: 0 12px 0 8px; margin-left: 2px;
    border: 1px solid var(--line-2); border-radius: 999px;
    background: rgba(22,41,92,.55); color: var(--tx-2);
    font-size: var(--fs-body-sm); font-weight: 700; white-space: nowrap; cursor: pointer;
    -webkit-tap-highlight-color: transparent; touch-action: manipulation;
    transition: color var(--mo-fast) var(--ease-out), border-color var(--mo-fast) var(--ease-out);
}
.topstrip__back i { font-size: var(--fs-body-strong); }
.topstrip__back:hover { color: var(--tx); border-color: var(--gold); }
.topstrip__back:active { transform: var(--press); }
/* cuando hay back, el brand no necesita empujar: el aux sigue llevando el margin-left:auto */
.topstrip__back + .topstrip__brand { margin-left: 2px; }

/* Acción real del topstrip (no contexto). Se usa donde la página no tiene cuerpo para
   alojarla — hoy solo CompletarEmail, que es un paso obligado del alta sin dock ni menú. */
.topstrip__act {
    margin-left: auto; flex: none;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 44px; padding: 0 14px;
    border: 1px solid rgba(255,93,119,.4); border-radius: 999px;
    background: rgba(255,93,119,.12); color: var(--loss-t);
    font-size: var(--fs-body-sm); font-weight: 700; white-space: nowrap; cursor: pointer;
    -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.topstrip__act:hover { background: rgba(255,93,119,.2); color: #fff; }
.topstrip__act:active { transform: var(--press); }

.crest8 { background: #fff; border-radius: 50%; display: grid; place-items: center; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(151,177,232,.3), 0 0 0 2px rgba(255,194,51,.3); flex: none; }
.crest8 img { width: 86%; height: 86%; object-fit: contain; }

/* dock flotante mobile */
.dock {
    position: fixed; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom));
    z-index: 60;
    display: flex; justify-content: space-around; align-items: stretch;
    background: rgba(9,18,44,.92);
    -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
    border: 1px solid var(--line-2);
    border-radius: 22px;
    box-shadow: 0 22px 50px -16px rgba(2,6,23,.95), var(--inlight);
    max-width: 560px; margin: 0 auto;
}
.dock a {
    flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    min-height: 58px; font-size: .55rem; font-weight: 700; letter-spacing: .02em;
    color: var(--tx-3); position: relative; border-radius: 18px;
}
.dock a i { font-size: 1.18rem; }
.dock a.on { color: var(--gold-2); }
.dock a.on::after { content: ""; position: absolute; bottom: 6px; width: 14px; height: 3px; border-radius: 2px; background: var(--gold); box-shadow: 0 0 10px rgba(255,194,51,.8); }

/* sidebar desktop */
.rail { display: none; }
@media (min-width: 1024px) {
    body.est { padding-bottom: 60px; }
    .topstrip, .dock { display: none; }
    .rail {
        position: fixed; left: 0; top: 0; bottom: 0; z-index: 60;
        width: var(--rail);
        display: flex; flex-direction: column; align-items: center; gap: 6px;
        padding: 18px 10px;
        background: rgba(5,12,32,.92);
        -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
        border-right: 1px solid var(--line);
    }
    .rail::after { /* hilo dorado */
        content: ""; position: absolute; top: 0; bottom: 0; right: -1px; width: 1px;
        background: linear-gradient(180deg, transparent, rgba(255,194,51,.35) 30%, rgba(255,194,51,.35) 70%, transparent);
    }
    .rail .crest8 { width: 46px; height: 46px; margin-bottom: 18px; }
    .rail a {
        position: relative; width: 100%;
        display: flex; flex-direction: column; align-items: center; gap: 3px;
        padding: 11px 4px; border-radius: 14px;
        font-size: .56rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
        color: var(--tx-3); transition: color .15s, background .15s;
    }
    .rail a i { font-size: 1.2rem; }
    .rail a:hover { color: var(--tx); background: rgba(61,123,255,.1); }
    .rail a.on { color: var(--gold-2); background: rgba(255,194,51,.08); }
    .rail a.on::before {
        content: ""; position: absolute; left: -10px; top: 18%; bottom: 18%; width: 3px;
        border-radius: 0 3px 3px 0; background: var(--gold); box-shadow: 0 0 12px rgba(255,194,51,.8);
    }
    .rail__foot { margin-top: auto; font-size: .54rem; color: var(--tx-3); text-align: center; letter-spacing: .08em; text-transform: uppercase; }
    .arena { margin-left: var(--rail); }
}

/* ============================================================
   CONTENIDO — el contenedor `arena` (OLA 3 · P3.1)
   `.arena` = canal de la página (gutters + descuento del rail).
   `.arena__in` = ancho de LECTURA. Su ancho lo elige un rol, no un número:
     (por defecto)          --arena         1180px
     .arena__in--narrow     --arena-narrow   720px   lectura / formularios
     .arena__in--wide       --arena-wide    1400px   grillas densas
   Los gutters escalan por breakpoint desde --gutter (16 → 24 → 32) y son la
   ÚNICA fuente del padding lateral: antes había 16px en mobile y 28px en
   desktop escritos a mano, y cada página que quería otro margen lo re-tipeaba.
   ============================================================ */
@media (min-width: 768px)  { :root { --gutter: 24px; } }
@media (min-width: 1024px) { :root { --gutter: 32px; } }

.arena { width: 100%; max-width: calc(var(--arena) + var(--gutter) * 2); margin: 0 auto; padding: 0 var(--gutter); }
@media (min-width: 1024px) {
    .arena { width: auto; max-width: none; margin: 0 0 0 var(--rail); padding: 0 var(--gutter); }
    .arena__in { max-width: var(--arena); margin: 0 auto; }
    .arena__in--narrow { max-width: var(--arena-narrow); }
    .arena__in--wide { max-width: var(--arena-wide); }
}

/* ============================================================
   TAPE — ticker de resultados broadcast
   ============================================================ */
/* sangra hasta el borde del canal: el negativo se deriva del MISMO --gutter que
   `.arena`, así el ticker sigue tocando los bordes cuando el gutter escala. */
.tape { position: relative; overflow: hidden; margin: 0 calc(var(--gutter) * -1); padding: 10px 0; border-bottom: 1px solid var(--line); background: linear-gradient(90deg, rgba(255,194,51,.06), rgba(5,12,32,.6) 22%); }
/* etiqueta fija a la izquierda + fade en los bordes */
/* El degradado arrancaba a transparentarse en el 60% del chip, o sea POR DEBAJO de las
   últimas letras: a ≤390px se leía "RESULTADOSSindicato Medico..." con el texto que corre
   pisando el "DOS". Ahora el oro es sólido hasta 22px del borde y el fade vive solo en el
   padding derecho, donde no hay letras. */
.tape::before {
    content: "RESULTADOS"; position: absolute; left: 0; top: 0; bottom: 0; z-index: 2;
    display: flex; align-items: center; padding: 0 26px 0 14px;
    font-family: var(--disp); font-size: var(--fs-body-sm); letter-spacing: .12em; color: var(--gold-ink);
    background: linear-gradient(90deg, var(--gold) 0 calc(100% - 22px), transparent);
}
.tape::after {
    content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 40px; z-index: 2; pointer-events: none;
    background: linear-gradient(90deg, transparent, var(--bg));
}
/* padding-left = ancho del chip ::before (creció 12px al ensanchar su padding derecho). */
.tape__in { display: flex; gap: 0; width: max-content; animation: tape-roll 40s linear infinite; padding-left: 128px; }
.tape:hover .tape__in { animation-play-state: paused; }
.tape__it { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-body-sm); font-weight: 700; color: var(--tx-2); white-space: nowrap; padding: 0 18px; position: relative; }
.tape__it::after { content: ""; position: absolute; right: 0; top: 28%; bottom: 28%; width: 1px; background: var(--line-2); }
.tape__it b { font-family: var(--disp); font-weight: 400; font-size: var(--fs-body); letter-spacing: .03em; color: var(--tx); }
.tape__r { width: 18px; height: 18px; border-radius: 5px; display: inline-grid; place-items: center; font-size: .58rem; font-weight: 800; flex: none; }
.tape__r.w { background: var(--win); color: #03301a; box-shadow: 0 0 8px rgba(52,217,123,.4); } .tape__r.d { background: rgba(147,164,200,.4); color: #eef2ff; } .tape__r.l { background: var(--loss); color: #38000b; }
@keyframes tape-roll { to { transform: translateX(-50%); } }

/* ============================================================
   POSTER — hero broadcast con diagonal y palabra fantasma
   ============================================================ */
.poster {
    position: relative; overflow: hidden;
    margin: 16px 0 0; padding: 30px 22px 44px;
    border-radius: var(--r-lg);
    /* en desktop el bottom 44px sumaba aire vacío bajo el hero (patrón "hero alto"): se reduce */
    background:
        radial-gradient(120% 100% at 0% -30%, rgba(61,123,255,.45), transparent 58%),
        radial-gradient(70% 60% at 100% 0%, rgba(255,194,51,.14), transparent 55%),
        linear-gradient(168deg, #142e6a 0%, #0b1a40 58%, #071330 100%);
    border: 1px solid rgba(151,177,232,.2);
    box-shadow: var(--sh-deep), var(--inlight);
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), 0 100%);
}
@media (min-width: 760px) { .poster { padding-bottom: 34px; } }
.poster::before { /* pasto */
    content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
    background: repeating-linear-gradient(90deg, rgba(255,255,255,.02) 0 56px, transparent 56px 112px);
}
.poster__lines { /* círculo central de cancha */
    position: absolute; right: -90px; top: -90px; width: 320px; height: 320px;
    border: 2px solid rgba(156,195,255,.12); border-radius: 50%; pointer-events: none;
}
.poster__lines::after { content: ""; position: absolute; inset: 36px; border: 2px solid rgba(156,195,255,.08); border-radius: 50%; }
.poster__ghost {
    position: absolute; right: -10px; bottom: -26px; pointer-events: none; user-select: none;
    font-family: var(--disp); font-size: clamp(5rem, 16vw, 11rem); line-height: 1;
    color: transparent; -webkit-text-stroke: 1px rgba(156,195,255,.11);
    text-transform: uppercase; letter-spacing: .02em; white-space: nowrap;
}
/* en columnas angostas (auth/forms) el fantasma compite con el subtítulo: lo atenuamos */
.page-login .poster__ghost, .page-registro .poster__ghost,
.page-miperfil .poster__ghost { opacity: .5; }
.poster__kick { position: relative; display: inline-flex; align-items: center; gap: 9px; font-size: .64rem; font-weight: 800; letter-spacing: .22em; text-transform: uppercase; color: var(--gold-2); }
.poster__kick::before { content: ""; width: 22px; height: 2px; background: var(--gold); box-shadow: 0 0 8px rgba(255,194,51,.7); }
.poster__title {
    position: relative; font-family: var(--disp); font-weight: 400; text-transform: uppercase;
    font-size: clamp(2.6rem, 9vw, 5rem); line-height: .92; letter-spacing: .01em;
    margin: 10px 0 0; color: var(--tx);
}
.poster__title em { font-style: normal; color: var(--gold); }
.poster__title .vs { display: block; font-size: .46em; line-height: 1.04; margin-top: 8px; color: var(--tx-2); }
.poster__sub { position: relative; margin-top: 12px; font-size: var(--fs-body-strong); color: var(--tx-2); max-width: 58ch; line-height: 1.45; }
/* sufijo/unidad de bajo énfasis junto al número grande del header (ej. "45 partidos",
   "133 rivales"): el número-protagonista no queda como cifra suelta sin contexto. */
.poster__unit { font-family: var(--body); font-weight: 800; font-size: var(--fs-body); letter-spacing: .04em; text-transform: lowercase; color: var(--tx-3); margin-left: 10px; vertical-align: baseline; white-space: nowrap; }
.poster__row { position: relative; display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; align-items: center; }

/* ============================================================
   BENTO
   ============================================================ */
.bento { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 16px; }
.tile {
    position: relative; overflow: hidden; min-width: 0;
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--r); box-shadow: var(--sh), var(--inlight);
    padding: 16px;
}
.tile--flat { background: rgba(10,24,56,.5); box-shadow: none; }
.tile--gold { border-color: rgba(255,194,51,.35); background: radial-gradient(90% 80% at 100% -10%, rgba(255,194,51,.2), transparent 55%), var(--card); }
.tile__k { color: var(--tx-3); display: flex; align-items: center; gap: 7px; }   /* tipografía: .kick8 */
.tile__k i { color: var(--gold); font-size: var(--fs-body); }
.tile__big { font-family: var(--disp); font-size: 2.4rem; line-height: 1; margin-top: 8px; font-variant-numeric: tabular-nums; }
.tile__big.gold { color: var(--gold); text-shadow: 0 0 24px rgba(255,194,51,.35); }
.tile__big.win { color: var(--win); }
.tile__big.loss { color: var(--loss); }
.tile__sub { font-size: var(--fs-body-sm); color: var(--tx-3); margin-top: 5px; }
.tile__ghostn { position: absolute; right: 2px; bottom: -18px; font-family: var(--disp); font-size: 5.4rem; line-height: 1; color: rgba(156,195,255,.07); pointer-events: none; font-variant-numeric: tabular-nums; }
.b2 { grid-column: span 2; }
@media (min-width: 760px) {
    .bento { grid-template-columns: repeat(4, 1fr); gap: 16px; }
    .b2 { grid-column: span 2; }
    .b3 { grid-column: span 3; }
    .b4 { grid-column: span 4; }
    .rowspan2 { grid-row: span 2; }
}
@media (min-width: 1180px) {
    .bento { grid-template-columns: repeat(6, 1fr); }
    .b2-lg { grid-column: span 2; }
    .b3-lg { grid-column: span 3; }
    .b4-lg { grid-column: span 4; }
    .b6-lg { grid-column: span 6; }
}

/* sección suelta (cuando no es bento) */
.blk { margin-top: 26px; }
.blk__hd { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.blk__t { font-family: var(--disp); font-weight: 400; font-size: 1.2rem; letter-spacing: .05em; text-transform: uppercase; display: flex; align-items: center; gap: 10px; }
.blk__t::before { content: ""; width: 5px; height: 19px; border-radius: 2px; background: linear-gradient(180deg, var(--gold-2), var(--gold)); box-shadow: 0 0 12px rgba(255,194,51,.5); }
.blk__more { font-size: var(--fs-body-sm); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--gold); white-space: nowrap; }

/* ============================================================
   DONUT (conic-gradient) + SBAR (barra con valor Anton)
   ============================================================ */
/* --p como propiedad animable: el donut se "llena" al cargar el dato */
@property --p { syntax: "<number>"; inherits: false; initial-value: 0; }
.donut { position: relative; width: 110px; height: 110px; border-radius: 50%; display: grid; place-items: center; background: conic-gradient(var(--gold) calc(var(--p,0)*1%), rgba(151,177,232,.15) 0); transition: --p .9s var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .donut { transition: none; } }
.donut::before { content: ""; position: absolute; inset: 11px; border-radius: 50%; background: #0d1d45; box-shadow: var(--inlight); }
.donut__v { position: relative; font-family: var(--disp); font-size: 1.5rem; }
.donut__v small { display: block; font-family: var(--body); font-size: .54rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--tx-3); text-align: center; }
.donut--win { background: conic-gradient(var(--win) calc(var(--p,0)*1%), rgba(151,177,232,.15) 0); }

.sbar { display: grid; grid-template-columns: minmax(64px,auto) 1fr auto; align-items: center; gap: 10px; padding: 7px 0; }
.sbar__l { font-size: var(--fs-body-sm); font-weight: 700; color: var(--tx-2); white-space: nowrap; }
.sbar__t { height: 9px; border-radius: 999px; background: rgba(7,17,41,.7); overflow: hidden; }
.sbar__f { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--blue), var(--gold)); transition: width .6s var(--ease-out); }
.sbar__f.win { background: var(--win); } .sbar__f.loss { background: var(--loss); } .sbar__f.draw { background: var(--draw); }
.sbar__v { font-family: var(--disp); font-size: 1rem; font-variant-numeric: tabular-nums; min-width: 2.2ch; text-align: right; }

/* barra apilada W-D-L */
.wdlbar { display: flex; height: 12px; border-radius: 999px; overflow: hidden; background: rgba(7,17,41,.7); }
.wdlbar span { display: block; height: 100%; transition: width .7s var(--ease-out); }
@media (prefers-reduced-motion: reduce) { .wdlbar span, .sbar__f { transition: none; } }
.wdlbar .w { background: var(--win); } .wdlbar .d { background: var(--draw); } .wdlbar .l { background: var(--loss); }
.wdlbar + .wdlleg { display: flex; gap: 14px; margin-top: 8px; font-size: .7rem; color: var(--tx-3); font-weight: 700; }
.wdlleg b { color: var(--tx); font-variant-numeric: tabular-nums; }

/* ============================================================
   TICKET — match card tipo entrada
   ============================================================ */
.tlist { display: flex; flex-direction: column; gap: 10px; }
.ticket {
    position: relative; display: grid; grid-template-columns: 64px 1fr auto; align-items: stretch;
    background: var(--card); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: var(--sh), var(--inlight); overflow: hidden; cursor: pointer;
    transition: transform .14s, border-color .14s;
}
.ticket:hover { transform: translateY(-2px); border-color: var(--line-2); }
.ticket__stub {
    position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
    border-right: 1px dashed var(--line-2); padding: 10px 6px;
    background: rgba(7,17,41,.55);
}
.ticket__stub::before, .ticket__stub::after { /* perforación */
    content: ""; position: absolute; right: -7px; width: 13px; height: 13px; border-radius: 50%;
    background: var(--bg); border: 1px solid var(--line);
}
.ticket__stub::before { top: -7px; } .ticket__stub::after { bottom: -7px; }
.ticket__day { font-family: var(--disp); font-size: 1.45rem; line-height: 1; }
.ticket__mon { font-size: .56rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--tx-3); }
.ticket__main { min-width: 0; padding: 11px 12px; display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.ticket__rival { font-weight: 700; font-size: var(--fs-body-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket__meta { font-size: .68rem; color: var(--tx-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket__meta b { color: var(--tx-2); font-weight: 700; }
.ticket__sc {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    padding: 0 14px 0 10px; position: relative;
}
.ticket__sc::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--draw); }
.ticket.w .ticket__sc::before { background: var(--win); box-shadow: 0 0 12px rgba(52,217,123,.55); }
.ticket.l .ticket__sc::before { background: var(--loss); box-shadow: 0 0 12px rgba(255,93,119,.45); }
.ticket.n .ticket__sc::before { background: var(--gold); box-shadow: 0 0 12px rgba(255,194,51,.5); }
.ticket__num { font-family: var(--disp); font-size: 1.5rem; font-variant-numeric: tabular-nums; }
.ticket__tag { font-size: .54rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--tx-3); }
.ticket.w .ticket__tag { color: var(--win-t); } .ticket.l .ticket__tag { color: var(--loss-t); } .ticket.n .ticket__tag { color: var(--gold-2); }
/* escudo del rival en el ticket (biblioteca team-crests; ver crest.js).
   Scoped a .ticket--crest para no afectar tickets sin escudo (perfil, detalle rival). */
.ticket--crest .ticket__main { flex-direction: row; align-items: center; gap: 10px; }
.ticket--crest .ticket__txt { min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.ticket__crest { flex: 0 0 auto; width: 34px; height: 34px; object-fit: contain; display: block; }

.month8 { margin: 22px 2px 10px; font-family: var(--disp); font-size: var(--fs-body-strong); letter-spacing: .12em; text-transform: uppercase; color: var(--tx-3); display: flex; align-items: center; gap: 12px; }
.month8::after { content: ""; flex: 1; height: 1px; background: var(--line); }
@media (min-width: 860px) { .tlist--grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; } .tlist--grid .month8 { grid-column: 1 / -1; } }
@media (min-width: 1280px) { .tlist--grid { grid-template-columns: repeat(3, 1fr); } }

/* ============================================================
   BOARD — leaderboard de vestuario (dorsal gigante)
   ============================================================ */
.board { display: flex; flex-direction: column; }
.board__row {
    display: grid; grid-template-columns: 48px 44px 1fr auto; align-items: center; gap: 12px;
    padding: 10px 8px; border-radius: 12px; cursor: pointer;
    transition: background .14s;
}
.board__row:hover { background: rgba(61,123,255,.09); }
.board__row + .board__row { border-top: 1px solid var(--line); }
.board__n { font-family: var(--disp); font-size: 1.5rem; text-align: center; color: rgba(156,195,255,.4); font-variant-numeric: tabular-nums; }
.board__row:nth-child(1) .board__n { color: var(--gold); text-shadow: 0 0 16px rgba(255,194,51,.5); }
.board__row:nth-child(2) .board__n { color: #d7e2f5; }
.board__row:nth-child(3) .board__n { color: #e8a76b; }
.board__av { width: 44px; height: 44px; border-radius: 12px; overflow: hidden; background: linear-gradient(180deg,#1b306f,#0d1c44); border: 1px solid var(--line-2); display: grid; place-items: center; font-family: var(--disp); color: rgba(156,195,255,.4); }
.board__av img { width: 100%; height: 100%; object-fit: cover; object-position: center 16%; }
.board__who { min-width: 0; }
.board__nm { font-weight: 700; font-size: var(--fs-body-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board__sub { font-size: .68rem; color: var(--tx-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board__v { text-align: right; }
.board__v b { display: block; font-family: var(--disp); font-weight: 400; font-size: 1.35rem; color: var(--gold); font-variant-numeric: tabular-nums; }
.board__v small { font-size: .56rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--tx-3); }

/* ============================================================
   STAGE — podio con pedestales
   ============================================================ */
.stage { display: grid; grid-template-columns: 1fr 1.15fr 1fr; gap: 10px; align-items: end; margin: 6px 0 4px; }
.pedestal { position: relative; text-align: center; cursor: pointer; }
.pedestal__av {
    width: 76px; height: 76px; margin: 0 auto; border-radius: 50%; overflow: visible;
    background: linear-gradient(180deg,#1b306f,#0d1c44); border: 3px solid var(--line-2);
    display: grid; place-items: center; font-family: var(--disp); font-size: 1.5rem; color: rgba(156,195,255,.4);
    position: relative; z-index: 1;
}
.pedestal__av img { width: 100%; height: 100%; object-fit: cover; object-position: center 16%; }
/* medalla numerada (oro/plata/bronce) colgando del avatar — premio, no un número suelto en la base */
.pedestal__av::after { position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%); z-index: 4;
    width: 27px; height: 27px; border-radius: 50%; display: grid; place-items: center;
    font-family: var(--disp); font-weight: 400; font-size: var(--fs-body-strong); line-height: 1;
    border: 2px solid #07122a; box-shadow: 0 4px 10px rgba(2,6,23,.55); }
.pedestal--1 .pedestal__av::after { content: "1"; color: #3a2800; background: linear-gradient(180deg, #ffe08a, var(--gold)); }
.pedestal--2 .pedestal__av::after { content: "2"; color: #1d2741; background: linear-gradient(180deg, #f3f7fd, #adbbd5); }
.pedestal--3 .pedestal__av::after { content: "3"; color: #2c1604; background: linear-gradient(180deg, #f1bd8c, #c4783c); }
.pedestal--2 .pedestal__av { border-color: #c6d2e8; box-shadow: 0 0 18px rgba(198,210,232,.28); }
.pedestal--3 .pedestal__av { border-color: #cf915f; box-shadow: 0 0 18px rgba(207,145,95,.28); }
.pedestal__nm { margin-top: 13px; font-weight: 700; font-size: var(--fs-body-sm); line-height: 1.15; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; min-height: 2.2em; }
.pedestal__v { font-family: var(--disp); font-size: 1.55rem; margin-top: 2px; font-variant-numeric: tabular-nums; }
.pedestal__base {
    margin-top: 10px; border-radius: 12px 12px 0 0; position: relative; overflow: hidden;
    font-size: 0; color: transparent;
    background: linear-gradient(180deg, rgba(151,177,232,.5), rgba(151,177,232,.16));
    box-shadow: var(--inlight);
}
.pedestal__base::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: rgba(255,255,255,.5); }
.pedestal--1 .pedestal__base { height: 84px; background: linear-gradient(180deg, var(--gold-2), #b88500); box-shadow: 0 -10px 40px -10px rgba(255,194,51,.5), var(--inlight); }
.pedestal--2 .pedestal__base { height: 58px; background: linear-gradient(180deg, #dfe8f8, #8d9cba); }
.pedestal--3 .pedestal__base { height: 42px; background: linear-gradient(180deg, #e8a76b, #8a5526); }
.pedestal--1 .pedestal__av { width: 96px; height: 96px; border-color: var(--gold); box-shadow: 0 0 30px rgba(255,194,51,.5); }
.pedestal--1 .pedestal__av::after { content: "1"; width: 30px; height: 30px; font-size: 1.1rem; bottom: -9px; }
.pedestal--1 .pedestal__v { color: var(--gold); font-size: 1.95rem; }
.pedestal--1::before { /* corona */
    content: "★"; position: absolute; top: -22px; left: 50%; transform: translateX(-50%);
    color: var(--gold); font-size: 1.1rem; text-shadow: 0 0 12px rgba(255,194,51,.8); z-index: 2;
}
@media (min-width: 760px) { .stage { max-width: 560px; margin-inline: auto; gap: 18px; } .pedestal__av { width: 86px; height: 86px; } .pedestal--1 .pedestal__av { width: 110px; height: 110px; } }
/* keyframes de la entrada del podio (salón de leyendas). Se APLICAN en ranking.css, que es donde
   ya vivía la animación del podio (y carga después → gana la cascada). El brillo es un drop-shadow
   aditivo → no pisa el anillo dorado estático del 1º. */
@keyframes pedestal-in { from { opacity: 0; transform: translateY(24px) scale(.93); } to { opacity: 1; transform: none; } }
@keyframes ped-glow { 0%, 100% { filter: none; } 50% { filter: drop-shadow(0 0 18px rgba(255,194,51,.85)); } }

/* ============================================================
   TCARD — trading card de jugador
   ============================================================ */
/* fotos fuente ~112-230px: columnas angostas para NO upscalear (se veían
   gigantes y pixeladas a 2 col mobile) */
.tgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
@media (min-width: 640px) { .tgrid { grid-template-columns: repeat(4, 1fr); gap: 12px; } }
@media (min-width: 1024px) { .tgrid { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 1380px) { .tgrid { grid-template-columns: repeat(6, 1fr); } }
.tcard {
    position: relative; overflow: hidden; border-radius: 14px;
    background: var(--card); border: 1px solid var(--line);
    box-shadow: var(--sh), var(--inlight);
    transition: transform .16s, border-color .16s;
}
.tcard:hover { transform: translateY(-3px) rotate(-.4deg); border-color: rgba(255,194,51,.45); }
.tcard__ph { display: block; position: relative; aspect-ratio: 1/1; background: linear-gradient(180deg, #1b306f, #0d1c44); overflow: hidden; }
/* scale + viñeta: disimulan marcos blancos embebidos en fotos carnet */
.tcard__ph img { width: 100%; height: 100%; object-fit: cover; object-position: center 12%; filter: saturate(1.05) contrast(1.03); transform: scale(1.07); }
.tcard__ph::before {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    box-shadow: inset 0 0 0 1px rgba(11,26,62,.85), inset 0 0 24px 7px rgba(7,17,41,.4);
}
.tcard__ph::after { /* banda diagonal inferior (chica: no comerse la foto) */
    content: ""; position: absolute; left: -6%; right: -6%; bottom: -14px; height: 30px;
    background: linear-gradient(168deg, #11244f, #0b1a3e);
    transform: rotate(-3deg);
}
/* fallback sin foto: camiseta del club con las iniciales en el pecho */
.tcard__fb {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 0;
}
.tcard__fb svg { width: 62%; height: auto; display: block; }
.tcard__fb b {
    position: absolute; top: 52%; left: 50%; transform: translate(-50%, -50%);
    font-family: var(--disp); font-weight: 400; font-size: 1.3rem; letter-spacing: .04em;
    color: var(--gold-2); text-shadow: 0 2px 8px rgba(2,6,23,.6);
}
.tcard__dot { position: absolute; top: 7px; right: 7px; width: 11px; height: 11px; border-radius: 50%; box-shadow: 0 0 0 3px rgba(5,12,32,.5); z-index: 1; }
.tcard__dot.ok { background: var(--win); } .tcard__dot.warn { background: var(--gold); } .tcard__dot.bad { background: var(--loss); }
.tcard__ghost { position: absolute; top: 1px; left: 6px; font-family: var(--disp); font-size: 1.9rem; color: transparent; -webkit-text-stroke: 1px rgba(243,246,255,.3); z-index: 1; font-variant-numeric: tabular-nums; }
.tcard__b { display: block; position: relative; padding: 8px 9px 10px; }
.tcard__nm { display: -webkit-box; }
.tcard__nm { font-family: var(--disp); font-weight: 400; font-size: var(--fs-body-sm); letter-spacing: .03em; text-transform: uppercase; line-height: 1.08; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; min-height: 2.16em; }
.tcard__pos { margin-top: 4px; font-size: .54rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--gold); display: flex; align-items: center; gap: 5px; }
.tcard__pos .grad { color: var(--gold-2); }
.tcard__meta { display: block; margin-top: 4px; font-size: .62rem; font-weight: 600; color: var(--tx-3); font-variant-numeric: tabular-nums; }
@media (min-width: 640px) { .tcard__nm { font-size: var(--fs-body); } .tcard__b { padding: 9px 11px 11px; } }

/* rail horizontal de tcards */
.trail { display: flex; gap: 10px; overflow-x: auto; padding: 4px 2px 12px; scroll-snap-type: x mandatory; scrollbar-width: none; }
.trail::-webkit-scrollbar { display: none; }
.trail .tcard { flex: none; width: 118px; scroll-snap-align: start; }
@media (min-width: 640px) { .trail .tcard { width: 132px; } }

/* ============================================================
   CONTROLES — chips, seg, search, select, botones
   ============================================================ */
.chip8 { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-body-sm); font-weight: 700; color: var(--tx-2); background: rgba(22,41,92,.55); border: 1px solid var(--line); border-radius: 999px; padding: 7px 13px; white-space: nowrap; }
.chip8 i { color: var(--gold); }
.chip8 b { color: var(--tx); }

.seg8 { display: inline-flex; gap: 4px; background: rgba(7,17,41,.6); border: 1px solid var(--line); border-radius: 999px; padding: 4px; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.seg8::-webkit-scrollbar { display: none; }
.seg8 button { flex: none; display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-body-sm); font-weight: 700; color: var(--tx-3); padding: 9px 14px; border-radius: 999px; min-height: 40px; transition: color .14s; white-space: nowrap; }
.seg8 button:hover { color: var(--tx); }
.seg8 button.on { background: linear-gradient(180deg, var(--gold-2), var(--gold)); color: var(--gold-ink); box-shadow: var(--sh-gold); }

.search8 { display: flex; align-items: center; gap: 10px; background: rgba(7,17,41,.6); border: 1px solid var(--line-2); border-radius: 999px; padding: 10px 16px; min-width: 0; }
.search8:focus-within { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(255,194,51,.15); }
.search8 i { color: var(--tx-3); }
.search8 input { flex: 1; min-width: 0; background: none; border: 0; outline: none; font: inherit; font-size: var(--fs-body-strong); color: var(--tx); }
.search8 input::placeholder { color: var(--tx-3); }

.sel8 { display: inline-flex; align-items: center; gap: 8px; background: var(--raise); border: 1px solid var(--line-2); border-radius: 12px; padding: 4px 12px; }
.sel8 i { color: var(--gold); flex: none; }
.sel8 select { background: none; border: 0; outline: none; font: inherit; font-size: var(--fs-body); font-weight: 600; color: var(--tx); min-height: 44px; cursor: pointer; }   /* P3.6: 42 -> 44 */
.sel8 select option { background: var(--raise); color: var(--tx); }

/* ============================================================
   DROPDOWN CUSTOM (.dd) — reemplaza la lista nativa fea del <select>.
   est.js envuelve cada <select> dentro de .sel8: oculta el real
   (sigue vivo para .value/change) y monta este trigger + panel.
   ============================================================ */
.sel8.dd-host { position: relative; cursor: pointer; }
.sel8.dd-host select.dd-native { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.dd-trigger { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-body); font-weight: 600; color: var(--tx); min-height: 44px; background: none; padding: 0; white-space: nowrap; }   /* P3.6: 42 -> 44 */
.dd-trigger .dd-val { max-width: 30vw; overflow: hidden; text-overflow: ellipsis; }
.dd-trigger .dd-caret { color: var(--tx-3); font-size: var(--fs-body-sm); transition: transform .2s; margin-left: 2px; }
.sel8.dd-open .dd-trigger .dd-caret { transform: rotate(180deg); color: var(--gold); }
@media (min-width: 1024px) { .dd-trigger .dd-val { max-width: 220px; } }

/* panel: bottom-sheet en mobile, popover en desktop */
.dd-panel {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
    background: linear-gradient(180deg, #13265a, #0b1a40);
    border-top: 1px solid var(--line-2); border-radius: 22px 22px 0 0;
    box-shadow: 0 -24px 60px -18px rgba(2,6,23,.95);
    max-height: 70vh; display: flex; flex-direction: column;
    padding-bottom: env(safe-area-inset-bottom);
    transform: translateY(102%); transition: transform .26s var(--ease-out);
}
.dd-panel.dd-on { transform: translateY(0); }
.dd-bk { position: fixed; inset: 0; z-index: 94; background: rgba(4,9,24,.66); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); opacity: 0; pointer-events: none; transition: opacity .2s; }
.dd-bk.dd-on { opacity: 1; pointer-events: auto; }
.dd-panel__hd { display: flex; align-items: center; gap: 10px; padding: 14px 18px 10px; }
.dd-panel__hd .dd-handle { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); width: 42px; height: 4px; border-radius: 2px; background: var(--line-2); }
.dd-panel__t { font-family: var(--disp); font-size: 1rem; letter-spacing: .04em; text-transform: uppercase; color: var(--tx-2); }
.dd-list { overflow-y: auto; padding: 4px 10px 14px; }
.dd-opt {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; text-align: left; padding: 13px 14px; border-radius: 12px;
    font-size: var(--fs-body-strong); font-weight: 600; color: var(--tx-2);
}
.dd-opt:hover { background: rgba(61,123,255,.1); color: var(--tx); }
.dd-opt.dd-sel { background: rgba(255,194,51,.12); color: var(--gold-2); }
.dd-opt.dd-sel::after { content: "\F26E"; font-family: "bootstrap-icons"; color: var(--gold); font-size: var(--fs-body); }
@media (min-width: 1024px) {
    .dd-bk { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
    .dd-panel {
        position: absolute; left: auto; right: auto; bottom: auto;
        min-width: 200px; max-width: 320px; max-height: 340px;
        border: 1px solid var(--line-2); border-radius: 14px;
        transform: translateY(-8px) scale(.98); opacity: 0; pointer-events: none;
        transition: transform .16s, opacity .16s;
        box-shadow: var(--sh-deep);
    }
    .dd-panel.dd-on { transform: translateY(0) scale(1); opacity: 1; pointer-events: auto; }
    .dd-panel__hd { display: none; }
    .dd-list { padding: 6px; }
    .dd-opt { padding: 9px 11px; font-size: var(--fs-body); }
}

.btn8 { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 46px; padding: 11px 18px; border-radius: 13px; font-weight: 800; font-size: var(--fs-body); background: linear-gradient(180deg, var(--gold-2), var(--gold)); color: var(--gold-ink); box-shadow: var(--sh-gold); transition: filter .14s, transform .14s; }
.btn8:hover { filter: brightness(1.06); transform: translateY(-1px); }
.btn8--ghost { background: rgba(22,41,92,.55); color: var(--tx-2); border: 1px solid var(--line-2); box-shadow: none; }
.btn8--block { width: 100%; }
/* destructivo: acción peligrosa (Borrar) en familia roja --loss, mismo tinte que .auth-status--err.
   Distingue visualmente lo destructivo de lo neutral sin tocar confirm() ni permisos. */
.btn8--danger { background: rgba(255,93,119,.12); color: var(--loss-t); border: 1px solid rgba(255,93,119,.4); box-shadow: none; }
.btn8--danger:hover { background: rgba(255,93,119,.2); color: #fff; filter: none; }
/* fix: `body.est a { color: inherit }` (especificidad 0,1,2) pisaba el color de los
   botones-link <a class="btn8"> (0,1,0), dejándolos con texto claro sobre el dorado
   (CTA ilegible del Match Center vacío, "Jugar la penca", etc.). Restaurar el color
   por variante cuando el botón es un <a>. La regla ghost es obligatoria: sin ella el
   gold-ink iría sobre el fondo oscuro del ghost y quedaría ilegible. */
body.est a.btn8 { color: var(--gold-ink); }
body.est a.btn8--ghost { color: var(--tx-2); }

/* ============================================================
   KICK8 — eyebrow / micro-label (OLA 3 · P3.3)

   El rótulo corto en mayúsculas que precede a un dato o encabeza un bloque estaba
   escrito a mano 13 veces, repartido en 5 archivos, con NUEVE tamaños distintos
   (.58 .60 .62 .64 .66 .68 .70 .72 .74rem) y seis trackings (.03 → .16em). Era la
   mayor fuente individual de deriva tipográfica del sistema: nadie lo escribía mal,
   simplemente nadie tenía dónde escribirlo bien.

   Dos tamaños, no uno: el eyebrow DENSO (dentro de una tile o una card, junto a un
   número) y el eyebrow de SECCIÓN (encabeza un bloque). Colapsar los nueve en uno
   solo habría movido `.pushprefs__hd` casi 2px — perceptible. Con dos pasos ninguna
   etiqueta se mueve más de 0,64px, o sea nada.

   La regla toca SOLO tipografía. `display`, `color`, márgenes y gaps siguen siendo
   de cada selector: un eyebrow dorado de premio y uno gris de metadato comparten la
   forma de la letra, no el significado del color.

   NO se migran: `.poster__kick` y `.loginhero__kick` (marca), `.pill8`,
   `.pstate-chip`, `.pmatch__state`, `.gamecard__tag`, `.posb`,
   `.trivia-result-badge` (estado / competencia), las etiquetas del Álbum (rareza) y
   las micro-anotaciones que viven pegadas a un número dentro de una caja apretada
   (`.ticket__mon`, `.ticket__tag`, `.tcard__pos`, `.board__v small`,
   `.donut__v small`, `.rgame__res`): ahí el tamaño es geometría del componente,
   no tipografía de texto.
   ============================================================ */
.kick8,
.lbl8,
.tile__k,
.t8 th,
.trivia-result-main .label,
.trivia-top-wrap .top-title,
.trivia-hint-title,
.today__lb,
.fhead__lbl,
.cuotagrp__t,
.rtable__grp,
.bench-sub,
.page-perfil .pcareer__k,
.page-stats .statfilter__k {
    font-size: var(--fs-caption);
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
}
/* eyebrow de sección: encabeza un bloque, no acompaña un número */
.kick8--lg,
.pushprefs__hd,
.mio-act__kick,
.mio-last__lb,
.seasonlbl,
.page-stats .kchip__k,
.mcbench__hd,
.mcstars__hd,
.dstar2__k,
.dmini__k,
.ve-blbl,
.dsum__hd,
.vehero__l {
    font-size: var(--fs-label);
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.lbl8 { display: block; color: var(--tx-3); margin-bottom: 6px; }
.inp8 { width: 100%; min-height: 48px; padding: 12px 14px; border: 1px solid var(--line-2); border-radius: 12px; background: rgba(7,17,41,.6); font: inherit; font-size: var(--fs-body-strong); color: var(--tx); outline: none; transition: border-color .14s, box-shadow .14s; }
textarea.inp8 { min-height: 120px; resize: vertical; }
.inp8::placeholder { color: var(--tx-3); }
.inp8:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(255,194,51,.16); }
.inp8.is-invalid { border-color: var(--loss); }
.feed8 { display: none; font-size: var(--fs-body-sm); font-weight: 600; color: var(--loss-t); margin-top: 6px; }
.inp8.is-invalid ~ .feed8 { display: block; }

/* ============================================================
   SHEET8 — bottom sheet propio (modal centrado desktop)
   ============================================================ */
.sheet8-bk { position: fixed; inset: 0; z-index: 80; background: rgba(4,9,24,.7); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); opacity: 0; pointer-events: none; transition: opacity .2s; }
.sheet8-bk.on { opacity: 1; pointer-events: auto; }
.sheet8 {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    background: linear-gradient(180deg, #13265a, #0b1a40);
    border-top: 1px solid var(--line-2); border-radius: 22px 22px 0 0;
    box-shadow: 0 -24px 60px -18px rgba(2,6,23,.95);
    max-height: 88vh; display: flex; flex-direction: column;
    padding-bottom: env(safe-area-inset-bottom);
    transform: translateY(102%); transition: transform .26s var(--ease-out);
}
.sheet8.on { transform: translateY(0); }
.sheet8__handle { width: 42px; height: 4px; border-radius: 2px; background: var(--line-2); margin: 10px auto 2px; flex: none; }
.sheet8__hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 18px 12px; border-bottom: 1px solid var(--line); }
.sheet8__t { font-family: var(--disp); font-size: 1.1rem; letter-spacing: .04em; text-transform: uppercase; }
/* P3.6 — el disco sigue midiendo 38px (crecerlo a 44 desbalancea el header del sheet
   contra el título); el área de toque la aporta el pseudo-elemento. Aplica también a
   los `.sheet8__x` de 34px de los overlays de Fantasy. */
.sheet8__x { position: relative; width: 38px; height: 38px; border-radius: 50%; background: var(--raise); color: var(--tx-2); display: grid; place-items: center; flex: none; }
.sheet8__x::after { content: ""; position: absolute; top: 50%; left: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); border-radius: 50%; }
/* overscroll-behavior: al llegar al final del contenido, el gesto NO se encadena a la
   página de atrás. Con el body fijo (Ola 1) el fondo ya no se mueve, pero esto evita el
   rebote de iOS y que el sheet "arrastre" la página al soltarlo. */
.sheet8__bd { padding: 16px 18px 20px; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.sheet8__ft { padding: 12px 18px 16px; border-top: 1px solid var(--line); }
/* Ola 1: la clase la pone y la saca EST.scrollLock, que además fija el body en mobile
   (position:fixed + top:-scrollY, lo único que frena el scroll en iOS Safari) y restaura
   la posición al soltar. `overflow:hidden` sigue siendo lo que bloquea en desktop.
   Duplicada también en fantasy.css con el mismo valor: se elimina allá al migrar. */
body.noscroll8 { overflow: hidden; }
@media (min-width: 860px) {
    .sheet8 { left: 50%; right: auto; bottom: auto; top: 50%; width: min(600px, 92vw); border-radius: var(--r-lg); border: 1px solid var(--line-2); max-height: 86vh; transform: translate(-50%, -44%) scale(.98); opacity: 0; pointer-events: none; transition: transform .22s, opacity .22s; }
    .sheet8.on { transform: translate(-50%, -50%) scale(1); opacity: 1; pointer-events: auto; }
    .sheet8__handle { display: none; }
    /* la reserva del aviso de red (ver .netnotice8) también acá: el modal centrado tiene
       otro max-height, y sin repetirlo la regla de afuera le ganaría por especificidad. */
    .sheet8[data-net-reserva] { max-height: calc(86vh - var(--net-reserve, 0px)); }
}

/* ============================================================
   TABLA board + listas + estados
   ============================================================ */
.t8wrap { overflow-x: auto; }
.t8 { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
.t8 th { text-align: left; color: var(--tx-3); padding: 9px 10px; border-bottom: 1px solid var(--line-2); white-space: nowrap; }   /* tipografía: .kick8 */
.t8 td { padding: 10px; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; }
.t8 tbody tr:hover { background: rgba(61,123,255,.07); }
.t8 .num { font-family: var(--disp); font-size: 1rem; }

.lrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 2px; }
.lrow + .lrow { border-top: 1px solid var(--line); }
/* P3.8 — `a.lrow` es una fila-link (goleadores, tops) y solo tenía `:active`: con mouse
   no daba ninguna señal de que se podía entrar. Hover solo en punteros que lo soportan,
   y solo sobre la forma interactiva (`a.`/`button.`): los `.lrow` que son datos sueltos
   no deben iluminarse. Fondo + radio, sin mover la fila (movería toda la lista). */
@media (hover: hover) {
    a.lrow:hover, button.lrow:hover { background: rgba(61,123,255,.09); border-radius: 10px; }
    a.lrow:hover .lrow__t, button.lrow:hover .lrow__t { color: var(--gold-2); }
}
a.lrow, button.lrow { cursor: pointer; }
.lrow__t { min-width: 0; font-weight: 700; font-size: var(--fs-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lrow__s { font-size: var(--fs-body-sm); color: var(--tx-3); }
.lrow__v { font-family: var(--disp); font-size: 1.15rem; color: var(--gold); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ============================================================
   EMPTY8 — "no hay nada" (OLA 3 · P3.7)

   `.empty8` y `.secerr8` se veían IGUAL: los dos con borde punteado, icono grande y
   texto gris centrado. El usuario no podía distinguir "todavía no jugó nadie" (una
   situación válida, no hay nada que hacer) de "no pudimos traer los datos" (un fallo,
   hay algo que reintentar). Ahora cada uno tiene su propia forma:

     empty8  = situación VÁLIDA sin datos → borde SÓLIDO y tenue, icono al tono del
               texto, sin oro y sin rojo. Es un vacío tranquilo, no una alarma.
     secerr8 = fallo RECUPERABLE → tinte de la familia --loss, icono rojo, borde
               continuo y "Reintentar" con ancho estable (abajo).

   El punteado pasa a significar UNA sola cosa en el sistema: "acá falta algo que
   deberías completar" (`.jrank__seed`, `.estado__tip`), no "acá se rompió".
   ============================================================ */
/* Ambos estados REEMPLAZAN a la lista, así que cuando el contenedor es un grid tienen
   que ocupar la fila entera. Sin esto caían en la primera celda: en Partidos a 1280
   (`.tlist--grid` de 3 columnas) el panel medía 368px pegado a la izquierda con 800px
   de vacío al lado, y se leía como una card rota, no como el estado de la sección.
   En contenedores flex la declaración se ignora sola. */
.empty8, .secerr8 { grid-column: 1 / -1; }
.empty8 { display: flex; flex-direction: column; align-items: center; gap: 9px; padding: 36px 16px; text-align: center; color: var(--tx-3); background: rgba(10,24,56,.45); border: 1px solid var(--line); border-radius: var(--r); }
.empty8 i { font-size: 1.7rem; color: var(--tx-3); opacity: .85; }
/* variante de página completa: estado vacío con jerarquía (sin caja), centrado en el alto disponible + acción de salida */
.empty8--page { min-height: 56vh; justify-content: center; gap: 13px; padding: 48px 20px; background: transparent; border: 0; }
.empty8--page i { font-size: 2.6rem; opacity: .8; }
.empty8__t { font-family: var(--disp); font-weight: 400; font-size: 1.55rem; line-height: 1; letter-spacing: .01em; color: var(--tx); }
.empty8__sub { font-size: var(--fs-body); color: var(--tx-3); max-width: 34ch; line-height: 1.45; margin: -3px 0 5px; }
.empty8--page .btn8 { text-decoration: none; }

.pill8 { display: inline-flex; align-items: center; gap: 5px; font-size: .62rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; padding: 5px 10px; border-radius: 999px; }
.pill8.w { background: rgba(52,217,123,.18); color: var(--win-t); }
.pill8.l { background: rgba(255,93,119,.16); color: var(--loss-t); }
.pill8.d { background: rgba(147,164,200,.18); color: var(--tx-2); }
.pill8.g { background: rgba(255,194,51,.16); color: var(--gold-2); }

/* forma W/D/L dots */
.form8 { display: inline-flex; gap: 6px; align-items: center; }
.form8 i { width: 23px; height: 23px; border-radius: 7px; display: inline-grid; place-items: center; font-style: normal; font-size: .64rem; font-weight: 800; }
.form8 .w { background: var(--win); color: #03301a; box-shadow: 0 0 10px rgba(52,217,123,.4); }
.form8 .d { background: rgba(147,164,200,.35); color: #e6ecfa; }
.form8 .l { background: var(--loss); color: #38000b; }

/* skeleton */
.sk8 { position: relative; overflow: hidden; background: var(--raise); border-radius: 10px; min-height: 14px; }
.sk8::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, rgba(156,195,255,.12), transparent); animation: sk8 1.2s infinite; }
@keyframes sk8 { to { transform: translateX(100%); } }

/* loader de página */
.load8 {
    position: fixed; inset: 0; z-index: 100; display: grid; place-items: center;
    background:
        radial-gradient(120% 70% at 12% -12%, rgba(61,123,255,.18), transparent 58%),
        linear-gradient(180deg, #0a1838 0%, var(--bg) 60%, #04091c 100%);
    transition: opacity .35s;
}
.load8.off { opacity: 0; pointer-events: none; }

/* spinner = pelota de fútbol que bota y gira sobre su sombra */
.load8 .spin {
    width: 70px; height: 92px; border: 0; border-radius: 0; background: none;
    position: relative; animation: none;
}
.ball8 { /* contenedor que BOTA (translateY) */
    display: block; position: absolute; top: 0; left: 50%; margin-left: -26px;
    width: 52px; height: 52px;
    animation: ball-bounce 1.05s cubic-bezier(.32,0,.5,1) infinite;
}
.ball8::after { /* iluminación FIJA (no gira): brillo especular sutil sobre la pelota */
    content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none; z-index: 2;
    background:
        radial-gradient(circle at 31% 24%, rgba(255,255,255,.5) 0 9%, rgba(255,255,255,0) 30%),
        radial-gradient(circle at 74% 84%, rgba(5,9,22,.3) 0, rgba(5,9,22,0) 62%);
}
.ball8__skin { /* gira (rotate) — pelota SVG nítida (paños clásicos distribuidos), no emoji ni raster */
    display: block; width: 100%; height: 100%;
    background: url("/Content/assets/ball.svg?v=6") center / contain no-repeat;
    animation: ball-spin 1.05s linear infinite;
}
.ball8__shadow {
    display: block; position: absolute; bottom: 6px; left: 50%; margin-left: -26px;
    width: 52px; height: 11px; border-radius: 50%;
    background: radial-gradient(closest-side, rgba(2,6,23,.62), transparent);
    animation: ball-shadow 1.05s cubic-bezier(.32,0,.5,1) infinite;
}
.load8 .spin::after { /* texto de carga: si el loader demora, no queda una pelota sola en pantalla */
    content: "Cargando…"; position: absolute; top: 106px; left: 50%; transform: translateX(-50%);
    white-space: nowrap; font-size: var(--fs-body); font-weight: 600; letter-spacing: .06em; color: #aebbdc;
}
@keyframes ball-bounce { 0%,100% { transform: translateY(34px); } 48% { transform: translateY(0); } }
@keyframes ball-spin { to { transform: rotate(360deg); } }
@keyframes ball-shadow { 0%,100% { transform: scaleX(1); opacity: .5; } 48% { transform: scaleX(.55); opacity: .22; } }
/* el spinner SIEMPRE anima (es indicador de carga, no decoración) — no se
   apaga bajo reduced-motion; girar/botar en su lugar no causa desorientación */

/* ============================================================
   PRESS FEEDBACK — respuesta inmediata al tap (mobile no tiene hover).
   scale sutil <100ms + touch-action quita el delay de 300ms del browser.
   ============================================================ */
.ticket, .tcard, .board__row, .pedestal, .dd-opt, .dd-trigger,
.btn8, .chip8, .seg8 button, .quick a, .dock a, .rail a,
.tile[data-key], .sheet8__x, .lrow, .xi__p, .mev,
.tape__it, .blk__more, .sec__more {
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}
/* El press-scale es feedback de ALGO QUE SE TOCA. `.chip8` y `.lrow` lo tenían sin
   condicionar, pero 11 de sus 13 usos son <span> de estado: una etiqueta que se achica
   al tocarla se lee como rota, no como presionable. Se condicionan a su forma
   interactiva, igual que ya hace `.tile[data-key]` — el patrón correcto ya existía. */
.ticket:active, .tcard:active, .board__row:active, .pedestal:active,
.dd-opt:active, .btn8:active, .tile[data-key]:active,
a.chip8:active, button.chip8:active, a.lrow:active, button.lrow:active,
.xi__p:active {
    transform: scale(.97);
    transition: transform .06s ease;
}
.seg8 button:active, .dd-trigger:active, .quick a:active { transform: scale(.95); }

/* transición al match center (entra desde abajo) */
#viewMatch:not(.hide) { animation: view-in .32s var(--ease-out); }
@keyframes view-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
/* el marcador del match center "aterriza" */
#viewMatch:not(.hide) .mc__num { animation: score-land .5s cubic-bezier(.18,.89,.32,1.1) .08s both; }
@keyframes score-land { 0% { opacity: 0; transform: scale(1.4); } 100% { opacity: 1; transform: none; } }
/* paneles de tabs del match center entran suave al cambiar */
.mline:not(.hide), #tabXi:not(.hide), #tabCambios:not(.hide), #tabRojas:not(.hide) { animation: view-in .24s ease; }
@media (prefers-reduced-motion: reduce) {
    #viewMatch:not(.hide), #viewMatch:not(.hide) .mc__num,
    .mline:not(.hide), #tabXi:not(.hide), #tabCambios:not(.hide), #tabRojas:not(.hide) { animation: none !important; }
}

/* entrada de página: el contenido y el hero aparecen suave en CADA navegación.
   Da continuidad entre páginas (Inicio→Match Center, etc.) y sensación de app viva. */
.arena__in { animation: page-in .34s ease both; }
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }
.arena__in > .poster:first-child, .arena__in > section.poster, .poster.mc__hero { animation: poster-in .5s var(--ease-out) both; }
@keyframes poster-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .arena__in, .arena__in > .poster:first-child, .arena__in > section.poster, .poster.mc__hero { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* reveals */
/* reveal de entrada: las cards/filas aparecen en cascada (stagger deportivo).
   El delay escalonado por posición da sensación de "se arma el equipo". */
.rv { opacity: 0; transform: translateY(12px); animation: rv8 .5s var(--ease-out) forwards; }
@keyframes rv8 { to { opacity: 1; transform: none; } }
.rv:nth-child(1) { animation-delay: .02s; }
.rv:nth-child(2) { animation-delay: .06s; }
.rv:nth-child(3) { animation-delay: .10s; }
.rv:nth-child(4) { animation-delay: .14s; }
.rv:nth-child(5) { animation-delay: .18s; }
.rv:nth-child(6) { animation-delay: .22s; }
.rv:nth-child(7) { animation-delay: .26s; }
.rv:nth-child(8) { animation-delay: .30s; }
.rv:nth-child(9) { animation-delay: .34s; }
.rv:nth-child(10) { animation-delay: .38s; }
.rv:nth-child(n+11) { animation-delay: .42s; }

/* ---- utilitarios de motion / posicion (lenguaje comun) ---- */
/* press feedback en cualquier tappable */
.tap { touch-action: manipulation; -webkit-tap-highlight-color: transparent; transition: transform var(--mo-fast) var(--ease-spring); }
.tap:active { transform: var(--press); }

/* badge de posicion deportiva, consistente con Fantasy (GK/DEF/MED/ATA) */
.posb { --pc: var(--tx-2); display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border-radius: 999px;
    font-size: .64rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
    color: var(--pc); background: color-mix(in srgb, var(--pc) 16%, transparent); border: 1px solid color-mix(in srgb, var(--pc) 35%, transparent); }
.posb::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--pc); }
.posb--GK { --pc: var(--pos-gk); } .posb--DEF { --pc: var(--pos-def); }
.posb--MED { --pc: var(--pos-med); } .posb--ATA { --pc: var(--pos-ata); }
.posb--none { --pc: var(--tx-3); }

/* match center: XI agrupado por lineas (legacy) */
.xiline { margin-bottom: 12px; }
.xiline__h { margin-bottom: 7px; }
.xiline__row { display: flex; flex-wrap: wrap; gap: 8px; }

/* posicion -> color (selector compartido; fantasy.css tiene literales equivalentes) */
.pos-GK { --pc: var(--pos-gk); } .pos-DEF { --pc: var(--pos-def); }
.pos-MED { --pc: var(--pos-med); } .pos-ATA { --pc: var(--pos-ata); }

/* ============================================================
   AVATAR / PLACEHOLDER RICO — fuente única (est.js EST.avatar/placeholder).
   --pc = color de posición. Skin A: camiseta teñida + dorsal fantasma +
   monograma. Skin C (--brand): monograma sobre disco azul-noche con rayo.
   ============================================================ */
.avph {
    /* --pc NO se fuerza aquí: se hereda del holder (.pos-*, .fph, .avph--POS) y cae a --tx-3.
       Forzarlo rompería el tinte que ya setean contenedores como .dmini__ph .fph { --pc } */
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; overflow: hidden;
    background: radial-gradient(120% 95% at 50% 22%, color-mix(in srgb, var(--pc, var(--tx-3)) 26%, #0e1f47), #091532 78%);
}
.avph--GK { --pc: var(--pos-gk); } .avph--DEF { --pc: var(--pos-def); }
.avph--MED { --pc: var(--pos-med); } .avph--ATA { --pc: var(--pos-ata); }
/* placeholder por defecto = monograma premium + identidad Olimar: escudo marca de agua + textura
   cancha tenue + halo de posición + acento. Sin z-index positivo → la foto siempre pinta por encima. */
.avph:not(.avph--brand) { background-image:
    radial-gradient(circle at 50% 32%, color-mix(in srgb, var(--pc, var(--tx-3)) 22%, transparent), transparent 60%),
    repeating-linear-gradient(0deg, transparent 0 12px, rgba(255,255,255,.02) 12px 13px),
    radial-gradient(120% 95% at 50% 20%, color-mix(in srgb, var(--pc, var(--tx-3)) 28%, #102450), #081530 82%); }
/* marca de agua del escudo: PNG8 de 128px (6,6 KB). Antes apuntaba a Olimar_transparente_v2.png,
   que pesa 1,81 MB a 2048×2048 y se descargaba en 7 páginas para pintarse a ~63px como máximo. */
.avph:not(.avph--brand)::before { content: ""; position: absolute; inset: 0; background: url('/images/olimar-watermark-128.png?v=1') center 30%/54% no-repeat; opacity: .16; }
.avph:not(.avph--brand)::after { content: ""; position: absolute; left: 16%; right: 16%; bottom: 9%; height: 3px; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--pc, var(--tx-3)), transparent); opacity: .65; }
/* dorsal fantasma: figura central, contorno tintado por posición */
.avph__num {
    position: absolute; top: 46%; left: 50%; transform: translate(-50%,-50%); pointer-events: none;
    font-family: var(--disp); font-weight: 400; line-height: 1; font-variant-numeric: tabular-nums;
    font-size: 2.7rem; color: color-mix(in srgb, var(--pc, var(--tx-3)) 24%, transparent);
    -webkit-text-stroke: 1.2px color-mix(in srgb, var(--pc, var(--tx-3)) 82%, #ffffff 10%);
    text-shadow: 0 2px 10px rgba(2,6,23,.5);
}
/* monograma: secundario, abajo del pecho */
.avph__mono {
    position: absolute; bottom: 9%; left: 50%; transform: translateX(-50%);
    font-family: var(--disp); font-weight: 400; font-size: var(--fs-body-strong); letter-spacing: .05em;
    color: var(--gold-2); text-shadow: 0 1px 5px rgba(2,6,23,.6);
}
/* sin dorsal disponible: el monograma toma el centro (premium, no compite con fotos reales) */
.avph--nonum .avph__mono { bottom: auto; top: 44%; transform: translate(-50%,-50%); font-size: 2.45rem; letter-spacing: .02em; color: color-mix(in srgb, #ffffff 88%, var(--pc, var(--tx-3))); text-shadow: 0 5px 18px rgba(2,6,23,.6); }
/* Skin C (marca): disco azul-noche + rayo del sol de mayo + monograma centrado */
.avph--brand { background: radial-gradient(120% 120% at 50% 28%, #1b3066, #0a1735 72%); }
.avph--brand .avph__ray { position: absolute; width: 76%; height: 76%; color: rgba(255,194,51,.15); }
.avph--brand .avph__mono { position: static; transform: none; font-size: 1.55rem; }

/* componente completo (board / podio / me-card / crests): llena el holder (que da el tamaño). */
.av { position: relative; display: block; width: 100%; height: 100%; aspect-ratio: 1/1; overflow: hidden; border-radius: 50%; background: #0a1735; }
.av--card { border-radius: 14px; }
.av__img { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; object-fit: cover; object-position: center 14%; }
.av--card .av__img { transform: scale(1.05); }
/* escalas del dorsal/monograma para circulos chicos/medios/grandes */
.av--sm .avph__num { font-size: 1.15rem; -webkit-text-stroke-width: .7px; }
.av--sm .avph__mono { font-size: .58rem; }
.av--sm .avph--nonum .avph__mono, .av--sm .avph--brand .avph__mono { font-size: var(--fs-body-strong); }
.av--md .avph__num { font-size: 1.7rem; -webkit-text-stroke-width: 1px; }
.av--md .avph__mono { font-size: var(--fs-body-sm); }
.av--md .avph--nonum .avph__mono, .av--md .avph--brand .avph__mono { font-size: 1.3rem; }
.av--lg .avph__num { font-size: 3.1rem; }
.av--lg .avph--nonum .avph__mono, .av--lg .avph--brand .avph__mono { font-size: 2.2rem; }

/* match center: XI en cancha estilo Fantasy */
.mcpitch { position: relative; border-radius: 16px; padding: 16px 8px 20px; display: flex; flex-direction: column; gap: 8px; overflow: hidden;
    background: radial-gradient(120% 60% at 50% 0%, rgba(255,255,255,.05), transparent 60%), repeating-linear-gradient(180deg,#0f4429 0 34px,#0c3a23 34px 68px);
    border: 1px solid rgba(255,255,255,.1); box-shadow: inset 0 0 50px rgba(0,0,0,.35); }
.mcpitch::before { content:""; position:absolute; left:50%; top:50%; width:84px; height:84px; transform:translate(-50%,-50%); border:2px solid rgba(255,255,255,.1); border-radius:50%; pointer-events:none; }
.mcpitch::after { content:""; position:absolute; left:8%; right:8%; top:50%; height:2px; background:rgba(255,255,255,.08); pointer-events:none; }
.mcrow { position: relative; z-index:1; display:flex; justify-content:center; gap:8px; flex-wrap:wrap; }
.mcp { position:relative; width:72px; display:flex; flex-direction:column; align-items:center; gap:3px; text-decoration:none; }
.mcp__ph { position:relative; width:46px; height:46px; border-radius:50%; overflow:hidden; background:#0c1a38; display:grid; place-items:center;
    box-shadow: 0 0 0 2.5px var(--pc,#2a3c56), 0 3px 8px rgba(0,0,0,.35); }
.mcp__n { font-family: var(--disp); font-size:1.05rem; color:#cdd7ee; }
.mcp__ph img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
/* distintivo de golero del partido: guantes en la esquina del círculo (no se clippea: cuelga de .mcp) */
.mcp__gk { position:absolute; top:28px; right:6px; width:20px; height:20px; border-radius:50%;
    background:#0c1a38; box-shadow:0 0 0 1.6px var(--gold-2,#ffc233), 0 2px 5px rgba(0,0,0,.45);
    display:grid; place-items:center; font-size:.64rem; line-height:1; z-index:3; }
.mcp__nm { font-size:.66rem; font-weight:800; color:#fff; text-align:center; max-width:72px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-shadow:0 1px 3px rgba(0,0,0,.7); }
.mcsp { margin-top:12px; }
@media (max-width:460px){ .mcp{width:60px} .mcp__ph{width:42px;height:42px} .mcp__nm{max-width:60px;font-size:.6rem} .mcp__gk{top:25px;right:4px;width:18px;height:18px;font-size:.58rem} }

/* ===== motion global: feedback tactil + hover + tab, sin tocar el JS de cada pagina =====
   Aplica sobre las clases compartidas de elementos INTERACTIVOS (no contenedores). */
body.est .btn8, body.est .ticket, body.est .tcard, body.est .player-card, body.est .pickrow,
body.est .rank-row, body.est .mrow, body.est .lrow, body.est .seg8 button, body.est .fseg button {
    transition: transform var(--mo-fast) var(--ease-spring), box-shadow var(--mo) var(--ease-out),
        background-color var(--mo) var(--ease-out), color var(--mo) var(--ease-out);
    touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
body.est .btn8:active, body.est .ticket:active, body.est .tcard:active, body.est .player-card:active,
body.est .pickrow:active, body.est .rank-row:active, body.est .mrow:active, body.est .lrow:active,
body.est .seg8 button:active, body.est .fseg button:active { transform: var(--press); }
@media (hover: hover) {
    body.est .ticket:hover, body.est .tcard:hover, body.est .player-card:hover, body.est .mrow:hover {
        transform: translateY(-2px); box-shadow: var(--sh);
    }
}
/* sheen tipo Sorare en fotos circulares (highlight radial sutil, "pop") */
.fph::after, .mcp__ph::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    background: radial-gradient(120% 80% at 30% 12%, rgba(255, 255, 255, .26), rgba(255, 255, 255, 0) 55%);
}
@media (prefers-reduced-motion: reduce) {
    body.est .btn8, body.est .ticket, body.est .tcard, body.est .player-card, body.est .pickrow,
    body.est .rank-row, body.est .mrow, body.est .lrow, body.est .seg8 button, body.est .fseg button { transition: none; }
    body.est .btn8:active, body.est .ticket:active, body.est .tcard:active, body.est .player-card:active,
    body.est .pickrow:active, body.est .rank-row:active, body.est .mrow:active, body.est .lrow:active,
    body.est .seg8 button:active, body.est .fseg button:active { transform: none; }
}

/* pulso sutil (capitan/destacado) */
@keyframes pulse8 { 0%,100% { box-shadow: 0 0 0 0 rgba(255,194,51,.5); } 50% { box-shadow: 0 0 0 5px rgba(255,194,51,0); } }
.pulse8 { animation: pulse8 2.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .pulse8 { animation: none; } .tap { transition: none; } }

/* ============================================================
   MATCH CENTER (detalle de partido)
   ============================================================ */
.mc__score { display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr); align-items: center; gap: 12px; position: relative; }
.mc__team { display: flex; flex-direction: column; align-items: center; gap: 10px; min-width: 0; }
.mc__crest { width: 70px; height: 70px; border-radius: 50%; background: #fff; display: grid; place-items: center; overflow: hidden; font-family: var(--disp); font-size: 1.4rem; color: #0e3a8c; box-shadow: 0 0 0 3px rgba(255,255,255,.12); }
.mc__crest img { width: 86%; height: 86%; object-fit: contain; }
.mc__nm { font-weight: 700; font-size: var(--fs-body); text-align: center; max-width: min(15ch,100%); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mc__sub { font-size: .66rem; color: var(--tx-3); }
.mc__num { font-family: var(--disp); font-size: clamp(3.2rem, 11vw, 5.4rem); line-height: .9; text-align: center; font-variant-numeric: tabular-nums; text-shadow: 0 8px 40px rgba(2,6,23,.7); }
.mc__state { text-align: center; margin-bottom: 6px; }

/* timeline central */
.mline { position: relative; padding: 8px 0; }
.mline::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; background: var(--line); transform: translateX(-50%); }
.mev { position: relative; display: flex; align-items: center; gap: 10px; padding: 9px 0; width: 50%; }
.mev--l { justify-content: flex-end; text-align: right; padding-right: 26px; }
.mev--r { margin-left: 50%; padding-left: 26px; }
.mev__dot { position: absolute; width: 30px; height: 30px; border-radius: 50%; background: #0d1d45; border: 2px solid var(--line-2); display: grid; place-items: center; font-size: var(--fs-body); z-index: 1; }
.mev--l .mev__dot { right: -15px; } .mev--r .mev__dot { left: -15px; }
.mev.gol .mev__dot { border-color: var(--win); } .mev.roja .mev__dot { border-color: var(--loss); } .mev.cambio .mev__dot { border-color: var(--blue); }
.mev__bd { min-width: 0; }
.mev__t { font-weight: 700; font-size: var(--fs-body); line-height: 1.2; }
.mev__s { font-size: var(--fs-body-sm); color: var(--tx-3); }
.mev__min { font-family: var(--disp); color: var(--gold); font-size: var(--fs-body-strong); flex: none; }

/* XI list */
.xi { display: grid; grid-template-columns: 1fr; gap: 6px; }
@media (min-width: 640px) { .xi { grid-template-columns: 1fr 1fr; } }
.xi__p { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 12px; background: rgba(10,24,56,.45); border: 1px solid var(--line); }
.xi__n { font-family: var(--disp); width: 30px; height: 30px; border-radius: 9px; background: rgba(255,194,51,.14); color: var(--gold-2); display: grid; place-items: center; font-size: var(--fs-body); flex: none; }
.xi__nm { font-weight: 600; font-size: var(--fs-body); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============================================================
   TRIVIA (markup generado por trivia-home.js — ids/clases legacy)
   ============================================================ */
.mt-2 { margin-top: 8px; }
#triviaSearchBox { position: relative; }
#triviaPlayerResults {
    margin-top: 8px; border: 1px solid var(--line-2); border-radius: 14px;
    background: linear-gradient(180deg, #13265a, #0b1a40);
    box-shadow: var(--sh-deep); overflow-y: auto; max-height: 280px;
}
.trivia-search-empty { padding: 14px 16px; font-size: var(--fs-body); color: var(--tx-3); }
.trivia-search-item {
    display: flex; align-items: center; gap: 11px; width: 100%;
    padding: 10px 12px; text-align: left; border-radius: 0;
    border-bottom: 1px solid var(--line); transition: background .12s;
}
.trivia-search-item:last-child { border-bottom: 0; }
.trivia-search-item:hover { background: rgba(61,123,255,.12); }
.trivia-search-avatar, .trivia-selected-avatar, .trivia-top-avatar {
    position: relative; width: 36px; height: 36px; border-radius: 50%; overflow: hidden; flex: none;
    background: linear-gradient(180deg,#1b306f,#0d1c44); border: 1px solid var(--line-2);
    display: inline-grid; place-items: center;
}
.trivia-search-avatar img, .trivia-selected-avatar img, .trivia-top-avatar img { width: 100%; height: 100%; object-fit: cover; object-position: center 16%; }
.trivia-search-avatar-fallback, .trivia-selected-avatar-fallback, .trivia-top-avatar-fallback {
    position: absolute; inset: 0; display: grid; place-items: center;
    font-size: .62rem; font-weight: 800; color: var(--sky);
}
.trivia-search-avatar.hasimg .trivia-search-avatar-fallback,
.trivia-selected-avatar.hasimg .trivia-selected-avatar-fallback,
.trivia-top-avatar.hasimg .trivia-top-avatar-fallback { display: none; }
.trivia-search-texts { min-width: 0; display: flex; flex-direction: column; }
.trivia-search-name { font-weight: 700; font-size: var(--fs-body); color: var(--tx); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trivia-search-meta { font-size: .66rem; color: var(--tx-3); }
#triviaSelected { margin-top: 10px; }
#triviaSelected .pill {
    display: inline-flex; align-items: center; gap: 9px; padding: 7px 14px 7px 8px;
    border-radius: 999px; background: rgba(255,194,51,.14); border: 1px solid rgba(255,194,51,.4);
    font-weight: 700; font-size: var(--fs-body); color: var(--gold-2);
}
.trivia-selected-avatar { width: 28px; height: 28px; }
/* resultado */
.trivia-result-card { border-radius: 14px; padding: 16px; border: 1px solid var(--line-2); background: rgba(7,17,41,.55); }
.trivia-result-card.ok { border-color: rgba(52,217,123,.45); background: linear-gradient(168deg, rgba(52,217,123,.12), rgba(7,17,41,.6)); }
.trivia-result-card.ko { border-color: rgba(255,93,119,.4); background: linear-gradient(168deg, rgba(255,93,119,.1), rgba(7,17,41,.6)); }
.trivia-result-badge { display: inline-block; font-size: .6rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; padding: 4px 10px; border-radius: 999px; background: rgba(255,255,255,.1); color: var(--tx-2); }
.trivia-result-card.ok .trivia-result-badge { background: rgba(52,217,123,.2); color: var(--win-t); }
.trivia-result-card.ko .trivia-result-badge { background: rgba(255,93,119,.18); color: var(--loss-t); }
.trivia-result-title { font-family: var(--disp); font-size: 1.25rem; letter-spacing: .03em; text-transform: uppercase; margin-top: 8px; }
.trivia-result-sub { font-size: var(--fs-body); color: var(--tx-2); margin-top: 4px; }
.trivia-result-main { margin-top: 12px; padding: 12px 14px; border-radius: 12px; background: rgba(10,24,56,.55); border: 1px solid var(--line); }
.trivia-result-main .label { color: var(--tx-3); }   /* tipografía: .kick8 */
.trivia-result-main .value { font-weight: 700; font-size: var(--fs-body-strong); margin-top: 3px; }
.trivia-result-main .metric { font-family: var(--disp); font-size: 1.3rem; color: var(--gold); margin-top: 6px; }
.trivia-top-wrap { margin-top: 14px; }
.trivia-top-wrap .top-title { color: var(--tx-3); margin-bottom: 8px; }   /* tipografía: .kick8 */
.trivia-top-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.trivia-top-item:last-child { border-bottom: 0; }
.trivia-top-item .left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.trivia-top-item .pos { font-family: var(--disp); width: 22px; text-align: center; color: var(--tx-3); }
.trivia-top-item.is-first .pos { color: var(--gold); }
.trivia-top-item .nm { font-weight: 700; font-size: var(--fs-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trivia-top-item .val { font-family: var(--disp); font-size: 1.05rem; color: var(--gold); }
/* pistas */
.trivia-hints { display: flex; flex-direction: column; gap: 8px; }
.trivia-hint-item { padding: 10px 13px; border-radius: 12px; border: 1px solid rgba(255,194,51,.3); background: rgba(255,194,51,.08); }
.trivia-hint-title { color: var(--gold-2); }   /* tipografía: .kick8 */
.trivia-hint-body { font-size: var(--fs-body); color: var(--tx-2); margin-top: 3px; }
.trivia-hints-more { font-size: var(--fs-body-sm); color: var(--tx-3); }
/* feedback animado */
@keyframes tshake { 0%,100%{transform:none} 25%{transform:translateX(-5px)} 75%{transform:translateX(5px)} }
.anim-ko { animation: tshake .3s ease; }
@keyframes tpop { 0%{transform:scale(.97);opacity:.6} 100%{transform:none;opacity:1} }
.anim-ok { animation: tpop .3s ease; }
/* toasts de app.js */
.app-toast, .ui-toast { position: fixed; left: 50%; bottom: calc(86px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 120; background: linear-gradient(180deg,#13265a,#0b1a40); border: 1px solid var(--line-2); color: var(--tx); padding: 11px 18px; border-radius: 12px; box-shadow: var(--sh-deep); font-size: var(--fs-body); font-weight: 600; }

/* prefers-reduced-motion: respetamos al usuario SIN apagar todo. Mantenemos
   las animaciones funcionales (spinner de carga = indica actividad, donut/barras
   = feedback de dato) y neutralizamos los movimientos grandes de entrada (reveal
   con translate) que sí pueden molestar. Las transiciones cortas (hover/focus)
   se conservan: son sub-200ms y no causan mareo.

   OLA 0B — el tape SÍ se apaga (antes se dejaba vivo a propósito). Motivo: es un
   marquee infinito de 40s y su único mecanismo de pausa era `.tape:hover`, que en
   touch no existe → en mobile no había NINGUNA forma de detenerlo (WCAG 2.2.2,
   nivel A). Apagarlo a secas escondería resultados, porque .tape recorta con
   overflow:hidden y la etiqueta "RESULTADOS" tapa los primeros 116px: por eso la
   tira pasa a ser scrolleable a mano y no se pierde ni un dato. home.js además
   deja de duplicar los items cuando reduced-motion está activo. */
@media (prefers-reduced-motion: reduce) {
    .rv { opacity: 1 !important; transform: none !important; animation: none !important; }
    .poster__ghost, .tcard:hover { transform: none !important; }
    .tape__in { animation: none !important; }
    .tape { overflow-x: auto; -webkit-overflow-scrolling: touch; }

    /* OLA 1 — cerrar los agujeros que dejaba apagar POR CLASE y no por keyframe.
       El bloque de arriba apaga `.rv`, pero el keyframe `rv8` lo reusan otras tres
       clases en otros archivos (.jpanel en juegos.css, .mcdet en matchcenter.css,
       .morefilt.open en plantel.css) y esos reusos se escapaban en silencio. Se
       listan acá, junto al keyframe, para que el próximo reuso se vea al leer. */
    .jpanel, .mcdet, .morefilt.open { animation: none !important; opacity: 1 !important; transform: none !important; }

    /* El shimmer del skeleton es decorativo e INFINITO, y aparece en todas las
       páginas durante la carga: es el peor caso para alguien sensible al
       movimiento. Se congela el gradiente; el bloque gris sigue comunicando
       "cargando" por su forma, no por el brillo. */
    .sk8 { animation: none !important; }

    /* Feedback de Trivia: `tshake` sacude ±5px. Se reemplaza por un cambio de
       color, que transmite lo mismo sin trayectoria. */
    .anim-ko, .anim-ok { animation: none !important; }

    /* Los overlays entran y salen SIN RECORRIDO PERCEPTIBLE.
       Se acorta la transición, NO se anula el transform. La versión anterior hacía
       `transform: none !important` y rompía el uso real: a ≥860px el `.sheet8` es un
       modal centrado con `translate(-50%,-50%)`, o sea que ahí el transform no es
       movimiento sino POSICIONAMIENTO. Anularlo mandaba la esquina superior izquierda
       del sheet al centro del viewport y dejaba ~324px por debajo del borde —
       inalcanzables, porque el body está bloqueado y el sheet es `position:fixed`.
       Medido a 1280: el botón de guardar pronósticos quedaba en y=1117.
       1ms en vez de `none` para que `transitionend` siga llegando: hay cierres que
       lo esperan para limpiar. */
    .sheet8, .alb-sheet, .oshare-box, .sheet8-bk, .alb-bk { transition-duration: 1ms !important; }
}

/* ============================================================
   SEGMENTOS HORIZONTALES — affordance de desborde (Ola 1)

   est.js (E.seg) escribe data-ovf="l" | "r" | "lr" | "" según haya contenido
   fuera de vista a izquierda, derecha, ambos o ninguno, y lo actualiza al
   scrollear y al redimensionar. Sin desborde no hay atributo con valor y no se
   dibuja nada: la pista aparece solo cuando hay algo que descubrir.

   Se usa máscara y no un botón ni una flecha: no tapa texto, no parece
   interactivo, y no ocupa espacio que a 320px no sobra.
   ============================================================ */
.seg8[data-ovf="r"], .fseg[data-ovf="r"], .pnav[data-ovf="r"] {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 36px), transparent);
}
.seg8[data-ovf="l"], .fseg[data-ovf="l"], .pnav[data-ovf="l"] {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 36px);
    mask-image: linear-gradient(90deg, transparent, #000 36px);
}
.seg8[data-ovf="lr"], .fseg[data-ovf="lr"], .pnav[data-ovf="lr"] {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 36px), transparent);
}
/* Scroll horizontal nativo, sin arrastrar la página en diagonal. */
.seg8, .fseg, .pnav, .alb-tabs, .rkmetrics { overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; }

/* ---- acceso a cuenta: rail (desktop) + topstrip (mobile) ---- */
.rail__sess{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;margin-top:auto;padding:10px 4px;color:var(--tx-2);text-decoration:none;font-size:.6rem;font-weight:700;letter-spacing:.03em}
.rail__sess img,.rail__sess .rail__sessav{width:34px;height:34px;border-radius:50%;object-fit:cover;display:inline-flex;align-items:center;justify-content:center;background:rgba(255,255,255,.08);font-size:var(--fs-body-sm);font-weight:800;border:1px solid var(--line-2)}
.rail__sess span{font-size:.6rem}
.rail__sess:hover{color:var(--gold-2)}
.rail__sess:hover img,.rail__sess:hover .rail__sessav{border-color:var(--gold-2)}
.rail__logout{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:6px 4px;color:var(--tx-3);text-decoration:none;font-size:.58rem;font-weight:700;letter-spacing:.03em}
.rail__logout i{font-size:1.15rem}
.rail__logout:hover{color:var(--loss-t)}
.topstrip__sess{margin-left:8px;color:inherit;font-size:1.1rem;text-decoration:none}
.meCard__av{width:46px;height:46px;border-radius:50%;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;background:rgba(255,255,255,.08);font-weight:800}
.meCard__av img{width:100%;height:100%;object-fit:cover}

/* matchday card — próximos partidos (Inicio): compacta (2 líneas) y clickeable */
a.mday, .mday{display:block;background:var(--card-flat);border:1px solid var(--line-2);border-radius:var(--r);padding:10px 14px;margin-bottom:8px;box-shadow:var(--inlight);text-decoration:none;color:inherit}
a.mday:hover{background:var(--raise)}
.mday__meta{display:flex;align-items:center;gap:8px;font-size:.66rem;color:var(--tx-3);letter-spacing:.04em}
.mday__cat{background:rgba(151,177,232,.12);padding:2px 8px;border-radius:999px;font-weight:800;text-transform:uppercase;color:var(--tx-2)}
.mday__date{font-variant-numeric:tabular-nums;text-transform:capitalize}
.mday__rec{margin-left:auto;display:inline-flex;gap:5px;font-variant-numeric:tabular-nums;font-size:var(--fs-body-sm);font-weight:800}
.mday__rec b.g{color:var(--win-t)} .mday__rec b.e{color:var(--draw)} .mday__rec b.l{color:var(--loss-t)}
.mday__chev{color:var(--tx-3);font-size:var(--fs-body);margin-left:2px}
.mday__teams{display:flex;align-items:center;gap:10px;margin-top:5px;font-weight:800;font-size:1rem;line-height:1.1}
.mday__teams .tm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mday__teams .tm--r{text-align:right}
.mday__teams .ol{color:var(--gold-2)}
.mday__teams .vs{flex:0 0 auto;color:var(--tx-3);font-weight:600;font-size:var(--fs-body-sm)}

/* ---- trivia CHOICE: botones de opción múltiple ---- */
.opt8{display:flex;flex-direction:column;gap:8px;margin:8px 0}
.opt8 button{width:100%;text-align:left;min-height:46px;padding:12px 14px;border-radius:12px;border:1px solid var(--line-2);background:rgba(7,17,41,.6);color:var(--tx);font:inherit;font-weight:600;transition:border-color .14s,background .14s}
.opt8 button:hover{border-color:var(--gold)}
.opt8 button.ok{border-color:var(--win);background:rgba(31,176,106,.18)}
.opt8 button.ko{border-color:var(--loss);background:rgba(226,74,74,.16)}
.opt8 button:disabled{opacity:.85;cursor:default}

/* ============================================================
   ACCESIBILIDAD — FOCO VISIBLE UNIFICADO (WCAG 2.4.7)
   :focus-visible solo dispara con teclado (no molesta mouse/touch).
   Anillo dorado consistente en TODO control interactivo del sistema.
   ============================================================ */
/* base: links de contenido, tiles clickeables y cualquier focusable sin override */
body.est :focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}
/* controles redondeados/branded: anillo con box-shadow que sigue su forma */
body.est .btn8:focus-visible,
body.est .seg8 button:focus-visible,
body.est .fseg button:focus-visible,
body.est .chip8:focus-visible,
body.est .dd-trigger:focus-visible,
body.est .dd-opt:focus-visible,
body.est .sheet8__x:focus-visible,
body.est .dock a:focus-visible,
body.est .rail a:focus-visible,
body.est .rail__sess:focus-visible,
body.est .opt8 button:focus-visible,
body.est .ticket:focus-visible,
body.est .tcard:focus-visible,
body.est .player-card:focus-visible,
body.est a.mday:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--gold);
}
/* inputs/textarea: refuerzan su anillo dorado existente, sin doble outline */
body.est .inp8:focus-visible,
body.est textarea.inp8:focus-visible {
    outline: none;
    border-color: var(--gold);
    box-shadow: 0 0 0 3px rgba(255,194,51,.3);
}
/* dropdown custom: el <select> nativo queda oculto pero focusable por teclado;
   reflejamos el foco en el host visible para que el usuario lo vea */
body.est .sel8.dd-host:focus-within {
    box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--gold);
    border-radius: 12px;
}
body.est select.dd-native:focus-visible { outline: none; }

/* ============================================================
   UTILIDADES DE LAYOUT — fuente única de spacing/grids/forms.
   Reemplazan los estilos inline repetidos en cada página.
   Mobile-first y responsive por defecto (auto-fit colapsa solo).
   ============================================================ */
/* grilla de formulario: columnas que se acomodan y colapsan a 1 en mobile */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--sp-3); }
.form-grid--wide { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.field { min-width: 0; }                    /* celda de form que puede encogerse */
.field--full { grid-column: 1 / -1; }       /* ocupa toda la fila */

/* fila de controles que envuelve (input + botón, chips de acción) */
.cluster8 { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.cluster8--end { align-items: flex-end; }
.cluster8--tight { gap: var(--sp-1); }
.grow { flex: 1; min-width: 160px; }        /* el input crece, el botón conserva tamaño */

/* stack vertical con ritmo */
.stack8 { display: flex; flex-direction: column; gap: var(--sp-3); }
.stack8--sm { gap: var(--sp-2); }
.stack8--lg { gap: var(--sp-5); }

/* caption legible (≥13px) para hints/ayudas de texto corrido */
.hint8 { font-size: var(--cap); color: var(--tx-3); line-height: 1.5; }
.hint8--sm { font-size: var(--fs-body-sm); line-height: 1.45; }
.hint8 a, .hint8--sm a { color: var(--gold-2); }

/* separación de secciones consistente dentro de una página */
.sec8 { margin-top: var(--sp-6); }
.sec8--sm { margin-top: var(--sp-5); }
.sec8__t { font-family: var(--disp); font-weight: 400; font-size: 1.4rem; letter-spacing: .04em; text-transform: uppercase; margin: 0 0 4px; }
.sec8__t--kick { color: var(--gold-2); }

/* helpers de margen puntuales (evitan inline mt repetido) */
.mt2 { margin-top: var(--sp-2); } .mt3 { margin-top: var(--sp-3); } .mt4 { margin-top: var(--sp-4); }

/* ============================================================
   DENSIDAD DESKTOP — layouts de 2 columnas para páginas livianas.
   Aprovechan el ancho en ≥1024px; en mobile las secciones siguen
   apiladas (mobile-first intacto).
   ============================================================ */
@media (min-width: 1024px) {
    /* Juegos: tarjetas + paneles a la izquierda, ranking del juego a la derecha */
    .jgrid { display: grid; grid-template-columns: 1.55fr 1fr; gap: var(--sp-4); align-items: start; }
    .jgrid__side > section:first-child { margin-top: 0; }
    /* Ranking: podio a la izquierda, tabla a la derecha (rellena la franja vacía) */
    .rank-cols { display: grid; grid-template-columns: minmax(300px, .92fr) 1.08fr; gap: var(--sp-3); align-items: start; }
    .rank-cols > #boardTile { margin-top: 14px; }

    /* Páginas de autenticación (sin rail): centrar la card de verdad en desktop.
       Antes heredaban el margin-left: var(--rail) (86px fantasma) → quedaba off-center
       y pegada arriba con mucho espacio muerto. Acá la centramos h+v. */
    .page-login .arena,
    .page-registro .arena,
    .page-completaremail .arena {
        margin-left: 0;
        min-height: calc(100vh - 64px);
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .page-login .arena__in,
    .page-registro .arena__in,
    .page-completaremail .arena__in {
        margin: 0;
    }
}

/* ===== Login: split-screen "entrada al club" en desktop. Mobile = solo el form (limpio). ===== */
.page-login .loginhero { display: none; }
.page-login .loginform { width: 100%; }
@media (min-width: 880px) {
    .page-login .loginwrap { max-width: 920px; width: 100%; display: grid; grid-template-columns: 1.05fr 420px; gap: 48px; align-items: center; }
    .page-login .loginform { max-width: 420px; justify-self: end; }
    /* en la card de 420px el título a 5rem (80px) se recortaba: lo acotamos para que "INGRESAR" entre */
    .page-login .loginform .poster__title { font-size: 3.4rem; }
    .page-login .loginhero { display: block; position: relative; padding: 10px 12px; }
    .page-login .loginhero__lines { position: absolute; inset: 0; pointer-events: none; opacity: .6;
        background:
            radial-gradient(120% 80% at 0% 0%, rgba(255, 194, 51, .10), transparent 55%),
            repeating-linear-gradient(115deg, transparent 0 38px, rgba(156, 195, 255, .045) 38px 39px); }
    .page-login .loginhero > :not(.loginhero__lines) { position: relative; }
    .page-login .loginhero__crest { display: inline-flex; width: 84px; height: 84px; border-radius: 22px; overflow: hidden;
        border: 1px solid rgba(255, 194, 51, .4); box-shadow: 0 16px 40px rgba(0, 0, 0, .4); }
    .page-login .loginhero__crest img { width: 100%; height: 100%; object-fit: cover; }
    .page-login .loginhero__kick { display: block; margin-top: 22px; font-size: var(--fs-body-sm); font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-2); }
    .page-login .loginhero__claim { font-family: var(--disp, Anton), sans-serif; font-weight: 400; font-size: 3rem; line-height: .98; margin: 10px 0 0; color: #fff; letter-spacing: .01em; }
    .page-login .loginhero__sub { margin: 16px 0 0; max-width: 34ch; font-size: var(--fs-body-strong); line-height: 1.5; color: var(--tx-2); }
}

/* ===== Auth (Login / Registro / CompletarEmail): centrado mobile + toggle pass + estados ===== */
/* Mobile: centrar el form verticalmente (el centrado h+v de arriba está gateado a ≥1024px,
   por eso en mobile el form quedaba pegado arriba con una franja muerta abajo). */
@media (max-width: 1023px) {
    /* CompletarEmail se omite a propósito: no se pudo validar su render (no existe cuenta
       RequiereEmail en la base) → queda pendiente, sin tocar, per pedido. */
    .page-login .arena, .page-registro .arena {
        min-height: calc(100dvh - 64px); display: flex; flex-direction: column; justify-content: center;
    }
}
/* campo contraseña con botón ojo (ver/ocultar) */
.pwwrap { position: relative; }
.pwwrap .inp8 { padding-right: 46px; }
.pwtog { position: absolute; top: 0; right: 0; height: 48px; width: 44px; display: inline-flex; align-items: center; justify-content: center;
    background: none; border: 0; color: var(--tx-3); cursor: pointer; font-size: 1.05rem; border-radius: 0 12px 12px 0; transition: color .14s; }
.pwtog:hover { color: var(--gold-2); }
.pwtog:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
/* estado del form (error / ok / info): visible y con color, no texto gris perdido */
.auth-status { display: none; align-items: flex-start; gap: 8px; margin-top: 12px; padding: 10px 12px; border-radius: 12px;
    font-size: var(--fs-body); font-weight: 600; line-height: 1.3; }
.auth-status.show { display: flex; }
.auth-status .bi { font-size: 1rem; flex: none; margin-top: 1px; }
.auth-status--err { color: var(--loss-t); background: rgba(255, 77, 94, .14); border: 1px solid rgba(255, 77, 94, .34); }
.auth-status--ok  { color: var(--win-t);  background: rgba(40, 194, 129, .14); border: 1px solid rgba(40, 194, 129, .34); }
.auth-status--info { color: var(--tx-2);  background: rgba(255, 255, 255, .05); border: 1px solid var(--line-2); }
/* spinner chico para botones async (hereda currentColor → sirve sobre el dorado) */
.btnspin { display: inline-block; width: 15px; height: 15px; vertical-align: -2px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: btnspin8 .6s linear infinite; }
@keyframes btnspin8 { to { transform: rotate(360deg); } }
/* Registro: estado de éxito fuerte (reemplaza el form) */
.auth-done { text-align: center; padding: 8px 4px; }
.auth-done__ic { width: 56px; height: 56px; margin: 0 auto 12px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    font-size: 1.7rem; color: var(--win-t); background: rgba(40, 194, 129, .16); border: 1px solid rgba(40, 194, 129, .4); }
.auth-done__t { font-family: var(--disp); font-size: 1.5rem; letter-spacing: .02em; margin: 0 0 6px; color: var(--tx); }
.auth-done__sub { font-size: var(--fs-body); color: var(--tx-2); margin: 0 0 18px; line-height: 1.45; }

/* ============================================================
   ROBUSTEZ DE RED — aviso global "sin conexión" + estado de error
   por sección con reintentar (OLA 3). Distinguen "falló la red"
   del vacío genuino.
   ============================================================ */
/* El chip global. `bottom` es el camino normal (sin ninguna capa abierta); cuando hay un
   overlay arriba —o el teclado virtual—, est.js escribe `top` inline y pone la clase
   `--top`, que es lo único que cambia: la dirección desde la que entra. Ver el bloque
   "AVISO GLOBAL DE RED" de est.js para el porqué de la política.
   `pointer-events: none` en TODOS los estados: el chip nunca se come un toque de lo que
   hay debajo, ni siquiera mientras se lo ve. */
.netnotice8 {
    position: fixed; left: 50%; bottom: calc(var(--dock-h, 60px) + 14px);
    --net-shift: 16px;
    transform: translate(-50%, var(--net-shift)); z-index: 200;
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 15px; border-radius: 999px;
    background: rgba(20, 8, 12, .96); color: #ffd9df;
    border: 1px solid var(--loss, #fb7185); box-shadow: 0 10px 30px -8px rgba(0,0,0,.6);
    font-size: var(--fs-body); font-weight: 600; white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity .25s, transform .25s;
}
/* arriba: entra bajando, no subiendo */
.netnotice8--top { --net-shift: -16px; }
.netnotice8.on { opacity: 1; transform: translate(-50%, 0); }
.netnotice8 .bi { color: var(--loss, #fb7185); }
@media (min-width: 1024px) { .netnotice8 { bottom: 20px; } }
/* reduced-motion: se acorta el RECORRIDO (16px → 4px), nunca el mensaje ni el tiempo que
   el aviso queda en pantalla. */
@media (prefers-reduced-motion: reduce) { .netnotice8, .netnotice8--top { --net-shift: 4px; } }

/* Último recurso de la política de bandas: cuando el sheet es tan alto contra el viewport
   que no deja hueco arriba NI abajo (típico: landscape de 360px de alto), est.js le pone
   `data-net-reserva` y el panel cede exactamente lo que el chip necesita. Como el sheet
   está anclado abajo, recortar el max-height libera espacio ARRIBA, que es donde va el
   chip. Sin overlay o sin aviso el atributo no existe y esta regla no participa. */
.sheet8[data-net-reserva] { max-height: calc(88vh - var(--net-reserve, 0px)); }
/* Mismo trato para el dropdown de filtros: es un bottom-sheet propio (no pasa por el
   manager de overlays) y en un viewport bajo puede no dejar banda libre tampoco. Se recorta
   contra su propio máximo (70vh, ver `.dd-panel`), no contra el del sheet. En desktop el
   panel es un popover anclado al trigger, no al borde de abajo: ahí recortarlo no liberaría
   la banda de arriba, así que la regla es sólo la de mobile. */
.dd-panel[data-net-reserva] { max-height: calc(70vh - var(--net-reserve, 0px)); }

/* SECERR8 — "se rompió, se puede reintentar" (OLA 3 · P3.7).
   Familia --loss, igual que `.auth-status--err` y `.btn8--danger`: quien ya vio un
   error en el login reconoce este. Borde continuo (el punteado es del vacío, ver
   arriba), fondo apenas teñido y texto en --tx-2, no --tx-3: es un mensaje que hay
   que LEER, no una nota al pie. El texto lo arma `E.errorMsg()` (motivo del backend →
   fallback de la página → texto neutro): nunca un "HTTP 500". */
.secerr8 {
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    text-align: center; padding: 22px 18px; color: var(--tx-2);
    border: 1px solid rgba(255, 93, 119, .34); border-radius: 14px;
    background: rgba(255, 93, 119, .07); font-size: var(--fs-body); line-height: 1.4;
    animation: secerr-in var(--mo) var(--ease-out) both;
}
@keyframes secerr-in { from { opacity: 0; } to { opacity: 1; } }
.secerr8 > .bi { font-size: 1.5rem; color: var(--loss, #fb7185); }
/* el botón NO cambia de ancho al pasar a "Cargando…": un CTA que se encoge y se
   estira mientras reintenta se lee como que algo salió mal otra vez. */
.secerr8__retry { margin-top: 2px; min-width: 148px; }
@media (prefers-reduced-motion: reduce) { .secerr8 { animation: none; } }

/* Fallo de una ACCIÓN, no de una sección (panel admin: "Revertir" que se cae). No puede ser
   un `.secerr8` —eso reemplaza la sección y se llevaría puesto el historial ya cargado—,
   así que va pegado al botón que falló. Lo que sí comparte con `.secerr8` es el LENGUAJE:
   familia --loss e ícono chico. Antes era texto plano alineado a la izquierda contra el
   borde de la card, y se leía como una nota de la fila en vez del fallo de la acción.
   El ícono lo pone el propio Bootstrap Icons: admin.js escribe `adm-actmsg bi bi-<lo que
   corresponda>` con el MISMO vocabulario que `E.errorIcono` usa en `.secerr8` (candado para
   401/403, triángulo para el resto, wifi tachado si no hubo respuesta). Como es un
   ::before, el texto del mensaje sigue siendo todo el textContent del nodo — que es lo que
   lee un lector de pantalla en esta live region. */
.adm-actmsg {
    flex-basis: 100%; display: flex; align-items: flex-start; gap: 6px;
    margin-top: 8px; font-size: .8rem; font-weight: 600; line-height: 1.35;
    color: var(--loss, #ff5d77);
}
.adm-actmsg::before { font-size: .95rem; line-height: 1.2; flex: 0 0 auto; }

/* ============================================================
   MOB-P1-01 (auditoría mobile prod 2026-06) — inputs de texto a 16px en mobile.
   iOS Safari hace auto-zoom al enfocar cualquier input con font-size < 16px; la
   página "pierde el ancho" y queda descuadrada (bug reportado en el buscador de
   Plantel, transversal a login/registro/contacto/MiPerfil/Penca/Fantasy/admin).
   16px ABSOLUTO (no rem) para neutralizar el root reducido del admin, donde .inp8
   caía a ~13.3px. Se EXCLUYEN los <select> a propósito (son dropdowns custom tipo
   bottom-sheet y no disparan el zoom): por eso se usa input.inp8/textarea.inp8 y
   selectores por tipo, nunca el .inp8 pelado que también matchea select.inp8.
   ============================================================ */
@media (max-width: 640px) {
    input.inp8,
    textarea.inp8,
    .search8 input,
    input[type="text"],
    input[type="search"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="password"],
    input[type="number"],
    input[type="date"],
    input[type="datetime-local"],
    input[type="time"],
    input[type="month"],
    input[type="week"],
    textarea {
        font-size: 16px;
    }
}

/* ============================================================
   OLA 1 (rediseño integral 2026-06) — tap targets ≥44px en los
   componentes táctiles compartidos. Solo amplía el área de toque;
   NO cambia el glifo/tipografía visible. Apple HIG / WCAG 2.5.5.
   habchip (plantel) y fseg/metric-chips (fantasy/ranking) se tratan
   en sus propias olas por estar en CSS de página.
   ============================================================ */
/* "Ver todos / Fixture completo / Tabla de goleadores": medían ~18px de alto.
   El margin negativo compensa el padding para no mover el layout del header. */
/* OLA 3 · P3.6 — 40 -> 44. El margin negativo sigue compensando el padding para no
   mover el layout del header (crece el área, no la caja). */
.blk__more, .sec__more {
    display: inline-flex; align-items: center;
    min-height: 44px; padding: 8px 4px; margin: -8px -4px;
}
/* switcher de temporadas / segmentos: 40 -> 44 */
.seg8 button { min-height: 44px; }
/* chips de filtro/estado: ~30 -> 40 (mantiene el look compacto premium) */
.chip8 { min-height: 40px; }
/* link de sesión del topstrip: glifo chico -> hit-area 44×44 sin agrandar el ícono.
   flex:none: el acceso a la cuenta nunca se comprime ni sale del viewport. */
.topstrip__sess {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px;
    flex: none;
    /* Ola 2: el empuje a la derecha vivía en `.topstrip__aux`. Como ahora hay páginas sin aux
       (Mi Olimar, Fantasy, Juegos, Login), el ícono de sesión tiene que saber empujarse solo,
       o queda pegado a la marca. Si SÍ hay aux, el aux ya empuja y acá solo hace falta el gap. */
    margin-left: auto;
}
.topstrip__aux ~ .topstrip__sess,
.topstrip__act ~ .topstrip__sess { margin-left: 8px; }

/* ---- invitación "Instalá Olimar" (PWA): banner compacto, no modal ---- */
.installcard {
    position: relative;
    display: flex; align-items: center; gap: 12px;
    margin-top: 14px; padding: 13px 42px 13px 14px;
    background: linear-gradient(120deg, rgba(255,194,51,.09), rgba(255,194,51,.02));
    border: 1px solid rgba(255,194,51,.3);
    border-radius: 16px;
}
.installcard--perfil { padding-right: 14px; }
.installcard__ic { flex: none; width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; font-size: 1.15rem; color: var(--gold-2); background: rgba(255,194,51,.12); }
.installcard__tx { min-width: 0; flex: 1; display: grid; gap: 2px; }
.installcard__tx > b { font-size: var(--fs-body); }
.installcard__tx > span { font-size: var(--fs-body-sm); color: var(--tx-2); line-height: 1.35; }
.installcard__steps { margin: 8px 0 0; padding-left: 18px; font-size: var(--fs-body-sm); color: var(--tx-2); display: grid; gap: 4px; }
.installcard__steps[hidden] { display: none; }   /* el display:grid no debe pisar el hidden */
.installcard__act { flex: none; display: flex; align-items: center; }
/* OLA 3 · P3.6 — acá vivía `min-height: 40px`, que ACHICABA el piso de 46px que
   `.btn8` ya cumplía. El botón de instalar es el CTA de la invitación: no puede ser
   el control más chico de la pantalla. Se quita el override y hereda los 46. */
.installcard .installcard__btn { padding: 8px 14px; font-size: var(--fs-body-sm); white-space: nowrap; }
.installcard__hint { font-size: var(--fs-body-sm); color: var(--tx-2); max-width: 16ch; line-height: 1.3; }
/* cerrar: el glifo sigue midiendo 32px (agrandarlo lo convertiría en un botón, y es
   un descarte secundario); el área de toque de 44 la da un pseudo-elemento invisible. */
.installcard__close { position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 32px; height: 32px; border: 0; background: none; color: var(--tx-3); font-size: var(--fs-body-sm); cursor: pointer; border-radius: 8px; }
.installcard__close::after { content: ""; position: absolute; top: 50%; left: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); }
/* instalación apunta al celular: en desktop no se muestra (decisión documentada) */
@media (min-width: 1024px) { .installcard { display: none; } }

/* ---- notificaciones push (MiPerfil) ---- */
.pushcard__sub { font-size: var(--fs-body); color: var(--tx-2); margin: 4px 0 12px; line-height: 1.4; }
.pushcard__hint { display: flex; gap: 8px; align-items: flex-start; font-size: var(--fs-body); color: var(--tx-2); line-height: 1.45; }
.pushcard__hint .bi { color: var(--gold-2); margin-top: 1px; flex: none; }
.pushcard__badge { display: inline-flex; align-items: center; gap: 7px; font-size: var(--fs-body); font-weight: 700; color: #7ee0a6; }
.pushcard__acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
/* OLA 3 · P3.6 — igual que `.installcard__btn`: bajaba el piso de 46 de `.btn8` a 42.
   Se elimina el override; los botones de notificaciones vuelven al piso del sistema. */

/* preferencias por categoría (fantasy/penca/trivia) dentro de la card de notificaciones */
.pushcard__prefs { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.pushprefs__hd { color: var(--tx-3); margin-bottom: 8px; }   /* tipografía: .kick8--lg */
.pushpref { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); cursor: pointer; }
.pushpref:last-of-type { border-bottom: 0; }
.pushpref__tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.pushpref__lb { font-weight: 700; font-size: var(--fs-body-strong); color: var(--tx); }
.pushpref__hint { font-size: var(--fs-body-sm); color: var(--tx-3); line-height: 1.3; }
/* switch accesible: checkbox real (focus/teclado) estilizado como interruptor */
.pushpref__sw { appearance: none; -webkit-appearance: none; flex: none; width: 46px; height: 28px; border-radius: 999px;
    background: var(--raise); border: 1px solid var(--line-2); position: relative; cursor: pointer; transition: background var(--mo) var(--ease-out); }
.pushpref__sw::after { content: ""; position: absolute; top: 2px; left: 2px; width: 22px; height: 22px; border-radius: 50%;
    background: var(--tx-2); transition: transform var(--mo) var(--ease-out), background var(--mo) var(--ease-out); }
.pushpref__sw:checked { background: var(--gold); border-color: var(--gold); }
.pushpref__sw:checked::after { transform: translateX(18px); background: var(--gold-ink); }
.pushpref__sw:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.pushpref__sw:disabled { opacity: .5; }
@media (prefers-reduced-motion: reduce) { .pushpref__sw, .pushpref__sw::after { transition: none; } }

/* ---- link de contacto al pie de MiPerfil: fix de scroll horizontal a 320px ----
   Causa raíz: `.blk__more` nace con `white-space: nowrap` porque se diseñó para
   etiquetas cortas que viven en el `.blk__hd` de Inicio/Estadísticas/MiOlimar
   ("Ver todos →", "Fixture completo →"), donde partirlas en dos líneas
   descuadraría el header. MiPerfil reusa la clase para una etiqueta larga
   ("¿Dudas o sugerencias? Contactá al club →"): su línea intrínseca mide ~316px
   y el canal de contenido de `.arena__in` a 320px es de 288px, así que el
   `nowrap` la fuerza a desbordar. Encima, el `margin: -6px -4px` del bloque de
   tap-targets (que compensa el padding para no mover el layout del header) suma
   4px más por derecha, y ahí sale el `scrollWidth` de 336 contra 320.
   Solución acotada a esta página: dejar que la etiqueta larga envuelva, cortarle
   el margin/padding lateral para que respete el mismo canal que el resto de la
   página, y limitarla al ancho del contenedor. NO se toca `white-space` global
   ni el `.blk__hd` de las otras páginas, ni se usa `overflow-x: hidden`. */
.page-miperfil .blk__more {
    white-space: normal;          /* la etiqueta larga puede partirse en dos líneas */
    max-width: 100%;              /* con box-sizing:border-box nunca excede el canal */
    margin-left: 0; margin-right: 0;  /* devuelve el gutter lateral del resto de la página */
    padding-left: 0; padding-right: 0;
    min-height: 44px;             /* tap target: no baja del mínimo aunque quede en 1 línea */
    text-align: center;           /* las líneas envueltas siguen el centrado del párrafo */
}
