/* ============================================================
   necROmantic — Modern layout (navbar + hero slider, no sidebar)
   Extends themes/necromantic/css/unknown.css — tokens are inherited.
   ============================================================ */

:root {
    --font-display: "Cinzel", "Alegreya Sans", serif;
    --nav-height: 84px;
    --scrim-hero:
        linear-gradient(0deg, rgba(8, 5, 16, 0.92) 0%, rgba(8, 5, 16, 0.55) 42%, rgba(8, 5, 16, 0.25) 70%, rgba(8, 5, 16, 0.5) 100%);
}

.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    left: 8px;
    top: -60px;
    z-index: 1000;
    background: var(--gold);
    color: var(--text-on-accent);
    padding: 10px 16px;
    border-radius: 10px;
    font-weight: 700;
    transition: top 0.2s ease;
}
.skip-link:focus {
    top: 8px;
    text-decoration: none;
}

/* The base theme (flux.css) locks html/body to a fixed 100vh app-shell
   with overflow:hidden, meant for the old sidebar layout's internal
   scrolling pane. This theme is a normal, page-scrolling document, so
   that mechanic is invalid here and must be fully overridden. */
html.theme-modern-doc {
    height: auto;
    min-height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
}
html.theme-modern-doc body.theme-modern {
    height: auto;
    min-height: 100%;
    display: block;
    overflow: visible;
}

/* Every raw <button> in the base theme gets a generic hand-point icon
   (button::before, flux.css) meant for old CP action buttons. Our nav
   buttons, toggles and dots supply their own icon (or none) explicitly,
   so it must not leak in here. */
body.theme-modern button::before {
    content: none;
}

/* ── Navbar ────────────────────────────────────────────────── */
#site-header-modern {
    position: sticky;
    top: 0;
    z-index: 200;
    background: var(--grad-header);
    box-shadow: var(--shadow-header);
}

.header-modern__bar {
    min-height: var(--nav-height);
    padding: 10px 28px;
    display: flex;
    align-items: center;
    gap: 22px;
}

.header-modern__bar #logo-link {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    text-decoration: none !important;
}
.header-modern__bar #logo-mark {
    width: 54px;
    height: 54px;
    object-fit: contain;
    filter: var(--shadow-logo);
}
.header-modern__bar #logo-text .logo-nec,
.header-modern__bar #logo-text .logo-mantic {
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 700;
    color: var(--text-logo);
}
.header-modern__bar #logo-text .logo-ro {
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 900;
    color: var(--gold);
    text-shadow: 0 0 16px var(--alpha-gold-42);
}
.header-modern__bar #logo-text .logo-tagline {
    display: block;
    font-size: 7pt;
    color: var(--text-logo-tagline);
    letter-spacing: 2px;
    text-transform: uppercase;
    margin-top: 3px;
}

#nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 40px;
    height: 40px;
    margin-left: auto;
    border-radius: 10px;
    background: var(--alpha-white-05);
    cursor: pointer;
}
#nav-toggle span {
    display: block;
    width: 20px;
    height: 2px;
    margin: 0 auto;
    background: var(--text-heading2);
    transition: transform 0.25s ease, opacity 0.2s ease;
}
#nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
#nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
#nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

#primary-nav {
    flex: 1;
    display: flex;
    justify-content: center;
}
.primary-nav__list {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    padding: 0;
}
.primary-nav__item { position: relative; }

.nav-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-radius: 12px;
    background: transparent;
    color: var(--text-heading2);
    font-family: var(--font-display);
    font-size: 9.5pt;
    letter-spacing: 0.3px;
    cursor: pointer;
    text-decoration: none !important;
    transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.15s ease;
}
.nav-link i:not(.nav-caret) { color: var(--gold); font-size: 9pt; }
.nav-link:hover,
.nav-link:focus-visible {
    background: var(--alpha-gold-12);
    color: var(--text-link-hover);
    transform: translateY(-1px);
}
.nav-caret { font-size: 7pt; margin-left: 2px; transition: transform 0.2s ease; opacity: 0.8; }
.has-dropdown:hover .nav-caret,
.has-dropdown.is-open .nav-caret { transform: rotate(180deg); }

.dropdown-panel {
    position: absolute;
    /* necROmantic 2026-07-29: pegado al elemento del menu, sin los 8px de separacion que
       habia antes. Esos 8px eran un hueco muerto: el desplegable se abre al pasar el raton,
       y al cruzarlo se salia del area activa y el menu se cerraba solo. */
    top: calc(100%);
    left: 0;
    min-width: 240px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px;
    border-radius: 18px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
    z-index: 210;
}
.dropdown-panel--right { left: auto; right: 0; }
.dropdown-panel__meta {
    padding: 6px 10px 10px;
    margin-bottom: 6px;
    font-size: 8pt;
    color: var(--text-muted);
}
.has-dropdown:hover .dropdown-panel,
.has-dropdown.is-open .dropdown-panel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.dropdown-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: 10px;
    color: var(--text-primary);
    font-size: 9pt;
    text-decoration: none !important;
    transition: background 0.15s ease, color 0.15s ease, padding-left 0.15s ease;
}
.dropdown-link i { color: var(--gold); width: 16px; text-align: center; }
.dropdown-link:hover {
    background: var(--alpha-gold-12);
    color: var(--text-link-hover);
    padding-left: 14px;
}

.header-modern__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

/* necROmantic 2026-07-29: el chip de cuenta tiene que ser un contenedor posicionado.
   Su .dropdown-panel es position:absolute, y sin esto el ancestro posicionado mas cercano
   pasaba a ser #site-header-modern (que es sticky, y sticky cuenta como posicionado). El
   panel se anclaba entonces a la cabecera entera: caia a los 84px del navbar en vez de a los
   60px del boton, 24px mas abajo, y el right:0 de --right lo alineaba al borde de la pagina
   en lugar de al del chip. Los menus de navegacion no lo sufrian porque
   .primary-nav__item ya lleva position: relative. */
.account-chip { position: relative; }

.account-chip__trigger {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 14px;
    border-radius: 999px;
    background: var(--surface-header-account);
    color: var(--text-header-account);
    font-size: 9pt;
    cursor: pointer;
}
.account-chip__trigger i.fa-circle-user { color: var(--gold); font-size: 12pt; }
.account-chip__name { font-weight: 700; color: var(--text-heading2); }

.btn-primary,
.btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    border-radius: 999px;
    font-size: 9pt;
    font-weight: 700;
    letter-spacing: 0.2px;
    text-decoration: none !important;
    transition: transform 0.18s ease, box-shadow 0.22s ease, background 0.22s ease, border-color 0.22s ease;
    white-space: nowrap;
}
.btn-primary {
    background: var(--grad-primary-button);
    color: var(--text-on-accent);
    box-shadow: 0 10px 22px var(--alpha-gold-20);
}
.btn-primary:hover {
    background: var(--grad-primary-button-hover);
    transform: translateY(-2px);
    box-shadow: var(--shadow-button-hover);
    color: var(--text-on-accent-strong);
}
.btn-ghost {
    background: var(--alpha-white-05);
    color: var(--text-heading2);
}
.btn-ghost:hover {
    color: var(--text-link-hover);
    transform: translateY(-2px);
    background: var(--alpha-gold-08);
}
.btn-lg { padding: 14px 26px; font-size: 10.5pt; }

/* ── Full-width content (no sidebar) ──────────────────────── */
#site-content-full {
    width: 100%;
    min-width: 0;
    padding: 18px 28px 0;
}

#site-content-full #content-panel {
    max-width: 1240px;
    width: 100%;
    margin: 4px auto 0;
    padding: 24px 28px;
    background: var(--bg-content);
    border-radius: 26px;
    box-shadow: var(--shadow-content);
    min-height: 0;
}

/* The homepage builds its own hero/sections full-bleed — the module
   pages (account, ranking, item db, ...) keep the card surface above. */
body.is-homepage #site-content-full #content-panel {
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
}

/* ── Hero slider ───────────────────────────────────────────── */
/* necROmantic 2026-07-29: el carrusel ya no vive dentro de #content-panel (ver header.php
   y main/heroslider.php). Va a sangre y pegado a la barra superior, asi que aqui se le
   quitan el margen negativo con el que antes se escapaba del panel y las esquinas
   redondeadas. Se centra solo y se corta a 1920px en pantallas muy anchas. */
.hero-slider {
    position: relative;
    /* OJO: el <body> de este tema es un contenedor flex en columna, asi que el carrusel es
       un item flex. Con "margin: 0 auto" el margen automatico se come el espacio libre y
       anula el estirado, y como TODO el contenido interior va en position:absolute el ancho
       natural resultante es 0 (carrusel invisible). Por eso hace falta width:100% explicito,
       igual que lo llevan #site-content-full y #content-panel. */
    width: 100%;
    margin: 0 auto;
    max-width: 1920px;
    height: min(74vh, 620px);
    min-height: 380px;
    overflow: hidden;
    border-radius: 0;
    box-shadow: var(--shadow-content);
}

.hero-slider__track { position: relative; width: 100%; height: 100%; }

/* necROmantic 2026-07-30: el cambio de diapositiva pasaba por el fondo de la pagina.
   Habia dos causas. Una: "visibility" cambiaba de valor pero no estaba en la lista de
   transition, asi que se aplicaba de golpe y la saliente desaparecia en el fotograma 0
   mientras la entrante subia de 0 a 1 durante un segundo sobre el fondo desnudo. Dos:
   aunque las dos se fundieran a la vez, en el punto medio ambas estarian al 50% y el
   fondo se colaria por debajo igualmente.
   Solucion: la saliente NO se funde. La marca .is-leaving (la pone modern.js) la deja
   opaca justo debajo mientras la entrante la cubre, y se retira cuando el fundido ya
   ha terminado. Como las imagenes del slider son opacas, en ningun momento hay un
   pixel del fondo a la vista. Si se toca la duracion de aqui hay que tocar tambien
   la opcion "fade" del carrusel en modern.js: las dos deben coincidir. */
.hero-slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    z-index: 0;
    /* el "0s linear 1s" retrasa el ocultado hasta que acaba el fundido, para que la
       diapositiva siga pintandose mientras dura */
    transition: opacity 1s ease, visibility 0s linear 1s;
}
.hero-slide.is-active {
    opacity: 1;
    visibility: visible;
    z-index: 2;
    transition: opacity 1s ease, visibility 0s;
}
.hero-slide.is-leaving {
    opacity: 1;
    visibility: visible;
    z-index: 1;
    transition: none;
}

