/* ============================================================================
   VELDAROZ · LAUNCHER — diseño
   ----------------------------------------------------------------------------
   Azul noche con oro. Arriba las secciones, en medio la sección elegida y
   abajo una barra fija con estado, progreso y JUGAR.

   CÓMO SE ADAPTA (leer esto antes de tocar medidas)
   -------------------------------------------------
   No hay dos diseños (uno para la app y otro para el navegador): hay UNO solo
   que se aprieta o se ensancha cambiando unas pocas variables de densidad.

     · DENSIDAD HOLGADA   navegador grande, pantalla alta
     · DENSIDAD COMPACTA  ventana de Windows (1080×660) y cualquier ventana
                          baja (alto ≤ 760) o estrecha (ancho ≤ 1150)
     · CELULAR            ancho ≤ 860: una columna y la página hace scroll

   La densidad solo redefine variables (--pad, --gap, --top-h, --fs-root…).
   Los componentes leen esas variables, así que NO hay que repetir cada regla
   para cada tamaño. Si algo se sale, casi siempre se arregla en el bloque de
   variables, no en el componente.

   CUENTAS DE LA VENTANA DE WINDOWS (1080×660 de área de contenido)
   ----------------------------------------------------------------
     660 de alto
     −  32  barra de la ventana (.appbar)
     −  46  barra de secciones (.top)
     −  66  barra de abajo (.dock)
     −  26  aire del contenido (--pad × 2)
     = 490  le quedan al contenido
   Por eso Inicio y Personajes entran enteros sin scroll a ese tamaño.
   Si algún día la ventana se hace redimensionable (main.js → resizable:true),
   este diseño ya aguanta: de ~900px para arriba se ve igual y por debajo
   entran las reglas de celular.

   RECURSOS (este launcher tiene que pesar poco)
   ---------------------------------------------
     · Nada de backdrop-filter: obliga a la tarjeta gráfica a desenfocar el
       fondo en cada cuadro. Se usan fondos sólidos con transparencia.
     · Las animaciones solo mueven opacidad y transform (las dos cosas que el
       navegador resuelve sin volver a dibujar). Ninguna es infinita.
     · El carrusel solo funde una imagen con otra: no hay zoom lento constante.
     · contain / content-visibility para que el navegador no recalcule lo que
       no se ve.

   QUÉ NO SE PUEDE ROMPER
   ----------------------
   Los nombres de clase que enciende y apaga el JavaScript: hidden, on,
   loading, open, active, msg, hint, y todas las que se generan dentro de
   launcher.js (avatar, char-card, person, eq, card, notif, tag…). Se puede
   cambiar CÓMO SE VEN, nunca cómo se llaman.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. VARIABLES
   --------------------------------------------------------------------------- */
:root {
  /* Fondos y superficies */
  --bg: #070a12; --bg2: #0c1120;
  --card: rgba(18, 23, 38, .88); --card2: rgba(24, 30, 50, .92);
  --sunken: rgba(0, 0, 0, .26);
  --line: rgba(255, 255, 255, .07); --line2: rgba(255, 255, 255, .14); --line3: rgba(255, 255, 255, .22);

  /* Texto */
  --text: #eef1f7; --soft: #c3c9d6; --muted: #848da1;

  /* Acentos */
  --gold: #e8c170; --gold2: #f7dda2; --gold3: #c39142; --teal: #54d6c9; --danger: #f47c72;
  --gold-soft: rgba(232, 193, 112, .14); --gold-line: rgba(232, 193, 112, .28);

  /* Estados de presencia */
  --online: #4ade80; --away: #facc15; --busy: #f87171; --offline: #6b7280; --playing: #54d6c9;

  /* Rarezas del equipo */
  --r-common: #c7ccd6; --r-uncommon: #63d86a; --r-rare: #4f9cff; --r-epic: #b36bff;
  --r-legendary: #ff9c3c; --r-mythic: #ff5e6c; --r-unique: #ffd45e; --r-set: #54d6c9;

  /* Tipografía. Una sola familia variable por rol: un archivo en vez de tres. */
  --font-title: 'Cinzel', Georgia, 'Times New Roman', serif;
  --font: 'Nunito Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Sombras: radios cortos, que las grandes cuestan relleno de pantalla */
  --sh1: 0 1px 2px rgba(0, 0, 0, .35);
  --sh2: 0 6px 18px rgba(0, 0, 0, .4);
  --sh3: 0 18px 44px rgba(0, 0, 0, .55);
  --glow: 0 0 0 1px var(--gold-line), 0 8px 24px rgba(232, 193, 112, .18);

  /* Movimiento */
  --t: .15s cubic-bezier(.4, 0, .2, 1);
  --t-slow: .28s cubic-bezier(.4, 0, .2, 1);

  /* --- DENSIDAD HOLGADA (por defecto) --- */
  --fs-root: 15px;      /* manda sobre todos los rem: al cambiarlo escala la interfaz entera */
  --pad: 18px;          /* aire exterior del contenido y de la barra de arriba/abajo */
  --gap: 14px;          /* separación entre bloques hermanos */
  --pad-card: 18px;     /* relleno dentro de los paneles */
  --radius: 14px; --radius-sm: 10px; --radius-xs: 8px;
  --top-h: 58px;        /* alto de la barra de secciones */
  --bar: 0px;           /* alto de la barra de la ventana: 0 fuera de la app */
  --avatar: 52px;
  --play-h: 54px; --play-w: 192px;
  --col-chars: 250px;   /* columna de la lista de personajes */
  --col-portrait: 200px;

  color-scheme: dark;
  accent-color: var(--gold);
}

/* --- DENSIDAD COMPACTA ---
   Entra sola cuando la ventana es baja o estrecha, y siempre dentro del
   programa de Windows (html.frameless), que mide 1080×660 fijos. */
@media (max-height: 760px), (max-width: 1150px) {
  :root {
    --fs-root: 13.5px;
    --pad: 13px; --gap: 10px; --pad-card: 14px;
    --radius: 11px; --radius-sm: 9px; --radius-xs: 7px;
    --top-h: 46px;
    --avatar: 44px;
    --play-h: 46px; --play-w: 152px;
    --col-chars: 228px;
    --col-portrait: 168px;
  }
}
html.frameless {
  --fs-root: 13.5px;
  --pad: 13px; --gap: 10px; --pad-card: 14px;
  --radius: 11px; --radius-sm: 9px; --radius-xs: 7px;
  --top-h: 46px;
  --bar: 32px;
  --avatar: 44px;
  --play-h: 46px; --play-w: 152px;
  --col-chars: 228px;
  --col-portrait: 168px;
}

/* ---------------------------------------------------------------------------
   2. BASE
   --------------------------------------------------------------------------- */
* { box-sizing: border-box; }
* { min-width: 0; }                                    /* ninguna rejilla desborda por culpa de un texto largo */

html {
  font-size: var(--fs-root);
  background: var(--bg);
  color-scheme: dark;
}
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font: 400 1rem/1.5 var(--font);
  overflow: hidden;                                    /* la ventana no hace scroll: lo hace .main */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--gold); text-decoration: none; transition: color var(--t); }
a:hover { color: var(--gold2); }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0; text-wrap: balance; }
p { text-wrap: pretty; }

svg { width: 1.45rem; height: 1.45rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; flex: none; }

.hidden { display: none !important; }
.muted { color: var(--muted); }

::selection { background: rgba(232, 193, 112, .28); color: #fff; }

/* Foco visible solo con teclado: el ratón no lo dispara. Sin esto la interfaz
   parece barata cuando alguien navega con Tab. */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 4px; }

/* Barras de scroll finas en toda la aplicación, no solo dentro del programa */
* { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .16) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .13); border-radius: 9px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .26); background-clip: content-box; }

/* ---------------------------------------------------------------------------
   3. CONTROLES
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
  padding: .62em 1.15em; border-radius: var(--radius-sm);
  border: 1px solid var(--line2); background: rgba(255, 255, 255, .045);
  cursor: pointer; font-weight: 700; letter-spacing: .01em; white-space: nowrap;
  transition: background var(--t), border-color var(--t), color var(--t), transform .08s, box-shadow var(--t), filter var(--t);
}
.btn:hover { background: rgba(255, 255, 255, .09); border-color: var(--line3); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: default; transform: none; }
.btn:disabled:hover { background: rgba(255, 255, 255, .045); border-color: var(--line2); }

.btn.primary {
  background: linear-gradient(180deg, #f8daa0, #d9a459 55%, #c8913f);
  color: #1b1307; border-color: transparent; box-shadow: var(--sh1), inset 0 1px 0 rgba(255, 255, 255, .5);
}
.btn.primary:hover { filter: brightness(1.07); border-color: transparent; }
.btn.ghost { background: transparent; }
.btn.ghost:hover { background: rgba(255, 255, 255, .06); }
.btn.small { padding: .4em .8em; font-size: .82rem; border-radius: var(--radius-xs); }
.btn.full { width: 100%; }
.btn.danger { color: var(--danger); border-color: rgba(244, 124, 114, .34); }
.btn.danger:hover { background: rgba(244, 124, 114, .14); border-color: rgba(244, 124, 114, .6); }

input:not([type=checkbox]):not([type=range]), select, textarea {
  width: 100%; padding: .62em .8em; border-radius: var(--radius-sm);
  border: 1px solid var(--line2); background: var(--sunken);
  transition: border-color var(--t), box-shadow var(--t), background var(--t);
}
input:hover:not([type=checkbox]):not([type=range]), select:hover { border-color: var(--line3); }
input:focus, select:focus, textarea:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(232, 193, 112, .15); background: rgba(0, 0, 0, .34); }
input::placeholder { color: var(--muted); }
select { cursor: pointer; }
select option { background: #121828; color: var(--text); }
input[type=range] { width: 100%; height: 1.4em; accent-color: var(--gold); cursor: pointer; }

.check { display: flex; align-items: center; gap: .6em; color: var(--muted); font-size: .9rem; cursor: pointer; transition: color var(--t); }
.check:hover { color: var(--soft); }
.check input { accent-color: var(--gold); width: 1.05em; height: 1.05em; cursor: pointer; }

/* ---------- Desplegable propio ----------
   El <select> de verdad sigue ahí debajo, tapado, para que la lógica no cambie
   (ver vestirSelect en launcher.js). Lo que se ve es este botón con su lista,
   con los colores y la tipografía del launcher en vez de la caja gris de
   Windows. La lista solo existe mientras está abierta. */
