  /* ============================================================
     ADRENALINE™ · DESIGN SYSTEM
     Dark-fantasy MMORPG dashboard. Neon-purple accent on deep black.
     Everything is driven by the tokens in :root — retune here and the
     whole app re-skins. Keep class names intact (the JS renders against them).
     ============================================================ */
  /* ── `hidden` ES HIDDEN, PUNTO (15 sep 2026) ────────────────────────────────────────────
     Va antes que nada y con !important, y es la unica vez en toda la hoja que se usa.

     El motivo es un fallo real, reportado el mismo dia que se subio la landing: «el boton de
     logear con google cuando le doy y elijo mi cuenta no funciona». El login SI funcionaba; lo
     que pasaba es que `.overlay[hidden]{display:none}` (linea ~549) y `.overlay.lp{display:block}`
     (linea ~597) tienen la MISMA especificidad (0,2,0), asi que ganaba la segunda por ir despues
     en el fichero. La portada no se ocultaba nunca y se quedaba tapando la aplicacion — y de paso
     pintando su fondo fijo para siempre, que era el «va un poco lag».

     Esto no era un descuido de una regla concreta: es una trampa que estaba puesta para
     cualquiera. `showOverlay`, `aplicarCongeladoApi`, `aplicarPermisosSubnav` y media docena de
     sitios mas ocultan cosas poniendo `el.hidden = true`, y bastaba con que alguien escribiera
     despues una regla de dos clases sobre ese mismo elemento para que dejara de ocultarse, sin
     un solo error en consola. Lo vigila dev/test_ocultar.js. */
  [hidden]{display:none !important;}

  :root{
    /* ---- Surfaces: deep black -> raised panels ---- */
    --bg:#0a0611; --bg-2:#120b1a;
    --panel:#160e26; --panel-2:#1f1436; --panel-3:#2a1c4a;
    --border:#3c2c63; --border-soft:#271a45; --border-strong:#4b1fab;

    /* ---- Neon-purple accent scale ---- */
    --accent:#a64dff; --accent-2:#7d2cff; --accent-deep:#4b1fab;
    --accent-soft:rgba(166,77,255,.14); --accent-glow:rgba(166,77,255,.45);
    /* Legacy aliases kept so existing rules re-skin automatically */
    --gold:#a64dff; --gold-bright:#c9a2ff; --silver:#a9a3c4;

    /* ---- Text ---- */
    --text:#ece9fb; --text-dim:#9a92c4; --text-mute:#6f679a;
    --on-accent:#0c0616;

    /* ---- Semantic ---- */
    --good:#43d6a3; --good-bg:rgba(67,214,163,.13);
    --warn:#e0a24f; --warn-bg:rgba(224,162,79,.13);
    --bad:#ff466e;  --bad-bg:rgba(255,70,110,.13);
    --blue:#5c9df5; --blue-bg:rgba(92,157,245,.13);
    /* `--danger` es un ALIAS de --bad: había código que pedía var(--danger,#ff5a5a) y,
       al no existir el token, caía siempre en ese respaldo #ff5a5a, que NO es del sistema.
       Se declara aquí para que cualquier uso suelto quede reconducido al rojo real. */
    --danger:#ff466e;

    /* ---- Escala de Gear Score (peor -> mejor) ----
       Vive aquí, no en el JS: es parte de la identidad y así se re-skinea con el resto.
       La usan gsColor() y GS_LEGEND en app.js vía var(). --gs-epic es el nivel ÉPICO
       (5500+), el único color ajeno a la gama morada a propósito: es el premio visual. */
    --gs-1:var(--text-dim); --gs-2:#8fb0ff; --gs-3:#6ee7a0; --gs-4:#c9a6ff;
    --gs-5:#ffd27a; --gs-6:var(--gold-bright); --gs-7:#ff86a6; --gs-epic:#00f5ff;
    --gs-epic-glow:rgba(0,245,255,.6);
    /* Y por encima de 6100, el tramo LEGENDARIO (13 ago 2026, pedido por Sirvine: «un color de
       neón ultra super mega hyper giga chetado»). Verde lima ácido: es el que queda más lejos de
       todo lo demás de la escala (el otro verde, --gs-3, es un mint pastel) y el que más grita
       sobre el fondo morado. El NÚMERO va en este color sólido a propósito, porque gsColor()
       también pinta barras y tiene que seguir siendo legible; lo que se vuelve loco es el halo. */
    --gs-god:#b6ff00; --gs-god-glow:rgba(182,255,0,.55);
    /* Color de la CURVA de progreso de Mi ficha. Se declara aquí para tener un valor por defecto
       —si algún día se pinta la curva fuera de `.gs-chart`, sale verde en vez de invisible— y lo
       reescribe `.gs-chart` a ámbar cuando el GS ha bajado. */
    --gsc:var(--good);

    /* ---- Clanes de la alianza ---- */
    --clan-adrenaline:var(--gold-bright); --clan-404:#ff8a80; --clan-latingamer:#7fe3c4;
    /* Paleta para los clanes que añada el Líder. Son cinco tonos separados en matiz a propósito:
       la etiqueta de clan se lee de reojo dentro de una party, y dos azules parecidos no se
       distinguen a ese tamaño. Los nombres son genéricos (p4..p8) porque el clan que lleve cada
       color cambia; atarlos a un nombre es como empezó el problema que esto viene a resolver. */
    --clan-p4:#8ab4ff; --clan-p5:#c9a6ff; --clan-p6:#ffb066; --clan-p7:#b6e06a; --clan-p8:#ff9ecb;

    /* ---- Tipografías (las 3 familias del proyecto) ---- */
    --font-body:'Rajdhani','Segoe UI',system-ui,sans-serif;
    --font-display:'Cinzel','Georgia',serif;
    --font-mono:'JetBrains Mono',monospace;

    /* ---- Radius (12px system) ---- */
    --r-xs:6px; --r-sm:8px; --r:12px; --r-lg:16px; --r-pill:999px;

    /* ---- Spacing ---- */
    --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px; --sp-8:32px;

    /* ---- Elevation & glow ---- */
    --shadow-1:0 2px 10px rgba(0,0,0,.35);
    --shadow-2:0 10px 34px rgba(0,0,0,.5);
    --glow:0 0 20px var(--accent-glow);
    --glow-soft:0 0 12px rgba(166,77,255,.28);
    --hairline:inset 0 1px 0 rgba(255,255,255,.04);

    /* ---- Motion (200–300ms) ---- */
    --tr:220ms cubic-bezier(.4,0,.2,1);
    --tr-fast:150ms cubic-bezier(.4,0,.2,1);
  }

  *{box-sizing:border-box;}
  /* TIPOGRAFÍA DE MARCA EN RUSO (12 ago 2026) — cierra el Pendiente #28.

     Cinzel y Rajdhani NO TIENEN CIRÍLICO (Google no publica esos subconjuntos), así que todo el
     texto en ruso lo pintaba la fuente de respaldo: la web en ruso no tenía tipografía de marca.
     Ya no. En ruso se cambian las DOS familias por un par que sí lo tiene:

       Titulares  Cinzel   -> Forum    Cinzel deriva de la Trajana: capitales romanas grabadas.
                                       Forum es esa misma voz (lapidaria, de inscripción) y es una
                                       de las pocas así con cirílico. Se elige por VOZ, no por
                                       parecido de trazo.
       Cuerpo     Rajdhani -> Exo 2    Rajdhani es una sans escuadrada y tecnológica; Exo 2 es la
                                       misma idea con cirílico completo y eje de peso variable.
                                       (Play era la otra opción, pero solo trae 400 y 700.)

     SOLO en ruso, a propósito: la identidad en es/en ya está decidida y funciona, y cambiarla
     para todos por un problema de un idioma sería empeorarla para la mayoría. De paso, quien no
     navegue en ruso NO descarga estos 188 KB — el navegador solo baja las fuentes que usa.

     El interruptor son estas dos variables. Por eso las 18 reglas que antes repetían la pila a
     mano ahora usan var(--font-display) / var(--font-body): si una regla vuelve a escribir
     'Cinzel' directamente, se salta el cambio de idioma y en ruso saldrá el respaldo otra vez.
     Lo vigila dev/test_recursos_locales.js.

     Los respaldos siguen elegidos a mano (Georgia / Segoe UI, que sí llevan cirílico) para el
     hueco entre que se pide la fuente y llega: con un `serif` pelado, un título en ruso salía en
     Times New Roman dorado. No los cambies por `serif`.

     `lang` lo mantiene al día applyStaticTranslations() en app.js. */
  html[lang="ru"]{
    --font-body:'Exo 2','Segoe UI',system-ui,sans-serif;
    --font-display:'Forum','Georgia',serif;
  }
  /* Y CAPITALES en los titulares rusos, que no es un capricho: **Cinzel es una fuente solo de
     capitales**, así que en es/en hasta un título en minúsculas sale grabado en piedra. Forum sí
     tiene minúsculas, y con ellas el mismo título ruso se leía como texto normal — misma familia,
     otra marca. Comparadas las tres en pantalla (Forum en minúsculas, Forum en capitales y
     Cinzel), la de capitales es la que comparte el ritmo lapidario del español; las minúsculas no.
     El interletrado va un poco más abierto que en Cinzel (.045em) porque las capitales cirílicas
     son más anchas y sin aire se apelotonan.

     La lista es EXACTAMENTE la de reglas que usan var(--font-display). Si añades un titular nuevo,
     añádelo aquí: dev/test_recursos_locales.js deriva la lista del propio CSS y falla si alguna se
     queda fuera (si no, ese título saldría en minúsculas solo en ruso y nadie lo vería). */
  html[lang="ru"] .page-title,
  html[lang="ru"] .section-label,
  html[lang="ru"] .party-card-head h3,
  html[lang="ru"] .cal-month-label,
  html[lang="ru"] .att-party-head h4,
  html[lang="ru"] .overlay-box h2,
  html[lang="ru"] .pitch-claim,
  html[lang="ru"] .paso-n,
  html[lang="ru"] .lp-mark span,
  html[lang="ru"] .lp-title,
  html[lang="ru"] .lp-h2,
  html[lang="ru"] .lp-card h3,
  html[lang="ru"] .lp-card-n,
  html[lang="ru"] .lp-tier-n,
  html[lang="ru"] .lp-tier h3,
  html[lang="ru"] .lp-fig b,
  html[lang="ru"] .aj-seccion,
  html[lang="ru"] .wiki-section h3{text-transform:uppercase;letter-spacing:.045em;}
  html,body{margin:0;padding:0;background:var(--bg);color:var(--text);font-family:var(--font-body);font-weight:500;}
  body{min-height:100vh;position:relative;background:
      radial-gradient(900px 500px at -5% -10%, rgba(166,77,255,.16), transparent 60%),
      radial-gradient(1000px 550px at 105% 0%, rgba(125,44,255,.13), transparent 55%),
      radial-gradient(700px 500px at 50% 115%, rgba(75,31,171,.12), transparent 60%), var(--bg);}
  body::before{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;opacity:.5;
    background-image:
      radial-gradient(1.5px 1.5px at 8% 15%, #e3d6ff 40%, transparent 100%),
      radial-gradient(1.5px 1.5px at 22% 60%, #e3d6ff 40%, transparent 100%),
      radial-gradient(2px 2px at 40% 25%, #c9a2ff 40%, transparent 100%),
      radial-gradient(1.5px 1.5px at 68% 12%, #e3d6ff 40%, transparent 100%),
      radial-gradient(2px 2px at 85% 45%, #c9a2ff 40%, transparent 100%),
      radial-gradient(1.5px 1.5px at 92% 78%, #e3d6ff 40%, transparent 100%),
      radial-gradient(1.5px 1.5px at 12% 88%, #e3d6ff 40%, transparent 100%),
      radial-gradient(2px 2px at 55% 92%, #c9a2ff 40%, transparent 100%);
    background-repeat:no-repeat;}
  ::selection{background:var(--accent);color:var(--on-accent);}

  /* ---- Custom scrollbar ---- */
  *{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent;}
  *::-webkit-scrollbar{width:10px;height:10px;}
  *::-webkit-scrollbar-track{background:transparent;}
  *::-webkit-scrollbar-thumb{background:linear-gradient(180deg,var(--accent-2),var(--accent-deep));border-radius:var(--r-pill);border:2px solid transparent;background-clip:padding-box;}
  *::-webkit-scrollbar-thumb:hover{background:linear-gradient(180deg,var(--accent),var(--accent-2));background-clip:padding-box;}

  .app{display:flex;min-height:100vh;position:relative;z-index:1;}

  /* ============================================================ SIDEBAR / NAV */
  .sidebar{width:236px;flex-shrink:0;background:linear-gradient(180deg,var(--panel),var(--bg));border-right:1px solid var(--border-soft);padding:var(--sp-6) var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-2);box-shadow:1px 0 0 rgba(166,77,255,.06);position:sticky;top:0;height:100vh;overflow-y:auto;}
  .sigil{display:flex;align-items:center;justify-content:center;padding:2px 4px 18px 4px;margin-bottom:var(--sp-4);position:relative;cursor:pointer;}
  .sigil:focus-visible{outline:2px solid var(--gold-bright);outline-offset:4px;border-radius:var(--r-sm);}
  /* Rótulos de los grupos del menú. Deliberadamente flojos: separan sin competir con las
     entradas, que es lo que se lee. */
  .nav-group{margin:var(--sp-4) 0 var(--sp-1);padding:0 var(--sp-3);font-family:var(--font-display);font-size:11px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--text-dim);opacity:.65;}
  .nav-group:first-of-type{margin-top:2px;}
  .sigil::after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:repeating-linear-gradient(90deg, var(--border-soft) 0 6px, transparent 6px 9px);}
  .sidebar-logo{width:100%;max-width:196px;height:auto;display:block;filter:drop-shadow(0 0 10px rgba(166,77,255,.35));animation:logo-glow 5s ease-in-out infinite;}
  @keyframes logo-glow{0%,100%{filter:drop-shadow(0 0 7px rgba(166,77,255,.28));}50%{filter:drop-shadow(0 0 14px rgba(166,77,255,.6));}}
  /* DISCORD siempre a la vista, debajo del logo (14 ago 2026). Morado neón de la casa y no el
     azul de Discord: va pegado al logo del clan y el azul rompía la barra entera. El icono
     hereda el color con fill:currentColor, así que basta una regla para el hover. */
  .discord-cta{display:flex;align-items:center;justify-content:center;gap:var(--sp-2);margin:-4px 0 16px;padding:var(--sp-3) var(--sp-3);
    text-decoration:none;border:1px solid var(--accent);border-radius:var(--r-sm);color:var(--accent-2);
    background:linear-gradient(180deg,rgba(166,77,255,.16),rgba(75,31,171,.10));
    font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:.14em;text-transform:uppercase;
    box-shadow:0 0 14px rgba(166,77,255,.16);transition:color var(--tr),border-color var(--tr),box-shadow var(--tr),transform var(--tr);}
  .discord-cta svg{width:21px;height:21px;fill:currentColor;flex:0 0 auto;filter:drop-shadow(0 0 6px currentColor);}
  .discord-cta:hover{color:var(--gold-bright);border-color:var(--gold);box-shadow:0 0 22px rgba(166,77,255,.38);transform:translateY(-1px);}
  .discord-cta:focus-visible{outline:2px solid var(--gold-bright);outline-offset:2px;}
  /* El mismo botón, en grande, para abrir la sección de Contacto de Información. Es lo primero
     que se ve al entrar en la pestaña, que es justo lo que la gente venía a buscar. */
  .discord-cta.wide{width:100%;margin:var(--sp-2) 0 var(--sp-1);padding:var(--sp-4) var(--sp-4);font-size:18px;letter-spacing:.18em;}
  .discord-cta.wide svg{width:27px;height:27px;}
  /* CON EL BANNER DEL CLAN. La imagen nace oculta y solo se muestra cuando ha cargado (el
     onload le pone `con-logo` al enlace), asi que un archivo que falte o un navegador sin WebP
     no dejan un hueco: se quedan con el boton de siempre.
     El banner ya trae su propio marco, asi que el enlace pierde borde, relleno y fondo — pero
     NO el aviso de que se puede pulsar, que es lo que pidio Sirvine: sigue subiendo 1px, el
     halo se enciende y la imagen se aclara al pasar por encima. */
  .discord-cta img{display:none;width:100%;height:auto;border-radius:var(--r-sm);transition:filter var(--tr);}
  .discord-cta.con-logo{padding:0;border:none;background:none;}
  .discord-cta.con-logo svg,.discord-cta.con-logo span{display:none;}
  .discord-cta.con-logo img{display:block;}
  .discord-cta.con-logo:hover img{filter:brightness(1.18) saturate(1.06);}
  /* El banner es 2,66:1, así que a todo lo ancho de la sección saldría de 300 px de alto: un
     cartel enorme que empuja el resto de Información hacia abajo en cada visita. Se queda del
     tamaño del de la barra lateral (unos 200 × 75), que ya se ve de sobra. */
  .discord-cta.wide.con-logo{max-width:200px;}
  .nav-toggle{display:none;}
  .nav-item{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-3);border-radius:var(--r-sm);cursor:pointer;color:var(--text-dim);font-weight:600;font-size:17px;letter-spacing:.02em;border:1px solid transparent;transition:color var(--tr),background var(--tr),border-color var(--tr),box-shadow var(--tr);user-select:none;position:relative;}
  .nav-item:hover{color:var(--text);background:var(--panel-2);}
  .nav-item.active{color:var(--gold-bright);background:linear-gradient(90deg,var(--accent-soft),transparent);border-color:var(--border);box-shadow:inset 3px 0 0 var(--accent), 0 0 14px rgba(166,77,255,.12);}
  .nav-item .ic{width:22px;height:22px;flex-shrink:0;background-size:contain;background-repeat:no-repeat;background-position:center;opacity:.8;transition:transform var(--tr),opacity var(--tr),filter var(--tr);}
  .nav-item:hover .ic{transform:translateX(1px);opacity:1;}
  .nav-item.active .ic{opacity:1;filter:drop-shadow(0 0 5px var(--accent-glow));}
  .ic-dashboard{background-image:url(../assets/icons/dashboard.png);}
  .ic-roster{background-image:url(../assets/icons/roster.png);}
  .ic-parties{background-image:url(../assets/icons/parties.png);}
  .ic-rules{background-image:url(../assets/icons/rules.png);}
  .ic-cta{background-image:url(../assets/icons/cta.png);}
  .ic-drops{background-image:url(../assets/icons/drops.png);}
  .ic-help{background-image:url(../assets/icons/help.png);}
  .ic-users{background-image:url(../assets/icons/users.png);}
  .nav-item[hidden]{display:none;}
  .sidebar-foot{margin-top:auto;padding-top:var(--sp-4);border-top:1px solid var(--border-soft);font-size:12.5px;color:var(--text-dim);display:flex;flex-direction:column;gap:var(--sp-3);}
  .conn-status{display:flex;align-items:center;font-size:12.5px;}
  .user-badge{display:flex;flex-direction:column;gap:2px;}
  .user-badge .u-name{color:var(--text);font-weight:600;font-size:15px;}
  .user-badge .u-role{font-size:12px;letter-spacing:.06em;text-transform:uppercase;}
  .u-role.admin{color:var(--gold-bright);}
  .u-role.oficial{color:var(--blue);}
  .u-role.cp_leader{color:var(--warn);}
  .u-role.member{color:var(--good);}
  .logout-link{color:var(--text-dim);font-size:13px;cursor:pointer;text-decoration:underline;transition:color var(--tr);}
  .logout-link:hover{color:var(--bad);}
  /* Pie de copyright de la barra lateral: presente pero discreto, que no compita con la
     navegación. El aviso legal completo vive en la pestaña Información. */
  .sidebar-legal{font-size:11px;line-height:1.5;color:var(--text-dim);opacity:.6;}
  .sidebar-legal a{color:inherit;text-decoration:underline;cursor:pointer;}
  .sidebar-legal a:hover{color:var(--gold-bright);}
  .sync-dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:var(--sp-2);flex-shrink:0;}
  .sync-dot.on{background:var(--good);box-shadow:0 0 6px var(--good);}
  .sync-dot.off{background:var(--bad);box-shadow:0 0 6px var(--bad);}
  .lang-switch{display:flex;gap:var(--sp-2);}
  .lang-btn{background:var(--panel-2);border:1px solid var(--border);color:var(--text-dim);font-size:12.5px;padding:3px 8px;border-radius:var(--r-xs);cursor:pointer;font-weight:700;transition:color var(--tr),border-color var(--tr);}
  .lang-btn.active{color:var(--gold-bright);border-color:var(--accent);box-shadow:0 0 10px rgba(166,77,255,.25);}

  /* ============================================================ MAIN / VIEWS */
  .main{flex:1;padding:32px 40px;max-width:1200px;}
  @media (min-width:1700px){ .main{max-width:1580px;padding:32px 48px;} }
  @media (min-width:2300px){ .main{max-width:2000px;padding:32px 56px;} }
  .view{display:none;}
  .view.active{display:block;animation:fadein .3s ease;}
  @keyframes fadein{from{opacity:0;transform:translateY(6px);}to{opacity:1;transform:none;}}

  /* ---- Submenú horizontal dentro de una pestaña (ruta `#vista/subvista`) ----
     Las pestañas grandes (CTA, Drops) se partieron en subvistas y solo se pinta
     la visible: ver RENDER_SCOPE en app.js.

     Se dibuja como un CONTROL SEGMENTADO, no como pestañas de subrayado fino:
     la primera versión (10 ago 2026) pasaba desapercibida y la gente no veía que
     había secciones nuevas. Aquí lo que importa es que las pestañas INACTIVAS ya
     parezcan botones pulsables — no basta con marcar bien la activa. */
  .subnav{display:inline-flex;gap:var(--sp-2);flex-wrap:wrap;margin:0 0 var(--sp-6) 0;padding:var(--sp-2);background:var(--bg-2);border:1px solid var(--border);border-radius:var(--r);box-shadow:inset 0 2px 7px rgba(0,0,0,.32);max-width:100%;}
  .subnav-item{background:var(--panel-2);border:1px solid var(--border);color:var(--text-dim);font-family:var(--font-body);font-weight:700;font-size:16px;letter-spacing:.06em;text-transform:uppercase;padding:var(--sp-3) var(--sp-5);border-radius:var(--r-sm);cursor:pointer;transition:all var(--tr);}
  .subnav-item:hover{color:var(--gold-bright);background:var(--panel-3);border-color:var(--accent);box-shadow:0 0 13px rgba(166,77,255,.2);}
  .subnav-item.active{background:linear-gradient(180deg,var(--accent),var(--accent-deep));border-color:var(--accent-2);color:#fff;box-shadow:0 4px 16px rgba(125,44,255,.4), var(--hairline);text-shadow:0 1px 2px rgba(0,0,0,.35);}
  .subnav-item.active:hover{filter:brightness(1.1);color:#fff;}
  .subnav-item:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
  .subview{display:none;}
  .subview.active{display:block;}
  /* En móvil el submenú no se parte en filas: se desliza en horizontal. */
  @media(max-width:640px){
    .subnav{display:flex;flex-wrap:nowrap;overflow-x:auto;border-radius:var(--r-sm);}
    .subnav-item{white-space:nowrap;padding:var(--sp-2) var(--sp-4);font-size:15px;letter-spacing:.04em;}
  }
  .page-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:var(--sp-5);flex-wrap:wrap;gap:var(--sp-3);}
  .page-title{font-family:var(--font-display);font-size:30px;color:var(--gold-bright);letter-spacing:.03em;margin:0;text-shadow:0 0 16px rgba(166,77,255,.3);}
  .streak-badge{height:1.15em;width:auto;vertical-align:-0.18em;margin-left:2px;filter:drop-shadow(0 0 4px var(--accent-glow));}
  .page-eyebrow{font-size:14px;letter-spacing:.16em;text-transform:uppercase;color:var(--text-dim);margin:0 0 var(--sp-1) 0;}
  .page-head::after{content:"";flex:0 0 100%;height:26px;margin-top:var(--sp-4);background-image:url(../assets/divider.png);background-repeat:no-repeat;background-position:center;background-size:min(540px,100%) auto;opacity:.72;pointer-events:none;}
  .page-eyebrow::before{content:"";display:inline-block;width:13px;height:13px;vertical-align:-1px;margin-right:var(--sp-2);background-image:url(../assets/spark.png);background-size:contain;background-repeat:no-repeat;background-position:center;opacity:.95;}

  /* ============================================================ BUTTONS */
  .btn{background:var(--panel-2);color:var(--text);border:1px solid var(--border);padding:var(--sp-2) var(--sp-4);border-radius:var(--r-sm);font-family:var(--font-body);font-weight:600;font-size:16px;letter-spacing:.03em;cursor:pointer;transition:all var(--tr);position:relative;}
  .btn:hover{border-color:var(--accent);color:var(--gold-bright);box-shadow:0 0 14px rgba(166,77,255,.2);}
  .btn:active{transform:translateY(1px);}
  .btn-primary{background:linear-gradient(180deg,var(--accent),var(--accent-deep));color:#fff;border:1px solid var(--accent-2);box-shadow:0 4px 16px rgba(125,44,255,.35), var(--hairline);text-shadow:0 1px 2px rgba(0,0,0,.35);}
  .btn-primary:hover{filter:brightness(1.1);color:#fff;box-shadow:0 6px 22px rgba(125,44,255,.5);}
  .btn-danger{border-color:var(--bad);color:var(--bad);background:transparent;}
  .btn-danger:hover{background:var(--bad-bg);box-shadow:0 0 14px rgba(255,70,110,.22);}
  .btn-sm{padding:var(--sp-1) var(--sp-3);font-size:14px;border-radius:var(--r-xs);}
  .btn:disabled{opacity:.45;cursor:default;box-shadow:none;filter:none;}
  .icon-btn{background:none;border:none;color:var(--text-dim);cursor:pointer;font-size:16px;padding:3px 5px;border-radius:var(--r-xs);transition:color var(--tr),background var(--tr);}
  .icon-btn:hover{color:var(--bad);background:var(--bad-bg);}

  /* ============================================================ STAT CARDS */
  .stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-4);margin-bottom:var(--sp-6);}
  .stat-card{background:linear-gradient(160deg,var(--panel),var(--bg-2));border:1px solid var(--border-soft);border-radius:var(--r);padding:var(--sp-4) var(--sp-5);position:relative;overflow:hidden;box-shadow:var(--shadow-1),var(--hairline);transition:transform var(--tr),border-color var(--tr),box-shadow var(--tr);}
  .stat-card:hover{transform:translateY(-2px);border-color:var(--border);box-shadow:var(--shadow-2),0 0 18px rgba(166,77,255,.12);}
  .stat-card.clickable{cursor:pointer;}
  .stat-card::before{content:"";position:absolute;top:0;left:0;width:3px;height:100%;background:linear-gradient(180deg,var(--accent),var(--accent-deep));box-shadow:0 0 10px var(--accent);opacity:.85;}
  .stat-num{font-family:'JetBrains Mono',monospace;font-size:30px;font-weight:700;color:var(--text);}
  .stat-label{font-size:14px;color:var(--text-dim);letter-spacing:.08em;text-transform:uppercase;margin-top:2px;}

  .section-label{font-family:var(--font-display);font-size:16px;color:var(--gold-bright);letter-spacing:.08em;text-transform:uppercase;margin:0 0 var(--sp-3) 0;padding-bottom:var(--sp-2);border-bottom:1px solid var(--border-soft);}

  /* ============================================================ TABLES */
  table{width:100%;border-collapse:collapse;background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-1);}
  thead th{text-align:left;font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-dim);padding:var(--sp-3) var(--sp-4);background:var(--panel-2);border-bottom:1px solid var(--border-soft);font-weight:600;}
  thead th.sortable{cursor:pointer;user-select:none;white-space:nowrap;transition:color var(--tr);}
  thead th.sortable:hover{color:var(--gold-bright);}
  thead th.sortable.active{color:var(--gold-bright);}
  .roster-sortbar{display:none;flex-wrap:wrap;gap:var(--sp-2);margin-bottom:var(--sp-3);}
  .roster-sortbar .sortbar-btn{background:var(--panel-2);border:1px solid var(--border-soft);color:var(--text-dim);font-size:12px;font-weight:600;padding:var(--sp-1) var(--sp-3);border-radius:999px;cursor:pointer;transition:color var(--tr),border-color var(--tr);}
  .roster-sortbar .sortbar-btn:hover,.roster-sortbar .sortbar-btn.active{color:var(--gold-bright);border-color:var(--gold);}
  .hist-cta-row{padding:var(--sp-1) 0;border-bottom:1px solid var(--border-soft);}
  .hist-cta-row:last-child{border-bottom:none;}
  tbody td{padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-soft);font-size:16.5px;font-weight:500;}
  tbody tr:last-child td{border-bottom:none;}
  tbody tr{transition:background var(--tr-fast);}
  tbody tr:hover{background:var(--panel-2);}
  tbody tr.mine-row{box-shadow:inset 3px 0 0 var(--accent);}
  td.num,th.num{font-family:'JetBrains Mono',monospace;}
  .tag-alt{font-size:11.5px;color:var(--text-dim);border:1px solid var(--border);padding:1px 7px;border-radius:var(--r-pill);margin-left:var(--sp-2);letter-spacing:.05em;}
  /* `white-space:nowrap` y `display:inline-block`: sin ellos, una etiqueta de dos piezas («⚔ ×4»)
     se parte por el espacio y la mitad se va a la línea siguiente. Pasaba en la fila de Sirvine, que
     es la que más etiquetas lleva, y quedaba horrible. */
  .tag-shield{display:inline-block;white-space:nowrap;font-size:11.5px;color:var(--good);border:1px solid var(--good);padding:1px 7px;border-radius:var(--r-pill);margin-left:var(--sp-2);letter-spacing:.05em;}

  /* ============================================================ FORMS / INPUTS */
  .form-row{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:flex-end;background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);padding:var(--sp-4);margin-bottom:var(--sp-5);box-shadow:var(--shadow-1);}
  .toolbar-row{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:flex-end;margin-bottom:var(--sp-4);}
  .field{display:flex;flex-direction:column;gap:var(--sp-1);}
  .field label{font-size:12.5px;color:var(--text-dim);letter-spacing:.08em;text-transform:uppercase;}
  .field.checkfield{flex-direction:row;align-items:center;gap:var(--sp-2);}
  .field.checkfield input{width:18px;height:18px;min-width:0;}
  input,select,textarea{background:var(--bg-2);border:1px solid var(--border);color:var(--text);padding:var(--sp-2) var(--sp-3);border-radius:var(--r-sm);font-family:var(--font-body);font-size:16px;font-weight:500;min-width:110px;transition:border-color var(--tr),box-shadow var(--tr),background var(--tr);}
  input::placeholder,textarea::placeholder{color:var(--text-mute);}
  input:hover,select:hover{border-color:var(--border-strong);}
  input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(166,77,255,.22);background:var(--panel);}
  input[type=number]{font-family:'JetBrains Mono',monospace;}
  /* Custom select caret */
  select{appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:
      linear-gradient(45deg,transparent 50%,var(--text-dim) 50%),
      linear-gradient(135deg,var(--text-dim) 50%,transparent 50%);
    background-position:calc(100% - 16px) 52%, calc(100% - 11px) 52%;
    background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:var(--sp-8);cursor:pointer;}
  select:focus{background-image:
      linear-gradient(45deg,transparent 50%,var(--accent) 50%),
      linear-gradient(135deg,var(--accent) 50%,transparent 50%);
    background-position:calc(100% - 16px) 52%, calc(100% - 11px) 52%;
    background-size:5px 5px,5px 5px;background-repeat:no-repeat;}
  select option{background:var(--panel);color:var(--text);}
  /* Custom checkbox */
  input[type=checkbox]{appearance:none;-webkit-appearance:none;min-width:0;width:18px;height:18px;padding:0;border:1px solid var(--border-strong);border-radius:var(--r-xs);background:var(--bg-2);cursor:pointer;position:relative;flex-shrink:0;transition:background var(--tr),border-color var(--tr),box-shadow var(--tr);}
  input[type=checkbox]:hover{border-color:var(--accent);}
  input[type=checkbox]:checked{background:linear-gradient(180deg,var(--accent),var(--accent-deep));border-color:var(--accent-2);box-shadow:0 0 10px rgba(166,77,255,.4);}
  input[type=checkbox]:checked::after{content:"";position:absolute;left:5px;top:1px;width:5px;height:10px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg);}
  input[type=checkbox]:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(166,77,255,.25);}

  .empty{color:var(--text-dim);font-size:16px;padding:var(--sp-8);text-align:center;border:1px dashed var(--border);border-radius:var(--r);background:var(--panel);}

  /* ============================================================ PARTY CARDS */
  .party-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--sp-4);}
  .party-card{background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-1),var(--hairline);transition:transform var(--tr),border-color var(--tr),box-shadow var(--tr);}
  .party-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-2);}
  .party-card.mine{border-color:var(--accent);background:linear-gradient(180deg,rgba(166,77,255,.10),var(--panel));box-shadow:0 0 0 1px rgba(166,77,255,.4),0 0 24px rgba(166,77,255,.2);}
  .party-card-head{display:flex;justify-content:space-between;align-items:center;padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-soft);background:linear-gradient(180deg,var(--panel-2),transparent);}
  .party-card-head h3{font-family:var(--font-display);font-size:18.5px;color:var(--gold-bright);margin:0;letter-spacing:.02em;}
  .status-pill{font-size:12px;letter-spacing:.08em;text-transform:uppercase;padding:3px 10px;border-radius:var(--r-pill);font-weight:700;}
  .status-ready{background:var(--good-bg);color:var(--good);}
  .status-warn{background:var(--warn-bg);color:var(--warn);}
  .status-bad{background:var(--bad-bg);color:var(--bad);}
  .style-pill{font-size:12px;letter-spacing:.08em;text-transform:uppercase;padding:3px 10px;border-radius:var(--r-pill);font-weight:700;background:var(--accent-soft);color:var(--gold-bright);border:1px solid rgba(166,77,255,.35);}
  .party-name-edit{cursor:pointer;transition:color var(--tr);}
  .party-name-edit:hover{color:var(--gold-bright);}
  /* Comparación con el roster del servidor (Roster → Todos, solo Líder u Oficial). Se lee de un
     vistazo y no compite con la tabla: chips en gris, sin colores de alarma. Lo que hay aquí son
     cosas que MIRAR, no incidencias — quien lleva 12 días sin entrar puede estar de vacaciones. */
  .srv-panel{background:var(--panel-2);border:1px solid var(--border-soft);border-radius:var(--r);
    padding:var(--sp-3) var(--sp-4);margin:0 0 var(--sp-4);}
  .srv-bloque{margin:0 0 var(--sp-3);}
  .srv-bloque:last-of-type{margin-bottom:var(--sp-1);}
  .srv-bloque h4{margin:0 0 var(--sp-2);font-size:13px;letter-spacing:.05em;text-transform:uppercase;color:var(--text-dim);}
  .srv-chips{display:flex;flex-wrap:wrap;gap:var(--sp-2);}
  .srv-chip{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-pill);
    padding:3px 10px;font-size:13px;color:var(--text);white-space:nowrap;}
  .srv-meta{margin:var(--sp-2) 0 0;font-size:12px;color:var(--text-mute);}
  /* En su propia pestaña el panel ya no compite con la tabla: los bloques respiran y el pie
     separa con una linea lo que ES del clan de lo que solo es contexto. */
  .srv-panel .srv-bloque{margin-bottom:var(--sp-4);}
  .srv-meta{border-top:1px solid var(--border-soft);padding-top:var(--sp-2);}
  .srv-ok{margin:0 0 var(--sp-1);color:var(--good);font-weight:600;}
  /* Avisos sobre la verificación, encima de la parrilla de asistencia (CTA de PvP y el de
     «casi nadie aparece en los datos del raid»). Ancho completo, para que no se lean como una
     etiqueta más de una party. */
  .verify-note{border:1px solid var(--good);background:var(--good-bg);color:var(--good);
    border-radius:var(--r-sm);padding:var(--sp-2) var(--sp-4);margin:0 0 var(--sp-4);font-size:14px;font-weight:600;}
  .verify-note.warn{border-color:var(--warn);background:var(--warn-bg);color:var(--warn);}
  .party-members{list-style:none;margin:0;padding:0;}
  .party-members li{display:flex;justify-content:space-between;align-items:center;padding:var(--sp-2) var(--sp-4);font-size:15.5px;border-bottom:1px solid var(--border-soft);transition:background var(--tr-fast);}
  .party-members li:last-child{border-bottom:none;}
  .party-members li.mine{background:var(--accent-soft);}
  /* Un nick es UNA sola palabra de hasta NICK_MAX_LEN (16) letras y no se puede partir, así que
     el navegador se negaba a encoger este bloque por debajo de su ancho: la fila se salía por la
     derecha y el `overflow:hidden` de .party-card se comía la ✕ de expulsar (la ✎ se salvaba por
     ir antes). Solo pasaba con los nombres largos — que es exactamente como se notó. Con esto la
     clase baja de línea cuando no cabe y el botón vuelve; con los nicks normales no cambia nada. */
  .pm-name{color:var(--text);min-width:0;overflow-wrap:anywhere;}
  .pm-class{color:var(--text-dim);font-size:13px;margin-left:var(--sp-2);}
  .pm-gs{font-family:'JetBrains Mono',monospace;color:var(--gold-bright);font-size:14.5px;}
  .pm-stats{display:flex;gap:var(--sp-3);align-items:center;flex-shrink:0;}
  .pm-lvl{font-family:'JetBrains Mono',monospace;color:var(--text-dim);font-size:14px;}
  .party-card-foot{display:flex;justify-content:space-between;padding:var(--sp-3) var(--sp-4);background:var(--panel-2);font-size:14px;color:var(--text-dim);}
  .party-card-foot b{color:var(--text);font-family:'JetBrains Mono',monospace;}
  .party-slot-empty{padding:var(--sp-2) var(--sp-4);font-size:14.5px;color:var(--text-dim);font-style:italic;}
  .party-card-actions{padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--border-soft);display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;}
  .party-leader-row{padding:var(--sp-2) var(--sp-4);border-top:1px solid var(--border-soft);font-size:14px;color:var(--text-dim);display:flex;align-items:center;gap:var(--sp-2);}
  .request-row{display:flex;justify-content:space-between;align-items:center;padding:var(--sp-2) var(--sp-4);font-size:15px;border-top:1px solid var(--border-soft);background:rgba(224,162,79,.06);}
  .cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sp-2);margin:0 0 var(--sp-4);}
  .cal-dow{text-align:center;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-dim);padding:var(--sp-1) 0;font-weight:700;}
  .cal-dow.weekend{color:var(--gold);opacity:.85;}
  .cal-day{min-height:66px;border:1px solid var(--border-soft);border-radius:var(--r-sm);padding:var(--sp-2);display:flex;flex-direction:column;gap:var(--sp-1);background:var(--panel);overflow:hidden;}
  .cal-day.empty{background:transparent;border-color:transparent;}
  .cal-day.weekend{background:rgba(255,255,255,.025);}
  .cal-day.today{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent),0 0 14px rgba(166,77,255,.18);}
  .cal-day.sel{border-color:var(--gold);background:rgba(224,162,79,.06);}
  .cal-num{font-size:11px;color:var(--text-dim);font-weight:700;}
  .cal-day.has .cal-num{color:var(--gold-bright);}
  .cal-day.today .cal-num{color:var(--accent-2);}
  .cal-num.dim{opacity:.35;}
  .cal-chip{font-size:11px;padding:2px 6px;border-radius:6px;cursor:pointer;text-align:left;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:1px solid transparent;}
  .cal-chip.epic{background:rgba(224,162,79,.16);color:var(--gold-bright);border-color:rgba(224,162,79,.35);}
  .cal-chip.siege{background:rgba(255,90,100,.14);color:#ff9aa2;border-color:rgba(255,90,100,.35);}
  .cal-chip.manual{background:rgba(166,77,255,.13);color:#c9a6ff;border-color:rgba(166,77,255,.3);}
  .cal-chip.event{cursor:pointer;display:inline-flex;align-items:center;gap:var(--sp-1);overflow:hidden;}
  .cal-chip.event .cal-chip-title{text-decoration:underline dotted rgba(255,255,255,.4);text-underline-offset:2px;}
  .cal-chip.event:hover{border-color:currentColor;box-shadow:0 0 8px rgba(0,0,0,.25);}
  .cal-chip.event:hover .cal-chip-title{text-decoration:underline solid;color:#fff;}
  .cal-chip-time{opacity:.8;font-weight:600;flex-shrink:0;}
  .cal-chip-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
  .cal-chip.ev-teal{background:rgba(80,200,170,.14);color:#7fe3c4;border-color:rgba(80,200,170,.35);}
  .cal-chip.ev-blue{background:rgba(90,150,255,.14);color:#9cc0ff;border-color:rgba(90,150,255,.35);}
  .cal-chip.ev-orange{background:rgba(255,160,70,.15);color:#ffc98a;border-color:rgba(255,160,70,.35);}
  .cal-chip.ev-pink{background:rgba(255,110,160,.14);color:#ffa6c6;border-color:rgba(255,110,160,.35);}
  .cal-chip-x{background:none;border:none;color:inherit;cursor:pointer;font-size:10px;padding:0 1px;opacity:.65;line-height:1;flex-shrink:0;}
  .cal-chip-x:hover{opacity:1;color:var(--bad);}
  .cal-chip:hover{border-color:currentColor;}
  .cal-chip.sel{font-weight:700;box-shadow:0 0 8px rgba(224,162,79,.35);}
  .cal-month-label{font-family:var(--font-display);font-weight:700;color:var(--gold-bright);min-width:150px;text-align:center;letter-spacing:.02em;}
  .cta-party-att{margin-bottom:var(--sp-2);padding:var(--sp-2) var(--sp-3);background:linear-gradient(180deg,rgba(224,162,79,.08),rgba(224,162,79,.02));border:1px solid var(--border-soft);border-radius:var(--r);}
  .cta-party-epics{margin-top:var(--sp-1);padding-left:2px;}
  .cta-party-att .hbar-line{margin-bottom:2px;}
  .cta-party-name{min-width:110px;max-width:200px;flex-shrink:0;font-weight:700;color:var(--gold-bright);letter-spacing:.02em;text-shadow:0 0 8px rgba(224,162,79,.3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .cta-attendees{display:flex;align-items:center;flex-wrap:wrap;gap:var(--sp-1);padding:3px 0 0 2px;line-height:1.4;}
  .cta-att-icon{opacity:.7;margin-right:3px;font-size:12px;}
  .cta-attendee{display:inline-flex;align-items:center;background:rgba(166,77,255,.14);border:1px solid var(--accent-deep);color:var(--text);font-size:12px;font-weight:600;padding:2px 9px;border-radius:999px;white-space:nowrap;transition:border-color var(--tr),background var(--tr);}
  .cta-attendee:hover{border-color:var(--accent);background:rgba(166,77,255,.24);}
  .cta-attendee.leader{background:rgba(255,80,120,.16);border-color:#ff5c8a;color:#ff86a6;font-weight:700;}
  .cta-attendee.leader:hover{background:rgba(255,80,120,.28);border-color:#ff86a6;}
  .cta-attendee.nopart{background:rgba(255,92,92,.16);border-color:var(--bad);color:var(--bad);text-decoration:line-through;}
  .epic-jewel{position:relative;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--gold);border-radius:6px;background:rgba(224,162,79,.14);margin-left:var(--sp-1);vertical-align:-3px;cursor:default;font-size:13px;line-height:1;}
  .epic-jewel img{width:16px;height:16px;border-radius:3px;display:block;}
  .clan-tag{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.05em;border:1px solid;border-radius:999px;padding:1px 8px;margin-left:var(--sp-2);vertical-align:1px;opacity:.95;}
  .epic-count{position:absolute;top:-5px;right:-5px;background:var(--gold);color:#1a1210;font-size:9px;font-weight:800;border-radius:999px;padding:0 3px;line-height:1.5;box-shadow:0 1px 3px rgba(0,0,0,.4);}

  /* ============================================================ CTA / ATTENDANCE */
  .cta-picker{display:flex;gap:var(--sp-3);align-items:center;margin-bottom:var(--sp-5);flex-wrap:wrap;}
  .cta-select{min-width:260px;}
  .attendance-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:var(--sp-4);margin-bottom:var(--sp-6);}
  .att-party{background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-1),var(--hairline);transition:border-color var(--tr),box-shadow var(--tr);}
  .att-party:hover{box-shadow:var(--shadow-2);}
  .att-party.mine{border-color:var(--accent);background:linear-gradient(180deg,rgba(166,77,255,.10),var(--panel));box-shadow:0 0 0 1px rgba(166,77,255,.35),0 0 20px rgba(166,77,255,.18);}
  .mine-badge{display:inline-block;background:var(--accent);color:#fff;font-size:10px;font-weight:800;letter-spacing:.08em;padding:2px 9px;border-radius:999px;box-shadow:0 0 10px rgba(166,77,255,.5);vertical-align:2px;}
  .att-party-head{display:flex;justify-content:space-between;align-items:center;padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-soft);background:var(--panel-2);}
  .att-party-head h4{margin:0;font-family:var(--font-display);font-size:16px;color:var(--gold-bright);}
  .att-pct{font-family:'JetBrains Mono',monospace;font-weight:700;font-size:17px;}
  .att-row{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-2) var(--sp-4);border-bottom:1px solid var(--border-soft);cursor:pointer;font-size:15.5px;transition:background var(--tr-fast);}
  .att-row:last-child{border-bottom:none;}
  .att-row:hover{background:var(--panel-2);}
  .att-row.readonly{cursor:default;opacity:.6;}
  .att-row.readonly:hover{background:none;}
  .att-row.self{background:var(--accent-soft);}
  .att-check{width:18px;height:18px;border-radius:var(--r-xs);border:1px solid var(--border);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:12.5px;transition:background var(--tr),border-color var(--tr);}
  .att-row.present .att-check{background:var(--good);border-color:var(--good);color:#08130d;box-shadow:0 0 8px rgba(67,214,163,.4);}
  .att-row.absent .att-check{background:transparent;color:transparent;}
  .att-row.absent{color:var(--text-dim);}
  /* Asistió en la web pero NO participó en el raid (verificación con la API) */
  .att-row.nopart{background:rgba(255,92,92,.07);}
  .att-row.nopart .att-check{background:var(--bad);border-color:var(--bad);color:#fff;box-shadow:none;}
  .att-row.nopart .nopart-tag{color:var(--bad);font-size:11.5px;font-weight:700;margin-left:var(--sp-2);border:1px solid var(--bad);border-radius:var(--r-pill);padding:0 var(--sp-2);white-space:nowrap;}

  /* ============================================================ PROGRESS BARS */
  .bar-track{background:var(--panel-2);border-radius:var(--r-pill);height:8px;overflow:hidden;flex:1;box-shadow:inset 0 0 0 1px rgba(255,255,255,.03);}
  .bar-fill{height:100%;border-radius:var(--r-pill);transition:width var(--tr);box-shadow:0 0 8px rgba(166,77,255,.3);}

  /* ============================================================ HISTORY / RANKING */
  .history-row{display:grid;grid-template-columns:170px 1fr;gap:var(--sp-4);padding:var(--sp-4) var(--sp-4);border-bottom:1px solid var(--border-soft);align-items:center;}
  .history-row:last-child{border-bottom:none;}
  .history-meta .cta-name{font-weight:700;color:var(--text);font-size:16px;}
  .history-meta .cta-date{font-size:13px;color:var(--text-dim);}
  .history-bars{display:flex;flex-direction:column;gap:var(--sp-2);}
  .hbar-line{display:flex;align-items:center;gap:var(--sp-2);font-size:14px;}
  .hbar-line .pname{width:80px;flex-shrink:0;color:var(--text-dim);}
  .hbar-line .pct{width:42px;text-align:right;font-family:'JetBrains Mono',monospace;color:var(--text);flex-shrink:0;}

  .ranking-item{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-soft);transition:background var(--tr-fast);}
  .ranking-item:hover{background:var(--panel-2);}
  .ranking-item:last-child{border-bottom:none;}
  .rank-medal{font-size:20.5px;width:28px;text-align:center;}
  .rank-name{width:110px;font-weight:600;flex-shrink:0;}
  .rank-pct{width:52px;text-align:right;font-family:'JetBrains Mono',monospace;font-weight:700;flex-shrink:0;}


  /* ============================================================ TOAST / NOTIFICATIONS */
  .toast{position:fixed;bottom:22px;right:22px;background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--accent);color:var(--gold-bright);padding:var(--sp-3) var(--sp-5);border-radius:var(--r);font-size:15.5px;font-weight:600;opacity:0;transform:translateY(12px);transition:opacity var(--tr),transform var(--tr);pointer-events:none;z-index:999;box-shadow:var(--shadow-2),0 0 20px rgba(166,77,255,.35);max-width:360px;}
  .toast.show{opacity:1;transform:none;}
  .toast.err{border-color:var(--bad);color:var(--bad);box-shadow:var(--shadow-2),0 0 20px rgba(255,70,110,.3);}

  /* Aviso de versión nueva: abajo y CENTRADO, para no pisar el toast (abajo a la derecha),
     que puede salir al mismo tiempo. El [hidden] explícito hace falta porque `display:flex`
     de la clase gana al `display:none` que trae el atributo por defecto. */
  .version-bar{position:fixed;bottom:22px;left:50%;transform:translateX(-50%);z-index:998;display:flex;align-items:center;gap:var(--sp-4);background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--accent);color:var(--text);padding:var(--sp-3) var(--sp-4);border-radius:var(--r);font-size:15px;font-weight:600;box-shadow:var(--shadow-2),0 0 20px rgba(166,77,255,.3);max-width:calc(100vw - 32px);}
  .version-bar[hidden]{display:none;}

  /* Rejilla de los cuatro rankings del Dashboard. `minmax(0,1fr)` y no `1fr`: con `1fr` las
     barras de progreso (bar-track) imponen su ancho mínimo y desbordan la columna. */
  .rank-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-2) var(--sp-6);align-items:start;}
  @media (max-width:900px){ .rank-grid{grid-template-columns:minmax(0,1fr);} }
  @media (max-width:640px){
    .version-bar{left:16px;right:16px;transform:none;bottom:16px;justify-content:space-between;font-size:14px;}
  }

  /* ============================================================ MODALS / OVERLAY */
  /* `align-items:flex-start` + `margin:auto` en la caja, y NO `align-items:center` (12 ago 2026).
     Con `center`, una caja más alta que la pantalla desborda por ARRIBA y por ABAJO a la vez, y ese
     desbordamiento NO se puede alcanzar ni con scroll en el padre: es el fallo clásico de centrar
     con flex. En 1080 con un kill de muchos items, el botón de repartir se quedaba fuera y no había
     forma de llegar a él. Con `margin:auto` la caja se centra cuando cabe y se ancla arriba cuando
     no, y entonces el `overflow-y` del overlay sí sirve. */
  .overlay{position:fixed;inset:0;z-index:50;background:rgba(6,3,14,.86);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;padding:var(--sp-6);animation:fadein .25s ease;}
  .splash-spinner{width:46px;height:46px;border-radius:50%;border:3px solid var(--border-strong);border-top-color:var(--accent);animation:splash-spin .8s linear infinite;box-shadow:0 0 16px rgba(166,77,255,.35);}
  @keyframes splash-spin{to{transform:rotate(360deg);}}
  .overlay[hidden]{display:none;}
  .overlay-box{max-width:480px;width:100%;margin:auto;background:linear-gradient(165deg,var(--panel),var(--bg-2));border:1px solid var(--accent);border-radius:var(--r-lg);padding:var(--sp-8);box-shadow:var(--shadow-2),0 0 44px rgba(166,77,255,.28);text-align:center;animation:pop .3s cubic-bezier(.4,0,.2,1);}
  /* ---------- RECLAMO DE RECLUTAMIENTO EN LA PUERTA DE ENTRADA (15 ago 2026) ----------
     Vive dentro de `.overlay-box`, que está centrada y es estrecha: aquí se ensancha la caja y
     se vuelve a alinear el texto a la izquierda, porque son párrafos y listas, no un diálogo. */
  #overlay-login .overlay-box{max-width:760px;}
  #login-pitch{margin-top:var(--sp-6);padding-top:var(--sp-6);border-top:1px solid var(--border);text-align:left;}
  /* El banner ANCHO (2048x330), no el cuadrado: dentro de la caja de login, uno de 1200x630
     ocupaba media pantalla y empujaba el botón de entrar fuera de la vista en el móvil. */
  .pitch-banner{width:100%;height:auto;display:block;border-radius:10px;border:1px solid var(--border-soft);
    box-shadow:0 0 22px var(--glow-soft);}
  .pitch-claim{font-family:var(--font-display);text-align:center;margin:var(--sp-5) 0 var(--sp-2);font-size:clamp(18px,4.2vw,25px);
    line-height:1.2;color:var(--gold-bright);text-shadow:0 0 16px var(--accent-glow);}
  .pitch-sub{margin:0 0 var(--sp-1);color:var(--text-dim);font-size:15px;line-height:1.55;text-align:center;}
  .pitch-sub b{color:var(--text);}
  .pitch-h{margin:var(--sp-6) 0 var(--sp-2);font-size:16px;color:var(--gold-bright);letter-spacing:.01em;}
  .pitch-list{margin:0;padding-left:var(--sp-5);}
  .pitch-list li{margin:0 0 var(--sp-2);color:var(--text-dim);font-size:14.5px;line-height:1.5;}
  .pitch-list li b{color:var(--text);}
  .pitch-num{padding-left:var(--sp-6);}
  /* El boton de Discord del reclamo. Reutiliza `.discord-cta` entera (colores, halo, hover,
     mayusculas del ruso) y solo la centra: aqui es una llamada a la accion, no una fila.
     Va SIN el logo del clan a proposito: `.con-logo` sustituye el boton entero por la imagen, y
     un desconocido necesita LEER «unirse al Discord», no adivinar un cuadrado. */
  .pitch-discord{display:flex;justify-content:center;margin-top:var(--sp-5);}
  .pitch-discord .discord-cta{margin:0;width:100%;max-width:340px;}
  .pitch-legal{margin:var(--sp-5) 0 0;padding-top:var(--sp-4);border-top:1px solid var(--border-soft);
    text-align:center;color:var(--text-mute);font-size:11.5px;line-height:1.5;}

  /* ══════════════════════════════════════════════════════════════════════════════
     LA PUERTA DE ENTRADA COMO PÁGINA DE CLAN (15 sep 2026)

     Sirvine: «se ve claramente que es html que no tiene ninguna complejidad», con
     luna.ageofsplendor.com como referencia. Lo que le faltaba no era color —la paleta ya
     era esta— sino las tres cosas que separan una página trabajada de un formulario:

       1. PROFUNDIDAD. Aquí el fondo tiene capas (dos halos + una trama diagonal fija) y los
          paneles tienen rail, muesca y sombra propia. Un color plano detrás de una caja con
          borde de 1px es exactamente lo que se lee como «HTML sin tocar».
       2. IMAGEN A SANGRE. El banner ocupa el ancho entero y se funde con la página. Metido
          dentro de una caja con borde parecía una captura pegada en un documento.
       3. ORNAMENTO Y RITMO. Cada sección tiene antetítulo, título y una regla con rombo; el
          ojo sabe dónde empieza cada cosa sin leer.

     Todo cuelga de #overlay-login para no tocar los otros seis overlays, que siguen siendo
     diálogos centrados y deben seguir siéndolo. ══════════════════════════════════════════ */

  /* El overlay deja de centrar una caja y pasa a ser el lienzo de la página. */
  .overlay.lp{display:block;padding:0;backdrop-filter:none;-webkit-backdrop-filter:none;
    /* El fondo va en el CONTENEDOR QUE HACE SCROLL, no en su contenido: el de un elemento con
       overflow se pinta sobre su caja y no se desplaza, asi que los halos quedan anclados a la
       pantalla. Puesto en `.lp-page` —el hijo que se mueve— se estiraban a lo largo de toda la
       pagina y quedaban lavados. Y sigue siendo UNA capa, que es lo que arreglo el lag: antes eran
       cuatro en un pseudo-elemento `position:fixed` dentro de este mismo scroll. */
    background:
      radial-gradient(ellipse 80% 50% at 50% -5%, rgba(166,77,255,.22), transparent 65%),
      radial-gradient(ellipse 60% 45% at 92% 38%, rgba(75,31,171,.16), transparent 70%),
      var(--bg);
    background-repeat:no-repeat;}
  /* Las capas del fondo, fijas: al hacer scroll el contenido se mueve sobre ellas y la página
     deja de sentirse como un documento que sube en bloque.
     La trama de 3px es lo que quita la sensación de «color plano»: no se ve, se nota. */
  /* El fondo va AQUÍ, en el propio contenedor, y no en un pseudo-elemento `position:fixed`.
     La primera versión tenía cuatro capas fijas —tres halos y una trama que se repetía cada 3 px—
     dentro de un contenedor con scroll propio, así que cada frame obligaba a rasterizar las cuatro
     sobre el viewport entero. Eso era el «va un poco lag».
     Pintado sobre el elemento que hace scroll, el compositor lo cachea una vez y lo desplaza. La
     trama se ha ido entera: aportaba un grano que no se aprecia y era la capa más cara de las
     cuatro (un patrón de paso pequeño no se puede simplificar, hay que dibujarlo). */
  .lp-page{position:relative;min-height:100%;isolation:isolate;}

  /* ---- Barra fija ---- */
  .lp-bar{
    position:sticky;top:0;z-index:5;display:flex;align-items:center;justify-content:space-between;
    gap:var(--sp-4);padding:var(--sp-3) clamp(16px,4vw,40px);
    /* Fondo SÓLIDO, sin backdrop-filter. El desenfoque se recalcula en cada frame y sobre todo
       lo que pasa por debajo: es el efecto más caro de la página y el que menos se nota, porque
       la barra es opaca de todos modos. */
    background:var(--bg);
    border-bottom:1px solid var(--border-soft);
  }
  /* Hilo de luz bajo la barra: separa sin dibujar una segunda línea dura. */
  .lp-bar::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
    background:linear-gradient(90deg,transparent,var(--accent),transparent);opacity:.55;}
  .lp-mark{display:flex;align-items:center;gap:var(--sp-3);text-decoration:none;flex:0 1 auto;min-width:0;}
  /* Ancho y alto fijos: el logo de la barra no puede mover la cabecera al decodificar. */
  .lp-mark img{width:34px;height:34px;object-fit:contain;filter:drop-shadow(0 0 10px var(--accent-glow));flex:none;}
  .lp-mark span{font-family:var(--font-display);font-weight:700;font-size:17px;letter-spacing:.06em;
    color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .lp-mark b{color:var(--gold-bright);font-weight:700;}
  .lp-bar-right{display:flex;align-items:center;gap:var(--sp-3);flex:none;}
  /* Dos clases a propósito: `.google-btn` se declara 300 líneas más abajo y empata en
     especificidad, así que con una sola ganaría por posición y habría que recurrir a
     !important — que es lo que hacía esta regla antes de que el test lo cazara. */
  .lp-bar .lp-entrar{margin:0;white-space:nowrap;}

  /* ---- Hero ---- */
  .lp-hero{position:relative;overflow:hidden;padding:clamp(48px,9vw,104px) clamp(16px,4vw,40px) clamp(40px,7vw,80px);
    text-align:center;}
  /* La imagen va en su propia capa para poder velarla sin tocar el texto, y desenfocada en los
     bordes: enfocada de lado a lado competía con el título en vez de sostenerlo. */
  /* Sin `filter:`: apagar la imagen con saturate/contrast obliga a filtrar la capa cada vez que
     se compone. Con opacidad sola se consigue lo mismo a la vista y el compositor lo aplica sin
     repintar. El `scale` se queda porque es un transform, que tampoco repinta. */
  .lp-hero-art{position:absolute;inset:0;
    background:url('../banner-dashboard.jpg') center/cover no-repeat;
    opacity:.30;transform:scale(1.06);}
  .lp-hero::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:
      radial-gradient(ellipse 70% 60% at 50% 45%, transparent 25%, rgba(10,6,17,.55) 75%),
      linear-gradient(180deg, rgba(10,6,17,.55) 0%, rgba(10,6,17,.10) 35%, rgba(10,6,17,.96) 100%);}
  .lp-hero-txt{position:relative;z-index:1;max-width:760px;margin:0 auto;
    display:flex;flex-direction:column;align-items:center;gap:var(--sp-3);}
  /* `aspect-ratio` con la proporcion REAL del fichero (300x126). Sin ella, el hueco mide 0 hasta
     que el PNG decodifica y toda la pagina pega un salto al aparecer. */
  .lp-hero-logo{width:clamp(96px,17vw,150px);aspect-ratio:300/126;height:auto;
    margin-bottom:var(--sp-2);filter:drop-shadow(0 0 26px var(--accent-glow));}
  .lp-eyebrow{margin:0;font-size:12px;letter-spacing:.3em;text-transform:uppercase;
    color:var(--gold-bright);font-weight:600;}
  .lp-title{
    font-family:var(--font-display);font-weight:700;margin:0;
    font-size:clamp(34px,8.5vw,68px);line-height:1.02;letter-spacing:.07em;color:var(--text);
    /* Tres sombras, no una: un halo ancho apagado, uno medio y un filo cercano. Un solo
       text-shadow grande sale como una mancha y es lo que hace que el neón parezca barato. */
    text-shadow:0 0 60px rgba(166,77,255,.45), 0 0 26px rgba(166,77,255,.35), 0 2px 2px rgba(0,0,0,.6);
  }
  /* Ornamento: dos reglas que se desvanecen y un rombo. Es el ritmo de la página. */
  .lp-orn{display:flex;align-items:center;justify-content:center;gap:var(--sp-3);width:min(320px,70vw);margin:var(--sp-1) 0;}
  .lp-orn::before,.lp-orn::after{content:"";flex:1;height:1px;
    background:linear-gradient(90deg,transparent,var(--accent));}
  .lp-orn::after{background:linear-gradient(90deg,var(--accent),transparent);}
  .lp-orn-d{width:7px;height:7px;transform:rotate(45deg);background:var(--gold-bright);
    box-shadow:0 0 12px var(--accent-glow);flex:none;}
  .lp-hero-sub{margin:0;max-width:56ch;color:var(--text-dim);font-size:clamp(15px,2.1vw,17.5px);line-height:1.6;}
  .lp-hero-sub b{color:var(--text);}
  .lp-cta{display:flex;flex-wrap:wrap;gap:var(--sp-3);justify-content:center;margin-top:var(--sp-4);}
  .lp-cta .discord-cta{margin:0;padding:var(--sp-3) var(--sp-6);}
  .lp-cta .google-btn{margin:0;width:auto;}

  /* ---- Secciones ---- */
  /* `content-visibility` va en las secciones de ABAJO, no en el hero: el hero es lo primero que
     se ve siempre, asi que ahi no ahorra nada y encima arriesga un salto si la altura estimada no
     coincide con la real. Aqui si: al cargar, ninguna de las cuatro esta en pantalla. */
  .lp-sec{max-width:1080px;margin:0 auto;padding:clamp(40px,6vw,72px) clamp(16px,4vw,40px) 0;
    content-visibility:auto;contain-intrinsic-size:auto 420px;}
  .lp-sec-head{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
    text-align:center;margin-bottom:var(--sp-6);}
  .lp-sec-head .lp-eyebrow{color:var(--accent-2);}
  .lp-h2{font-family:var(--font-display);font-weight:700;margin:0;color:var(--text);
    font-size:clamp(22px,4vw,32px);letter-spacing:.04em;text-wrap:balance;}
  .lp-lede{margin:0;max-width:62ch;color:var(--text-dim);font-size:16px;line-height:1.65;text-align:center;}
  .lp-lede b{color:var(--text);}

  /* ---- Tarjetas ---- */
  /* Siempre son TRES tarjetas (una rejilla por idioma, tres tarjetas cada una), así que las únicas
     reparticiones sin huérfano son 3 y 1. El `auto-fit` de antes pasaba por 2 entre 558 y 842 px y
     dejaba un 2+1: dos arriba y una sola abajo ocupando media fila. Se fija a 3, y a 1 de golpe
     cuando 3 ya no caben — sin pasar por el 2. */
  .lp-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-4);}
  @media (max-width:860px){ .lp-grid{grid-template-columns:minmax(0,1fr);} }
  .lp-card{
    position:relative;padding:var(--sp-6) var(--sp-5);border:1px solid var(--border-soft);
    border-radius:var(--r);background:linear-gradient(165deg,var(--panel-2),var(--panel));
    box-shadow:var(--shadow-1);overflow:hidden;
    transition:transform var(--tr),border-color var(--tr),box-shadow var(--tr);
  }
  /* El rail de arriba es lo que convierte un rectángulo con borde en una pieza. */
  .lp-card::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;
    background:linear-gradient(90deg,transparent,var(--accent),transparent);opacity:.7;}
  .lp-card:hover{transform:translateY(-3px);border-color:var(--accent);
    box-shadow:var(--shadow-2),0 0 26px rgba(166,77,255,.20);}
  .lp-card h3{font-family:var(--font-display);font-size:17px;margin:0 0 var(--sp-2);color:var(--gold-bright);
    letter-spacing:.03em;}
  .lp-card p{margin:0;color:var(--text-dim);font-size:15px;line-height:1.6;}
  .lp-card p b{color:var(--text);}
  .lp-card-n{position:absolute;right:var(--sp-4);top:var(--sp-3);font-family:var(--font-display);
    font-size:40px;line-height:1;color:var(--accent);opacity:.16;font-weight:700;}

  /* ---- El reparto: los dos niveles ----
     Es el argumento que diferencia al clan, así que tiene tratamiento propio y no una tarjeta
     más. El segundo nivel es el que responde a «¿o se lo lleva siempre el mismo?», y por eso
     lleva el borde dorado y el sello: es lo que hay que leer sí o sí. */
  .lp-tiers{display:flex;flex-direction:column;gap:var(--sp-4);}
  .lp-tier{position:relative;padding:var(--sp-6);border:1px solid var(--border-soft);border-radius:var(--r);
    background:linear-gradient(160deg,var(--panel-2),var(--panel));box-shadow:var(--shadow-1);
    display:flex;gap:var(--sp-5);align-items:flex-start;}
  .lp-tier-n{font-family:var(--font-display);font-size:clamp(28px,5vw,42px);line-height:1;font-weight:700;
    color:var(--accent);flex:none;opacity:.55;min-width:1.4em;text-align:center;}
  .lp-tier h3{font-family:var(--font-display);font-size:18px;margin:0 0 var(--sp-2);color:var(--text);letter-spacing:.03em;}
  .lp-tier p{margin:0;color:var(--text-dim);font-size:15.5px;line-height:1.65;}
  .lp-tier p b{color:var(--text);}
  .lp-tier p + p{margin-top:var(--sp-3);}
  .lp-tier-top{border-color:var(--gold);box-shadow:var(--shadow-2),0 0 30px rgba(166,77,255,.16);}
  .lp-tier-top .lp-tier-n{color:var(--gold-bright);opacity:.85;}
  .lp-tier-top h3{color:var(--gold-bright);}
  .lp-sello{display:inline-block;margin-bottom:var(--sp-3);padding:var(--sp-1) var(--sp-3);border-radius:var(--r-pill);
    border:1px solid var(--gold);color:var(--gold-bright);background:var(--accent-soft);
    font-family:var(--font-display);font-size:11.5px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;}

  /* ---- Lo que pedimos: lista con marca, no viñetas ---- */
  /* Son CUATRO items, así que la rejilla tiene que dar 2×2 o uno se queda huérfano — y eso es lo
     que pasaba. El contenido mide 1000px (los 1080 del `.lp-sec` menos 40+40 de padding), y con
     `minmax(260px)` caben TRES columnas y no cuatro: 3×260+2×12 = 804 sí, 4×260+3×12 = 1076 no.
     Resultado: tres arriba y el cuarto solo abajo, ocupando un tercio del ancho y dejando dos
     tercios en blanco. Era lo último de la página, así que era lo último que se veía.

     Con 340px caben dos y no tres (2×340+12 = 692 sí, 3×340+24 = 1044 no): 2×2 en escritorio y una
     sola columna por debajo de ~700px de contenido, sin necesidad de media query. Y de paso el
     texto respira: ~60 caracteres por línea en vez de los ~25 que daría ponerlos los cuatro en
     fila, que era la otra forma de no dejar huérfano. */
  .lp-pide{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:var(--sp-3);
    list-style:none;margin:0;padding:0;}
  .lp-pide li{position:relative;padding:var(--sp-3) var(--sp-4) var(--sp-3) calc(var(--sp-6) + 6px);
    border-left:2px solid var(--accent-deep);border-radius:0 var(--r-sm) var(--r-sm) 0;
    background:linear-gradient(90deg,var(--accent-soft),transparent 70%);
    color:var(--text-dim);font-size:15px;line-height:1.55;}
  .lp-pide li b{color:var(--text);display:block;}
  .lp-pide li::before{content:"";position:absolute;left:var(--sp-4);top:1.35em;width:6px;height:6px;
    transform:rotate(45deg);background:var(--gold-bright);box-shadow:0 0 8px var(--accent-glow);}

  /* ---- Las cifras del clan ---- */
  .lp-figs{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--sp-4);}
  .lp-fig{text-align:center;padding:var(--sp-5) var(--sp-3);border:1px solid var(--border-soft);
    border-radius:var(--r);background:rgba(22,14,38,.55);}
  .lp-fig b{display:block;font-family:var(--font-display);font-size:clamp(28px,5vw,40px);line-height:1;
    color:var(--gold-bright);font-variant-numeric:tabular-nums;text-shadow:0 0 22px var(--accent-glow);}
  .lp-fig span{display:block;margin-top:var(--sp-2);font-size:12px;letter-spacing:.14em;
    text-transform:uppercase;color:var(--text-mute);}

  /* ---- Cierre y pie ---- */
  .lp-cierre{max-width:1080px;margin:clamp(48px,7vw,88px) auto 0;padding:clamp(36px,6vw,64px) clamp(16px,4vw,40px);
    text-align:center;border-top:1px solid var(--border-soft);
    background:radial-gradient(ellipse 70% 100% at 50% 100%, rgba(166,77,255,.13), transparent 70%);}
  .lp-foot{padding:var(--sp-6) clamp(16px,4vw,40px) var(--sp-8);text-align:center;
    color:var(--text-mute);font-size:12.5px;line-height:1.7;border-top:1px solid var(--border-soft);
    margin-top:clamp(32px,5vw,56px);}
  .lp-foot a{color:var(--text-dim);}

  /* El aviso de navegador embebido y el subtítulo de estado del login. */
  .lp-aviso{max-width:680px;margin:var(--sp-5) auto 0;padding:var(--sp-4) var(--sp-5);text-align:left;
    background:var(--warn-bg);border:1px solid var(--warn);border-radius:var(--r);}
  .lp-aviso p{color:var(--warn);font-size:14.5px;margin:0 0 var(--sp-3);}
  .lp-aviso .btn{width:100%;}
  .lp-aviso[hidden]{display:none;}
  .lp-sub{max-width:680px;margin:var(--sp-4) auto 0;text-align:center;color:var(--text-dim);font-size:14.5px;}
  .lp-sub:empty{display:none;}

  /* La entrada: cada bloque sube un poco al cargar. `backwards` es deliberado — el estado en
     REPOSO es visible, así que si la animación no llega a correr (o el usuario la desactiva)
     la página se ve entera igual. Nada depende de un observer ni del scroll. */
  @keyframes lp-sube{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:none;}}
  .lp-hero-txt > *{animation:lp-sube .55s cubic-bezier(.2,.7,.3,1) backwards;}
  .lp-hero-txt > *:nth-child(1){animation-delay:.02s;}
  .lp-hero-txt > *:nth-child(2){animation-delay:.08s;}
  .lp-hero-txt > *:nth-child(3){animation-delay:.14s;}
  .lp-hero-txt > *:nth-child(4){animation-delay:.20s;}
  .lp-hero-txt > *:nth-child(5){animation-delay:.26s;}
  .lp-hero-txt > *:nth-child(6){animation-delay:.32s;}

  @media (max-width:720px){
    .lp-bar{flex-wrap:wrap;gap:var(--sp-2);padding:var(--sp-2) var(--sp-4);}
    .lp-bar-right{width:100%;justify-content:space-between;}
    .lp-tier{flex-direction:column;gap:var(--sp-3);}
    .lp-tier-n{text-align:left;}
    .lp-cta{flex-direction:column;align-items:stretch;}
    .lp-cta .discord-cta,.lp-cta .google-btn{width:100%;}
  }
  @media (prefers-reduced-motion:reduce){
    .lp-hero-txt > *{animation:none;}
    .lp-card:hover{transform:none;}
  }

  /* --- Normas de AdrenalineTM --- */
  .overlay-box.wide{max-width:720px;text-align:left;}
  .rules-warn{background:rgba(255,120,80,.10);border:1px solid var(--warn);color:var(--warn);border-radius:var(--r-sm);padding:var(--sp-3) var(--sp-4);margin:var(--sp-4) 0;font-weight:600;font-size:15px;line-height:1.45;}
  .rules-scroll{max-height:46vh;overflow-y:auto;border:1px solid var(--border);border-radius:var(--r-sm);padding:var(--sp-4) var(--sp-5);background:var(--panel-2);text-align:left;margin-top:var(--sp-2);line-height:1.6;}
  .rules-scroll::-webkit-scrollbar{width:10px;} .rules-scroll::-webkit-scrollbar-thumb{background:var(--accent-deep);border-radius:6px;}
  .rules-list{margin:0;padding-left:var(--sp-6);} .rules-list li{margin:0 0 var(--sp-3);color:var(--text);}
  /* Marcas de «Cómo empezar» (marcarPasosInicio). Lo ya hecho se ATENÚA, no se borra ni se tacha:
     sigue siendo una guía que se consulta, no una lista de la compra que se vacía. */
  .paso-marca{display:inline-block;min-width:1.15em;margin-right:var(--sp-2);font-weight:700;}

  /* ---- CÓMO EMPEZAR, en fichas (15 sep 2026) ----
     Sirvine: «que la gente no sienta que es algo tedioso». Era una lista numerada de cuatro
     frases largas; leída de arriba abajo parecía deberes. En cuadrícula se ve de un golpe
     CUÁNTOS pasos son, que es la pregunta real de quien acaba de entrar, y cada ficha cabe en
     dos líneas. El paso hecho se pone verde entero: la recompensa tiene que verse de lejos,
     no ser un ✓ de 12px al principio de un párrafo. */
  .pasos{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));
    gap:var(--sp-3);margin:var(--sp-4) 0 var(--sp-5);}
  .paso{position:relative;padding:var(--sp-4);padding-left:calc(var(--sp-8) + 18px);
    border:1px solid var(--border-soft);border-radius:var(--r);background:var(--panel-2);
    transition:border-color var(--tr),background var(--tr);}
  .paso-n{position:absolute;left:var(--sp-4);top:var(--sp-4);width:26px;height:26px;
    display:grid;place-items:center;border-radius:var(--r-pill);
    font-family:var(--font-display);font-weight:700;font-size:13px;
    background:var(--accent-soft);border:1px solid var(--accent);color:var(--gold-bright);
    transition:border-color var(--tr),color var(--tr),background var(--tr);}
  .paso h4{margin:0 0 var(--sp-1);font-size:15px;color:var(--text);}
  .paso p{margin:0;color:var(--text-dim);font-size:14px;line-height:1.5;}
  /* Hecho: el número se vuelve verde y el borde con él. NO se baja la opacidad de la ficha
     entera —eso es lo que hace la lista de toda la vida— porque un paso cumplido no es un
     paso que estorba: es el que te dice que vas bien. */
  .paso.paso-hecho{border-color:var(--good);background:var(--good-bg);}
  .paso.paso-hecho .paso-n{background:var(--good-bg);border-color:var(--good);color:var(--good);}
  .paso.paso-hecho h4{color:var(--good);}
  .paso.paso-espera .paso-n,.paso.paso-aviso .paso-n{border-color:var(--warn);color:var(--warn);
    background:var(--warn-bg);}
  .paso.paso-espera{border-color:var(--warn);}
  /* La marca (✓ / · / ⏳) la mete marcarPasosInicio dentro del <h4>. En la ficha sobra, porque el
     color ya lo dice todo y el icono partía el título en dos: se esconde solo aquí. */
  .paso .paso-marca{display:none;}

  /* La leyenda de arriba de Bonos: tres etiquetas sueltas, no un párrafo. */
  .rule-leyenda{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0 0 var(--sp-4);}
  .rules-list li.paso-hecho{opacity:.55;}
  .paso-hecho .paso-marca{color:var(--good);}
  .paso-pendiente .paso-marca{color:var(--text-dim);}
  .paso-espera .paso-marca,.paso-aviso .paso-marca{color:var(--warn);}
  .rules-scroll h2{color:var(--gold-bright);font-size:18px;letter-spacing:.02em;margin:var(--sp-6) 0 var(--sp-2);padding-bottom:var(--sp-2);border-bottom:1px solid var(--border);}
  .rules-scroll h2:first-child{text-align:center;font-size:22px;border-bottom:none;margin:2px 0 10px;text-shadow:0 0 14px var(--accent-glow);}
  .rules-scroll h3{color:var(--accent-2);font-size:15.5px;margin:var(--sp-4) 0 var(--sp-1);}
  .rules-scroll p{margin:0 0 var(--sp-2);color:var(--text);}
  .rules-scroll ul{margin:var(--sp-1) 0 var(--sp-3);padding-left:var(--sp-5);} .rules-scroll ul li{margin:0 0 var(--sp-1);color:var(--text-dim);}
  .rules-scroll b{color:var(--text);}
  /* Tabla de DISCIPLINA Y SANCIONES (normas v7, 12 ago 2026). Antes no había ningún estilo de
     tabla dentro de las normas: un <table> ahí salía sin bordes ni cabecera, con las tres columnas
     pegadas. La última columna va en color de aviso porque es la de reincidencia — la severidad se
     lee de un vistazo sin tener que leer la celda. */
  .rules-table{width:100%;border-collapse:collapse;margin:var(--sp-4) 0 var(--sp-2);font-size:14.5px;}
  .rules-table th{background:var(--panel-2);color:var(--gold-bright);font-family:var(--font-display);
    font-size:12.5px;letter-spacing:.07em;text-transform:uppercase;text-align:left;padding:var(--sp-2) var(--sp-3);
    border:1px solid var(--border);}
  .rules-table td{padding:var(--sp-2) var(--sp-3);border:1px solid var(--border-soft);color:var(--text);
    vertical-align:top;line-height:1.45;}
  .rules-table tbody tr:nth-child(even) td{background:rgba(255,255,255,.02);}
  .rules-table td:first-child{font-weight:600;}
  .rules-table td:last-child{color:var(--warn);}
  /* En el móvil la tabla se APILA: cada fila pasa a ser una tarjeta y cada celda enseña su
     etiqueta delante (`data-label`), el mismo patrón que la tabla del roster. Las normas se leen
     sobre todo en el teléfono, y tres columnas de texto ahí son ilegibles. */
  @media (max-width:640px){
    /* `display:block` también en la tabla y en el tbody, no solo en las filas. NO es por
       desbordamiento: medido en un móvil real de 390 px, no desborda de ninguna de las dos
       maneras. Es porque con la tabla en `display:table` y las filas en `display:block`, el
       navegador envuelve las filas en cajas de tabla anónimas y el `margin-bottom` que separa las
       tarjetas deja de ser fiable. Y es el mismo patrón que ya usa la tabla del roster
       (#roster-table-wrap table), que es la referencia de la casa para esto.

       Nota para quien lo compruebe: Chrome headless no baja de 500 px de ancho de ventana, así que
       una captura pedida a 390 px sale RECORTADA y parece que el contenido desborda cuando no lo
       hace. Para medir un móvil de verdad, la página dentro de un <iframe> de 390 px. */
    .rules-table{display:block;min-width:0;}
    .rules-table tbody{display:block;}
    .rules-table thead{display:none;}
    .rules-table tbody tr{display:block;background:var(--panel);border:1px solid var(--border);
      border-radius:var(--r-sm);margin-bottom:var(--sp-3);overflow:hidden;}
    .rules-table tbody tr:nth-child(even) td{background:transparent;}
    .rules-table td{display:block;border:none;border-bottom:1px solid var(--border-soft);}
    .rules-table td:last-child{border-bottom:none;}
    .rules-table td[data-label]::before{content:attr(data-label);display:block;color:var(--text-dim);
      font-size:11px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;margin-bottom:3px;}
  }
  .rule-new{margin:var(--sp-5) 0 var(--sp-2);padding:var(--sp-4) var(--sp-4);border:2px solid var(--gold);border-radius:var(--r);background:linear-gradient(180deg,rgba(224,162,79,.14),rgba(224,162,79,.04));box-shadow:0 0 20px rgba(224,162,79,.28);}
  .rule-new-badge{display:inline-block;background:var(--gold);color:#1a1210;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;padding:3px 10px;border-radius:999px;margin-bottom:var(--sp-3);box-shadow:0 0 10px rgba(224,162,79,.6);}
  .rule-new h3{margin-top:0 !important;}
  .rules-scroll-hint{color:var(--gold-bright);font-size:13.5px;font-weight:700;text-align:center;margin:var(--sp-3) 0 var(--sp-1);transition:opacity var(--tr);}
  .rules-scroll-hint.done{opacity:.3;}
  .rules-agree{display:flex;align-items:flex-start;gap:var(--sp-3);margin:14px 2px 4px;font-size:15px;color:var(--text);user-select:none;cursor:pointer;line-height:1.4;}
  .rules-agree input{width:20px;height:20px;flex:0 0 20px;margin-top:1px;accent-color:var(--accent);cursor:pointer;}
  .rules-actions{display:flex;gap:var(--sp-3);align-items:center;justify-content:space-between;flex-wrap:wrap;margin-top:var(--sp-4);}
  .btn[disabled]{opacity:.45;cursor:not-allowed;filter:grayscale(.4);box-shadow:none;}
  .rules-status{border-radius:var(--r-sm);padding:var(--sp-3) var(--sp-4);margin-bottom:var(--sp-4);font-weight:600;}
  .rules-status.ok{background:rgba(90,220,140,.08);border:1px solid var(--good);color:var(--good);}
  .rules-status.no{background:rgba(255,120,80,.08);border:1px solid var(--warn);color:var(--warn);}
  @keyframes pop{from{opacity:0;transform:translateY(14px) scale(.98);}to{opacity:1;transform:none;}}

  /* ARCOÍRIS DEL GS LEGENDARIO (6100+). Lo aplica gsGlow() con `animation:` en línea, así que basta
     definir los fotogramas aquí y no hay que tocar los sitios donde se pinta el número.

     Se anima el COLOR y el HALO a la vez, los dos por el mismo tono (13 ago 2026, pedido por
     Sirvine). Que esto funcione sin tocar gsColor() es un detalle del cascade: una animación pisa
     las declaraciones normales, **incluido el `style` en línea**, mientras corre. Así el número
     lleva su `color:var(--gs-god)` en línea como base y el arcoíris lo sobreescribe encima:
     gsColor() sigue devolviendo un color sólido para las BARRAS del ranking, que no pueden ir con
     text-shadow, y solo el texto cicla.

     Los siete tonos están elegidos, no sacados de un hue-rotate: todos son neones claros que se
     leen sobre el fondo morado oscuro. Nada de azul o violeta saturado, que ahí se hunden — de ahí
     el violeta lavanda en vez de un índigo. Y 3,6 s para el ciclo completo: es un cambio de tono
     lento y continuo, no un parpadeo. */
  @keyframes gs-chetado{
    0%,100%{color:#ff4060;text-shadow:0 0 6px #ff4060,0 0 16px #ff4060,0 0 30px rgba(255,64,96,.5);}
    14%{color:#ff9a1f;text-shadow:0 0 6px #ff9a1f,0 0 16px #ff9a1f,0 0 30px rgba(255,154,31,.5);}
    28%{color:#ffe600;text-shadow:0 0 6px #ffe600,0 0 16px #ffe600,0 0 30px rgba(255,230,0,.5);}
    42%{color:var(--gs-god);text-shadow:0 0 6px var(--gs-god),0 0 16px var(--gs-god),0 0 30px var(--gs-god-glow);}
    57%{color:#00f5ff;text-shadow:0 0 6px #00f5ff,0 0 16px #00f5ff,0 0 30px rgba(0,245,255,.5);}
    71%{color:#a78bff;text-shadow:0 0 6px #a78bff,0 0 16px #a78bff,0 0 30px rgba(167,139,255,.5);}
    85%{color:#ff00e6;text-shadow:0 0 6px #ff00e6,0 0 16px #ff00e6,0 0 30px rgba(255,0,230,.5);}
  }
  /* Para quien pide menos movimiento en su sistema, los fotogramas se redefinen VACÍOS: el navegador
     se queda con el color y el text-shadow fijos que gsGlow() ya trae en línea (lima con su halo),
     así que el número sigue brillando pero no cambia de tono. Es la única forma de apagar una
     animación declarada en línea sin quitársela a todo el mundo — y por eso el color base en línea
     no se puede quitar: es lo que ve quien tiene el movimiento reducido. */
  @media (prefers-reduced-motion:reduce){
    @keyframes gs-chetado{ 0%,100%{} }
  }
  .overlay-box.wide{max-width:640px;text-align:left;}
  .overlay-box h2{font-family:var(--font-display);color:var(--gold-bright);margin-top:0;text-shadow:0 0 14px rgba(166,77,255,.25);}
  .overlay-box p{line-height:1.6;color:var(--text);font-size:16.5px;}
  /* Aviso general (config.js: AVISO_VERSION). El tope de altura es para el móvil: sin él, un
     aviso largo empuja el botón de cerrar fuera de la pantalla y no hay forma de quitarlo.
     En oro solo lo de la lista (los bonos), que es el dato que tiene que saltar a la vista. */
  .aviso-body{text-align:left;line-height:1.6;font-size:16px;max-height:58vh;overflow-y:auto;}
  .aviso-body p{margin:0 0 var(--sp-3);color:var(--text);}
  .aviso-body ul{margin:var(--sp-2) 0 var(--sp-3);padding-left:var(--sp-5);}
  .aviso-body li{margin:0 0 var(--sp-2);color:var(--text-dim);}
  .aviso-body li b{color:var(--gold-bright);}
  .google-btn{display:inline-flex;align-items:center;gap:var(--sp-3);background:#fff;color:#1a1a2e;border:none;padding:var(--sp-3) var(--sp-6);border-radius:var(--r-sm);font-family:var(--font-body);font-weight:700;font-size:17px;cursor:pointer;margin-top:var(--sp-3);transition:filter var(--tr),transform var(--tr);}
  .google-btn:hover{filter:brightness(.96);transform:translateY(-1px);}
  .lang-options{display:flex;gap:var(--sp-3);justify-content:center;margin-top:var(--sp-5);flex-wrap:wrap;}
  .lang-option{background:var(--panel-2);border:1px solid var(--border);color:var(--text);padding:var(--sp-4) var(--sp-6);border-radius:var(--r);cursor:pointer;font-weight:700;font-size:17px;transition:all var(--tr);}
  .lang-option:hover{border-color:var(--accent);color:var(--gold-bright);box-shadow:0 0 16px rgba(166,77,255,.2);transform:translateY(-2px);}

  .role-select-row{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-soft);flex-wrap:wrap;}
  .role-select-row:last-child{border-bottom:none;}
  .role-select-row .ru-name{flex:1;min-width:140px;font-weight:600;}

  /* BANDA DE VENTANA ABIERTA. Ámbar y no morado a propósito: es lo único de la interfaz que
     caduca solo, así que tiene que romper el color de la casa para que se note. Cuando ya te
     has marcado pasa a verde y se calla (sin botón), que es la mitad del valor: saber que no
     tienes que hacer nada. */
  .open-window{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin:0 0 var(--sp-5);padding:var(--sp-3) var(--sp-4);
    border:1px solid var(--warn);border-radius:var(--r);background:rgba(255,150,60,.10);
    box-shadow:0 0 18px rgba(255,150,60,.12);}
  .open-window.ok{border-color:var(--good);background:rgba(60,220,150,.08);box-shadow:none;}
  .open-window .ow-dot{width:9px;height:9px;border-radius:50%;background:var(--warn);flex:0 0 auto;
    animation:ow-pulse 1.6s ease-in-out infinite;}
  .open-window.ok .ow-dot{background:var(--good);animation:none;}
  .open-window .ow-text{font-weight:700;color:var(--text);}
  .open-window .ow-time{color:var(--text-dim);font-variant-numeric:tabular-nums;margin-left:auto;}
  @keyframes ow-pulse{0%,100%{opacity:1;} 50%{opacity:.25;}}
  @media (prefers-reduced-motion:reduce){ @keyframes ow-pulse{ 0%,100%{} } }

  /* «Ha muerto el épico, cierra la CTA». Misma forma que la banda de arriba para que se lea
     igual de rápido, pero en ROJO: aquella informa, esta pide una acción que si no se hace
     mete kills ajenos en el reparto. El punto late más deprisa por lo mismo. */
  .epic-down{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin:0 0 var(--sp-5);padding:var(--sp-3) var(--sp-4);
    border:1px solid var(--danger);border-radius:var(--r);background:rgba(255,80,80,.10);
    box-shadow:0 0 18px rgba(255,80,80,.14);}
  .epic-down .ed-dot{width:9px;height:9px;border-radius:50%;background:var(--danger);flex:0 0 auto;
    animation:ow-pulse 1s ease-in-out infinite;}
  .epic-down .ed-text{font-weight:700;color:var(--text);}
  .epic-down .ed-time{color:var(--text-dim);font-variant-numeric:tabular-nums;margin-left:auto;}
  /* Variante ámbar para lo que aún es un RIESGO y no un daño ya hecho (la CTA que se pasó de
     hora sin iniciar). El rojo se reserva para lo que ya ha salido mal; si todo fuera rojo,
     el rojo dejaría de querer decir nada. */
  .epic-down.aviso{border-color:var(--warn);background:rgba(255,150,60,.10);box-shadow:0 0 18px rgba(255,150,60,.12);}
  .epic-down.aviso .ed-dot{background:var(--warn);animation-duration:1.6s;}
  .epic-down .ed-text + .btn{margin-left:auto;}
  .epic-down .ed-time + .btn{margin-left:0;}
  /* «De dónde sale este número»: la cadena que explica el % de asistencia. En una sola línea
     que se parte sola — la mitad del clan lo mira desde el móvil, y una tabla de pasos ahí
     sería ilegible. Gris y pequeño a propósito: acompaña al número, no compite con él. */
  .att-why{display:flex;flex-wrap:wrap;align-items:center;gap:3px 7px;padding:2px 16px 8px;
    font-size:12px;color:var(--text-dim);line-height:1.5;}
  .att-why span::after{content:'·';margin-left:var(--sp-2);color:var(--border-strong);}
  .att-why span:last-of-type::after{content:none;}
  .att-why b{color:var(--text);font-variant-numeric:tabular-nums;}

  /* Curva de GS en Mi ficha. `min-width:0` en el SVG es lo que deja que encoja dentro del flex
     en pantallas estrechas — sin él, en el móvil empuja el texto fuera de la tarjeta. */
  /* LA CURVA DE GEAR SCORE (rehecha el 14 sep 2026). Sirvine: «ahora está todo comprimido y mal,
     me gustaría que se vieran los puntos de mejora, que el martes tenga un punto y el miércoles
     otro». Antes era una chispa de 34 px de alto apretada al lado de un texto, con hasta 24 puntos
     dentro y estirada sin respetar la proporción.

     Ahora ocupa su propia fila y el SVG escala PROPORCIONALMENTE (`height:auto`, sin
     `preserveAspectRatio="none"`), que es lo que impide que la curva se deforme y que los puntos
     salgan ovalados. Los colores salen de los tokens y no del JS, así que un re-skin la arrastra. */
  .gs-chart{background:var(--panel-2);border:1px solid var(--border-soft);border-radius:var(--r);
    padding:var(--sp-3) var(--sp-2) var(--sp-2);}
  .gs-chart svg{display:block;width:100%;height:auto;overflow:visible;}

  /* Verde subiendo, ámbar bajando: el mismo par semántico que usa el resto de la app. */
  .gs-chart{--gsc:var(--good);}
  .gs-chart.gs-chart-baja{--gsc:var(--warn);}

  .gs-chart .gsc-linea{stroke:var(--gsc);stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round;
    vector-effect:non-scaling-stroke;}
  .gs-chart .gsc-area{fill:url(#gsc-fill);}
  /* Los `stop` de un gradiente no heredan `color`, asi que el tono va en stop-color y la opacidad
     hace el degradado — asi el area tiñe sin tapar las lineas de referencia. */
  .gs-chart .gsc-stop-a{stop-color:var(--gsc);stop-opacity:.28;}
  .gs-chart .gsc-stop-b{stop-color:var(--gsc);stop-opacity:0;}

  .gs-chart .gsc-punto{fill:var(--panel);stroke:var(--gsc);stroke-width:2;
    vector-effect:non-scaling-stroke;}
  /* El ultimo punto es el dato de HOY: relleno solido y halo para que se encuentre de un vistazo. */
  .gs-chart .gsc-ultimo{fill:var(--gsc);filter:drop-shadow(0 0 6px var(--gsc));}

  .gs-chart .gsc-guia{stroke:var(--border-soft);stroke-width:1;vector-effect:non-scaling-stroke;}
  .gs-chart .gsc-eje{fill:var(--text-mute);font-size:13px;font-family:var(--font-mono);}
  .gs-chart .gsc-dia{fill:var(--text-dim);font-size:13px;}
  .gs-chart .gsc-delta{display:block;margin-top:var(--sp-2);text-align:right;
    color:var(--text-dim);font-size:12.5px;font-variant-numeric:tabular-nums;}

  /* En movil el SVG se encoge y el texto de dentro con el: se sube el tamaño para que los dias y
     los GS sigan leyendose. El SVG escala por viewBox, asi que esto es proporcion, no px reales. */
  @media (max-width:720px){
    .gs-chart .gsc-eje, .gs-chart .gsc-dia{font-size:17px;}
  }

  /* ---- AJUSTES (14 sep 2026) ----
     Una fila por ajuste: a la izquierda qué es y para qué sirve, a la derecha el número. Todo sale
     de la escala de espaciado y de los radios del sistema — ni un px suelto, que es justo lo que
     hace que una pantalla se vea «casi» consistente. */
  .aj-caja{background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);
    overflow:hidden;}
  .aj-fila{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-6);
    padding:var(--sp-4) var(--sp-5);border-top:1px solid var(--border-soft);}
  .aj-fila:first-child{border-top:0;}
  .aj-txt{min-width:0;}
  .aj-nombre{display:block;color:var(--text);font-weight:600;font-size:15px;}
  .aj-ayuda{margin:var(--sp-1) 0 0;color:var(--text-dim);font-size:13.5px;max-width:46ch;line-height:1.45;}

  .aj-campo{display:flex;flex-direction:column;align-items:flex-end;gap:var(--sp-1);flex:none;}
  .aj-input{display:flex;align-items:center;gap:var(--sp-2);}
  /* Ancho fijo y cifras tabulares: sin esto el campo cambia de tamaño segun el numero que tenga
     dentro y la columna de la derecha «baila» al escribir. */
  .aj-input input{width:96px;text-align:right;font-family:var(--font-mono);
    font-variant-numeric:tabular-nums;}
  .aj-unidad{color:var(--text-dim);font-size:13.5px;min-width:56px;}
  .aj-meta{color:var(--text-mute);font-size:12px;font-variant-numeric:tabular-nums;}

  .aj-acciones{display:flex;gap:var(--sp-3);margin-top:var(--sp-5);justify-content:flex-end;}
  .aj-seccion{font-family:var(--font-display);color:var(--text);font-size:22px;margin:0 0 var(--sp-2);}

  /* ---- Los clanes de la alianza ----
     Una fila por clan: color, nombre, quién es el propio y el aspa de quitar. Mismas medidas que
     las filas de ajustes de arriba para que las dos listas se lean como la misma pantalla. */
  .aj-clan{display:flex;align-items:center;gap:var(--sp-3);
    padding:var(--sp-3) var(--sp-5);border-top:1px solid var(--border-soft);}
  .aj-clan:first-child{border-top:0;}
  .aj-clan-nombre{flex:1;min-width:0;}
  /* La muestra de color es un BOTON, no un adorno: se pulsa y rota a la siguiente de la paleta.
     Un desplegable de ocho colores ocupaba mas que la fila entera. */
  .aj-color{width:26px;height:26px;flex:none;border-radius:var(--r-pill);cursor:pointer;
    border:2px solid var(--border-soft);padding:0;transition:transform .12s ease;}
  .aj-color:hover{transform:scale(1.12);}
  .aj-propio{display:flex;align-items:center;gap:var(--sp-2);color:var(--text-dim);
    font-size:13.5px;white-space:nowrap;cursor:pointer;margin:0;}
  .aj-propio input{margin:0;cursor:pointer;}
  /* Cuantos jugadores lleva cada clan. Esta aqui para que borrar no sea a ciegas. */
  .aj-clan-n{color:var(--text-mute);font-size:12px;font-variant-numeric:tabular-nums;
    min-width:60px;text-align:right;}
  .aj-clan-add{margin:var(--sp-3) 0 0;}
  /* Mientras hay cambios sin guardar, el borde de la caja avisa: esta lista NO se autoguarda. */
  .aj-caja.sucia{border-color:var(--warn);}

  @media (max-width:720px){
    .aj-clan{flex-wrap:wrap;}
    .aj-clan-nombre{flex:1 1 100%;order:1;}
    .aj-color{order:0;}
    .aj-propio{order:2;}
    .aj-clan-n{order:3;flex:1;text-align:left;}
  }

  /* En movil la fila se parte y el numero baja debajo de su explicacion, alineado a la izquierda
     como el resto: a 400 px, un campo pegado al borde derecho se lee como un error de maquetacion. */
  @media (max-width:720px){
    .aj-fila{flex-direction:column;align-items:stretch;gap:var(--sp-3);}
    .aj-campo{align-items:flex-start;}
    .aj-acciones{justify-content:stretch;}
    .aj-acciones .btn{flex:1;}
  }

  /* Los tres campos de deseos, que no se estiren cada uno a un ancho distinto. */
  .mf-wish{min-width:170px;flex:1;}

  /* La Wishlist dentro de la tabla de equidad. El nombre de la party se subraya de puntos
     para que se vea que se puede pulsar sin gritarlo: la tabla es de lectura y no debe
     parecer un formulario. */
  .wish-toggle{cursor:pointer;border-bottom:1px dotted var(--border);}
  .wish-toggle:hover{color:var(--gold-bright);border-bottom-color:var(--gold);}
  .wish-chip{cursor:pointer;margin-left:var(--sp-2);font-size:12px;color:var(--gold-bright);
    border:1px solid var(--border);border-radius:999px;padding:1px 7px;white-space:nowrap;}
  .wish-chip:hover{border-color:var(--gold);}
  .wish-row td{padding:2px 10px 12px;background:var(--panel-2);}
  .wish-row .wish-label{color:var(--text-dim);font-size:12.5px;text-transform:uppercase;
    letter-spacing:.08em;margin-right:var(--sp-2);}
  .wish-row .wb{margin:0 var(--sp-1) var(--sp-1) 0;display:inline-block;}

  /* ============================================================ TOOLTIPS (reusable) */
  [data-tooltip]{position:relative;}
  [data-tooltip]::after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%) translateY(4px);
    background:var(--panel-3);color:var(--text);border:1px solid var(--border-strong);border-radius:var(--r-sm);
    padding:var(--sp-2) var(--sp-3);font-size:12.5px;font-weight:600;letter-spacing:.02em;white-space:nowrap;pointer-events:none;
    opacity:0;transition:opacity var(--tr),transform var(--tr);box-shadow:var(--shadow-2);z-index:60;}
  [data-tooltip]::before{content:"";position:absolute;bottom:calc(100% + 3px);left:50%;transform:translateX(-50%) translateY(4px);
    border:5px solid transparent;border-top-color:var(--border-strong);opacity:0;transition:opacity var(--tr),transform var(--tr);pointer-events:none;z-index:60;}
  [data-tooltip]:hover::after,[data-tooltip]:hover::before{opacity:1;transform:translateX(-50%) translateY(0);}

  /* ============================================================ HELP / WIKI */
  .wiki-section{background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);padding:var(--sp-5) var(--sp-6);margin-bottom:var(--sp-4);box-shadow:var(--shadow-1);}
  .wiki-section h3{font-family:var(--font-display);color:var(--gold-bright);font-size:18.5px;margin:0 0 var(--sp-3) 0;}
  .wiki-section h4{color:var(--gold);font-size:15.5px;margin:var(--sp-4) 0 var(--sp-2) 0;letter-spacing:.03em;text-transform:uppercase;}
  .wiki-section h4:first-of-type{margin-top:var(--sp-1);}
  .wiki-section p, .wiki-section li{color:var(--text);font-size:16px;line-height:1.7;}
  .wiki-section ul{margin:var(--sp-2) 0;padding-left:var(--sp-5);}
  .rule-card{border-left:3px solid var(--border);background:var(--panel-2);border-radius:0 var(--r-sm) var(--r-sm) 0;padding:var(--sp-3) var(--sp-4);margin:var(--sp-3) 0;}
  .rule-card h4{margin:0 0 4px 0 !important;}
  .rule-card p{margin:0;font-size:15.5px;}
  .rule-up{border-left-color:var(--good);background:var(--good-bg);}
  .rule-up h4{color:var(--good) !important;}
  .rule-down{border-left-color:var(--bad);background:var(--bad-bg);}
  .rule-down h4{color:var(--bad) !important;}
  .rule-info{border-left-color:var(--blue);background:var(--blue-bg);}
  .rule-info h4{color:var(--blue) !important;}
  .rule-star{border-left-color:var(--accent);background:var(--accent-soft);}
  .rule-star h4{color:var(--gold-bright) !important;}
  .wb{display:inline-block;font-size:12.5px;font-weight:700;letter-spacing:.05em;padding:1px 8px;border-radius:var(--r-pill);border:1px solid;white-space:nowrap;}
  .wb-good{color:var(--good);border-color:var(--good);background:var(--good-bg);}
  .wb-bad{color:var(--bad);border-color:var(--bad);background:var(--bad-bg);}
  .wb-warn{color:var(--warn);border-color:var(--warn);background:var(--warn-bg);}
  .wb-opt{color:var(--gold-bright);border-color:var(--accent);background:var(--accent-soft);}
  .wb-neutral{color:var(--silver);border-color:var(--border);background:var(--panel);}
  /* ---- TABLERO DE COMPOSICIÓN (Partys → Composición) ----
     Reutiliza .party-card, .status-pill y las chapas .wb: lo único propio es la fila de fichas y
     el hueco vacío, que es lo que no existía en ninguna otra pantalla. */
  /* Las tarjetas van APILADAS Y SEPARADAS, y esto no es estética (18 ago 2026, lo vio Sirvine:
     «se solapan y están temblando en cuanto interactúo con ellas»):
       · sin hueco, el borde y la sombra de dos tarjetas seguidas se pisan;
       · y peor, .party-card:hover las levanta 2 px — con el puntero en el borde, la tarjeta se sale
         de debajo del ratón, deja de estar en hover, baja, vuelve a entrar... un temblor perpetuo.
     El hueco quita el solape y aleja el borde del puntero. */
  #composicion-board{display:flex;flex-direction:column;gap:var(--sp-4);}
  .cmp-resumen{color:var(--text-dim);font-size:14.5px;margin:0;}
  /* Y aquí no se pulsa nada: la tarjeta no se levanta. Un relieve que promete clic donde no hay
     ninguno es, además de mentira, la mitad del temblor de arriba. */
  #composicion-board .party-card{transition:none;}
  #composicion-board .party-card:hover{transform:none;box-shadow:var(--shadow-1),var(--hairline);}
  .cmp-slots{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:var(--sp-3) 0 var(--sp-1) 0;}
  .cmp-slot{display:inline-flex;align-items:center;gap:var(--sp-2);background:var(--panel-2);
    border:1px solid var(--border-soft);border-radius:var(--r-pill);padding:3px 10px;font-size:13.5px;
    color:var(--text-dim);max-width:100%;min-width:0;}
  .cmp-slot b{color:var(--text);font-weight:600;overflow-wrap:anywhere;min-width:0;}
  /* El hueco se ve VACÍO a propósito: de un tirón se cuenta cuánta gente falta sin leer nada. */
  .cmp-slot-libre{border-style:dashed;border-color:var(--warn);color:var(--warn);
    background:transparent;justify-content:center;min-width:38px;font-weight:700;}
  .cmp-hueco{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);padding:var(--sp-2) 0;
    border-top:1px solid var(--hairline);}
  .cmp-cand{color:var(--text-dim);font-size:13px;overflow-wrap:anywhere;min-width:0;}
  .cmp-banco{margin-top:var(--sp-5);}
  .n-up{color:var(--good);font-weight:700;}
  .n-down{color:var(--bad);font-weight:700;}

  /* ============================================================ DASHBOARD CALENDAR */
  .cal-head{display:flex;align-items:center;justify-content:center;gap:var(--sp-4);margin-bottom:var(--sp-4);}
  .cal-month{font-weight:700;font-size:16px;color:var(--text);min-width:190px;text-align:center;}
  .cal-nav{background:var(--panel-2);border:1px solid var(--border-soft);color:var(--text);width:34px;height:34px;border-radius:var(--r-sm);cursor:pointer;font-size:18px;line-height:1;transition:border-color var(--tr),color var(--tr),box-shadow var(--tr);}
  .cal-nav:hover{border-color:var(--accent);color:var(--gold-bright);box-shadow:0 0 12px rgba(166,77,255,.2);}
  .cal-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sp-1);margin-bottom:var(--sp-1);}
  .cal-weekdays>div{text-align:center;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-dim);padding:var(--sp-1) 0;}
  .cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sp-1);}
  .cal-cell{min-height:68px;border:1px solid var(--border-soft);border-radius:var(--r-sm);padding:4px 4px 3px;background:var(--panel);position:relative;overflow:hidden;transition:border-color var(--tr);}
  .cal-cell.cal-out{opacity:.35;}
  .cal-cell.cal-today{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent) inset,0 0 12px rgba(166,77,255,.18);}
  .cal-cell.cal-has{background:var(--panel-2);cursor:pointer;}
  .cal-cell.cal-has:hover{border-color:var(--accent);}
  .cal-num{font-size:12px;color:var(--text-dim);font-weight:600;}
  .cal-today .cal-num{color:var(--gold-bright);}
  .cal-ev{margin-top:3px;font-size:10.5px;line-height:1.25;color:var(--text);background:var(--good-bg);border-left:2px solid var(--good);border-radius:3px;padding:2px 4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  .cal-ev-event{background:rgba(80,200,170,.12);border-left-color:#57c4a4;color:#9fe6cd;cursor:pointer;}
  .cal-ev-event .cal-ev-title{text-decoration:underline dotted rgba(255,255,255,.4);text-underline-offset:2px;}
  .cal-ev-event:hover{border-left-color:#7fe3c4;box-shadow:0 0 6px rgba(0,0,0,.2);}
  .cal-ev-event:hover .cal-ev-title{text-decoration:underline solid;color:#fff;}
  .dash-event{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;padding:var(--sp-2) var(--sp-3);border-radius:var(--r-sm);border:1px solid var(--border-soft);background:var(--panel);margin-bottom:var(--sp-2);cursor:pointer;transition:border-color var(--tr);}
  .dash-event:hover{border-color:var(--accent);}
  .dash-ev-dot{width:10px;height:10px;border-radius:999px;flex-shrink:0;}
  .dash-ev-dot.ev-teal{background:#57c4a4;}
  .dash-ev-dot.ev-blue{background:#5a96ff;}
  .dash-ev-dot.ev-orange{background:#ffa046;}
  .dash-ev-dot.ev-pink{background:#ff6ea0;}
  .dash-ev-title{font-weight:600;color:var(--text);flex:1;min-width:120px;}
  .dash-ev-when{color:var(--text-dim);font-size:13px;}
  .dash-ev-count{color:var(--text-dim);font-size:13px;white-space:nowrap;}
  .cal-ev-time{color:var(--gold-bright);font-weight:600;}

  /* ============================================================ RESPONSIVE */
  @media (max-width:820px){
    .app{flex-direction:column;}
    .sidebar{width:auto;height:auto;position:static;flex-direction:row;flex-wrap:wrap;align-items:center;
      gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);border-right:none;border-bottom:1px solid var(--border-soft);box-shadow:none;overflow:visible;}
    .sigil{flex:1 1 auto;padding:0;margin:0;}
    .sigil::after{display:none;}
    .sidebar-logo{max-width:150px;}
    /* En móvil la barra es una cabecera: el Discord se queda en esa fila, entre el logo y el
       ☰, y NO se esconde con el menú (ese era el problema: había que desplegar para verlo).
       A 390 px caben los tres: logo 150 + Discord ~112 + ☰ 44 + huecos. */
    .discord-cta{flex:0 0 auto;margin:0;padding:var(--sp-2) var(--sp-3);font-size:12.5px;letter-spacing:.1em;}
    .discord-cta svg{width:18px;height:18px;}
    /* Con el banner hay que FIJAR el ancho: aquí la barra es una fila y el enlace mide lo que
       mida su contenido, así que una imagen de 800 px de ancho natural reventaría la cabecera. */
    .discord-cta.con-logo{width:124px;}
    /* El de Información sí ocupa el ancho, pero a 18px con interletrado se partía en tres
       renglones en un móvil de 390. Aquí el texto manda sobre el efecto. */
    .discord-cta.wide{width:100%;margin:var(--sp-2) 0 var(--sp-1);padding:var(--sp-3) var(--sp-3);font-size:14px;letter-spacing:.08em;}
    .discord-cta.wide svg{width:22px;height:22px;}
    .nav-toggle{display:flex;align-items:center;justify-content:center;flex:0 0 auto;width:44px;height:44px;
      font-size:24px;line-height:1;background:var(--panel-2);border:1px solid var(--border);border-radius:var(--r-sm);
      color:var(--gold-bright);cursor:pointer;transition:border-color var(--tr),box-shadow var(--tr);}
    .nav-toggle:hover{border-color:var(--accent);box-shadow:0 0 12px rgba(166,77,255,.2);}
    .nav-item{flex-basis:100%;font-size:16px;padding:var(--sp-3) var(--sp-3);display:none;}
    .sidebar.nav-open .nav-item:not([hidden]){display:flex;}
    /* Los rótulos de grupo viajan con el menú: escondidos hasta desplegar el ☰. */
    .nav-group{display:none;flex-basis:100%;margin:var(--sp-3) 0 0;}
    .sidebar.nav-open .nav-group:not([hidden]){display:block;}
    .sidebar-foot{flex-basis:100%;margin-top:var(--sp-1);padding-top:var(--sp-3);flex-direction:row;flex-wrap:wrap;
      align-items:center;justify-content:space-between;gap:var(--sp-2) var(--sp-4);display:none;}
    .sidebar.nav-open .sidebar-foot{display:flex;}
    .user-badge{flex-direction:row;align-items:baseline;gap:var(--sp-2);}
    .main{padding:var(--sp-5) var(--sp-4);max-width:100%;}
    .page-title{font-size:22px;}
    .page-eyebrow{font-size:12.5px;}
    .stat-grid{grid-template-columns:1fr 1fr;}
    .party-grid,.attendance-grid{grid-template-columns:1fr;}
    .form-row .field,.toolbar-row .field,.cta-picker .field{flex:1 1 100%;min-width:0;}
    .form-row input,.form-row select,.toolbar-row input,.toolbar-row select{width:100%;}
    #roster-table-wrap{overflow-x:visible;}
    #roster-table-wrap table{display:block;min-width:0;border:none;background:none;box-shadow:none;}
    #roster-table-wrap thead{display:none;}
    .roster-sortbar{display:flex;}
    #roster-table-wrap tbody{display:block;}
    #roster-table-wrap tbody tr{display:block;background:var(--panel);border:1px solid var(--border-soft);
      border-radius:var(--r);margin-bottom:var(--sp-3);overflow:hidden;box-shadow:var(--shadow-1);}
    #roster-table-wrap tbody tr.mine-row{box-shadow:inset 3px 0 0 var(--accent);}
    #roster-table-wrap td{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);text-align:right;
      padding:var(--sp-2) var(--sp-4);border-bottom:1px solid var(--border-soft);}
    #roster-table-wrap td:last-child{border-bottom:none;}
    #roster-table-wrap td[data-label]::before{content:attr(data-label);color:var(--text-dim);font-size:11.5px;
      letter-spacing:.08em;text-transform:uppercase;font-weight:700;text-align:left;flex-shrink:0;}
    #roster-table-wrap td.roster-nick{background:var(--panel-2);justify-content:flex-start;flex-wrap:wrap;gap:var(--sp-2);
      font-size:18px;font-weight:700;color:var(--gold-bright);}
    #roster-table-wrap td.roster-actions{justify-content:flex-end;gap:var(--sp-3);}
    #roster-table-wrap td.roster-actions .icon-btn{font-size:20px;padding:var(--sp-2) var(--sp-3);}
    #roster-table-wrap td.roster-history{display:block;text-align:left;}
    #roster-table-wrap .icon-btn{margin-right:0 !important;}
    .history-row{grid-template-columns:1fr !important;row-gap:var(--sp-2);}
    .cta-select{min-width:0;}
    .overlay{padding:var(--sp-4);}
    .overlay-box{padding:var(--sp-6);}
  }
  @media(max-width:640px){
    .cal-cell{min-height:52px;}
    .cal-ev{font-size:9px;padding:1px 3px;}
    .cal-num{font-size:11px;}
    .cal-month{min-width:140px;font-size:15px;}
  }