.hero-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.05);
    animation: heroKenBurns 14s ease-in-out infinite alternate;
}
@keyframes heroKenBurns {
    from { transform: scale(1.05) translate(0, 0); }
    to   { transform: scale(1.16) translate(-1.5%, -1.5%); }
}

.hero-slide__scrim {
    position: absolute;
    inset: 0;
    background:
        var(--scrim-hero);
}

.hero-slide__content {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    max-width: 900px;
    margin: 0 auto;
    padding: 0 40px 56px;
    text-align: center;
}

.hero-kicker {
    display: inline-block;
    padding: 6px 14px;
    border-radius: 999px;
    background: var(--grad-silver-chip);
    color: var(--gold);
    font-size: 8pt;
    letter-spacing: 1.6px;
    text-transform: uppercase;
    opacity: 0;
    animation: heroFadeUp 0.8s ease 0.15s forwards;
}

.hero-title {
    font-family: var(--font-display);
    font-size: clamp(26px, 4vw, 46px);
    line-height: 1.12;
    margin: 16px 0 14px;
    color: var(--text-hero-title);
    text-shadow: 0 6px 30px rgba(0,0,0,0.55);
    border: 0;
    padding: 0;
    opacity: 0;
    animation: heroFadeUp 0.8s ease 0.28s forwards;
}

.hero-text {
    max-width: 62ch;
    margin: 0 auto;
    color: var(--text-hero-intro);
    font-size: 11pt;
    opacity: 0;
    animation: heroFadeUp 0.8s ease 0.4s forwards;
}

.hero-cta {
    margin-top: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    flex-wrap: wrap;
    opacity: 0;
    animation: heroFadeUp 0.8s ease 0.52s forwards;
}

@keyframes heroFadeUp {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

.hero-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--surface-header-account);
    color: var(--text-heading2);
    cursor: pointer;
    backdrop-filter: blur(6px);
    transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.hero-nav:hover { background: var(--alpha-gold-16);  transform: translateY(-50%) scale(1.06); }
.hero-nav--prev { left: 20px; }
.hero-nav--next { right: 20px; }

.hero-dots {
    position: absolute;
    left: 0; right: 0;
    bottom: 18px;
    z-index: 5;
    display: flex;
    justify-content: center;
    gap: 9px;
}
.hero-dot {
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--alpha-silver-42);
    cursor: pointer;
    padding: 0;
    transition: background 0.2s ease, transform 0.2s ease, width 0.2s ease;
}
.hero-dot.is-active {
    background: var(--gold);
    width: 24px;
    border-radius: 6px;
    box-shadow: 0 0 12px var(--alpha-gold-42);
}

/* ── Rates strip ───────────────────────────────────────────── */
.rates-strip {
    margin: 22px 0 0;
    padding: 16px 22px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 14px 30px;
    border-radius: 20px;
    background: var(--grad-hero);
    box-shadow: inset 0 1px 0 var(--alpha-white-04);
}
.rates-strip__item {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 9.5pt;
    color: var(--text-panel-soft);
}
.rates-strip__item i { color: var(--gold); font-size: 11pt; }
.rates-strip__item strong { color: var(--text-heading2); }

/* ── Generic section blocks ───────────────────────────────── */
.section-block { margin: 46px 0; }
.section-heading { max-width: 720px; margin: 0 auto 26px; text-align: center; }
.section-kicker {
    display: inline-block;
    color: var(--gold);
    font-size: 8pt;
    letter-spacing: 1.6px;
    text-transform: uppercase;
    margin-bottom: 8px;
}
.section-title {
    font-family: var(--font-display);
    font-size: 22px;
    color: var(--text-heading2);
    border: 0;
    padding: 0;
    margin: 0 0 8px;
    text-shadow: 0 0 14px var(--alpha-bronze-24);
}
.section-intro { color: var(--text-muted); font-size: 9.5pt; }
.section-empty { text-align: center; color: var(--text-muted); padding: 20px 0; }

/* ── Feature grid ──────────────────────────────────────────── */
.feature-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
}
.feature-card {
    padding: 22px;
    border-radius: 22px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
}
.feature-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-card), 0 0 24px var(--alpha-gold-16);
}
.feature-card__icon {
    width: 46px; height: 46px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 14px;
    margin-bottom: 14px;
    background: var(--alpha-gold-12);
    color: var(--gold);
    font-size: 16pt;
    transition: transform 0.25s ease;
}
.feature-card:hover .feature-card__icon { transform: rotate(-6deg) scale(1.08); }
.feature-card__title {
    font-family: var(--font-display);
    font-size: 12pt;
    color: var(--text-heading2);
    border: 0; padding: 0; margin: 0 0 8px;
    text-transform: none;
    letter-spacing: 0;
}
.feature-card__text { color: var(--text-muted); font-size: 9pt; line-height: 1.55; margin: 0; }

/* ── Steps ─────────────────────────────────────────────────── */
.steps-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
}
.step-card {
    position: relative;
    padding: 24px 22px 22px;
    border-radius: 22px;
    background: var(--alpha-gold-12);
    text-align: center;
}
.step-card__number {
    width: 40px; height: 40px;
    margin: 0 auto 12px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--grad-primary-button);
    color: var(--text-on-accent);
    font-family: var(--font-display);
    font-weight: 900;
    font-size: 13pt;
    box-shadow: 0 8px 20px var(--alpha-gold-24);
}
.step-card__title {
    font-family: var(--font-display);
    font-size: 11pt;
    color: var(--text-heading2);
    border: 0; padding: 0; margin: 0 0 6px;
    text-transform: none;
}
.step-card__text { color: var(--text-muted); font-size: 8.8pt; margin: 0; }

/* ── News grid ─────────────────────────────────────────────── */
.news-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}
.news-card {
    padding: 20px;
    border-radius: 20px;
    background: var(--bg-content);
    box-shadow: var(--shadow-soft);
}
.news-card__title { font-family: var(--font-display); font-size: 11.5pt; color: var(--text-heading); margin: 0 0 6px; border: 0; padding: 0; }
.news-card__meta { font-size: 7.8pt; color: var(--text-muted); margin-bottom: 8px; }
.news-card__body { font-size: 9pt; color: var(--text-primary); line-height: 1.55; }
.news-card__modified { font-size: 7.5pt; color: var(--text-muted); margin-top: 8px; }
.news-card__link { display: inline-block; margin-top: 10px; font-size: 8.5pt; color: var(--gold); }
.news-card__link:hover { color: var(--text-link-hover); }

/* ── Footer ────────────────────────────────────────────────── */
#site-footer-modern {
    margin: 40px -28px 0;
    padding: 40px 28px 24px;
    background: var(--grad-footer);
}
.footer-modern__grid {
    max-width: 1240px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1.4fr repeat(3, 1fr);
    gap: 24px;
}
.footer-modern__col h4 {
    font-family: var(--font-display);
    font-size: 9.5pt;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--gold);
    margin: 0 0 12px;
}
.footer-modern__col a {
    display: block;
    padding: 5px 0;
    color: var(--text-footer);
    font-size: 9pt;
    text-decoration: none !important;
}
.footer-modern__col a:hover { color: var(--text-footer-link); padding-left: 4px; }
.footer-brand {
    font-family: var(--font-display);
    font-size: 17px;
    margin-bottom: 10px;
}
.footer-modern__brand p { color: var(--text-footer); font-size: 8.8pt; line-height: 1.6; max-width: 40ch; }

.footer-modern__bottom {
    max-width: 1240px;
    margin: 28px auto 0;
    padding-top: 18px;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 8pt;
    color: var(--text-footer);
}
.footer-modern__bottom a { color: var(--text-footer-link); }

/* ── Motion sensitivity ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .hero-slide img { animation: none; transform: none; }
    .hero-kicker, .hero-title, .hero-text, .hero-cta { animation: none; opacity: 1; }
    .feature-card, .btn-primary, .btn-ghost, .hero-nav, .news-nav { transition: none; }
}

/* ── Responsive ────────────────────────────────────────────── */
@media (max-width: 1080px) {
    .feature-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .steps-grid { grid-template-columns: 1fr; }
    .news-grid { grid-template-columns: 1fr; }
    .footer-modern__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
    #nav-toggle { display: flex; }
    #primary-nav {
        position: fixed;
        top: var(--nav-height);
        left: 0; right: 0;
        bottom: 0;
        background: var(--bg-header);
        padding: 16px;
        overflow-y: auto;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        z-index: 199;
        justify-content: flex-start;
    }
    #primary-nav.is-open { transform: translateX(0); }
    .primary-nav__list { flex-direction: column; align-items: stretch; width: 100%; gap: 6px; }
    .nav-link { width: 100%; justify-content: flex-start; }
    .dropdown-panel {
        position: static;
        opacity: 1; visibility: visible; transform: none;
        display: none;
        box-shadow: none;
        margin: 4px 0 4px 14px;
    }
    .has-dropdown.is-open .dropdown-panel { display: flex; }
    .account-chip__name { display: none; }
    .hero-slider { margin: 0; border-radius: 0; } /* necROmantic 2026-07-29: a sangre tambien en movil */
    #site-content-full { padding: 14px 18px 0; }
    .header-modern__bar { padding: 10px 18px; }
}

@media (max-width: 640px) {
    .feature-grid { grid-template-columns: 1fr; }
    .footer-modern__grid { grid-template-columns: 1fr; }
    .hero-cta { flex-direction: column; align-items: stretch; }
    .hero-cta .btn-lg { justify-content: center; }
    #site-footer-modern { margin: 32px -18px 0; padding: 32px 18px 20px; }
}

/* ==========================================================================
   necROmantic 2026-07-28 — Estado del servidor dentro del desplegable
   "Informacion": tres LEDs (login / personajes / mapas) y el numero de
   jugadores conectados ahora mismo.

   El dato lo aporta necromantic_modern_server_status() en header.php, cacheado
   en fichero con el TTL de ServerStatusCache. El contador excluye a los
   vendedores en @autotrade y a los companions @helpme (`online` = 2 en la BD).

   Para revertir: borrar este bloque y el bloque .server-status-mini de
   header.php (el desplegable vuelve a mostrar solo los enlaces).
   ========================================================================== */
