  /* ============================================================
     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).
     ============================================================ */
  :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);

    /* ---- Clanes de la alianza ---- */
    --clan-adrenaline:var(--gold-bright); --clan-404:#ff8a80; --clan-latingamer:#7fe3c4;

    /* ---- 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"] .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:22px 16px;display:flex;flex-direction:column;gap:6px;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:14px;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:14px 0 4px;padding:0 12px;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:9px;margin:-4px 0 16px;padding:10px 12px;
    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:6px 0 4px;padding:15px 14px;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:10px;padding:11px 12px;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:14px;border-top:1px solid var(--border-soft);font-size:12.5px;color:var(--text-dim);display:flex;flex-direction:column;gap:10px;}
  .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:6px;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:6px;}
  .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:6px;flex-wrap:wrap;margin:0 0 26px 0;padding:6px;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:10px 20px;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:9px 15px;font-size:15px;letter-spacing:.04em;}
  }
  .page-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:10px;}
  .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 4px 0;}
  .page-head::after{content:"";flex:0 0 100%;height:26px;margin-top:14px;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:8px;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:9px 17px;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:5px 11px;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:14px;margin-bottom:28px;}
  .stat-card{background:linear-gradient(160deg,var(--panel),var(--bg-2));border:1px solid var(--border-soft);border-radius:var(--r);padding:16px 18px;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 12px 0;padding-bottom:8px;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:11px 14px;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:6px;margin-bottom:12px;}
  .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:4px 10px;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:5px 0;border-bottom:1px solid var(--border-soft);}
  .hist-cta-row:last-child{border-bottom:none;}
  tbody td{padding:11px 14px;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:6px;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:6px;letter-spacing:.05em;}

  /* ============================================================ FORMS / INPUTS */
  .form-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;background:var(--panel);border:1px solid var(--border-soft);border-radius:var(--r);padding:16px;margin-bottom:18px;box-shadow:var(--shadow-1);}
  .toolbar-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;margin-bottom:16px;}
  .field{display:flex;flex-direction:column;gap:5px;}
  .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:8px;}
  .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:9px 11px;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:30px;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:30px;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:16px;}
  .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:12px 16px;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:12px 16px;margin:0 0 14px;}
  .srv-bloque{margin:0 0 10px;}
  .srv-bloque:last-of-type{margin-bottom:4px;}
  .srv-bloque h4{margin:0 0 6px;font-size:13px;letter-spacing:.05em;text-transform:uppercase;color:var(--text-dim);}
  .srv-chips{display:flex;flex-wrap:wrap;gap:6px;}
  .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:8px 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:16px;}
  .srv-meta{border-top:1px solid var(--border-soft);padding-top:8px;}
  .srv-ok{margin:0 0 4px;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:9px 14px;margin:0 0 14px;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:8px 16px;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:6px;}
  .pm-gs{font-family:'JetBrains Mono',monospace;color:var(--gold-bright);font-size:14.5px;}
  .pm-stats{display:flex;gap:10px;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:10px 16px;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:8px 16px;font-size:14.5px;color:var(--text-dim);font-style:italic;}
  .party-card-actions{padding:10px 16px;border-top:1px solid var(--border-soft);display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
  .party-leader-row{padding:8px 16px;border-top:1px solid var(--border-soft);font-size:14px;color:var(--text-dim);display:flex;align-items:center;gap:8px;}
  .request-row{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;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:6px;margin:0 0 16px;}
  .cal-dow{text-align:center;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-dim);padding:4px 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:6px;display:flex;flex-direction:column;gap:4px;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:4px;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:8px;padding:9px 12px;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:5px;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:4px;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:4px;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:6px;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:10px;align-items:center;margin-bottom:20px;flex-wrap:wrap;}
  .cta-select{min-width:260px;}
  .attendance-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px;margin-bottom:26px;}
  .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:10px 14px;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:10px;padding:8px 14px;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:6px;border:1px solid var(--bad);border-radius:var(--r-pill);padding:0 7px;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:16px;padding:14px 16px;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:6px;}
  .hbar-line{display:flex;align-items:center;gap:8px;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:14px;padding:12px 16px;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:12px 20px;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:14px;background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--accent);color:var(--text);padding:11px 16px;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:6px 22px;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:24px;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:34px;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:26px;padding-top:22px;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:18px 0 6px;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 4px;color:var(--text-dim);font-size:15px;line-height:1.55;text-align:center;}
  .pitch-sub b{color:var(--text);}
  .pitch-h{margin:22px 0 8px;font-size:16px;color:var(--gold-bright);letter-spacing:.01em;}
  .pitch-list{margin:0;padding-left:20px;}
  .pitch-list li{margin:0 0 8px;color:var(--text-dim);font-size:14.5px;line-height:1.5;}
  .pitch-list li b{color:var(--text);}
  .pitch-num{padding-left:22px;}
  /* 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:20px;}
  .pitch-discord .discord-cta{margin:0;width:100%;max-width:340px;}
  .pitch-legal{margin:20px 0 0;padding-top:14px;border-top:1px solid var(--border-soft);
    text-align:center;color:var(--text-mute);font-size:11.5px;line-height:1.5;}

  /* --- 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:12px 14px;margin:14px 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:16px 18px;background:var(--panel-2);text-align:left;margin-top:6px;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:22px;} .rules-list li{margin:0 0 12px;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:6px;font-weight:700;}
  .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:24px 0 8px;padding-bottom:6px;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:16px 0 4px;}
  .rules-scroll p{margin:0 0 9px;color:var(--text);}
  .rules-scroll ul{margin:4px 0 10px;padding-left:20px;} .rules-scroll ul li{margin:0 0 5px;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:14px 0 6px;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:9px 11px;
    border:1px solid var(--border);}
  .rules-table td{padding:9px 11px;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:10px;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:18px 0 6px;padding:14px 16px;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:10px;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:12px 0 4px;transition:opacity var(--tr);}
  .rules-scroll-hint.done{opacity:.3;}
  .rules-agree{display:flex;align-items:flex-start;gap:10px;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:12px;align-items:center;justify-content:space-between;flex-wrap:wrap;margin-top:16px;}
  .btn[disabled]{opacity:.45;cursor:not-allowed;filter:grayscale(.4);box-shadow:none;}
  .rules-status{border-radius:var(--r-sm);padding:12px 14px;margin-bottom:16px;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 10px;color:var(--text);}
  .aviso-body ul{margin:6px 0 12px;padding-left:20px;}
  .aviso-body li{margin:0 0 7px;color:var(--text-dim);}
  .aviso-body li b{color:var(--gold-bright);}
  .google-btn{display:inline-flex;align-items:center;gap:10px;background:#fff;color:#1a1a2e;border:none;padding:11px 22px;border-radius:var(--r-sm);font-family:var(--font-body);font-weight:700;font-size:17px;cursor:pointer;margin-top:10px;transition:filter var(--tr),transform var(--tr);}
  .google-btn:hover{filter:brightness(.96);transform:translateY(-1px);}
  .lang-options{display:flex;gap:12px;justify-content:center;margin-top:18px;flex-wrap:wrap;}
  .lang-option{background:var(--panel-2);border:1px solid var(--border);color:var(--text);padding:14px 22px;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:10px;padding:12px 14px;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:12px;flex-wrap:wrap;margin:0 0 18px;padding:11px 15px;
    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:12px;flex-wrap:wrap;margin:0 0 18px;padding:11px 15px;
    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:7px;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. */
  .gs-spark{display:flex;align-items:center;gap:12px;}
  .gs-spark svg{flex:1;min-width:0;height:34px;}
  .gs-spark span{color:var(--text-dim);font-size:12.5px;white-space:nowrap;font-variant-numeric:tabular-nums;}

  /* 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:6px;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:8px;}
  .wish-row .wb{margin:0 4px 4px 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:6px 10px;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:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-1);}
  .wiki-section h3{font-family:var(--font-display);color:var(--gold-bright);font-size:18.5px;margin:0 0 10px 0;}
  .wiki-section h4{color:var(--gold);font-size:15.5px;margin:16px 0 6px 0;letter-spacing:.03em;text-transform:uppercase;}
  .wiki-section h4:first-of-type{margin-top:4px;}
  .wiki-section p, .wiki-section li{color:var(--text);font-size:16px;line-height:1.7;}
  .wiki-section ul{margin:6px 0;padding-left:20px;}
  .rule-card{border-left:3px solid var(--border);background:var(--panel-2);border-radius:0 var(--r-sm) var(--r-sm) 0;padding:10px 16px;margin:12px 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:16px;}
  .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:6px;margin:10px 0 4px 0;}
  .cmp-slot{display:inline-flex;align-items:center;gap:6px;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:8px;padding:6px 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:18px;}
  .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:16px;margin-bottom:14px;}
  .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:4px;margin-bottom:4px;}
  .cal-weekdays>div{text-align:center;font-size:11px;text-transform:uppercase;letter-spacing:.5px;color:var(--text-dim);padding:4px 0;}
  .cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;}
  .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:10px;flex-wrap:wrap;padding:8px 10px;border-radius:var(--r-sm);border:1px solid var(--border-soft);background:var(--panel);margin-bottom:6px;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:8px;padding:12px 14px;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:9px 11px;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:6px 0 4px;padding:13px 12px;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:12px 12px;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:10px 0 0;}
    .sidebar.nav-open .nav-group:not([hidden]){display:block;}
    .sidebar-foot{flex-basis:100%;margin-top:4px;padding-top:12px;flex-direction:row;flex-wrap:wrap;
      align-items:center;justify-content:space-between;gap:8px 16px;display:none;}
    .sidebar.nav-open .sidebar-foot{display:flex;}
    .user-badge{flex-direction:row;align-items:baseline;gap:6px;}
    .main{padding:18px 14px;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:12px;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:12px;text-align:right;
      padding:9px 14px;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:6px;
      font-size:18px;font-weight:700;color:var(--gold-bright);}
    #roster-table-wrap td.roster-actions{justify-content:flex-end;gap:10px;}
    #roster-table-wrap td.roster-actions .icon-btn{font-size:20px;padding:6px 10px;}
    #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:8px;}
    .cta-select{min-width:0;}
    .overlay{padding:16px;}
    .overlay-box{padding:22px;}
  }
  @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;}
  }