.sel { position: relative; }
.sel > select { position: absolute; inset: 0; width: 100%; opacity: 0; pointer-events: none; }
.sel-btn {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem; width: 100%;
  padding: .55em .75em; border-radius: var(--radius-sm); border: 1px solid var(--line2);
  background: var(--sunken); cursor: pointer; font: inherit; font-weight: 700; text-align: left; color: var(--text);
  transition: border-color var(--t), background var(--t);
}
.sel-btn:hover { border-color: var(--line3); background: rgba(0, 0, 0, .34); }
.sel-btn > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sel-btn svg { width: 1.05rem; height: 1.05rem; color: var(--muted); transition: transform var(--t); }
.sel-btn:disabled { opacity: .5; cursor: default; }
.sel.open .sel-btn { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(232, 193, 112, .15); }
.sel.open .sel-btn svg { transform: rotate(180deg); color: var(--gold2); }
.sel-menu {
  display: none; position: absolute; left: 0; right: 0; top: calc(100% + 5px); z-index: 25;
  max-height: 14rem; overflow: auto; padding: .25rem;
  border-radius: var(--radius-sm); background: #101628; border: 1px solid var(--line2); box-shadow: var(--sh3);
}
.sel.open .sel-menu { display: block; }
.sel-menu button {
  display: block; width: 100%; padding: .42em .6em; border: 0; border-radius: var(--radius-xs);
  background: none; color: var(--soft); cursor: pointer; text-align: left; font: inherit; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sel-menu button:hover { background: rgba(255, 255, 255, .07); color: var(--text); }
.sel-menu button.on { background: var(--gold-soft); color: var(--gold2); font-weight: 800; }

.otp { text-align: center; font-size: 1.55rem !important; font-weight: 800; letter-spacing: .5em; padding-left: .5em !important; font-variant-numeric: tabular-nums; }
.msg { min-height: 1.2em; margin: 0; color: var(--danger); font-size: .88rem; }
.msg.ok { color: var(--online); }
.hint { margin: 0; color: var(--muted); font-size: .88rem; }
.links { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; font-size: .88rem; }

.icon-btn {
  position: relative; width: 2.5rem; height: 2.5rem; display: grid; place-items: center;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
  cursor: pointer; color: var(--soft); transition: background var(--t), color var(--t), border-color var(--t);
}
.icon-btn:hover { background: rgba(255, 255, 255, .09); color: #fff; border-color: var(--line2); }
.icon-btn svg { width: 1.25rem; height: 1.25rem; }

.badge {
  position: absolute; top: -5px; right: -5px; min-width: 1.15rem; height: 1.15rem; padding: 0 .3em;
  border-radius: 999px; background: #e5484d; color: #fff;
  font: 800 .68rem/1.15rem var(--font); font-style: normal; text-align: center;
  box-shadow: 0 0 0 2px var(--bg);
}

.dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%; background: var(--offline); flex: none; }
.dot.offline { background: var(--offline); box-shadow: none; }
.dot.online { background: var(--online); box-shadow: 0 0 7px rgba(74, 222, 128, .65); }
.dot.playing { background: var(--playing); box-shadow: 0 0 7px rgba(84, 214, 201, .75); }
.dot.away { background: var(--away); }
.dot.busy { background: var(--busy); }

/* Etiquetas de color (novedades del inicio) */
.tag { font-style: normal; }
.tag.news { background: rgba(84, 150, 255, .14); color: #9cc3ff; }
.tag.patch { background: var(--gold-soft); color: var(--gold2); }
.tag.event { background: rgba(84, 214, 201, .14); color: var(--teal); }
.tag.soon { background: rgba(179, 107, 255, .16); color: #d2b2ff; }
.tag.warn { background: rgba(250, 204, 21, .14); color: #fde68a; }

/* ---------------------------------------------------------------------------
   4. PORTADA DE CARGA Y PANTALLA DE CUENTA
   --------------------------------------------------------------------------- */
.boot {
  position: fixed; inset: var(--bar) 0 0; z-index: 50;
  display: grid; place-content: center; gap: 1.4rem;
  background: radial-gradient(ellipse at 50% 38%, #18203a, var(--bg) 72%);
  transition: opacity var(--t-slow), visibility var(--t-slow);
}
.app:not(.loading) .boot { opacity: 0; visibility: hidden; pointer-events: none; }

.brand-big {
  font: 800 2.6rem/1 var(--font-title); letter-spacing: .2em; text-align: center;
  background: linear-gradient(180deg, #fff6e2, var(--gold) 60%, var(--gold3));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.spinner {
  width: 2.2rem; height: 2.2rem; margin: auto; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .1); border-top-color: var(--gold);
  animation: spin .85s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.auth {
  position: fixed; inset: var(--bar) 0 0; z-index: 45;
  display: grid; place-items: center; padding: 1.4rem; overflow: auto;
  background: linear-gradient(rgba(7, 10, 18, .5), rgba(7, 10, 18, .92)), url('/launcher/arte-1.jpg') center / cover no-repeat, var(--bg);
}
.auth-card {
  width: min(26rem, 100%); padding: 2rem 1.9rem; border-radius: 18px;
  background: rgba(13, 17, 30, .94); border: 1px solid var(--line2);
  box-shadow: var(--sh3), inset 0 1px 0 rgba(255, 255, 255, .06);
}
.auth-sub { text-align: center; color: var(--muted); letter-spacing: .3em; text-transform: uppercase; font-size: .72rem; margin: .45rem 0 1.4rem; }
.auth form { display: flex; flex-direction: column; gap: .75rem; }
.auth h2 { font: 700 1.15rem var(--font-title); color: var(--gold2); text-align: center; letter-spacing: .04em; }

/* ---------- Aceptar la política de privacidad y las condiciones (28/09/2026) ----------
   Al crear la cuenta: un botón que abre el texto y la casilla, que sigue apagada hasta
   haberlo leído entero. El texto de la casilla va en un <span>: .check es flex, y suelto
   cada <b> contaría como una columna y la frase saldría partida en trocitos. */
.legal-bloque { display: flex; flex-direction: column; gap: .55rem; padding: .75rem .8rem; border-radius: var(--radius-sm); background: var(--sunken); border: 1px solid var(--line); }
.legal-abrir { width: 100%; font-size: .86rem; }
.legal-check { align-items: flex-start; line-height: 1.45; font-size: .86rem; }
.legal-check input { margin-top: .15em; flex: none; }
.legal-check > span { flex: 1; min-width: 0; }
.legal-check b { color: var(--soft); }
.legal-check:has(input:disabled) { opacity: .55; cursor: default; }
.legal-check:has(input:disabled):hover { color: var(--muted); }
.legal-check input:disabled { cursor: default; }

/* Lector: por encima de la pantalla de cuenta (z 45) y por debajo de los avisos (z 60) */
.legal-lector { position: fixed; inset: var(--bar) 0 0; z-index: 50; display: grid; place-items: center; padding: 1.4rem; background: rgba(3, 5, 10, .8); }
.legal-caja {
  display: flex; flex-direction: column; width: min(46rem, 100%); max-height: min(86vh, 48rem); overflow: hidden;
  border-radius: 18px; background: #0f1526; border: 1px solid var(--line2); box-shadow: var(--sh3);
}
.legal-caja > header { display: flex; align-items: baseline; justify-content: space-between; gap: .8rem; padding: 1.1rem 1.4rem .8rem; border-bottom: 1px solid var(--line); }
.legal-caja > header h2 { font: 700 1.1rem var(--font-title); color: var(--gold2); letter-spacing: .03em; }
.legal-caja > header span { color: var(--muted); font-size: .78rem; white-space: nowrap; }
.legal-scroll { position: relative; flex: 1; min-height: 0; display: flex; }
.legal-cuerpo { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: .3rem 1.4rem 1.2rem; line-height: 1.6; font-size: .9rem; color: var(--soft); }
.legal-cuerpo:focus-visible { outline: 2px solid var(--gold-line); outline-offset: -2px; }
.legal-cuerpo h2 { margin: 1.1rem 0 .25rem; font: 700 1.08rem var(--font-title); color: var(--text); }
.legal-cuerpo h3 { margin: 1.25rem 0 .35rem; font-size: .96rem; color: var(--gold); }
.legal-cuerpo p { margin: .45rem 0; }
.legal-cuerpo .fecha { margin: 0 0 .8rem; color: var(--muted); font-size: .8rem; }
.legal-cuerpo b, .legal-cuerpo strong { color: var(--text); }
.legal-cuerpo dt { margin-top: .75rem; font-weight: 800; color: var(--text); }
.legal-cuerpo dd { margin: .2rem 0 0; }
.legal-cuerpo ul { margin: .4rem 0; padding-left: 1.25rem; }
.legal-cuerpo li { margin: .3rem 0; }
.legal-cuerpo a { color: var(--gold); }
.legal-cuerpo hr { margin: 1.8rem 0 .5rem; border: 0; border-top: 1px solid var(--gold-line); }
.legal-cuerpo .legal-cargando { padding: 1.5rem 0; text-align: center; color: var(--muted); }
/* Botón redondo con la flecha: baja una pantalla de golpe. Se esconde al llegar al final. */
.legal-baja {
  position: absolute; right: 1rem; bottom: .9rem; z-index: 2; display: grid; place-items: center;
  width: 2.8rem; height: 2.8rem; padding: 0; border-radius: 50%; cursor: pointer;
  color: #1c1406; background: linear-gradient(180deg, var(--gold2), var(--gold)); border: 0;
  box-shadow: var(--sh2); transition: transform var(--t);
}
.legal-baja svg { width: 1.3rem; height: 1.3rem; stroke-width: 2.4; }
.legal-baja:hover { transform: translateY(2px); }
.legal-baja:active { transform: translateY(3px) scale(.94); }
.legal-caja > footer { display: flex; align-items: center; justify-content: space-between; gap: .8rem; padding: .8rem 1.4rem 1rem; border-top: 1px solid var(--line); }
.legal-aviso { color: var(--muted); font-size: .82rem; }
.legal-aviso.ok { color: var(--teal); }
.legal-botones { display: flex; gap: .6rem; }
@media (max-width: 560px) {
  .legal-lector { padding: .6rem; }
  .legal-caja { max-height: 94vh; }
  .legal-caja > header, .legal-cuerpo, .legal-caja > footer { padding-left: 1rem; padding-right: 1rem; }
  .legal-caja > header { flex-direction: column; gap: .2rem; }
  .legal-caja > footer { flex-direction: column; align-items: stretch; }
  .legal-aviso { text-align: center; }
  .legal-botones .btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) { .legal-baja { transition: none; } }

/* ---------------------------------------------------------------------------
   5. ESTRUCTURA: barra de arriba · contenido · barra de abajo
   --------------------------------------------------------------------------- */
.shell {
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  height: 100dvh; height: calc(100dvh - var(--bar)); margin-top: var(--bar);
  background:
    radial-gradient(ellipse 70% 55% at 18% -12%, rgba(78, 108, 220, .11), transparent 62%),
    radial-gradient(ellipse 55% 45% at 108% 112%, rgba(232, 193, 112, .065), transparent 62%),
    var(--bg);
}

.top {
  position: relative; z-index: 5;
  display: flex; align-items: center; gap: 1.6rem;
  height: var(--top-h); padding: 0 var(--pad);
  background: rgba(7, 10, 18, .8);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .03) inset;
}
.brand { display: flex; align-items: center; gap: .55rem; font: 800 1rem var(--font-title); letter-spacing: .22em; color: var(--gold2); flex: none; }
.brand svg { width: 1.5rem; height: 1.5rem; color: var(--gold); }

.tabs { display: flex; align-self: stretch; gap: 2px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
  position: relative; display: flex; align-items: center; flex: none;
  padding: 0 .95rem; font-weight: 700; font-size: .93rem; color: var(--muted);
  border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  transition: color var(--t), background var(--t);
}
.tabs a::after {
  content: ''; position: absolute; left: .95rem; right: .95rem; bottom: -1px; height: 2px;
  border-radius: 2px 2px 0 0; background: linear-gradient(90deg, var(--gold3), var(--gold2), var(--gold3));
  transform: scaleX(0); transition: transform var(--t-slow);
}
.tabs a:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.tabs a.on { color: var(--gold2); background: linear-gradient(180deg, transparent, rgba(232, 193, 112, .07)); }
.tabs a.on::after { transform: scaleX(1); }
.tabs a .badge { position: static; margin-left: .4em; box-shadow: none; }

.top-right { margin-left: auto; display: flex; align-items: center; gap: .6rem; flex: none; }

.server-pill {
  display: inline-flex; align-items: center; gap: .45rem; padding: .35rem .7rem;
  border-radius: 999px; border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
  font-size: .76rem; font-weight: 700; color: var(--soft); white-space: nowrap;
}
.server-pill i { width: .5rem; height: .5rem; border-radius: 50%; background: var(--offline); flex: none; }
.server-pill.online i { background: var(--online); box-shadow: 0 0 7px rgba(74, 222, 128, .6); }
.server-pill.maintenance i { background: var(--away); box-shadow: 0 0 7px rgba(250, 204, 21, .5); }
.server-pill.down i { background: var(--busy); box-shadow: 0 0 7px rgba(248, 113, 113, .5); }
/* El ping va aparte: se ve aunque la ventana sea estrecha y el color ya lo dice todo */
.server-pill .ping { padding: .05em .45em; border-radius: 999px; font-size: .72rem; font-weight: 800; font-variant-numeric: tabular-nums; background: rgba(255, 255, 255, .07); color: var(--soft); }
.server-pill .ping.ok { color: var(--online); }
.server-pill .ping.warn { color: var(--away); }
.server-pill .ping.bad { color: var(--busy); }

.bell-wrap, .user-wrap { position: relative; }
.user-btn {
  display: flex; align-items: center; gap: .5rem; height: 2.5rem; padding: 0 .6rem 0 .75rem;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
  cursor: pointer; font-weight: 700; transition: background var(--t), border-color var(--t);
}
.user-btn:hover { background: rgba(255, 255, 255, .08); border-color: var(--line2); }
.user-btn svg { width: 1rem; height: 1rem; color: var(--muted); }
#myName { max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dropdown {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 30;
  width: 19rem; max-height: min(70vh, 30rem); overflow: auto; padding: .5rem;
  border-radius: var(--radius); background: #101628; border: 1px solid var(--line2);
  box-shadow: var(--sh3);
}
.dropdown button {
  display: flex; align-items: center; gap: .65rem; width: 100%; padding: .55rem .65rem;
  border: 0; border-radius: var(--radius-xs); background: none; cursor: pointer; text-align: left; font-weight: 700;
  transition: background var(--t);
}
.dropdown button:hover { background: rgba(255, 255, 255, .07); }
.dropdown hr { border: 0; border-top: 1px solid var(--line); margin: .4rem 0; }
.dd-title { padding: .4rem .65rem; color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .12em; font-weight: 800; }
.notif { padding: .65rem; border-radius: var(--radius-xs); display: grid; gap: .5rem; }
.notif + .notif { border-top: 1px solid var(--line); border-radius: 0; }
.notif .n-actions { display: flex; gap: .4rem; }

.main { overflow: auto; overscroll-behavior: contain; padding: var(--pad); }
.view { max-width: 1440px; margin: 0 auto; }

.panel {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  /* contain: layout, NO paint. Con paint el panel recorta lo que se salga de su
     caja, y los desplegables propios de Ajustes se cortaban al abrirse cerca del
     borde. Layout ya evita que el panel obligue a recalcular la página entera. */
  padding: var(--pad-card); contain: layout;
}
.row-title { display: flex; align-items: center; justify-content: space-between; gap: .7rem; margin: 1.3rem 0 .8rem; }
.row-title:first-child { margin-top: 0; }
.row-title.sub { margin-top: 1.3rem; }
.row-title h3 { font: 700 .95rem var(--font-title); letter-spacing: .07em; color: var(--gold2); }
.list { display: flex; flex-direction: column; gap: 3px; }
.empty { padding: .9rem; border-radius: var(--radius-sm); border: 1px dashed var(--line2); color: var(--muted); text-align: center; font-size: .9rem; }

/* ---------------------------------------------------------------------------
   6. INICIO: arte grande a la izquierda, personaje y novedades a la derecha
   --------------------------------------------------------------------------- */
/* Dos filas: el aviso de mantenimiento (si lo hay) y el resto.
   .home va SIEMPRE en la fila 2 a propósito. Cuando no hay mantenimiento el
   aviso está en display:none y la fila 1 se queda en cero, pero si no se fija
   la fila el navegador colocaría .home arriba, en la fila «auto», y perdería
   el alto completo que necesita para no hacer scroll. */
.view[data-page="inicio"] { height: 100%; display: grid; grid-template-rows: auto minmax(0, 1fr); }
#homeMaint { grid-row: 1; margin-bottom: var(--gap); }
.home { grid-row: 2; display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(min(310px, 34%), 1fr); gap: var(--gap); height: 100%; }

.art {
  position: relative; min-height: 0; border-radius: var(--radius); overflow: hidden;
  background: #0d1322; border: 1px solid var(--line2); box-shadow: var(--sh2);
  isolation: isolate; contain: paint;
}
.slides { position: absolute; inset: 0; z-index: -2; }
/* Funde una imagen con la siguiente. Solo opacidad: es lo único que el
   navegador puede animar sin volver a dibujar nada. */
.slide { position: absolute; inset: 0; background: #0d1322 center / cover no-repeat; opacity: 0; transition: opacity .55s ease; }
.slide.on { opacity: 1; }
/* Velo: oscurece la izquierda y el pie para que el texto se lea sobre
   cualquier imagen, por clara que sea. */
.art::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(5, 8, 14, .92) 0%, rgba(5, 8, 14, .6) 36%, rgba(5, 8, 14, 0) 66%),
    linear-gradient(0deg, rgba(5, 8, 14, .9) 0%, rgba(5, 8, 14, 0) 48%);
}
.art-info { position: absolute; left: 0; bottom: 0; display: grid; justify-items: start; gap: .45rem; max-width: min(34rem, 72%); padding: 1.7rem 1.8rem 1.8rem; }
.art-kicker { color: var(--gold); font-size: .72rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; }
.art-info h2 { font: 800 clamp(1.35rem, 2.4vw, 2.1rem)/1.15 var(--font-title); color: #fff; text-shadow: 0 2px 14px rgba(0, 0, 0, .75); }
.art-info p { margin: 0; color: #d7dce7; font-size: .95rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.btn.art-btn { margin-top: .3rem; padding: .48em 1em; font-size: .86rem; border-color: rgba(232, 193, 112, .5); color: var(--gold2); background: rgba(6, 9, 16, .55); }
.btn.art-btn:hover { background: rgba(232, 193, 112, .18); border-color: var(--gold); color: #fff; }

.art-nav { position: absolute; right: 1.1rem; bottom: 1.2rem; display: flex; align-items: center; gap: .5rem; }
.sl-dots { display: flex; gap: .35rem; margin-right: .3rem; }
.sl-dots button { width: 1.2rem; height: 4px; padding: 0; border: 0; border-radius: 2px; background: rgba(255, 255, 255, .34); cursor: pointer; transition: width var(--t), background var(--t); }
.sl-dots button:hover { background: rgba(255, 255, 255, .6); }
.sl-dots button.on { width: 2rem; background: var(--gold); }
.sl-nav { width: 2.2rem; height: 2.2rem; display: grid; place-items: center; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .24); background: rgba(6, 9, 16, .6); color: #fff; cursor: pointer; transition: background var(--t), border-color var(--t); }
.sl-nav:hover { background: rgba(6, 9, 16, .9); border-color: rgba(255, 255, 255, .55); }
.sl-nav svg { width: 1.1rem; height: 1.1rem; }

.home-side { display: flex; flex-direction: column; gap: var(--gap); min-height: 0; }

/* Tarjeta del héroe: la identidad de quien juega. Es la única superficie con
   tinte dorado, para que sea lo primero que se mire al abrir. */
.hero-card {
  display: grid; gap: .7rem; padding: var(--pad-card); border-radius: var(--radius);
  background: linear-gradient(158deg, rgba(232, 193, 112, .1), rgba(18, 23, 38, .94) 48%);
  border: 1px solid var(--gold-line);
  box-shadow: var(--sh1), inset 0 1px 0 rgba(255, 255, 255, .06);
}
.hc-top { display: grid; grid-template-columns: var(--avatar) minmax(0, 1fr); gap: .8rem; align-items: center; }
.hc-info { min-width: 0; display: grid; gap: 1px; }
.hc-kicker { color: var(--teal); font-size: .68rem; font-weight: 800; letter-spacing: .15em; text-transform: uppercase; }
.hc-info b { font: 800 1.2rem var(--font-title); color: var(--gold2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hc-info > span:last-child { color: var(--soft); font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag.clan { font-family: var(--font); font-size: .78rem; color: var(--teal); }
.hc-meta { display: flex; justify-content: space-between; gap: .7rem; padding-top: .6rem; border-top: 1px solid var(--line); color: var(--muted); font-size: .8rem; }
.hc-meta span { display: inline-flex; align-items: center; gap: .4rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hc-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem; }
.hc-row select { padding: .45em .6em; font-size: .86rem; font-weight: 700; }

.box { position: relative; display: flex; flex-direction: column; min-height: 0; flex: 1; padding: var(--pad-card); border-radius: var(--radius); background: var(--card); border: 1px solid var(--line); contain: layout paint; }
/* Degradado al pie de las listas que hacen scroll: la última fila se corta y
   así se ve que hay más abajo, en vez de parecer que se acabó. Es un
   degradado pintado, no una máscara: no cuesta nada. */
.box::after, .friends-layout > .panel:first-child::after {
  content: ''; position: absolute; left: 1px; right: 1px; bottom: 1px; height: 1.5rem; pointer-events: none;
  border-radius: 0 0 var(--radius) var(--radius);
  background: linear-gradient(rgba(18, 23, 38, 0), rgba(15, 19, 32, .97));
}
.box-h { display: flex; align-items: center; justify-content: space-between; gap: .7rem; margin-bottom: .5rem; }
.box-h h3 { font: 700 .95rem var(--font-title); letter-spacing: .07em; color: var(--gold2); }
.link-more { font-size: .8rem; font-weight: 700; }

.feed { list-style: none; margin: 0; padding: 0; display: grid; align-content: start; gap: 1px; overflow: auto; min-height: 0; }
/* El titular manda: va primero, grande y a todo el ancho que le quede. La
   etiqueta del tipo se encoge a su palabra y se aparta a la derecha, en vez de
   ser un bloque fijo de seis letras que pesaba más que la noticia. */
.feed a {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  column-gap: .6rem; row-gap: .1rem; align-items: center;
  padding: .45rem .55rem; border-radius: var(--radius-xs); color: var(--text);
  transition: background var(--t);
}
.feed a:hover { background: rgba(255, 255, 255, .055); }
.feed b { grid-column: 1; grid-row: 1; font-weight: 700; font-size: .91rem; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed .tag {
  grid-column: 2; grid-row: 1; justify-self: end; padding: .2em .55em; border-radius: 5px;
  font-size: .62rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; white-space: nowrap;
}
.feed span { grid-column: 1; grid-row: 2; color: var(--muted); font-size: .76rem; line-height: 1.35; }
.feed .none { padding: .5rem; color: var(--muted); }

/* ---------------------------------------------------------------------------
   7. BARRA DE ABAJO — lo más importante de un launcher: estado y JUGAR.
   Es igual en todas las secciones y nunca se desplaza.
   --------------------------------------------------------------------------- */
.dock {
  position: relative; z-index: 6;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 1.4rem;
  padding: .7rem var(--pad);
  background: linear-gradient(180deg, rgba(14, 19, 34, .99), rgba(7, 10, 18, .99));
  border-top: 1px solid var(--gold-line);
  box-shadow: 0 -8px 24px rgba(0, 0, 0, .35);
}
.dock-status { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "line acts" "bar bar"; align-items: center; gap: .35rem .8rem; }
.dock-line { grid-area: line; display: flex; align-items: baseline; gap: .8rem; min-width: 0; }
.dock-text { flex: none; font-weight: 800; font-size: .95rem; color: var(--text); white-space: nowrap; }
.dock-text::before { content: ''; display: inline-block; width: .5rem; height: .5rem; margin-right: .55em; border-radius: 50%; background: var(--muted); vertical-align: .08em; }
.dock-text.ok::before { background: var(--online); box-shadow: 0 0 7px rgba(74, 222, 128, .6); }
.dock-text.warn { color: #fde68a; }
.dock-text.warn::before { background: var(--away); box-shadow: 0 0 7px rgba(250, 204, 21, .5); }
.dock-text.bad { color: #fecaca; }
.dock-text.bad::before { background: var(--busy); box-shadow: 0 0 7px rgba(248, 113, 113, .5); }
.dock-meta { min-width: 0; color: var(--muted); font-size: .82rem; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dock-acts { grid-area: acts; display: flex; gap: .35rem; }
.dock-acts:empty { display: none; }
.dock-acts .btn.small { padding: .3em .7em; font-size: .78rem; }

/* ---------- Barra de descarga ----------
   Alta y clara, con el porcentaje dentro a la derecha: al instalar o actualizar
   es lo único que se mira. El porcentaje llega en un atributo (data-pct) y se
   pinta con content: así no hay ningún elemento nuevo que crear en cada
   refresco, y por un atributo no se puede colar HTML. */
.pbar {
  grid-area: bar; position: relative; height: 15px; border-radius: 999px;
  background: rgba(0, 0, 0, .4); border: 1px solid var(--line); overflow: hidden;
}
.pbar i {
  display: block; height: 100%; width: 0; border-radius: inherit;
  background: linear-gradient(90deg, var(--gold3), var(--gold2));
  box-shadow: 0 0 10px rgba(232, 193, 112, .35);
  transition: width .25s linear;
}
.pbar[data-pct]::after {
  content: attr(data-pct); position: absolute; right: .6em; top: 0; height: 100%;
  display: flex; align-items: center;
  font: 800 .7rem/1 var(--font); font-variant-numeric: tabular-nums;
  color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .75); letter-spacing: .02em;
}
.pbar.paused i { background: linear-gradient(90deg, #6b7385, #b8bfcc); box-shadow: none; }

.dock-btns { display: flex; align-items: center; gap: .6rem; }

.btn.play {
  position: relative; overflow: hidden;
  min-width: var(--play-w); min-height: var(--play-h); padding: .4em 1.6em;
  border-radius: 12px; border: 0; color: #1a1206;
  font: 800 1.1rem var(--font); letter-spacing: .08em;
  background: linear-gradient(180deg, #ffe3a8, #e9b862 52%, #c78a37);
  box-shadow: 0 8px 22px rgba(232, 193, 112, .26), inset 0 1px 0 rgba(255, 255, 255, .6);
  transition: filter var(--t), box-shadow var(--t), transform .08s;
}
.btn.play:hover:not(:disabled) { filter: brightness(1.06); box-shadow: 0 10px 28px rgba(232, 193, 112, .38), inset 0 1px 0 rgba(255, 255, 255, .6); }
/* Destello al pasar por encima. Es un pseudo-elemento que se mueve con
   transform: no repinta el botón, solo lo desliza el compositor. */
.btn.play::after {
  content: ''; position: absolute; inset: -2px; pointer-events: none;
  background: linear-gradient(104deg, transparent 42%, rgba(255, 255, 255, .5) 50%, transparent 58%);
  transform: translateX(-130%); transition: transform .55s ease;
}
.btn.play:hover:not(:disabled)::after { transform: translateX(130%); }
.btn.play:disabled { filter: saturate(.28) brightness(.72); opacity: .85; }
.btn.play:disabled::after { display: none; }
.btn.play svg { width: 1.3rem; height: 1.3rem; fill: currentColor; stroke: none; }
.play-txt { display: grid; justify-items: start; line-height: 1.1; }
.play-txt small { font-size: .7rem; font-weight: 700; letter-spacing: .02em; opacity: .74; text-transform: none; }
.play-txt small:empty { display: none; }

.btn.update { min-height: var(--play-h); padding: .4em 1.1em; border-radius: 12px; font-weight: 800; letter-spacing: .06em; color: var(--teal); border: 1px solid rgba(84, 214, 201, .5); background: rgba(84, 214, 201, .1); }
.btn.update:hover:not(:disabled) { background: rgba(84, 214, 201, .19); border-color: var(--teal); }
.btn.update:disabled { opacity: .9; cursor: progress; }
.btn.stop { min-height: var(--play-h); padding: .4em 1em; border-radius: 12px; font-weight: 800; color: #ffb3aa; border: 1px solid rgba(244, 124, 114, .5); background: rgba(244, 124, 114, .1); }
.btn.stop:hover { background: rgba(244, 124, 114, .2); border-color: var(--danger); color: #fff; }
.btn.stop svg { width: 1rem; height: 1rem; fill: currentColor; stroke: none; }

.patch-acts { display: flex; flex-wrap: wrap; gap: .5rem; }
#appPanel .patch-acts { margin: .8rem 0; }
#appSettings { display: grid; gap: .6rem; }

/* ---------------------------------------------------------------------------
   8. TARJETAS Y LISTAS COMUNES
   --------------------------------------------------------------------------- */
.avatar { position: relative; width: var(--avatar); height: var(--avatar); border-radius: calc(var(--radius) - 3px); overflow: hidden; background: linear-gradient(158deg, #1f2a46, #0f1524); display: grid; place-items: center; border: 1px solid var(--line2); flex: none; }
/* Bolita de estado en la esquina del avatar, como en Discord: el color dice si
   está en línea, ausente, ocupado o jugando, y el nombre del estado sale al
   pasar el ratón. Así la lista no repite la palabra en cada fila. */
.presencia {
  position: absolute; right: 1px; bottom: 1px; width: .58rem; height: .58rem;
  border-radius: 50%; background: var(--offline); box-shadow: 0 0 0 2px #111728;
}
.presencia.online { background: var(--online); }
.presencia.playing { background: var(--playing); }
.presencia.away { background: var(--away); }
.presencia.busy { background: var(--busy); }
.avatar img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; transform: scale(1.9); transform-origin: 50% 8%; }
.avatar svg { width: 55%; height: 55%; color: rgba(232, 193, 112, .6); }
.avatar.sm { width: 2.4rem; height: 2.4rem; border-radius: var(--radius-xs); }

.char-card {
  position: relative; display: grid; grid-template-columns: var(--avatar) minmax(0, 1fr); gap: .7rem; align-items: center;
  padding: .55rem .7rem; border-radius: var(--radius-sm); background: var(--card); border: 1px solid var(--line);
  cursor: pointer; text-align: left; width: 100%;
  transition: background var(--t), border-color var(--t), transform .08s;
}
.char-card:hover { border-color: var(--line2); background: var(--card2); }
.char-card:active { transform: translateY(1px); }
.char-card.on { border-color: var(--gold-line); background: linear-gradient(158deg, rgba(232, 193, 112, .09), var(--card2) 55%); box-shadow: inset 0 0 0 1px rgba(232, 193, 112, .18); }
.char-card b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.char-card span { display: block; color: var(--muted); font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.char-card .main-star { position: absolute; top: .4rem; right: .5rem; color: var(--gold); font-size: .8rem; }
.char-card.new { grid-template-columns: 1fr; place-items: center; color: var(--muted); border-style: dashed; min-height: calc(var(--avatar) + 1.1rem); }
.char-card.new:hover { color: var(--gold2); border-color: var(--gold-line); }

/* align-items: start es importante: sin él todas las tarjetas de una fila se
   estiran al alto de la más alta, y una noticia sin foto al lado de una con
   foto queda como un cajón medio vacío. Así cada una mide lo que necesita. */
/* Filas flexibles, no rejilla fija. Con rejilla, la última fila dejaba el hueco
   de las columnas que sobraban: una sección con una destacada a todo lo ancho y
   una tarjeta suelta debajo se veía coja. Así la última fila reparte lo que
   queda entre las tarjetas que haya y no sobra sitio nunca.
   Las de una misma fila SÍ se estiran todas al mismo alto (align-items:
   stretch): si no, una con el resumen de dos líneas y otra de una acaban con
   el borde de abajo a distinta altura y la fila se ve torcida.

   El ritmo de la sección es a propósito: las que llevan foto van DE DOS EN DOS
   (con 360px de base, a 1080 entran dos y se reparten el ancho) y las de solo
   texto ocupan la FILA ENTERA como una tira. Así se alternan bloques anchos y
   parejas, y no queda todo igual ni sobra sitio en ningún lado. */
.cards { display: flex; flex-wrap: wrap; gap: var(--gap); align-items: stretch; }
.cards > * { flex: 1 1 min(360px, 100%); min-width: 0; }
.cards > .empty { flex-basis: 100%; }
.card {
  display: flex; flex-direction: column; border-radius: var(--radius); overflow: hidden;
  background: var(--card); border: 1px solid var(--line);
  content-visibility: auto; contain-intrinsic-size: auto 280px;    /* el navegador no dibuja las que quedan fuera de pantalla */
  transition: border-color var(--t), transform var(--t), box-shadow var(--t);
}
.card:hover { border-color: var(--line2); transform: translateY(-2px); box-shadow: var(--sh2); }
/* El tope de alto es el seguro de auto-fit: si en una sección hay una sola
   tarjeta, ocupa todo el ancho y sin este tope su foto mediría medio metro. */
.card .img { aspect-ratio: 16 / 8; max-height: 12rem; background: #0f1522 center / cover no-repeat; }
/* El cuerpo se estira y la fecha se va al fondo. Así todas las tarjetas de una
   misma fila miden lo mismo aunque una tenga dos líneas de texto y otra una, y
   las fechas quedan alineadas abajo en vez de a alturas distintas. */
.card .body { flex: 1; padding: .85rem 1rem 1rem; display: flex; flex-direction: column; gap: .3rem; }
.card .type { color: var(--gold); font-size: .7rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.card h4 { font-size: 1rem; }
.card p { margin: 0; color: var(--soft); font-size: .88rem; }
.card time { margin-top: auto; padding-top: .25rem; color: var(--muted); font-size: .76rem; }
/* ---------- Noticia sin foto ----------
   Una tarjeta sin imagen es un rectángulo alto medio vacío. En su lugar ocupa
   el ancho entero como una fila: el tipo a la izquierda, el titular y el
   resumen en medio, la fecha a la derecha. Se llena el bloque y se lee mejor,
   sin inventar relleno. */
.card.sin-foto { flex-basis: 100%; }
.card.sin-foto .body {
  display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto;
  column-gap: 1.1rem; row-gap: .12rem; align-items: start; padding: .7rem 1rem;
}
.card.sin-foto .type {
  grid-column: 1; grid-row: 1 / -1; align-self: center; text-align: center;
  padding: .3em .2em; border-radius: 6px; background: var(--gold-soft); letter-spacing: .1em;
}
.card.sin-foto h4 { grid-column: 2; grid-row: 1; }
.card.sin-foto p { grid-column: 2; }
.card.sin-foto time { grid-column: 3; grid-row: 1; white-space: nowrap; }

.card.banner { flex-basis: 100%; display: grid; grid-template-columns: 1.4fr 1fr; }
.card.banner .img { aspect-ratio: auto; min-height: 10rem; max-height: none; }
.card.banner h4 { font: 800 1.4rem var(--font-title); color: var(--gold2); }
.card.banner .body { justify-content: center; padding: 1.2rem 1.4rem; }

.event { display: grid; gap: .25rem; padding: .6rem .75rem; border-radius: var(--radius-sm); background: rgba(84, 214, 201, .08); border: 1px solid rgba(84, 214, 201, .22); margin-bottom: .5rem; }
.event b { color: #c4f3ee; }
.event span { color: var(--muted); font-size: .8rem; }
/* ---------- Aviso de mantenimiento ----------
   Sale igual en Inicio (arriba del todo) y en Noticias. Ámbar, con el borde
   izquierdo marcado: tiene que cantar sin llegar a parecer un error. Lo genera
   maintHtml() en launcher.js. */
.maint {
  display: flex; align-items: flex-start; gap: .7rem;
  padding: .65rem .9rem; border-radius: var(--radius-sm);
  background: linear-gradient(90deg, rgba(250, 204, 21, .17), rgba(250, 204, 21, .06));
  border: 1px solid rgba(250, 204, 21, .3); border-left: 3px solid var(--away);
  color: #fde68a;
}
.maint + .maint { margin-top: .45rem; }
.maint > svg { width: 1.15rem; height: 1.15rem; color: var(--away); margin-top: .12rem; stroke-width: 1.5; }
.mh-body { display: grid; gap: .08rem; min-width: 0; }
.mh-title { font-weight: 800; font-size: .95rem; color: #fdefc0; }
.mh-when { font-size: .85rem; font-weight: 600; color: #ecd9a4; }
.mh-when b { font-weight: 800; color: #fff6dd; }            /* la hora, que es lo que se busca */
.mh-now { color: #fff6dd; }
.mh-left { font-style: normal; margin-left: .3em; padding: .08em .55em; border-radius: 999px; background: rgba(250, 204, 21, .22); color: #fff6dd; font-size: .78rem; font-weight: 800; white-space: nowrap; }
.mh-sum { font-size: .83rem; font-weight: 400; color: #cfc39a; }

/* Bloque de estadísticas sueltas (statTiles de launcher.js) */
.stat { display: grid; gap: 1px; padding: .5rem .7rem; border-radius: var(--radius-xs); background: var(--sunken); text-align: center; }
.stat b { font-size: 1rem; font-variant-numeric: tabular-nums; color: var(--gold2); }
.stat span { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; }

/* ---------------------------------------------------------------------------
   9. PERSONAJES
   La ficha entra entera en el alto que deja la barra de abajo y NO hace
   scroll: cabecera arriba, y debajo tres columnas (retrato, estadísticas y
   equipo) que se reparten el alto restante.
   --------------------------------------------------------------------------- */
.view[data-page="personajes"] { height: 100%; }
.chars-layout { display: grid; grid-template-columns: var(--col-chars) minmax(0, 1fr); gap: var(--gap); height: 100%; min-height: 0; }
.char-list { display: flex; flex-direction: column; gap: .4rem; min-height: 0; overflow: auto; padding-right: 2px; }
.char-detail { display: flex; flex-direction: column; gap: .7rem; min-height: 0; overflow: hidden; }
.char-detail > .empty { margin: auto; }

.cd-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(10rem, 15rem) auto; align-items: center; gap: .4rem 1.1rem; padding-bottom: .7rem; border-bottom: 1px solid var(--line); }
.cd-name { min-width: 0; display: grid; gap: .15rem; }
.char-detail h2 { font: 800 1.65rem var(--font-title); color: var(--gold2); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hero-kicker { color: var(--teal); font-weight: 800; letter-spacing: .2em; text-transform: uppercase; font-size: .72rem; }
.hero-meta { display: flex; flex-wrap: wrap; gap: .2rem .85rem; color: var(--soft); font-weight: 700; font-size: .9rem; }
.hero-meta span { display: inline-flex; align-items: center; gap: .35rem; }
.hero-meta .tag { padding: .05em .5em; border-radius: 5px; background: rgba(84, 214, 201, .12); color: var(--teal); font-weight: 800; }

.cd-exp { display: grid; gap: .35rem; }
.cd-exp-top { display: flex; align-items: baseline; justify-content: space-between; gap: .7rem; }
.cd-exp-top h3, .cd-col > h3 { font: 700 .82rem var(--font-title); letter-spacing: .07em; color: var(--gold2); }
.cd-exp-top span { font-size: .8rem; font-variant-numeric: tabular-nums; }

.cd-body { flex: 1; min-height: 0; display: grid; grid-template-columns: var(--col-portrait) minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; }
.cd-col { min-height: 0; display: flex; flex-direction: column; gap: .5rem; }
/* El retrato lleva marco propio: los retratos del juego no siempre tienen la
   misma forma, y sin marco una imagen que no llena la columna parece un agujero
   en la ficha en vez de un retrato. */
.char-detail .portrait {
  display: grid; place-items: center; min-height: 0; overflow: hidden;
  border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: radial-gradient(ellipse at 50% 72%, rgba(232, 193, 112, .12), transparent 70%), var(--sunken);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
}
/* cover, no contain: el retrato llena el marco. Con contain quedaban franjas
   negras arriba y abajo cuando la imagen no tenía la forma exacta del hueco. */
.char-detail .portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; }
.portrait-empty { position: relative; z-index: 1; display: grid; place-items: center; gap: .6rem; width: min(100%, 12rem); height: min(100%, 18rem); border-radius: var(--radius-sm); border: 1px dashed var(--line2); background: rgba(0, 0, 0, .25); color: var(--muted); text-align: center; padding: 1rem; font-size: .82rem; }
.portrait-empty svg { width: 4.4rem; height: 4.4rem; color: rgba(232, 193, 112, .45); stroke-width: 1.2; }

.bar { height: 7px; border-radius: 4px; background: rgba(255, 255, 255, .08); overflow: hidden; }
.bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--gold3), var(--gold2)); }

.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .35rem .9rem; font-size: .9rem; align-content: start; }
.kv dt, .kv .k { color: var(--muted); }
.kv dd, .kv .v { margin: 0; font-weight: 700; text-align: right; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.cd-col .kv { row-gap: 0; column-gap: 0; font-size: .82rem; overflow: auto; }
.cd-col .kv > * { padding: .22rem 0; border-bottom: 1px solid rgba(255, 255, 255, .05); }
.cd-col .kv > .k { padding-right: .6rem; }
.cd-col .kv > .v { padding-left: .6rem; }
.cd-col .kv .k, .cd-col .kv .v { white-space: nowrap; }

.equip-table { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; gap: 2px; overflow: auto; }
/* Cada pieza lleva el color de su rareza en el borde izquierdo: se lee de un
   vistazo sin tener que mirar el rombo. */
.eq {
  display: inline-flex; align-items: center; gap: .4rem; padding: .2rem .55rem;
  border-radius: var(--radius-xs); background: var(--sunken); border: 1px solid var(--line);
  border-left: 3px solid var(--rc, var(--r-common));
  font-size: .78rem; font-weight: 700;
}
.eq i { display: inline-block; width: .5rem; height: .5rem; border-radius: 2px; transform: rotate(45deg); background: var(--rc, var(--r-common)); flex: none; }
.equip-table .eq { justify-content: space-between; gap: .5rem; padding: .16rem .5rem; font-size: .76rem; line-height: 1.4; }
.equip-table .eq > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.equip-table .eq em { flex: none; color: var(--muted); font-style: normal; font-weight: 600; font-size: .92em; }

/* ---------------------------------------------------------------------------
   10. AMIGOS
   --------------------------------------------------------------------------- */
.person { display: grid; grid-template-columns: 2.4rem minmax(0, 1fr) auto; gap: .65rem; align-items: center; padding: .4rem .5rem; border-radius: var(--radius-xs); transition: background var(--t); }
.person:hover { background: rgba(255, 255, 255, .045); }
.person[data-profile] { cursor: pointer; }
.person .who { min-width: 0; }
.person .who b { display: flex; align-items: center; gap: .4rem; font-size: .92rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.person .who span { display: block; color: var(--muted); font-size: .78rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.person .who span.playing { color: var(--teal); font-weight: 700; }
/* align-items: center es obligatorio. Sin él, el rango del clan (un <span>)
   se estira a lo alto de la fila y queda como una caja enorme. */
.person .acts { display: flex; align-items: center; gap: .25rem; flex-wrap: wrap; justify-content: flex-end; }
.person .ctag { color: var(--teal); font-size: .74rem; font-weight: 800; }
.search { margin-bottom: .5rem; }

/* Amigos ocupa todo el alto de la ventana: los dos paneles llegan hasta abajo
   y la lista de amigos hace scroll DENTRO. Antes los paneles medían lo que
   medía su contenido y dejaban un hueco muerto de casi 150px al final. */
.view[data-page="amigos"] { height: 100%; }
.friends-layout { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--gap); height: 100%; min-height: 0; align-items: stretch; }
.friends-layout > .panel { min-height: 0; display: flex; flex-direction: column; }
.friends-layout > .panel > .row-title { flex: none; }
.friends-layout > .panel:last-child { overflow: auto; }        /* la columna de buscar y solicitudes es una tira larga */
#friendsFull { flex: 1 1 auto; min-height: 0; overflow: auto; }

/* ---------------------------------------------------------------------------
   11. CLAN Y FORMULARIOS
   --------------------------------------------------------------------------- */
/* Clan a dos columnas: el clan y sus miembros a la izquierda (la lista hace
   scroll dentro) y la gestión a la derecha. En una sola columna los botones de
   cada miembro quedaban a medio metro de su nombre. */
.view[data-page="clan"] { height: 100%; }
#clanView { height: 100%; min-height: 0; }
.clan-layout { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: var(--gap); height: 100%; min-height: 0; }
.clan-layout.sola { grid-template-columns: minmax(0, 1fr); }     /* sin invitaciones ni permisos: no hay columna derecha */
.clan-main { display: flex; flex-direction: column; min-height: 0; }
.clan-main > .clan-head, .clan-main > .row-title { flex: none; }
.clan-members { flex: 1 1 auto; min-height: 0; overflow: auto; }
.clan-side { display: flex; flex-direction: column; gap: var(--gap); min-height: 0; overflow: auto; }
.clan-side > .panel { flex: none; }
.clan-id { min-width: 0; }
.clan-id .muted { font-size: .84rem; overflow: hidden; text-overflow: ellipsis; }
.clan-acts { margin-left: auto; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

.clan-head { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-bottom: .9rem; }
.clan-emblem { width: 4.2rem; height: 4.2rem; display: grid; place-items: center; border-radius: var(--radius); background: linear-gradient(158deg, #283350, #121828); border: 1px solid var(--gold-line); font: 800 1.1rem var(--font-title); color: var(--gold2); flex: none; }
/* En una fila de invitación el emblema ocupa el hueco del avatar: si se deja
   del tamaño grande se sale de su columna y pisa el nombre del clan. */
.person > .clan-emblem { width: 2.4rem; height: 2.4rem; border-radius: var(--radius-xs); font-size: .66rem; letter-spacing: .02em; }
.clan-head h2 { font: 800 1.65rem var(--font-title); color: var(--gold2); }
.rank { font-size: .72rem; font-weight: 800; padding: .1em .55em; border-radius: 5px; background: rgba(255, 255, 255, .07); color: var(--soft); text-transform: uppercase; letter-spacing: .06em; white-space: nowrap; }
.rank.leader { background: var(--gold-soft); color: var(--gold2); }
.rank.officer { background: rgba(84, 214, 201, .12); color: var(--teal); }
/* Los formularios pequeños no crecen a lo ancho del panel: un campo de texto
   de mil píxeles para escribir un nombre de usuario se ve mal en cualquier
   sitio, y el botón se queda pegado a la izquierda en vez de estirarse. */
.mini-form { display: grid; gap: .5rem; margin-top: 1.2rem; max-width: 26rem; }
.mini-form .btn { justify-self: start; }
.mini-form h4 { font: 700 .88rem var(--font-title); color: var(--gold2); letter-spacing: .05em; }
.field { display: grid; gap: .35rem; margin: .7rem 0; font-size: .86rem; font-weight: 700; color: var(--soft); }

/* ---------- Ajustes: una fila por opción ----------
   Como cualquier panel de ajustes: el nombre a la izquierda, el control a la
   derecha y una línea fina entre filas. Antes era una torre de deslizadores a
   todo lo ancho que no se parecía a los ajustes de ningún juego.
   Al ser filas completas no sobra sitio y no hay huecos que rellenar. */
#gameSettings .grp, #appSettings .grp {
  margin: 1.1rem 0 .2rem; font: 800 .7rem var(--font); letter-spacing: .16em; text-transform: uppercase; color: var(--gold);
}
#gameSettings .grp:first-of-type { margin-top: .6rem; }
#gameSettings .field, #appSettings .field,
#gameSettings .check.fila, #appSettings .check.fila {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(7rem, 16rem);
  align-items: center; gap: .3rem 1.2rem; margin: 0; padding: .5rem 0; max-width: none;
  border-bottom: 1px solid var(--line);
}
#gameSettings .check.fila, #appSettings .check.fila { color: var(--soft); font-size: .86rem; font-weight: 700; }
#gameSettings .check.fila input, #appSettings .check.fila input { justify-self: end; width: 1.1rem; height: 1.1rem; }
#gameSettings .field > span, #appSettings .field > span { min-width: 0; }
/* El valor del deslizador va pegado a su nombre, no perdido al otro lado */
#gameSettings .field b[data-out] { margin-left: .45em; }
#gameSettings > p, #appSettings > p { margin-top: .8rem; }
.field b { color: var(--gold2); font-weight: 800; font-variant-numeric: tabular-nums; }
/* ---------------------------------------------------------------------------
   CUENTA (pantalla propia, separada de Ajustes)
   Ajustes es cómo se ve el juego en ESTE equipo; Cuenta es tu cuenta en el
   servidor. Mezclarlas obligaba a bajar por deslizadores de brillo para llegar
   a cambiar la contraseña.
   --------------------------------------------------------------------------- */
.view[data-page="cuenta"] { height: 100%; }
.cuenta-layout { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--gap); height: 100%; min-height: 0; align-items: stretch; }
.cuenta-col { display: flex; flex-direction: column; gap: var(--gap); min-height: 0; overflow: auto; }
/* Los dos marcos llegan hasta abajo del todo, como pidió el diseño: ninguno se
   queda a media pantalla. En la ficha de cuenta el hueco no queda en medio
   porque la cabecera con el retrato es generosa y los botones van pegados al
   fondo; en sesiones, la lista crece y el botón de cerrar todas queda al pie. */
.cuenta-col > .panel { flex: 1; display: flex; flex-direction: column; min-height: 0; }
#sessionsList { flex: 1 1 auto; min-height: 0; overflow: auto; }

/* Ficha de identidad: retrato grande y centrado, nombre y correo debajo. Es lo
   primero que se mira, y al ser generosa llena la parte de arriba del marco en
   vez de dejar un hueco. */
#accountPanel { background: linear-gradient(170deg, rgba(232, 193, 112, .12), rgba(18, 23, 38, .94) 42%); border-color: var(--gold-line); }
#accountInfo { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.cuenta-id { display: grid; justify-items: center; text-align: center; gap: .55rem; padding: .8rem 0 1.1rem; margin-bottom: 1rem; border-bottom: 1px solid var(--line); }
.cuenta-id .avatar { width: 5rem; height: 5rem; border-radius: 50%; }
.cuenta-id .presencia { width: .85rem; height: .85rem; right: 4px; bottom: 4px; box-shadow: 0 0 0 3px #161b2c; }
.cuenta-quien { min-width: 0; max-width: 100%; display: grid; gap: 2px; justify-items: center; }
.cuenta-quien b { font: 800 1.45rem var(--font-title); color: var(--gold2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.cuenta-mail { color: var(--soft); font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
/* column-gap: 0 a propósito. La línea de cada fila se dibuja debajo de las dos
   celdas; con hueco entre columnas la raya sale PARTIDA en dos trozos y parece
   un error. El aire entre el nombre y el valor lo da el relleno de las celdas. */
#accountInfo .kv { font-size: .86rem; column-gap: 0; row-gap: 0; }
#accountInfo .kv > * { padding: .3rem 0; border-bottom: 1px solid rgba(255, 255, 255, .06); }
#accountInfo .kv > .k { padding-right: 1rem; }
#accountInfo .kv > .v { padding-left: 1rem; }
#accountInfo .kv > *:nth-last-child(-n+2) { border-bottom: 0; }

/* Los botones van pegados ABAJO de la tarjeta, no flotando detrás de los datos.
   Para eso la tarjeta se estira a lo alto de su columna y el bloque de acciones
   se empuja al fondo con margin-top: auto. */
.cuenta-acciones { margin-top: auto; padding-top: 1rem; border-top: 1px solid var(--line); display: grid; justify-items: start; gap: .5rem; }
.cuenta-acciones .hint { font-size: .8rem; }
.cuenta-mail { font-variant-numeric: tabular-nums; letter-spacing: .01em; }

/* Ventana flotante estrecha: para un formulario de tres campos, los 54rem de
   ancho normales quedan ridículos. */
.modal-card.estrecha { width: min(24rem, 100%); }
.modal-card.estrecha .mini-form { margin-top: 0; max-width: none; }
.modal-card.estrecha .mini-form .btn { justify-self: stretch; }

/* Sesiones: icono del aparato, dónde y cuándo, y el botón de cerrar.
   La de ahora mismo va marcada en verde para que no la cierres por error. */
#sessionsPanel .hint { margin-bottom: .7rem; }
#sessionsPanel > .btn { margin-top: .8rem; }
.sess { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: .75rem; align-items: center; padding: .55rem .7rem; border-radius: var(--radius-xs); background: var(--sunken); border: 1px solid transparent; font-size: .86rem; }
.sess.actual { border-color: rgba(74, 222, 128, .3); background: rgba(74, 222, 128, .07); }
.sess-icono { display: grid; place-items: center; width: 2.2rem; height: 2.2rem; border-radius: var(--radius-xs); background: rgba(255, 255, 255, .05); color: var(--soft); }
.sess.actual .sess-icono { color: var(--online); background: rgba(74, 222, 128, .12); }
/* Macizos: hay que apagar el trazo que lleva por defecto todo svg del launcher
   y encender el relleno (ver SVG_EQUIPO / SVG_MOVIL en launcher.js). */
.sess-icono svg { width: 1.3rem; height: 1.3rem; display: block; fill: currentColor; stroke: none; }
.sess-quien { min-width: 0; }
.sess-quien b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sess span { color: var(--muted); display: block; font-size: .78rem; }
.sess-yo { color: var(--online) !important; font-size: .74rem !important; font-weight: 800; white-space: nowrap; }
/* Ajustes en dos columnas de verdad.
   Con una rejilla, los cuatro paneles (Juego, Programa de Windows, Diagnóstico
   y Cuenta) se emparejan por filas y cada fila crece hasta el más alto: queda
   un escalón enorme al lado del panel corto. Con columnas de texto el navegador
   los reparte él solo para que las dos columnas acaben a la misma altura, que
   es justo lo que hace falta aquí. break-inside evita que un panel se parta. */
.settings-layout { display: block; column-count: 2; column-gap: var(--gap); }
.settings-layout > .panel { break-inside: avoid; margin-bottom: var(--gap); }

/* ---------------------------------------------------------------------------
   12. VENTANA EMERGENTE Y AVISO
   --------------------------------------------------------------------------- */
.modal { position: fixed; inset: var(--bar) 0 0; z-index: 40; display: grid; place-items: center; padding: 1.4rem; background: rgba(3, 5, 10, .75); }
.modal-card { width: min(54rem, 100%); max-height: 86vh; overflow: auto; padding: 1.4rem; border-radius: 18px; background: #0f1526; border: 1px solid var(--line2); box-shadow: var(--sh3); }
.modal-top { display: flex; align-items: center; justify-content: space-between; gap: .8rem; margin-bottom: .9rem; }
.modal-top h2 { font: 800 1.3rem var(--font-title); color: var(--gold2); }
/* En la ficha de un jugador el estado SÍ va escrito: está solo, no hay una
   lista de bolitas al lado con la que comparar el color. */
.perfil-estado { margin: 0 0 .9rem; color: var(--soft); font-weight: 700; font-size: .9rem; }
.perfil-estado .playing { color: var(--teal); }

.toast {
  position: fixed; left: 50%; bottom: calc(var(--play-h) + 3.6rem); transform: translateX(-50%); z-index: 60;
  padding: .7rem 1.1rem; border-radius: 12px; background: #111830; border: 1px solid var(--line2);
  box-shadow: var(--sh3); font-weight: 700; max-width: calc(100vw - 2rem);
}
.toast.bad { border-color: rgba(244, 124, 114, .5); color: #fecaca; }

/* ---------------------------------------------------------------------------
   13. PROGRAMA DE WINDOWS: barra de la ventana
   Solo lo que existe únicamente dentro de la app. Todo lo demás (tamaños,
   densidad) ya lo resuelven las variables de arriba.
   --------------------------------------------------------------------------- */
.appbar { display: none; }

/* html.in-app  → estamos dentro del programa de Windows (lo pone launcher.js).
   html.frameless → además la ventana no tiene marco de Windows y se dibuja la
   barra propia (.appbar). Son dos cosas distintas: puede haber in-app sin
   frameless si algún día la ventana lleva marco del sistema. Dentro del
   programa nunca se ofrece la descarga del instalador ni se abre nada fuera. */
html.in-app { cursor: default; }
html.in-app a[href^="http"] { cursor: pointer; }

html.frameless body { user-select: none; }                         /* una ventana de escritorio no se selecciona como una página */
html.frameless input, html.frameless textarea { user-select: text; }
html.frameless .appbar {
  position: fixed; inset: 0 0 auto; height: var(--bar); z-index: 80;
  display: flex; align-items: center; gap: .6rem; padding-left: .9rem;
  background: #05080e; border-bottom: 1px solid var(--line);
  -webkit-app-region: drag;
}
.appbar-brand { font: 800 .74rem var(--font-title); letter-spacing: .3em; background: linear-gradient(180deg, #fff3dc, var(--gold)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.appbar-ver { color: var(--muted); font-size: .68rem; font-weight: 700; letter-spacing: .04em; }
.win-ctl { margin-left: auto; display: flex; height: 100%; -webkit-app-region: no-drag; }
.win-ctl button { width: 2.9rem; height: 100%; display: grid; place-items: center; border: 0; background: none; color: #c9d1de; cursor: pointer; transition: background .1s; }
.win-ctl button:hover { background: rgba(255, 255, 255, .1); color: #fff; }
.win-ctl button.close:hover { background: #e5484d; color: #fff; }
.win-ctl svg { width: .9rem; height: .9rem; stroke-width: 1.6; }

html.frameless .brand { display: none; }                           /* el nombre ya está en la barra de la ventana */
html.frameless .server-pill span { display: inline; }              /* dentro de la app siempre cabe */

/* ---------------------------------------------------------------------------
   14. NAVEGADOR Y CELULAR
   De mayor a menor ancho. Cada corte deshace una columna, empezando por la
   que peor aguanta el estrechamiento.
   --------------------------------------------------------------------------- */

/* Ventanas a media pantalla: primero se recorta el texto de la píldora del
   servidor, que es lo que menos falta hace (el color y el ping ya lo dicen). */
@media (max-width: 1180px) {
  html:not(.frameless) .server-pill span { display: none; }
  html:not(.frameless) .server-pill .ping { display: inline; }
}

/* Amigos y Ajustes aguantan dos columnas hasta bastante estrecho: a 1080 -el
   ancho de la ventana de Windows- deben seguir a dos, o Amigos queda con filas
   de un metro y Ajustes con deslizadores de lado a lado. */
@media (max-width: 900px) {
  .friends-layout { grid-template-columns: minmax(0, 1fr); }
  .settings-layout { column-count: 1; }
  /* Cuenta vuelve a una columna */
  .view[data-page="cuenta"] { height: auto; }
  .cuenta-layout { grid-template-columns: minmax(0, 1fr); height: auto; }
  .cuenta-col { display: block; overflow: visible; }
  .cuenta-col > .panel + .panel { margin-top: var(--gap); }
  /* Clan vuelve a una columna y manda el scroll de la página */
  .view[data-page="clan"], #clanView { height: auto; }
  .clan-layout { grid-template-columns: minmax(0, 1fr); height: auto; }
  .clan-main, .clan-side { display: block; overflow: visible; }
  .clan-side > .panel { margin-top: var(--gap); }
  .clan-members { overflow: visible; }
  /* Apilado ya no tiene sentido llenar el alto: cada panel mide lo suyo y
     manda el scroll de la página. */
  .view[data-page="amigos"] { height: auto; }
  .friends-layout { height: auto; align-items: start; }
  .friends-layout > .panel, .friends-layout > .panel:last-child { display: block; overflow: visible; }
  .friends-layout > .panel:first-child::after { display: none; }
  #friendsFull { overflow: visible; }
}

/* Tabletas: el inicio deja de ser lado a lado y el arte pasa a ser una banda.
   OJO: estos selectores van SIN prefijo a propósito. Si se les pone
   html:not(.frameless) suben de especificidad y dejan de poder pisarse en el
   corte de celular de abajo (ya pasó: el inicio se salía a lo ancho en móvil).
   No hace falta prefijo: la ventana del programa mide 1080 y nunca entra aquí. */
@media (max-width: 1040px) {
  .home { grid-template-columns: minmax(0, 1fr); height: auto; }
  .view[data-page="inicio"] { height: auto; }
  .art { aspect-ratio: 16 / 7; }
  .home-side { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  .box { flex: none; }
  .feed { max-height: 16rem; }
  .view[data-page="personajes"] { height: auto; }
  .chars-layout { grid-template-columns: minmax(0, 1fr); height: auto; }
  .char-list { flex-direction: row; flex-wrap: wrap; overflow: visible; }
  .char-list .char-card { flex: 1 1 15rem; }
  .char-detail { overflow: visible; }
  .cd-head { grid-template-columns: minmax(0, 1fr); }
  .cd-col .kv, .equip-table { overflow: visible; }
}

/* Celular y ventanas estrechas: una sola columna y la página entera hace
   scroll. La barra de abajo se queda pegada porque JUGAR tiene que estar
   siempre a mano sin desplazar. */
@media (max-width: 860px) {
  body { overflow: auto; }
  .shell { height: auto; min-height: 100dvh; grid-template-rows: auto auto auto; }
  .top { position: sticky; top: 0; flex-wrap: wrap; height: auto; gap: 0 .8rem; padding: .6rem var(--pad) 0; background: rgba(7, 10, 18, .97); }
  .tabs { order: 3; width: 100%; height: 2.8rem; }
  .main { overflow: visible; }
  .art { aspect-ratio: 4 / 3; }
  .art-info { max-width: 100%; padding: 1.1rem; }
  .art-info p { display: none; }
  .art-nav { top: .9rem; bottom: auto; right: .9rem; }
  .home-side { grid-template-columns: minmax(0, 1fr); }
  .feed { max-height: none; }
  .card.banner { grid-template-columns: minmax(0, 1fr); }
  .cd-body { grid-template-columns: minmax(0, 1fr); }
  .char-detail .portrait { min-height: 14rem; }
  .modal-card { max-height: 92vh; }
  .dock { position: sticky; bottom: 0; grid-template-columns: minmax(0, 1fr); gap: .7rem; padding: .7rem var(--pad) calc(.7rem + env(safe-area-inset-bottom)); }
  .dock-btns .btn { flex: 1; }
  .btn.play { min-width: 0; }
  .toast { bottom: 9rem; }
}

/* Celular estrecho: se recorta lo prescindible antes de dejar que algo desborde. */
@media (max-width: 480px) {
  :root { --pad: 12px; --gap: 10px; }
  .brand span { display: none; }
  #myName { max-width: 5.5rem; }
  .dock-meta { display: none; }
  .dock-status { grid-template-columns: minmax(0, 1fr); grid-template-areas: "line" "bar" "acts"; }
  /* En un celular el aviso de estado puede ser largo: aquí parte en varias
     líneas, que es mejor que salirse de la pantalla. Hace falta quitarle el
     flex:none del diseño ancho, o se niega a encoger y se corta igual. */
  .dock-text { white-space: normal; flex: 1 1 auto; min-width: 0; }
  .dock-acts { flex-wrap: wrap; }
  .auth-card { padding: 1.5rem 1.1rem; }
  .brand-big { font-size: 2.1rem; }
  .cards { grid-template-columns: minmax(0, 1fr); }
  .char-list .char-card { flex: 1 1 100%; }
  .person { grid-template-columns: 2.4rem minmax(0, 1fr); }
  .person .acts { grid-column: 1 / -1; justify-content: flex-start; }
  .clan-head > div[style] { margin-left: 0 !important; width: 100%; }
  /* En un celular el nombre del ajuste necesita más sitio que su control */
  #gameSettings .field, #appSettings .field,
  #gameSettings .check.fila, #appSettings .check.fila { grid-template-columns: minmax(0, 1fr) minmax(5rem, 8.5rem); gap: .3rem .7rem; }
}

/* Pantallas bajas y apaisadas: el arte no puede comerse el alto. */
@media (max-height: 620px) and (min-width: 861px) {
  .art-info { padding: 1.1rem 1.2rem 1.2rem; gap: .3rem; }
  .art-info p { -webkit-line-clamp: 1; }
  .art-info h2 { font-size: 1.3rem; }
}

/* Quien prefiera menos movimiento no ve nada animarse. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

/* ---------------------------------------------------------------------------
   15. DIAGNÓSTICO (Ajustes)
   Un cuaderno de lo que hace el juego en este equipo. Se lee y se copia; no se
   envía a ningún sitio.
   --------------------------------------------------------------------------- */
.diag-text {
  width: 100%; margin: .6rem 0 .5rem; padding: .6rem .75rem; border-radius: var(--radius-sm); resize: vertical;
  background: rgba(3, 6, 12, .8); border: 1px solid var(--line); color: #cdd6e6;
  font: 12px/1.45 var(--font-mono); white-space: pre;
}
.diag-text:focus { border-color: rgba(232, 193, 112, .5); }
#diagPanel .muted b { color: var(--gold); }

/* ============================================================================
   16. PIEZAS PREPARADAS QUE TODAVÍA NADIE PINTA
   ----------------------------------------------------------------------------
   El estilo ya está hecho; falta que launcher.js (o quien integre) genere el
   HTML. Cada una dice qué hay que hacer para encenderla.
   ============================================================================ */

/* AVISO DE RECONEXIÓN — se ve cuando el servidor no responde.
   PARA IMPLEMENTAR en launcher.js: en el catch de load(), si el error NO es 401,
   insertar al principio de #main:
     <div class="reconnect">Sin conexión con el servidor · reintentando…</div>
   y quitarlo en cuanto load() vuelva a funcionar. Ahora mismo ese caso solo
   saca un toast de 3,8 s y el usuario se queda sin saber qué pasa. */
.reconnect {
  display: flex; align-items: center; gap: .6rem; margin-bottom: var(--gap);
  padding: .6rem .9rem; border-radius: var(--radius-sm);
  background: rgba(244, 124, 114, .1); border: 1px solid rgba(244, 124, 114, .3);
  color: #fecaca; font-weight: 700; font-size: .88rem;
}
.reconnect::before { content: ''; width: .5rem; height: .5rem; border-radius: 50%; background: var(--busy); flex: none; }

/* ESQUELETOS DE CARGA — bloques grises mientras llegan los datos.
   PARA IMPLEMENTAR en launcher.js: antes del primer load(), rellenar #charList,
   #friendsFull y #homeFeed con unos cuantos <div class="skel"></div> con la
   altura de la fila real. Evita el salto feo de vacío a lleno.
   Nota: la animación es un degradado que se desplaza con transform, así que no
   cuesta apenas; aun así solo debe estar viva mientras dura la carga. */
.skel { position: relative; overflow: hidden; height: 3rem; border-radius: var(--radius-sm); background: rgba(255, 255, 255, .04); }
.skel::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .07), transparent);
  transform: translateX(-100%); animation: skel 1.3s ease-in-out infinite;
}
@keyframes skel { to { transform: translateX(100%); } }

/* MODO AHORRO — distintivo para cuando el launcher deja de preguntar al
   servidor porque el juego está abierto (ver launcher.js → modoAhorro).
   PARA IMPLEMENTAR si se quiere que se vea: añadir la clase 'saving' a
   #serverPill mientras dure, y quitarla al volver. Es solo informativo: el
   ahorro ya funciona sin esto. */
.server-pill.saving { opacity: .55; }
.server-pill.saving .ping { color: var(--muted); }

/* ============================================================================
   17. TEMA DEL JUEGO (29/09/2026)
   ----------------------------------------------------------------------------
   El launcher se viste igual que el HUD y las pantallas del juego
   (1-JUEGO/fuente/estilos 01, 16 y 17): azul marino translúcido, hilo dorado
   fino con escuadras en las esquinas, marfil para el texto, botones de oro con
   escalón, barras con brillo (azul de maná y oro de experiencia) y títulos de
   sección en mayúsculas espaciadas, como «MISIONES».
   Solo cambia CÓMO SE VE: no toca medidas, densidades ni nombres de clase.
   Para volver al diseño anterior basta con borrar este apartado entero
   (copia en copias/antes-fantasia-20260929).
   Sin backdrop-filter y sin animaciones nuevas: las escuadras son SVG en el
   propio fondo del panel, no elementos ni pseudo-elementos.
   ============================================================================ */
:root {
  /* Colores del juego */
  --bg: #060a14; --bg2: #0a1020;
  --card: rgba(11, 17, 34, .86); --card2: rgba(18, 27, 50, .9);
  --sunken: rgba(3, 6, 14, .5);
  --line: rgba(226, 191, 116, .13); --line2: rgba(226, 191, 116, .24); --line3: rgba(226, 191, 116, .45);
  --text: #f2ead9; --soft: #c9cfdc; --muted: #8e98ad;
  --gold: #ecc35f; --gold2: #f8ecc6; --gold3: #b9852c;
  --teal: #5cc4ff;                                   /* el acento frío del juego es el azul del maná */
  --danger: #ff6b82;
  --gold-soft: rgba(236, 195, 95, .14); --gold-line: rgba(226, 191, 116, .45);
  --online: #6fe08a; --playing: #7ccfff;
  --glow: 0 0 0 1px var(--gold-line), 0 8px 24px rgba(236, 195, 95, .18);
  --sh2: 0 8px 22px rgba(0, 0, 0, .45);
  --sh3: 0 18px 46px rgba(0, 0, 0, .55);

  /* Panel del juego (.vd-panel) */
  --vd-bg: linear-gradient(160deg, rgba(11, 17, 34, .9), rgba(5, 8, 17, .94));
  --vd-sh: 0 12px 32px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .05);
  /* Escuadras doradas: arriba a la izquierda y abajo a la derecha, encima del borde */
  --c-tl: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23ecc35f' stroke-width='1.5'%3E%3Cpath d='M.75 14V3Q.75.75 3 .75h11'/%3E%3C/svg%3E");
  --c-br: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none' stroke='%23ecc35f' stroke-width='1.5'%3E%3Cpath d='M13.25 0v11q0 2.25-2.25 2.25H0'/%3E%3C/svg%3E");
  --orn: var(--c-tl) left top / 14px no-repeat border-box, var(--c-br) right bottom / 14px no-repeat border-box;

  /* Barras con brillo, como las de vida, maná y experiencia del HUD */
  --bar-mp: linear-gradient(#7ccfff, #1ea3ff 45%, #0e6fd6);
  --bar-xp: linear-gradient(#ffe98f, #f0b62a);
  --bar-gloss: inset 0 1.5px 0 rgba(255, 255, 255, .28), inset 0 -2px 3px rgba(0, 0, 0, .2);
}

/* ---------- Base ---------- */
::selection { background: rgba(236, 195, 95, .3); color: #fff; }
* { scrollbar-color: rgba(226, 191, 116, .3) transparent; }
::-webkit-scrollbar-thumb { background: rgba(226, 191, 116, .28); background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: rgba(226, 191, 116, .5); background-clip: content-box; }

.shell {
  background:
    radial-gradient(ellipse 70% 55% at 15% -12%, rgba(30, 163, 255, .08), transparent 62%),
    radial-gradient(ellipse 55% 45% at 105% 112%, rgba(236, 195, 95, .08), transparent 62%),
    linear-gradient(180deg, #0a1020, var(--bg) 60%);
}

/* ---------- Botones ---------- */
/* Normal: el botón oscuro de las pantallas del juego (.vd-btn) */
.btn {
  border-radius: 10px; color: var(--text); border: 1px solid rgba(226, 191, 116, .2);
  background: linear-gradient(180deg, rgba(14, 21, 40, .82), rgba(6, 10, 20, .9));
}
.btn:hover { border-color: var(--gold-line); background: linear-gradient(180deg, rgba(24, 33, 58, .9), rgba(10, 15, 28, .92)); box-shadow: 0 0 0 1px rgba(226, 191, 116, .12), 0 8px 20px rgba(0, 0, 0, .4); }
.btn:disabled:hover { border-color: rgba(226, 191, 116, .2); background: linear-gradient(180deg, rgba(14, 21, 40, .82), rgba(6, 10, 20, .9)); box-shadow: none; }
/* Principal: el botón de oro del juego, con su escalón debajo */
.btn.primary {
  color: #1d1406; background: linear-gradient(#f3d38c, #d6a64b); border: 1px solid #8b6a2c;
  box-shadow: 0 3px 0 #7a5a20, 0 6px 14px rgba(0, 0, 0, .35); font-weight: 800;
}
.btn.primary:hover { filter: brightness(1.1); border-color: #8b6a2c; box-shadow: 0 3px 0 #7a5a20, 0 6px 14px rgba(0, 0, 0, .35); }
.btn.primary:active { transform: translateY(2px); box-shadow: 0 1px 0 #7a5a20; }
.btn.ghost { background: rgba(255, 255, 255, .03); }
.btn.ghost:hover { background: rgba(236, 195, 95, .08); }
.btn.danger { color: var(--danger); border-color: rgba(255, 107, 130, .38); background: rgba(255, 53, 88, .06); }
.btn.danger:hover { background: rgba(255, 53, 88, .16); border-color: rgba(255, 107, 130, .7); }

/* ---------- Campos ---------- */
input:not([type=checkbox]):not([type=range]), select, textarea, .sel-btn {
  background: rgba(3, 6, 14, .55); border-color: rgba(226, 191, 116, .2); border-radius: 10px;
}
input:hover:not([type=checkbox]):not([type=range]), select:hover, .sel-btn:hover { border-color: rgba(226, 191, 116, .38); }
input:focus, select:focus, textarea:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(236, 195, 95, .15); background: rgba(3, 6, 14, .7); }
.sel-menu, .dropdown { background: linear-gradient(160deg, #0e1630, #070b17); border-color: var(--gold-line); box-shadow: var(--sh3), inset 0 1px 0 rgba(255, 255, 255, .05); }
.sel-menu button:hover, .dropdown button:hover { background: rgba(236, 195, 95, .09); color: var(--text); }
select option { background: #0e1630; }
.dd-title { color: var(--gold); letter-spacing: .18em; }
.dropdown hr { border-top-color: var(--line2); }

/* Botones de icono: redondos, como los de arriba del HUD */
.icon-btn { border-radius: 50%; background: rgba(8, 12, 22, .78); border: 1.5px solid rgba(226, 191, 116, .45); box-shadow: 0 3px 8px rgba(0, 0, 0, .4), inset 0 0 10px rgba(0, 0, 0, .5); }
.icon-btn:hover { background: rgba(20, 30, 54, .9); border-color: var(--gold); color: var(--gold2); }
.user-btn { border-radius: 999px; background: rgba(8, 12, 22, .78); border: 1.5px solid rgba(226, 191, 116, .45); box-shadow: 0 3px 10px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255, 236, 190, .1); }
.user-btn:hover { background: rgba(20, 30, 54, .9); border-color: var(--gold); }
/* Aviso rojo del HUD */
.badge { background: linear-gradient(#ff4a5a, #d9182e); box-shadow: 0 0 0 2px var(--bg), 0 2px 4px rgba(0, 0, 0, .5); font-weight: 900; }

.tag.news { background: rgba(92, 196, 255, .14); color: #a6dbff; }
.tag.patch { background: rgba(236, 195, 95, .16); color: var(--gold2); }
.tag.event { background: rgba(111, 224, 138, .14); color: #9df0b2; border: 0; margin: 0; }   /* .event (la caja de eventos) también la pillaba */
.tag.soon { background: rgba(179, 107, 255, .16); color: #d6b8ff; }

/* ---------- Paneles: el marco de Veldaroz ---------- */
.panel, .box {
  background: var(--orn), var(--vd-bg);
  border: 1px solid var(--gold-line);
  box-shadow: var(--vd-sh);
}
.box::after, .friends-layout > .panel:first-child::after { background: linear-gradient(rgba(5, 8, 17, 0), rgba(5, 8, 17, .96)); }

/* Títulos de sección como «MISIONES» en el HUD: oro, mayúsculas espaciadas */
.row-title h3, .box-h h3, .cd-exp-top h3, .cd-col > h3 {
  font: 800 .78rem var(--font); letter-spacing: .2em; text-transform: uppercase; color: var(--gold);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}
/* Hilo dorado que se apaga hacia los lados, bajo el título (como .qhead) */
.box-h { position: relative; padding-bottom: .45rem; }
.box-h::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: linear-gradient(90deg, rgba(226, 191, 116, 0), rgba(226, 191, 116, .4) 15%, rgba(226, 191, 116, .4) 85%, rgba(226, 191, 116, 0)); }
#gameSettings .grp, #appSettings .grp { color: var(--gold); letter-spacing: .2em; }
.empty { border-color: rgba(226, 191, 116, .25); }

/* ---------- Barra de arriba ---------- */
.top {
  background: linear-gradient(180deg, rgba(10, 16, 32, .96), rgba(6, 10, 20, .92));
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, rgba(226, 191, 116, 0), rgba(226, 191, 116, .55) 20%, rgba(226, 191, 116, .55) 80%, rgba(226, 191, 116, 0)) 1;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .4);
}
.brand { color: var(--gold2); }
.tabs a { font-weight: 800; letter-spacing: .06em; color: var(--soft); text-shadow: 0 1px 2px rgba(0, 0, 0, .6); }
.tabs a:hover { color: #fff; background: linear-gradient(180deg, transparent, rgba(236, 195, 95, .06)); }
.tabs a.on { color: var(--gold2); background: linear-gradient(180deg, transparent 20%, rgba(236, 195, 95, .1)); }
.tabs a::after { background: linear-gradient(90deg, rgba(236, 195, 95, 0), var(--gold) 25%, var(--gold2) 50%, var(--gold) 75%, rgba(236, 195, 95, 0)); }
/* Rombo dorado de la pestaña elegida: el mismo remate que las barras de vida */
.tabs a::before {
  content: ''; position: absolute; left: 50%; bottom: 1px; width: 6px; height: 6px; margin-left: -3px; z-index: 1;
  background: var(--gold2); border: 1px solid #8b6a2c; transform: rotate(45deg) scale(0); transition: transform var(--t-slow);
}
.tabs a.on::before { transform: rotate(45deg) scale(1); }
/* Píldora del servidor como las del HUD (.pill) */
.server-pill { background: rgba(8, 12, 22, .78); border: 1.5px solid rgba(226, 191, 116, .45); box-shadow: 0 3px 10px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255, 236, 190, .1); color: var(--text); }

/* ---------- Inicio ---------- */
.art { border: 1px solid var(--gold-line); box-shadow: var(--vd-sh); background: #0a1020; }
.art::after {
  background:
    linear-gradient(90deg, rgba(5, 8, 17, .92) 0%, rgba(5, 8, 17, .58) 36%, rgba(5, 8, 17, 0) 66%),
    linear-gradient(0deg, rgba(5, 8, 17, .9) 0%, rgba(5, 8, 17, 0) 48%);
}
.art::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: var(--orn); }
.art-kicker { color: var(--gold); text-shadow: 0 1px 3px rgba(0, 0, 0, .8); }
.art-info h2 { color: var(--gold2); }
.btn.art-btn { border-color: rgba(226, 191, 116, .55); background: rgba(8, 12, 22, .7); }
.btn.art-btn:hover { background: rgba(236, 195, 95, .18); }
/* Puntos del carrusel en rombo */
.sl-dots button { width: 7px; height: 7px; margin: 0 .2rem; border-radius: 1px; transform: rotate(45deg); background: rgba(255, 255, 255, .4); }
.sl-dots button.on { width: 7px; background: var(--gold); box-shadow: 0 0 6px rgba(236, 195, 95, .8); transform: rotate(45deg) scale(1.4); }
.sl-nav { background: rgba(8, 12, 22, .78); border: 1.5px solid rgba(226, 191, 116, .45); color: var(--gold2); }
.sl-nav:hover { background: rgba(20, 30, 54, .9); border-color: var(--gold); }

.hero-card {
  background: var(--orn), radial-gradient(ellipse 90% 80% at 0% 0%, rgba(236, 195, 95, .12), transparent 62%), var(--vd-bg);
  border: 1px solid var(--gold-line); box-shadow: var(--vd-sh);
}
.hc-kicker, .hero-kicker { color: var(--gold); }
.hc-info b, .char-detail h2, .clan-head h2, .cuenta-quien b, .modal-top h2 { color: var(--gold2); }
.hc-meta { border-top-color: var(--line2); }
.tag.clan { color: #a6dbff; }
.feed a:hover { background: rgba(236, 195, 95, .07); }

/* ---------- Barra de abajo ---------- */
.dock {
  background: linear-gradient(180deg, rgba(10, 16, 32, .98), rgba(4, 7, 15, .99));
  border-top: 1px solid transparent;
  border-image: linear-gradient(90deg, rgba(226, 191, 116, 0), rgba(226, 191, 116, .6) 15%, rgba(226, 191, 116, .6) 85%, rgba(226, 191, 116, 0)) 1;
  box-shadow: 0 -8px 24px rgba(0, 0, 0, .4);
}
/* Descarga: la barra de maná del HUD, con el rombo dorado al final */
.pbar { background: rgba(0, 0, 0, .45); border: 1px solid rgba(226, 191, 116, .35); box-shadow: 0 1px 4px rgba(0, 0, 0, .35); }
.pbar i { background: var(--bar-mp); box-shadow: var(--bar-gloss); }
.pbar[data-pct]::after { text-shadow: 0 1px 2px rgba(0, 0, 0, .85), 0 0 3px rgba(0, 0, 0, .6); }
.pbar.paused i { background: linear-gradient(#b8bfcc, #6b7385); box-shadow: var(--bar-gloss); }
/* JUGAR: el botón de oro del juego, en grande */
.btn.play {
  border-radius: 12px; color: #1d1406; letter-spacing: .1em; font-weight: 900;
  background: linear-gradient(#f8dc98, #e0b057 55%, #c99238);
  border: 1px solid #8b6a2c;
  box-shadow: 0 4px 0 #7a5a20, 0 10px 22px rgba(0, 0, 0, .45), 0 0 22px rgba(236, 195, 95, .18), inset 0 1px 0 rgba(255, 255, 255, .55);
  text-shadow: 0 1px 0 rgba(255, 240, 200, .5);
}
.btn.play:hover:not(:disabled) { filter: brightness(1.08); box-shadow: 0 4px 0 #7a5a20, 0 12px 26px rgba(0, 0, 0, .45), 0 0 30px rgba(236, 195, 95, .32), inset 0 1px 0 rgba(255, 255, 255, .55); }
.btn.play:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 #7a5a20, 0 6px 14px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .55); }
.btn.update { color: #a6dbff; border-color: rgba(92, 196, 255, .55); background: linear-gradient(180deg, rgba(30, 163, 255, .2), rgba(14, 111, 214, .08)); }
.btn.update:hover:not(:disabled) { background: linear-gradient(180deg, rgba(30, 163, 255, .3), rgba(14, 111, 214, .14)); border-color: #7ccfff; }
.btn.stop { color: #ffb0bd; border-color: rgba(255, 107, 130, .5); background: rgba(255, 53, 88, .1); }

/* ---------- Personajes, avatares y equipo ---------- */
.avatar { border: 1.5px solid rgba(226, 191, 116, .6); background: radial-gradient(circle at 45% 40%, rgba(38, 52, 82, .9), rgba(10, 14, 26, .95)); box-shadow: 0 3px 8px rgba(0, 0, 0, .4); }
.avatar svg { color: rgba(236, 195, 95, .75); }
.presencia { box-shadow: 0 0 0 2px #0a1020; }
.char-card { background: var(--vd-bg); border-color: var(--line2); }
.char-card:hover { border-color: var(--gold-line); background: linear-gradient(160deg, rgba(20, 30, 54, .92), rgba(8, 12, 24, .94)); }
.char-card.on { border-color: var(--gold); background: var(--orn), linear-gradient(160deg, rgba(236, 195, 95, .12), rgba(11, 17, 34, .92) 55%); box-shadow: 0 0 0 1px rgba(236, 195, 95, .25), 0 0 16px rgba(236, 195, 95, .14); }
.char-card.new:hover { color: var(--gold2); border-color: var(--gold-line); }
.cd-head { border-bottom-color: var(--line2); }
.char-detail .portrait { border-color: var(--gold-line); background: radial-gradient(ellipse at 50% 72%, rgba(236, 195, 95, .12), transparent 70%), rgba(3, 6, 14, .6); }
/* Experiencia: la barra de experiencia del HUD */
.bar { background: rgba(10, 10, 6, .45); box-shadow: 0 0 0 1px rgba(226, 191, 116, .5), 0 1px 3px rgba(0, 0, 0, .4); }
.bar i { background: var(--bar-xp); box-shadow: var(--bar-gloss); }
.stat { background: rgba(3, 6, 14, .5); border: 1px solid var(--line); }

/* ---------- Clan y cuenta ---------- */
.clan-emblem { background: radial-gradient(circle at 45% 40%, rgba(38, 52, 82, .9), rgba(10, 14, 26, .95)); border: 1.5px solid var(--gold); box-shadow: 0 3px 8px rgba(0, 0, 0, .4); }
.rank.officer { background: rgba(92, 196, 255, .14); color: #a6dbff; }
#accountPanel { background: var(--orn), radial-gradient(ellipse 90% 50% at 50% 0%, rgba(236, 195, 95, .12), transparent 65%), var(--vd-bg); border-color: var(--gold-line); }
.cuenta-id { border-bottom-color: var(--line2); }
.cuenta-id .presencia { box-shadow: 0 0 0 3px #0a1020; }

/* ---------- Noticias ---------- */
.card { background: var(--vd-bg); border: 1px solid var(--line2); }
.card:hover { border-color: var(--gold-line); }
.card .img { border-bottom: 1px solid var(--line2); }
.card.banner { background: var(--orn), var(--vd-bg); border-color: var(--gold-line); }

/* ---------- Pantalla de cuenta ---------- */
.auth { background: linear-gradient(rgba(5, 8, 17, .45), rgba(5, 8, 17, .9)), url('/launcher/arte-1.jpg') center / cover no-repeat, var(--bg); }
.auth-card {
  border-radius: 12px; background: var(--orn), var(--vd-bg);
  border: 1px solid var(--gold-line); box-shadow: 0 18px 46px rgba(0, 0, 0, .55), inset 0 1px 0 rgba(255, 255, 255, .05);
}
.auth-sub { display: flex; align-items: center; gap: .8rem; color: var(--soft); }
.auth-sub::before, .auth-sub::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, rgba(226, 191, 116, 0), rgba(226, 191, 116, .5)); }
.auth-sub::after { background: linear-gradient(90deg, rgba(226, 191, 116, .5), rgba(226, 191, 116, 0)); }
.legal-bloque { background: rgba(3, 6, 14, .5); border-color: var(--line2); }

/* ---------- Carga, ventanas y avisos ---------- */
.boot { background: radial-gradient(ellipse at 50% 38%, #111b36, var(--bg) 72%); }
.spinner { border-color: rgba(226, 191, 116, .15); border-top-color: var(--gold); }
.modal, .legal-lector { background: rgba(2, 4, 10, .78); }
.modal-card, .legal-caja { background: var(--orn), linear-gradient(160deg, #0e1630, #060a15); border: 1px solid var(--gold-line); box-shadow: var(--sh3); }
.legal-caja > header, .legal-caja > footer { border-color: var(--line2); }
.legal-baja { background: linear-gradient(#f3d38c, #d6a64b); border: 1px solid #8b6a2c; }
.toast { background: linear-gradient(160deg, #0e1630, #070b17); border-color: var(--gold-line); }

html.frameless .appbar { background: #04070f; border-bottom: 1px solid var(--line2); }
.win-ctl button:hover { background: rgba(236, 195, 95, .12); color: var(--gold2); }
.win-ctl button.close:hover { background: #d9182e; color: #fff; }

.diag-text { background: rgba(3, 6, 14, .85); border-color: var(--line2); }

@media (max-width: 860px) {
  .top { background: linear-gradient(180deg, rgba(10, 16, 32, .99), rgba(6, 10, 20, .98)); }
}