.server-status-mini {
    padding: 10px 10px 12px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--alpha-white-05, rgba(255, 255, 255, 0.06));
}
.server-status-mini__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}
.server-status-mini__title {
    font-family: var(--font-display);
    font-size: 8.4pt;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-heading2);
}
.server-status-mini__players {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    font-size: 8.2pt;
    color: var(--text-muted);
    white-space: nowrap;
}
.server-status-mini__players i { color: var(--gold); font-size: 8pt; }
.server-status-mini__players strong {
    color: var(--gold);
    font-size: 10pt;
    font-weight: 700;
}
.server-status-mini__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.server-status-mini__row {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 8.6pt;
    color: var(--text-primary);
}
.server-status-mini__name { flex: 1 1 auto; }
.server-status-mini__state {
    font-size: 7.8pt;
    color: var(--text-muted);
    white-space: nowrap;
}

/* necROmantic 2026-08-23 — toda la region es un enlace a /character/online/.
   El <a> NO envuelve el bloque: la pagina se pasa por tidy con output-xhtml y ahi un
   <a> no puede contener <div>/<ul>/<li>. Va superpuesto (inset: 0) sobre el contenedor,
   que para eso pasa a position: relative.

   El resalte se pinta sobre el CONTENEDOR (:hover / :focus-within), no sobre el <a>:
   si el fondo lo pusiera el enlace, al estar por encima teñiria el texto de los LEDs.

   Oro de verdad: la rampa --aq-gold-* de themes/necromantic/css/unknown.css (:root).
   El --gold del tema NO vale aqui, que en esta piel es rosa-magenta. */
.server-status-mini--linked {
    position: relative;
    border-radius: 8px;
    transition: background 140ms ease, box-shadow 140ms ease;
}
.server-status-mini__link {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    text-decoration: none;
}
.server-status-mini--linked:hover,
.server-status-mini--linked:focus-within {
    background: linear-gradient(180deg, var(--aq-gold-soft), transparent 78%);
    box-shadow: inset 0 0 0 1px var(--aq-gold-mid), 0 0 14px var(--aq-gold-glow);
}
.server-status-mini--linked:hover .server-status-mini__title,
.server-status-mini--linked:focus-within .server-status-mini__title {
    color: var(--aq-gold-light);
}
.server-status-mini--linked:hover .server-status-mini__players strong,
.server-status-mini--linked:focus-within .server-status-mini__players strong,
.server-status-mini--linked:hover .server-status-mini__players i,
.server-status-mini--linked:focus-within .server-status-mini__players i {
    color: var(--aq-gold-light);
}
.server-status-mini--linked:hover .server-status-mini__players span,
.server-status-mini--linked:focus-within .server-status-mini__players span,
.server-status-mini--linked:hover .server-status-mini__name,
.server-status-mini--linked:focus-within .server-status-mini__name {
    color: var(--aq-gold);
}

@media (prefers-reduced-motion: reduce) {
    .server-status-mini--linked { transition: none; }
}

/* El LED en si: circulo con halo. El "latido" solo se anima si el servidor
   esta arriba, y se desactiva para quien pida menos movimiento. */
.status-led {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
    position: relative;
}
.status-led--up {
    background: #35d07f;
    box-shadow: 0 0 6px 1px rgba(53, 208, 127, 0.75);
    animation: necro-led-pulse 2.4s ease-in-out infinite;
}
.status-led--down {
    background: #e2504a;
    box-shadow: 0 0 6px 1px rgba(226, 80, 74, 0.6);
}
.status-led--up + .server-status-mini__name { color: var(--text-primary); }
.status-led--down ~ .server-status-mini__state { color: #e2504a; }

@keyframes necro-led-pulse {
    0%, 100% { box-shadow: 0 0 5px 1px rgba(53, 208, 127, 0.55); }
    50%      { box-shadow: 0 0 9px 2px rgba(53, 208, 127, 0.95); }
}

@media (prefers-reduced-motion: reduce) {
    .status-led--up { animation: none; }
}

/* ==========================================================================
   necROmantic 2026-07-28 — Bloque "Estado del servidor" de la portada.
   Reutiliza .status-led (definido mas arriba, junto al panel del menu).
   Para revertir: borrar este bloque y la <section class="section-block--status">
   de themes/necromantic-modern/main/index.php.
   ========================================================================== */
.status-grid {
    display: grid;
    grid-template-columns: minmax(200px, 260px) 1fr;
    gap: 18px;
    align-items: stretch;
}
.status-players {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 26px 18px;
    border-radius: 18px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    text-align: center;
}
.status-players__ring {
    position: relative;
    width: 104px;
    height: 104px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background:
        radial-gradient(circle at 50% 50%, rgba(53, 208, 127, 0.10), transparent 65%);
    border: 2px solid var(--alpha-gold-42, rgba(214, 178, 96, 0.42));
    box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.28);
}
.status-players__value {
    font-family: var(--font-display);
    font-size: 30pt;
    font-weight: 700;
    line-height: 1;
    color: var(--gold);
    text-shadow: 0 0 18px var(--alpha-gold-42, rgba(214, 178, 96, 0.42));
}
.status-players__label { display: flex; flex-direction: column; gap: 2px; }
.status-players__label strong {
    font-size: 10pt;
    color: var(--text-heading2);
    font-family: var(--font-display);
    letter-spacing: 0.02em;
}
.status-players__label span { font-size: 8.4pt; color: var(--text-muted); }

.status-servers {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.status-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    border-radius: 16px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    border-left: 3px solid transparent;
    transition: border-color 0.2s ease, transform 0.2s ease;
}
.status-card.is-up { border-left-color: #35d07f; }
.status-card.is-down { border-left-color: #e2504a; }
.status-card:hover { transform: translateX(3px); }
.status-card__icon {
    flex: 0 0 auto;
    width: 34px;
    text-align: center;
    font-size: 15pt;
    color: var(--gold);
}
.status-card__body { flex: 1 1 auto; min-width: 0; }
.status-card__title {
    margin: 0 0 2px;
    font-family: var(--font-display);
    font-size: 11pt;
    color: var(--text-heading2);
}
.status-card__desc { margin: 0; font-size: 8.6pt; color: var(--text-muted); }
.status-card__state {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 8.8pt;
    white-space: nowrap;
    color: var(--text-muted);
}
.status-card.is-up .status-card__state { color: #35d07f; }
.status-card.is-down .status-card__state { color: #e2504a; }

@media (max-width: 720px) {
    .status-grid { grid-template-columns: 1fr; }
    .status-card__desc { display: none; }
}

/* ==========================================================================
   necROmantic 2026-07-28 — Enlaces en las tarjetas de "Tres pasos" y bloque
   de hardware del servidor (portada, debajo de las noticias).
   Revertir: borrar este bloque + la <section class="section-block--hardware">
   y el <a class="step-card__cta"> de themes/necromantic-modern/main/index.php.
   ========================================================================== */
.step-card__cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    padding: 9px 16px;
    border-radius: 999px;
    background: var(--alpha-gold-12, rgba(214, 178, 96, 0.12));
    border: 1px solid var(--alpha-gold-42, rgba(214, 178, 96, 0.42));
    color: var(--gold);
    font-size: 8.8pt;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none !important;
    transition: background 0.16s ease, transform 0.16s ease, box-shadow 0.16s ease;
}
.step-card__cta:hover {
    background: var(--gold);
    color: var(--text-on-accent);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px var(--alpha-gold-42, rgba(214, 178, 96, 0.42));
}
.step-card__cta i { font-size: 8.4pt; }

.hardware-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 16px;
}
.hardware-card {
    position: relative;
    padding: 22px 18px 20px;
    border-radius: 18px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    text-align: center;
    overflow: hidden;
    transition: transform 0.2s ease;
}
.hardware-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--gold), transparent);
    opacity: 0.55;
}
.hardware-card:hover { transform: translateY(-3px); }
.hardware-card__icon {
    font-size: 19pt;
    color: var(--gold);
    margin-bottom: 12px;
    display: block;
}
.hardware-card__value {
    font-family: var(--font-display);
    font-size: 17pt;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-heading2);
}
.hardware-card__label {
    font-size: 9pt;
    color: var(--gold);
    margin-top: 3px;
    letter-spacing: 0.02em;
}
.hardware-card__note {
    margin: 9px 0 0;
    font-size: 8.2pt;
    line-height: 1.5;
    color: var(--text-muted);
}
.hardware-foot {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 18px auto 0;
    max-width: 760px;
    font-size: 8.8pt;
    line-height: 1.6;
    color: var(--text-muted);
    text-align: left;
}
.hardware-foot i { color: #35d07f; margin-top: 3px; flex: 0 0 auto; }

@media (max-width: 560px) {
    .hardware-foot { text-align: center; flex-direction: column; align-items: center; }
    .hardware-foot i { margin-top: 0; }
}

/* ==========================================================================
   necROmantic 2026-07-28 — Carrusel de noticias de la portada.
   Mismo comportamiento que el slider principal (initCarousel en modern.js).
   Las diapositivas se apilan en la MISMA celda de grid: asi el contenedor
   adopta la altura de la noticia mas larga y no pega saltos al pasar de una
   a otra, que es el problema clasico de hacerlo con position:absolute.
   ========================================================================== */
.news-slider { position: relative; }
.news-slider__track {
    display: grid;
    border-radius: 18px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}
.news-slide {
    grid-area: 1 / 1;
    padding: 28px 74px;
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition: opacity 0.35s ease, transform 0.35s ease, visibility 0.35s;
    pointer-events: none;
}
.news-slide.is-active {
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
}
.news-slide__meta {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 8.2pt;
    color: var(--text-muted);
    margin-bottom: 10px;
}
.news-slide__meta i { color: var(--gold); }
.news-slide__author::before { content: "·"; margin-right: 9px; }
.news-slide__title {
    margin: 0 0 12px;
    font-family: var(--font-display);
    font-size: 15pt;
    line-height: 1.25;
    color: var(--text-heading2);
}
/* necROmantic 2026-08-02: las diapositivas se apilan en la MISMA celda de grid, asi que la
   altura del carrusel es la de la noticia mas larga -- y esa altura la paga la portada
   entera, aunque se este viendo una noticia corta. Con un articulo de fondo (la guia de
   mercenarios pasa de 19 KB) la portada se estiraba varias pantallas. El cuerpo se acota
   aqui y hace su propio scroll: las noticias cortas ni se enteran (no llegan al tope) y las
   largas se leen enteras sin deformar la portada. El articulo completo sigue estando en
   /news/, donde no hay tope ninguno. */
.news-slide__body {
    font-size: 9.4pt;
    line-height: 1.65;
    color: var(--text-primary);
    max-height: min(560px, 62vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--alpha-bronze-24) transparent;
    /* Aire a la derecha para que el texto no quede pegado a la barra de scroll. */
    padding-right: 6px;
}
.news-slide__body::-webkit-scrollbar { width: 8px; }
.news-slide__body::-webkit-scrollbar-track { background: transparent; }
.news-slide__body::-webkit-scrollbar-thumb {
    background: var(--alpha-bronze-24);
    border-radius: 8px;
}
.news-slide__body p:last-child { margin-bottom: 0; }
.news-slide__body img { max-width: 100%; height: auto; border-radius: 10px; }
.news-slide__modified { margin-top: 10px; font-size: 7.8pt; color: var(--text-muted); }
.news-slide__link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 14px;
    color: var(--gold);
    font-size: 8.8pt;
    font-weight: 600;
    text-decoration: none !important;
}
.news-slide__link:hover { text-decoration: underline !important; }

/* Flechas: mismas que las del slider principal.
   IMPORTANTE: el :hover TIENE que repetir el translateY(-50%). flux.css trae un
   `button:hover { transform: translateY(-1px) }` global que, si aqui no se declara
   transform, SUSTITUYE al centrado de la regla base y tira la flecha hacia abajo
   media altura. .hero-nav ya lo resolvia asi; esto solo replica su solucion. */
.news-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--surface-header-account);
    color: var(--text-heading2);
    cursor: pointer;
    backdrop-filter: blur(6px);
    transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.news-nav:hover {
    background: var(--alpha-gold-16);
    transform: translateY(-50%) scale(1.06);
}
.news-nav--prev { left: 14px; }
.news-nav--next { right: 14px; }

.news-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 16px;
    flex-wrap: wrap;
}
.news-dot {
    width: 9px;
    height: 9px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--alpha-white-05, rgba(255, 255, 255, 0.22));
    cursor: pointer;
    transition: background 0.16s ease, transform 0.16s ease, width 0.16s ease;
}
.news-dot:hover { background: var(--alpha-gold-42, rgba(214, 178, 96, 0.42)); }
.news-dot.is-active {
    width: 22px;
    border-radius: 999px;
    background: var(--gold);
}

@media (max-width: 720px) {
    .news-slide { padding: 22px 56px; }
    .news-nav { width: 38px; height: 38px; }
    .news-nav--prev { left: 6px; }
    .news-nav--next { right: 6px; }
}

/* ── Pie anclado al fondo del viewport ─────────────────────────
   En paginas con poco contenido (un listado vacio, por ejemplo) el
   pie subia hasta quedar colgado justo debajo de la tarjeta y
   dejaba media pantalla vacia por debajo. El documento pasa a ser
   una columna flexible de altura completa y el margen automatico
   del pie absorbe el espacio sobrante, sin estirar la tarjeta.   */
html.theme-modern-doc body.theme-modern {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}

#site-content-full {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
}

/* El hueco entre la tarjeta y el pie lo pone ahora el contenido:
   asi el margen superior del pie queda libre para el 'auto'.     */
#site-content-full #content-panel { margin-bottom: 40px; }
#site-footer-modern { margin-top: auto; }

@media (max-width: 640px) {
    #site-content-full #content-panel { margin-bottom: 32px; }
    #site-footer-modern { margin-top: auto; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-30 — Barra superior mas compacta
   Con "Cuenta" fuera de la barra y "Cómo se entra aquí" dentro de Información
   quedan menos elementos, pero aun asi se aprieta todo un poco para que la
   navegacion no se parta en pantallas de portatil.
   ══════════════════════════════════════════════════════════════ */
:root { --nav-height: 66px; }              /* antes 84px */

.header-modern__bar {
    min-height: var(--nav-height);
    padding: 6px 20px;                     /* antes 10px 28px */
    gap: 14px;                             /* antes 22px */
}

/* Logo: mas pequeno y sin el eslogan, que era la linea que mas alto anadia. */
.header-modern__bar #logo-mark { width: 42px; height: 42px; }
.header-modern__bar #logo-link { gap: 10px; }
.header-modern__bar #logo-text .logo-nec,
.header-modern__bar #logo-text .logo-mantic,
.header-modern__bar #logo-text .logo-ro { font-size: 18px; }
.header-modern__bar #logo-text .logo-tagline { display: none; }

/* Enlaces de navegacion: menos aire horizontal y letra algo menor. */
.primary-nav__list { gap: 2px; }
.nav-link {
    padding: 8px 10px;
    font-size: 9pt;
    border-radius: 10px;
}
.nav-link i:not(.nav-caret) { font-size: 8.5pt; }
.nav-caret { font-size: 6.5pt; }

/* El chip de cuenta, en linea con el resto. */
.account-chip__trigger { padding: 7px 12px; font-size: 8.5pt; }
.account-chip__trigger i.fa-circle-user { font-size: 11pt; }

/* ── A 1300px o menos: fuera el logo ──────────────────────────
   Es el elemento que mas ancho ocupa y el unico prescindible: el icono de
   "Inicio" del menu ya lleva a la portada. */
@media (max-width: 1300px) {
    /* Tiene que ser .header-modern__bar #logo-link, no solo #logo-link: la regla base usa
       clase + id y es mas especifica, asi que ganaria aunque este fuera del media query. */
    .header-modern__bar #logo-link { display: none; }
    .header-modern__bar { padding: 6px 14px; gap: 10px; }
    #primary-nav { justify-content: flex-start; }
    .nav-link { padding: 8px 8px; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-05 — Página de acceso
   Aqui vivia un parche de 60 lineas que sacaba a .generic-form-table del modelo
   de tabla y lo centraba todo (`body.page-account-login #content-panel {
   text-align: center }`), porque la plantilla compartida de themes/default/
   pintaba el acceso como una tabla de etiquetas y campos.
   Ya no: themes/necromantic/account/login.php es un override propio con el
   componente .lgn (unknown.css), asi que el parche sobraba — y de hecho estorbaba,
   porque el centrado heredado alcanzaba a las etiquetas, a las pistas y a la
   columna de ayuda. La pagina se estiliza entera desde su componente.
   ══════════════════════════════════════════════════════════════ */

/* ==========================================================================
   necROmantic 2026-07-30 — Widget "Quien esta detras" de la portada.
   Pareja del contenido de /sobre-mi/ (tema padre, componente .about-*). Aqui
   solo esta la version compacta de portada. Sin bordes: el bloque se separa
   con fondo y sombra, como el resto del sitio.
   ========================================================================== */
.about-widget {
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 24px 26px;
    border-radius: 22px;
    background: var(--grad-hero);
    box-shadow: var(--shadow-card), inset 0 1px 0 var(--alpha-white-05);
}

.about-widget__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--alpha-gold-12);
    color: var(--gold);
    font-size: 17pt;
    box-shadow: 0 0 22px var(--alpha-gold-16), inset 0 1px 0 var(--alpha-white-06);
}

.about-widget__body { min-width: 0; }

.about-widget__title {
    /* El .section-kicker de encima ya trae su propio margin-bottom: aqui no se suma otro. */
    margin: 0 0 8px;
    font-family: var(--font-display);
    font-size: 20px;
    line-height: 1.15;
    color: var(--text-hero-title);
    border: 0;
    padding: 0;
}

.about-widget__text {
    margin: 0;
    max-width: 78ch;
    font-size: 9.4pt;
    line-height: 1.7;
    color: var(--text-hero-intro);
}

.about-widget__text strong { color: var(--text-heading2); }

.about-widget__cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* Hermano del cuerpo: se va al hueco de la derecha del panel. */
    flex: 0 0 auto;
    margin-left: auto;
    padding: 9px 18px;
    border-radius: 999px;
    background: var(--alpha-gold-12);
    color: var(--gold);
    font-size: 8.8pt;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-decoration: none !important;
    box-shadow: inset 0 0 0 1px var(--alpha-gold-42);
    transition: background 0.16s ease, transform 0.16s ease, box-shadow 0.16s ease;
}

.about-widget__cta:hover {
    background: var(--gold);
    color: var(--text-on-accent);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px var(--alpha-gold-42);
}

.about-widget__cta i { font-size: 8.4pt; }

@media (max-width: 560px) {
    .about-widget { flex-direction: column; align-items: flex-start; gap: 14px; padding: 20px; }
    .about-widget__cta { margin-left: 0; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Rework del menú de la barra
   ══════════════════════════════════════════════════════════════
   Tres problemas de fondo:

   1. NO SE VEÍA DÓNDE ESTABAS. La barra no marcaba la sección actual, así que con
      siete categorías había que mirar la URL o el título para orientarse. Ahora el
      enlace activo lleva un filo inferior y fondo propio, y su categoría padre también
      se marca aunque el desplegable esté cerrado (el header pone .is-current y
      .has-current).
   2. TODO SE MOVÍA AL SEÑALAR: los enlaces subían 1px y los del desplegable se
      desplazaban 4px a la derecha. Fuera: ahora solo se iluminan. Un menú que se mueve
      bajo el cursor obliga a recolocar el ojo en cada pasada.
   3. El desplegable de las últimas categorías se salía por la derecha de la ventana.
      Se alinean al borde derecho las dos últimas.
   ══════════════════════════════════════════════════════════════ */

.nav-link {
    position: relative;
    font-size: 0.86rem;
    border: 1px solid transparent;
    transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

/* Sin transform: solo luz. */
.nav-link:hover,
.nav-link:focus-visible {
    background: var(--alpha-gold-12);
    border-color: var(--alpha-gold-24, var(--alpha-gold-12));
    color: var(--text-link-hover);
    transform: none;
}

/* --- Sección actual --- */

.nav-link.is-current {
    background: var(--alpha-gold-12);
    color: var(--text-link-hover);
}

/* Filo inferior: la marca de "estás aquí". Se dibuja con ::after para no alterar la
   caja del enlace y que no baile nada al activarse. */
.nav-link.is-current::after {
    content: "";
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 3px;
    height: 2px;
    border-radius: 2px;
    background: var(--gold);
}

.nav-link.is-current i:not(.nav-caret) { color: var(--text-link-hover); }

/* Una categoría cuyo desplegable contiene la página actual se marca aunque esté
   cerrada: si no, al entrar en "Objetos" la barra no decía nada. */
.has-dropdown.has-current > .nav-link { color: var(--text-link-hover); }

/* --- Desplegable --- */

.dropdown-panel {
    min-width: 250px;
    max-width: min(320px, calc(100vw - 32px));
    padding: 8px;
    border: 1px solid var(--alpha-gold-12);
}

/* Las dos últimas categorías abren hacia la izquierda o se salen de la ventana. */
.primary-nav__item:nth-last-child(-n+2) .dropdown-panel { left: auto; right: 0; }

/* Punta que ancla el panel a su botón: sin ella el desplegable flota suelto. */
.dropdown-panel::before {
    content: "";
    position: absolute;
    top: -5px;
    left: 22px;
    width: 10px;
    height: 10px;
    transform: rotate(45deg);
    background: var(--grad-sidebar-card);
    border-left: 1px solid var(--alpha-gold-12);
    border-top: 1px solid var(--alpha-gold-12);
}

.primary-nav__item:nth-last-child(-n+2) .dropdown-panel::before { left: auto; right: 22px; }

.dropdown-panel__title {
    margin: 2px 0 6px;
    padding: 4px 10px;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.dropdown-link {
    font-size: 0.85rem;
    border: 1px solid transparent;
    /* Sin padding-left en el hover: desplazaba el texto bajo el cursor. */
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.dropdown-link:hover,
.dropdown-link:focus-visible {
    background: var(--alpha-gold-12);
    border-color: var(--alpha-gold-12);
    color: var(--text-link-hover);
    padding-left: 10px;
}

.dropdown-link.is-current {
    background: var(--alpha-gold-12);
    color: var(--text-link-hover);
}

/* Marca lateral en la entrada activa del desplegable. */
.dropdown-link.is-current::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 50%;
    width: 3px;
    height: 16px;
    margin-top: -8px;
    border-radius: 2px;
    background: var(--gold);
}

.dropdown-link { position: relative; }

@media (prefers-reduced-motion: reduce) {
    .nav-link,
    .dropdown-link,
    .dropdown-panel { transition: none; }
    .nav-caret { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Zona de acciones de la barra
   ══════════════════════════════════════════════════════════════
   El chip de cuenta era una pastilla plana: sin borde, sin estado al señalar (no había
   NI UNA regla :hover para .account-chip__trigger), sin marca de abierto y con un icono
   genérico. Y sin sesión, "Entrar" y "Crear cuenta" vivían escondidas dentro de ese
   desplegable — las dos únicas cosas que un visitante nuevo necesita, a un clic y sin
   ninguna pista de que estaban ahí.

   Ahora: sin sesión salen como botones (el de entrar destacado); con sesión, el chip
   lleva la imagen de cuenta del jugador —la misma que subió en su ficha—, borde propio
   y estados de señalado, foco y abierto.
   ══════════════════════════════════════════════════════════════ */

.header-modern__actions { gap: 8px; }

/* --- Botones de la barra (sin sesión) --- */

.hdr-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--alpha-gold-24, rgba(223, 160, 198, 0.24));
    border-radius: 999px;
    color: var(--text-heading2);
    font-family: var(--font-display);
    font-size: 0.84rem;
    font-weight: 600;
    white-space: nowrap;
    text-decoration: none !important;
    transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.hdr-btn i { color: var(--gold); font-size: 0.82rem; }

.hdr-btn:hover,
.hdr-btn:focus-visible {
    background: var(--alpha-gold-12);
    border-color: var(--gold);
    color: var(--text-link-hover);
}

/* El de entrar manda: relleno sólido para que se distinga del secundario de un vistazo. */
.hdr-btn--primary {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--bg-content);
}

.hdr-btn--primary i { color: var(--bg-content); }

.hdr-btn--primary:hover,
.hdr-btn--primary:focus-visible {
    background: var(--gold);
    color: var(--bg-content);
    filter: brightness(1.1);
}

/* --- Chip de cuenta (con sesión) --- */

.account-chip__trigger {
    gap: 10px;
    padding: 6px 14px 6px 6px;
    border: 1px solid var(--alpha-gold-24, rgba(223, 160, 198, 0.24));
    font-size: 0.84rem;
    transition: background 0.18s ease, border-color 0.18s ease;
}

.account-chip__trigger:hover,
.account-chip__trigger:focus-visible,
.account-chip.is-open .account-chip__trigger {
    background: var(--alpha-gold-12);
    border-color: var(--gold);
}

/* La imagen de cuenta, o la inicial si no ha subido ninguna. */
.account-chip__avatar {
    width: 30px;
    height: 30px;
    flex: 0 0 auto;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.account-chip__avatar--letter {
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
    font-family: var(--font-display);
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
}

.account-chip__name {
    font-weight: 700;
    color: var(--text-heading2);
    max-width: 16ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

@media (max-width: 1080px) {
    /* El texto de los botones sobra antes que el icono: se queda el icono solo. */
    .hdr-btn span { display: none; }
    .hdr-btn { padding: 9px 12px; }
}

@media (prefers-reduced-motion: reduce) {
    .hdr-btn,
    .account-chip__trigger { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Submenús anidados en los desplegables
   ══════════════════════════════════════════════════════════════
   "Información" había crecido a quince entradas sueltas en una sola columna. Ahora tres
   de ellas son grupos (Mercado, Base de datos, Rankings) que abren un panel lateral.

   Se despliegan por CSS, con :hover y :focus-within — sin JavaScript. El JS de la barra
   solo gobierna el primer nivel, y el :focus-within hace que funcione con teclado: al
   tabular dentro del grupo, el panel se queda abierto.
   ══════════════════════════════════════════════════════════════ */

.dropdown-group { position: relative; }

.dropdown-link--group {
    width: 100%;
    background: transparent;
    border: 1px solid transparent;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

.dropdown-group__caret {
    margin-left: auto;
    font-size: 0.62rem;
    opacity: 0.7;
    transition: transform 0.18s ease;
}

.dropdown-group:hover > .dropdown-link--group,
.dropdown-group:focus-within > .dropdown-link--group {
    background: var(--alpha-gold-12);
    border-color: var(--alpha-gold-12);
    color: var(--text-link-hover);
}

.dropdown-group:hover .dropdown-group__caret,
.dropdown-group:focus-within .dropdown-group__caret { transform: translateX(2px); }

/* Un desplegable con grupos NO se alinea al borde derecho aunque sea de las últimas
   categorías: necesita el espacio de su derecha para el submenú. Pisa a la regla
   :nth-last-child(-n+2) de más arriba.
   La clase la pone el header cuando la categoría tiene grupos. Se hizo así, y no con
   :has(.dropdown-group), para no jugarse la colocación a que el navegador soporte :has():
   si fallara, el panel se quedaría pegado al borde derecho y el submenú se saldría de la
   pantalla. Una clase la entiende cualquier navegador. */
.primary-nav__item:nth-last-child(-n+2) .dropdown-panel--groups {
    left: 0;
    right: auto;
}

.primary-nav__item:nth-last-child(-n+2) .dropdown-panel--groups::before {
    left: 22px;
    right: auto;
}

/* Panel lateral: sale por la DERECHA del grupo, que es hacia donde se avanza al leer.
   Para que quepa, el desplegable que contiene grupos se ancla por su izquierda al botón
   (regla de abajo) en vez de al borde derecho: así queda toda la mitad derecha libre
   para el submenú. */
.dropdown-subpanel {
    position: absolute;
    top: -8px;
    left: calc(100% + 6px);
    min-width: 220px;
    max-width: min(280px, calc(100vw - 32px));
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px;
    border: 1px solid var(--alpha-gold-12);
    border-radius: 16px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
    opacity: 0;
    visibility: hidden;
    transform: translateX(-6px);
    transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
    z-index: 220;
}

.dropdown-group:hover > .dropdown-subpanel,
.dropdown-group:focus-within > .dropdown-subpanel {
    opacity: 1;
    visibility: visible;
    transform: translateX(0);
}

/* Una categoría cuya página actual vive dentro de un grupo también se marca. */
.dropdown-group.has-current > .dropdown-link--group { color: var(--text-link-hover); }

/* necROmantic 2026-08-07 (usuario) — el submenú de "Mi cuenta" abre hacia la IZQUIERDA.
   El desplegable del chip de cuenta está anclado al borde derecho de la ventana
   (.dropdown-panel--right), así que a su derecha no queda sitio: un submenú lateral como
   el de "Información" se saldría de la pantalla. Aquí se invierte todo lo que tiene lado:
   de qué borde cuelga el panel, hacia dónde entra al aparecer y hacia dónde apunta y se
   desplaza la flecha del grupo (que además es un chevron-left en el HTML).

   La clase va en el grupo y no en el subpanel a propósito: una sola marca gobierna las
   tres cosas, y el HTML del submenú queda idéntico al de los demás. */
.dropdown-group--left > .dropdown-subpanel {
    left: auto;
    right: calc(100% + 6px);
    transform: translateX(6px);
}

.dropdown-group--left:hover > .dropdown-subpanel,
.dropdown-group--left:focus-within > .dropdown-subpanel { transform: translateX(0); }

.dropdown-group--left:hover .dropdown-group__caret,
.dropdown-group--left:focus-within .dropdown-group__caret { transform: translateX(-2px); }

/* En pantallas estrechas no hay sitio a los lados: el grupo se despliega hacia abajo,
   dentro del propio panel, en lugar de volar fuera de la ventana. */
@media (max-width: 860px) {
    .dropdown-subpanel {
        position: static;
        min-width: 0;
        max-width: none;
        margin: 4px 0 4px 14px;
        padding: 4px 0 4px 10px;
        border: 0;
        border-left: 1px solid var(--alpha-gold-12);
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        transform: none;
        display: none;
    }
    .dropdown-group:hover > .dropdown-subpanel,
    .dropdown-group:focus-within > .dropdown-subpanel { display: flex; }
    .dropdown-group__caret { transform: rotate(90deg); }

    /* Aquí ya no hay izquierda ni derecha: el submenú se despliega hacia abajo dentro del
       propio panel, así que el desplazamiento lateral sobra. Hace falta decirlo porque las
       reglas de .dropdown-group--left son más específicas que el transform: none de arriba.
       La flecha gira al revés que la de los otros grupos: es un chevron-left, y girándolo
       90° como los demás quedaría apuntando hacia arriba en vez de hacia abajo. */
    .dropdown-group--left > .dropdown-subpanel,
    .dropdown-group--left:hover > .dropdown-subpanel,
    .dropdown-group--left:focus-within > .dropdown-subpanel { transform: none; }
    .dropdown-group--left .dropdown-group__caret,
    .dropdown-group--left:hover .dropdown-group__caret,
    .dropdown-group--left:focus-within .dropdown-group__caret { transform: rotate(-90deg); }
}

@media (prefers-reduced-motion: reduce) {
    .dropdown-subpanel,
    .dropdown-group__caret { transition: none; }
}

/* ============================================================================
   Conmutador de idioma
   necROmantic 2026-08-02: parte del proyecto de web bilingüe. Son enlaces, no un
   <select>, para que funcionen sin JavaScript y se puedan abrir en otra pestaña.
   Usa los mismos tokens que .hdr-btn para que no parezca un añadido.
   ============================================================================ */

.lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--alpha-gold-24, rgba(223, 160, 198, 0.24));
    border-radius: 999px;
}

.lang-switch__opt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    padding: 5px 9px;
    border-radius: 999px;
    color: var(--text-heading2);
    font-family: var(--font-display);
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 1;
    text-decoration: none !important;
    transition: background 0.18s ease, color 0.18s ease;
}

.lang-switch__opt:hover,
.lang-switch__opt:focus-visible {
    background: var(--alpha-gold-12);
    color: var(--text-link-hover);
}

/* El idioma activo va relleno: se distingue de un vistazo cuál de los dos se está viendo. */
.lang-switch__opt.is-current {
    background: var(--gold);
    color: var(--bg-content);
    cursor: default;
}

/* En pantallas estrechas la barra ya va justa: el selector se queda, pero más compacto. */
@media (max-width: 720px) {
    .lang-switch__opt { min-width: 28px; padding: 5px 7px; font-size: 0.7rem; }
}

/* Aviso de contenido sin traducir. necROmantic 2026-08-02. */
.news-card__untranslated,
.cms-page__untranslated {
    margin: 0 0 14px;
    padding: 8px 12px;
    border-left: 3px solid var(--gold);
    background: var(--alpha-gold-12);
    border-radius: 0 6px 6px 0;
    font-size: 0.82rem;
    opacity: 0.9;
}

/* ============================================================================
   necROmantic 2026-08-05 · Avisos de "entra un jugador" + refresco en vivo
   ============================================================================
   Segunda version, por peticion del usuario: "que se queden en la zona superior
   acumulados con una X de cierre hasta que el visitante lo cierre o que duren 60
   segundos, que no desaparezcan con Alpha de forma automatica solo por haber
   llegado arriba".

   O sea que ya NO son globos que viajan y se desvanecen al llegar arriba: son
   avisos que se apilan en la esquina superior, se leen con calma y se van solo
   cuando alguien los cierra o cuando cumplen su minuto. La animacion que queda es
   la de ENTRADA (aparecer) y la de SALIDA (al cerrarse), nunca una desaparicion
   por el mero hecho de haber subido.

   El contenedor no captura clics (pointer-events:none) pero cada aviso SI
   (pointer-events:auto): asi la columna flota sobre la pagina sin robar un solo
   clic a lo que haya debajo, y la X sigue siendo pulsable. */

.jbub {
    position: fixed;
    left: 18px;
    top: calc(var(--nav-height) + 12px);
    width: 300px;
    max-height: calc(100vh - var(--nav-height) - 24px);
    z-index: 900;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    overflow: hidden;
}

.jbub__item {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 10px 8px 14px;
    border-radius: 999px;
    border: 1px solid rgba(212, 175, 55, 0.45);
    background: rgba(18, 12, 28, 0.92);
    backdrop-filter: blur(4px);
    color: #f3ead8;
    font-size: 9.5pt;
    line-height: 1.25;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
    /* Solo ENTRADA. Al terminar se queda quieto y opaco hasta que lo cierren. */
    animation: jbub-in 260ms ease-out;
}

/* Estado de salida: lo pone el JS al cerrar (X o los 60 s) y quita el nodo cuando
   acaba la transicion. Es la UNICA via por la que un aviso se desvanece. */
.jbub__item--out {
    opacity: 0;
    transform: translateX(-18px);
    transition: opacity 220ms ease-in, transform 220ms ease-in;
}

@keyframes jbub-in {
    from { opacity: 0; transform: translateX(-18px); }
    to   { opacity: 1; transform: translateX(0); }
}

/* Icono de la clase, a la izquierda del nombre. Tamano fijo y flex-shrink:0 para que
   un icono que tarde en cargar no descuadre la fila ni la encoja. */
.jbub__icon {
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
    object-fit: contain;
    image-rendering: pixelated;   /* son sprites; el suavizado los emborrona */
}

.jbub__text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jbub__name {
    font-family: var(--font-display);
    color: var(--gold, #d4af37);
    font-weight: 700;
}

/* El nivel, discreto: informa sin competir con el nombre. */
.jbub__lv {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    background: rgba(212, 175, 55, 0.16);
    color: #e9dcc0;
    font-size: 8pt;
    font-weight: 600;
    letter-spacing: 0.02em;
}

/* La X. Boton de verdad (<button>), no un span con onclick: asi entra en el orden de
   tabulacion, responde a Enter y Espacio y los lectores de pantalla lo anuncian. */
.jbub__close {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: #b9ac93;
    font-size: 13pt;
    line-height: 1;
    cursor: pointer;
    transition: background-color 140ms ease, color 140ms ease;
}

.jbub__close:hover,
.jbub__close:focus-visible {
    background: rgba(212, 175, 55, 0.18);
    color: #f3ead8;
}

/* En pantallas estrechas el lateral estorba: se centra y se estrecha. */
@media (max-width: 720px) {
    .jbub {
        left: 50%;
        transform: translateX(-50%);
        width: min(84vw, 320px);
        align-items: stretch;
    }
}

/* Quien pide menos movimiento no recibe deslizamientos. Los avisos siguen
   apareciendo, apilandose y cerrandose igual: lo que se quita es el viaje. */
@media (prefers-reduced-motion: reduce) {
    .jbub__item {
        animation: none;
    }
    .jbub__item--out {
        transform: none;
        transition: opacity 160ms linear;
    }
}

/* Marca discreta de "esto se acaba de actualizar solo", para que un numero que
   cambia sin que nadie toque nada no parezca un error de lectura. */
.is-live-bump {
    animation: live-bump 620ms ease-out;
}

@keyframes live-bump {
    0%   { transform: scale(1);    }
    35%  { transform: scale(1.18); }
    100% { transform: scale(1);    }
}

@media (prefers-reduced-motion: reduce) {
    .is-live-bump { animation: none; }
}

/* ============================================================================
 * necROmantic 2026-08-07 (usuario) — "Personajes" despliega la lista de personajes
 * ============================================================================
 * Tercer nivel del menú: chip de cuenta → "Mi cuenta" → "Personajes" → cada personaje,
 * con su icono de clase, su nombre y su nivel base.
 *
 * Reutiliza .dropdown-group--left tal cual, así que hereda de dónde cuelga, hacia dónde
 * entra y hacia dónde apunta la flecha. Aquí solo va lo que es propio de una fila de
 * personaje: que quepan tres cosas en una línea sin apretarse.
 *
 * El nivel se alinea a la derecha con margin-left:auto y NO con un ancho fijo, porque
 * "Nv. 9" y "Nv. 175" no miden lo mismo y una columna fija dejaría a uno de los dos
 * descolocado. */
.dropdown-subpanel--chars { min-width: 240px; }

/* ============================================================================
 * TERCER NIVEL: las secciones de cada personaje (necROmantic 2026-08-29)
 * ============================================================================
 * Peticion del usuario: desde el nodo del personaje, ir directo a cada seccion de su ficha.
 *
 * Casi todo lo hereda: el grupo lleva tambien `--left`, asi que las reglas de arriba ya lo
 * despliegan hacia la izquierda, con su transicion y su flecha. Aqui solo va lo que cambia por
 * estar UN NIVEL MAS ADENTRO.
 *
 * La fila del personaje pasa a ser cabecera de grupo y por eso necesita sitio para la flecha: sin
 * el `padding-right` el chevron se monta sobre el "Nv. 119".
 */
.dropdown-group--char > .dropdown-link--char { padding-right: 22px; }

/* La flecha, vertical al centro de una fila que es mas alta que las demas (icono de clase de
   24 px). El `position: absolute` cuelga del enlace, que ya es el contexto de posicionamiento de
   los carets del resto del menu. */
.dropdown-group--char > .dropdown-link--char .dropdown-group__caret {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
}

.dropdown-group--char:hover > .dropdown-link--char .dropdown-group__caret,
.dropdown-group--char:focus-within > .dropdown-link--char .dropdown-group__caret {
    transform: translateY(-50%) translateX(-2px);
}

/* Nueve secciones entran de sobra en una columna; se le pone tope de altura por si algun dia son
   mas, para que el panel no se salga por abajo en una pantalla corta. */
.dropdown-subpanel--secs {
    min-width: 210px;
    max-height: min(70vh, 460px);
    overflow-y: auto;
    z-index: 230;   /* por encima del panel de personajes del que cuelga */
}

.dropdown-link--sec {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.86rem;
}

/* En estrecho los tres niveles se apilan hacia abajo (regla general de @media 860px). Con tres
   sangrias seguidas el texto se iria al centro de la pantalla, asi que el ultimo nivel no sangra
   otra vez: le basta con la linea de la izquierda para leerse como hijo. */
@media (max-width: 860px) {
    .dropdown-subpanel--secs { margin-left: 8px; padding-left: 8px; }
}

.dropdown-link--char {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* 24px es el tamaño nativo de los iconos de clase del cliente (data/jobs/icons/): así no
   se reescalan y no salen borrosos. El flex-shrink evita que un nombre largo los estruje. */
.dropdown-link__jobicon {
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
    object-fit: contain;
    image-rendering: pixelated;
}

/* El nombre cede sitio antes que el nivel: si no cabe, se corta el nombre -- que se sigue
   reconociendo por el principio -- y no el número, que sin su última cifra miente. */
.dropdown-link__charname {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dropdown-link__charlv {
    flex: 0 0 auto;
    margin-left: auto;
    font-size: 0.75rem;
    font-style: normal;
    opacity: 0.75;
}

/* El hover del enlace mete padding-left para desplazar el texto; en una fila de tres piezas
   eso movería el icono fuera de sitio, así que aquí se compensa con el mismo número. */
.dropdown-link--char:hover,
.dropdown-link--char:focus-visible { padding-left: 10px; }

/* ============================================================================
 * necROmantic 2026-08-07 (usuario) — cifras a la derecha de cada sección
 * ============================================================================
 * Minutos de automatización, nivel de jugador, días de racha, personajes y almacén.
 *
 * margin-left:auto las empuja al borde derecho sin tocar el ancho de nada: la fila ya es
 * flex por .dropdown-link, así que la etiqueta ocupa lo que necesite y la cifra se queda
 * pegada al lado contrario.
 *
 * font-variant-numeric: tabular-nums para que "8" y "120" no bailen de ancho al cambiar,
 * que es lo que hace que un menú con cifras vivas parezca que tiembla. */
.navbadge {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-style: normal;
    font-weight: 600;
    line-height: 1.5;
    font-variant-numeric: tabular-nums;
    border: 1px solid transparent;
    background: var(--alpha-gold-12);
    color: var(--text-link-hover);
}

/* El caret del grupo va DESPUÉS de la cifra, así que la cifra no puede comerse su hueco. */
.dropdown-link--group .navbadge { margin-right: 6px; }

/* Los cuatro estados de la racha, con el mismo vocabulario que escribe el NPC:
   green = fichado hoy · blue = salvado por un protector · red = racha rota ·
   pending = aún no ha cubierto los 15 minutos de hoy.
   Se usan los tokens del tema y no colores sueltos, para que funcione en claro y en oscuro. */
.navbadge--green   { background: rgba(64, 192, 96, 0.18);  color: #6ee08a; border-color: rgba(64, 192, 96, 0.35); }
.navbadge--blue    { background: rgba(80, 150, 240, 0.18); color: #8ab6ff; border-color: rgba(80, 150, 240, 0.35); }
.navbadge--red     { background: rgba(226, 74, 74, 0.18);  color: #ff9090; border-color: rgba(226, 74, 74, 0.35); }
.navbadge--pending { background: rgba(226, 168, 74, 0.18); color: #ffc978; border-color: rgba(226, 168, 74, 0.35); }

/* La cuota en pausa (hay un automatismo en marcha) se marca igual que en la ficha: no es un
   error, es que ese número no está subiendo ahora mismo. */
.navbadge--pausa   { background: rgba(160, 120, 220, 0.18); color: #c9a0ff; border-color: rgba(160, 120, 220, 0.35); }

@media (prefers-color-scheme: light) {
    .navbadge--green   { color: #1d7a3a; }
    .navbadge--blue    { color: #1f5fb0; }
    .navbadge--red     { color: #b02626; }
    .navbadge--pending { color: #9a6410; }
    .navbadge--pausa   { color: #6b3fb0; }
}

/* necROmantic 2026-08-13 -- Acompañantes (/character/<id>/): elementales y homunculo.
   ============================================================================
   LA VITRINA. Cada criatura en su urna de cristal, iluminada por dentro con SU
   propio color, sobre un pedestal. Todo por clases y tokens; ni un color suelto
   fuera de las variables de tema de cada elemento. */

.elecare { margin: 2.25rem 0; }
/* El <h2> de la seccion se retiro el 2026-08-26: el titulo lo pone ahora la cabecera
   del plegable (.fold__title en unknown.css). */
.elecare-empty { color: #9b91c4; margin: 0 0 1.15rem; font-size: .9rem; }
.elecare-empty.is-hidden { display: none; }
.elecare-empty.is-online { color: #d7ab3f; }

.elecare-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	gap: 1.4rem;
}

/* necROmantic 2026-08-13 (peticion del usuario): CON EL PERSONAJE DENTRO DEL JUEGO, a media luz.

   No es decoracion. Mientras se juega manda la partida: esta pagina no puede escribir, y lo que lee
   es lo ultimo que se guardo -- el personaje vive en la memoria del map-server. Un panel apagado y
   quieto cuenta eso mejor que un aviso, y el aviso sigue arriba a plena luz
   (.elecare-empty.is-online), que es justo lo que hay que poder leer.

   Se apaga la REJILLA y no la seccion entera por eso mismo: el titulo y la explicacion tienen que
   quedar legibles. El JS ademas deja de sondear mientras dure, asi que tampoco parpadea nada. */
.elecare-grid.is-ingame { opacity: .33; }

/* --- El color de cada criatura ------------------------------------------------
   Un solo token por tarjeta (--glow) y de el cuelga TODO: el halo de la urna, el
   filo del cristal, la barra, el nombre. Cambiar un elemento de color es tocar
   una linea, y ninguna pieza se puede quedar descolgada. */
.elecare-card            { --glow: #8f8fa8; --glow-soft: rgba(143,143,168,.30); }
.elecare-card.el-agni    { --glow: #ff7a3d; --glow-soft: rgba(255,122,61,.34); }
.elecare-card.el-aqua    { --glow: #4fb6f0; --glow-soft: rgba(79,182,240,.34); }
.elecare-card.el-ventus  { --glow: #6fe3b5; --glow-soft: rgba(111,227,181,.32); }
.elecare-card.el-tera    { --glow: #d2a25a; --glow-soft: rgba(210,162,90,.32); }
.elecare-card.el-homun   { --glow: #b58ce0; --glow-soft: rgba(181,140,224,.32); }
/* necROmantic 2026-09-03 (peticion del usuario): la tarjeta de la PAPELERA -- un homunculo
   borrado por error que todavia se puede recuperar. Ambar y no morado como el homunculo vivo:
   la tarjeta tiene que leerse como un aviso antes de leer una sola palabra. */
.elecare-card.el-trash   { --glow: #e0b24a; --glow-soft: rgba(224,178,74,.30); }
/* El sprite va apagado porque la criatura NO ESTA: pintarla igual que a las vivas seria decir
   que sigue ahi. Vuelve a color al pasar por encima, que es cuando el jugador la esta mirando. */
.elecare-card.el-trash .elecare-sprite { filter: grayscale(1); opacity: .55; }
.elecare-card.el-trash:hover .elecare-sprite { filter: grayscale(.25); opacity: .85; }
.elecare-trash-when { margin: .35rem 0 0; font-size: .78rem; opacity: .7; }
/* Ya rescatada: se queda en pantalla con el mensaje, apagada y sin invitar a nada mas. Desaparece
   sola en la siguiente lectura del panel. */
.elecare-card.is-done { opacity: .6; }
.elecare-card.is-done .elecare-btn { display: none; }

.elecare-card {
	position: relative;
	display: flex;
	flex-direction: column;
	/* Que todas las de una fila midan lo mismo: la rejilla ya las estira, pero sin esto el
	   contenido manda y quedaban escalonadas. */
	height: 100%;
	border-radius: 1rem;
	overflow: hidden;
	background: linear-gradient(180deg, rgba(26,18,48,.92) 0%, rgba(8,5,16,.96) 100%);
	box-shadow:
		0 2px 4px rgba(0,0,0,.4),
		0 12px 28px rgba(0,0,0,.32),
		inset 0 0 0 1px rgba(178,150,255,.16);
	/* Sin desplazamiento al señalar (peticion del usuario): la tarjeta se ilumina y nada mas.
	   Con cuatro o cinco en rejilla, moverlas hacia arriba hacia saltar la fila entera. */
	transition: box-shadow .22s ease;
}
.elecare-card:hover {
	box-shadow:
		0 4px 8px rgba(0,0,0,.45),
		0 22px 46px rgba(0,0,0,.45),
		inset 0 0 0 1px var(--glow-soft);
}

/* --- LA URNA ---------------------------------------------------------------- */
.elecare-screen {
	position: relative;
	aspect-ratio: 1 / 1;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	padding: 1rem 1rem 1.6rem;
	/* Tres capas: el halo del elemento detras de la criatura, la penumbra del
	   fondo y la vinyeta que cierra los bordes. Sin la vinyeta la urna parece un
	   recorte; con ella, un espacio con profundidad. */
	background:
		radial-gradient(58% 48% at 50% 62%, var(--glow-soft), transparent 70%),
		radial-gradient(120% 80% at 50% -10%, rgba(255,255,255,.09), transparent 60%),
		linear-gradient(180deg, rgba(38,26,66,.95) 0%, rgba(8,5,16,1) 100%);
}
/* El cristal: un filo de luz arriba y un reflejo diagonal muy tenue. */
.elecare-screen::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient(115deg, rgba(255,255,255,.07) 0%, transparent 38%);
	box-shadow: inset 0 1px 0 rgba(255,255,255,.13), inset 0 -30px 40px -30px #000;
}
/* EL PEDESTAL. Una losa con su brillo: es lo que convierte "un sprite sobre un
   fondo" en "una pieza expuesta". */
.elecare-screen::after {
	content: "";
	position: absolute;
	left: 50%;
	bottom: .75rem;
	transform: translateX(-50%);
	width: 62%;
	height: .85rem;
	border-radius: 50%;
	background:
		radial-gradient(50% 100% at 50% 50%, var(--glow-soft), transparent 72%),
		rgba(0,0,0,.55);
	filter: blur(2px);
}

.elecare-sprite {
	position: relative;
	z-index: 1;
	/* width/height al 100 % y no max-*: con `max-` el navegador solo ENCOGE lo que se pasa, asi
	   que un Agni pequeño (88x82) se quedaba de miniatura al lado de un Ventus grande (334x356) y
	   la vitrina parecia descuadrada. Dando medida completa, `contain` escala en los dos sentidos
	   y las 33 criaturas ocupan su urna por igual, cada una con su proporcion intacta. */
	/* ABSOLUTO, y esto es lo que cierra el asunto: con la imagen en el flujo normal era ELLA la
	   que fijaba la altura de la urna, asi que el `aspect-ratio` no llegaba a mandar nunca y cada
	   vitrina medía lo que midiera su criatura. Sacandola del flujo, la urna es cuadrada siempre y
	   la criatura se ajusta dentro. */
	/* La caja ocupa la urna entera y el hueco se hace con PADDING, no con las cuatro pegadas.
	   Con `inset` a los cuatro lados y tamaño automatico, una imagen -- que es un elemento
	   reemplazado -- conserva su tamaño intrinseco y se ancla arriba a la izquierda: object-fit
	   no llega a mandar nunca. Dandole medida completa y `border-box`, `contain` escala dentro del
	   hueco y `center bottom` la apoya en el pedestal. */
	position: absolute;
	inset: 0;
	box-sizing: border-box;
	width: 100%;
	height: 100%;
	padding: 2.2rem 1rem 1.5rem;
	object-fit: contain;
	object-position: center bottom;
	image-rendering: pixelated;  /* pixel art: sin esto el navegador lo emborrona al escalar */
	filter: drop-shadow(0 3px 5px rgba(0,0,0,.55)) drop-shadow(0 0 12px var(--glow-soft));
	animation: elecare-float 5.5s ease-in-out infinite;
}
/* Flota un pelin. Muy poco: es una criatura expuesta, no un globo. */
@keyframes elecare-float { 50% { transform: translateY(-3px); } }

/* --- El icono de una mascota (necROmantic 2026-08-13, informe del usuario: "si el icono debe ser
   pequeno no quiero que se vea estirado") -------------------------------------------------------
   Una mascota se ilustra con el icono de su huevo, y un icono de objeto mide 24x24 REALES. La
   regla de arriba esta hecha para sprites de criatura de cientos de pixeles: da medida completa a
   la urna, asi que estiraba esos 24 pixeles hasta ocho veces su tamano. `object-fit: contain`
   evitaba la deformacion -- la proporcion nunca se rompio -- pero un dibujo de 24 puntos ampliado
   x8 se ve como una mancha, y eso es lo que se lee como "estirado".
   Aqui se le da una caja fija de 96 px, que es 24 x CUATRO EXACTOS. El entero es la parte que
   importa: con `image-rendering: pixelated` un factor entero copia cada pixel el mismo numero de
   veces y el dibujo sale nitido; con 3,7 el navegador tiene que repartir medios pixeles y vuelve
   la mancha.
   Se centra con `margin` y NO con `transform`, aunque sea mas corto: la animacion de flotar que
   hereda de .elecare-sprite usa transform, y las dos se pisarian -- el icono daria un salto
   lateral a mitad de cada ciclo. */
.elecare-icon {
	inset: auto 0 1.6rem;
	width: 96px;
	height: 96px;
	margin-inline: auto;
	padding: 0;
	object-fit: contain;
}


/* --- Pastilla de estado y grado ---------------------------------------------- */
.elecare-pill,
.elecare-badge {
	position: absolute;
	top: .7rem;
	z-index: 2;
	padding: .25rem .6rem;
	border-radius: 999px;
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	background: rgba(8,5,16,.72);
	box-shadow: inset 0 0 0 1px rgba(178,150,255,.20);
	backdrop-filter: blur(3px);
}
.elecare-pills {
	position: absolute;
	top: .7rem; left: .7rem;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	gap: .3rem;
}
.elecare-pill { position: static; display: inline-flex; align-items: center; gap: .4rem; }
.elecare-pill::before {
	content: "";
	width: .42rem; height: .42rem;
	border-radius: 50%;
	background: currentColor;
	box-shadow: 0 0 6px currentColor;
}

/* LOS BOCADILLOS, sobre la criatura y no en una etiqueta.
   Van en el tercio superior de la urna, que es el hueco que las siluetas dejan libre: casi todas
   se apoyan abajo, asi que ahi arriba no tapan nada. Y por delante del sprite, para que un
   Senor elemental que llene la caja no se los coma. */
.elecare-says {
	position: absolute;
	top: 16%;
	left: 50%;
	transform: translateX(-50%);
	z-index: 3;
	display: flex;
	align-items: flex-end;
	pointer-events: none;
	animation: elecare-say 2.6s ease-in-out infinite;
}
/* Un balanceo minimo: en el juego el globo aparece y desaparece, y algo de vida evita que
   parezca una calcomania pegada. */
@keyframes elecare-say { 50% { transform: translateX(-50%) translateY(-3px); } }

/* Caja CUADRADA e igual para todos. Los de emotion.act tienen proporciones muy distintas entre
   si -- unos son un globo ancho y otros una gota alta -- asi que con `width: auto` cada uno salia
   de un ancho y el amontonamiento quedaba descuadrado: el solapamiento es un margen fijo y solo
   cuadra si todas las piezas miden lo mismo.
   `contain` mantiene la proporcion de cada dibujo dentro de esa caja comun, sin deformar ninguno. */
.elecare-emote {
	width: 2.1rem;
	height: 2.1rem;
	object-fit: contain;
	object-position: center bottom;
	image-rendering: pixelated;
	filter: drop-shadow(0 2px 3px rgba(0,0,0,.55));
}

/* AMONTONADOS, no en fila (peticion del usuario). Con varias necesidades a la vez los globos se
   pisan y se ladean, como cuando una criatura suelta varias cosas seguidas: el de delante tapa
   un trozo del de detras y se ve que hay mas de uno de un vistazo.
   El desorden es FIJO por posicion, no aleatorio: asi la tarjeta no baila en cada refresco, que
   es cada pocos segundos. */
.elecare-says .elecare-emote:not(:first-child) { margin-left: -.95rem; }
.elecare-says .elecare-emote:nth-child(1) { transform: rotate(-7deg) translateY(2px); z-index: 3; }
.elecare-says .elecare-emote:nth-child(2) { transform: rotate(5deg)  translateY(-4px); z-index: 2; }
.elecare-says .elecare-emote:nth-child(3) { transform: rotate(-3deg) translateY(1px);  z-index: 1; }
.elecare-badge { right: .7rem; color: #cdc4ee; font-weight: 600; letter-spacing: .04em; }

/* El color va POR PASTILLA y no por tarjeta: una criatura puede estar hambrienta, sucia y
   enfadada a la vez, y con el color heredado del estado "dominante" las tres se pintaban igual. */
.elecare-pill.p-ok     { color: #63c58a; }
.elecare-pill.p-hungry { color: #e0b24a; }
.elecare-pill.p-mess,
.elecare-pill.p-upset  { color: #e2726a; }

/* --- Los datos ---------------------------------------------------------------- */
.elecare-body {
	padding: 1rem 1.05rem 1.1rem;
	display: flex;
	flex-direction: column;
	gap: .6rem;
	background: linear-gradient(180deg, rgba(255,255,255,.028), transparent 40%);
}
.elecare-name {
	margin: 0;
	font-size: 1.12rem;
	line-height: 1.15;
	letter-spacing: .01em;
	text-shadow: 0 0 14px var(--glow-soft);
}
.elecare-sub { margin: -.25rem 0 0; font-size: .78rem; color: #9b91c4; letter-spacing: .04em; }

.elecare-bar { display: flex; flex-direction: column; gap: .25rem; }
.elecare-bar > span { display: flex; justify-content: space-between; align-items: baseline; }
.elecare-bar b { font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: #8d84b8; }
.elecare-bar i { font-style: normal; font-size: .78rem; color: #cdc4ee; }
.elecare-track {
	height: .34rem;
	border-radius: 999px;
	background: rgba(0,0,0,.45);
	box-shadow: inset 0 0 0 1px rgba(178,150,255,.14);
	overflow: hidden;
}
.elecare-fill {
	display: block;
	height: 100%;
	border-radius: 999px;
	background: linear-gradient(90deg, var(--glow), #fff6);
	box-shadow: 0 0 8px var(--glow-soft);
	transition: width .5s cubic-bezier(.2,.7,.3,1);
}
.elecare-fill.is-low { background: linear-gradient(90deg, #e2726a, #fff4); box-shadow: 0 0 8px rgba(226,114,106,.4); }

.elecare-mood {
	margin: .1rem 0 0;
	padding: .55rem .65rem;
	font-size: .84rem;
	line-height: 1.45;
	color: #b6adda;
	border-radius: .5rem;
	background: rgba(8,5,16,.45);
	box-shadow: inset 0 0 0 1px rgba(178,150,255,.12);
}

/* Los botones, pegados abajo: asi quedan alineados entre tarjetas aunque el texto del estado
   ocupe una linea en una y tres en otra. */
.elecare-body { flex: 1; }
.elecare-actions { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: auto; padding-top: .5rem; }
.elecare-btn {
	flex: 1 1 auto;
	padding: .55rem .8rem;
	font: inherit;
	font-weight: 600;
	letter-spacing: .02em;
	cursor: pointer;
	color: #ece8ff;
	border: 1px solid rgba(178,150,255,.30);
	background: rgba(140,110,225,.14);
	border-radius: .5rem;
	transition: background .16s ease, border-color .16s ease, box-shadow .16s ease, transform .1s ease;
}
.elecare-btn:hover {
	background: var(--glow-soft);
	border-color: var(--glow);
	box-shadow: 0 0 14px var(--glow-soft);
}
.elecare-btn:active { transform: translateY(1px); }

.elecare-msg { margin: 0; min-height: 1.05em; font-size: .8rem; color: #e2726a; }

/* EL AVISO, RODEANDO LA FICHA ENTERA.
   Antes era un `box-shadow: inset` sobre la tarjeta, y por eso solo se veia por abajo: una
   sombra interior la pinta el elemento sobre SU fondo, y encima van la urna y el cuerpo con los
   suyos, que la tapan. Solo asomaba por la franja donde el fondo de la tarjeta quedaba a la
   vista. Se resuelve con una capa propia por delante de todo: mismo radio, sin capturar clics, y
   es su borde el que late. */
.elecare-card::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 5;
	border: 2px solid transparent;
	border-radius: inherit;
	pointer-events: none;
	transition: border-color .3s ease;
}
@keyframes elecare-breathe {
	0%, 100% { border-color: rgba(226,114,106,.28); }
	50%      { border-color: rgba(226,114,106,.95); }
}
.elecare-card.is-poop::after,
.elecare-card.is-angry::after { animation: elecare-breathe 2.8s ease-in-out infinite; }
.elecare-card.is-hungry::after { border-color: rgba(224,178,74,.42); }

@media (prefers-reduced-motion: reduce) {
	.elecare-card, .elecare-card::after, .elecare-sprite, .elecare-says, .elecare-fill, .elecare-btn { animation: none; transition: none; }
	.elecare-card.is-poop::after, .elecare-card.is-angry::after { border-color: rgba(226,114,106,.8); }
}
