/*  ============================================================
    necROmantic – Dark Theme for UnknownCP
    Ragnarok Online Private Server
    ============================================================ */

/* ── Variables (CSS custom properties) ─────────────────────── */
:root {
    /* ── Paleta "Violeta de medianoche" (romantico-gotica) ──────
       Fondos violeta-noche, superficies amatista, acento primario
       rosa-magenta (token --gold, conservado por compatibilidad),
       acento secundario violeta (tokens --alpha-bronze-*) y
       neutros lavanda (tokens --alpha-silver-*).                  */
    --bg-body:               #0a0713;
    --bg-surface:            #150e26;
    --bg-surface-alt:        #1f1638;
    --bg-sidebar:            #0f0a1c;
    --bg-sidebar-head:       #291d47;
    --bg-sidebar-item:       #171029;
    --bg-header:             #0e0a1af2;
    --bg-content:            #150e26;
    --bg-loginbox:           #180f2b;
    --bg-table-head:         #291d47;
    --bg-table-row:          #171029;
    --bg-table-alt:          #1e1536;
    --bg-input:              #1f1638;
    --bg-footer:             #0e0a1af2;

    --border:                #3a2c5c;
    --border-light:          #52407c;
    --border-accent:         #8a6fbe;

    --text-primary:          #ece5f8;
    --text-muted:            #a99cc4;
    --text-heading:          #ded3f2;
    --text-heading2:         #f6f1ff;
    --text-link:             #ddd2f0;
    --text-link-hover:       #f5b8da;
    --text-footer:           #cabfe0;

    --accent-red:            #c96f9e;
    --accent-red-h:          #ffe1f1;
    --accent-purple:         #b48cf0;
    --accent-purple-h:       #e6d8ff;

    /* El color de la SERIE de la estrella de caracteristicas (2026-08-26). Es un escalon
       propio y no --accent-purple porque aquel se sale por arriba de la banda de luminosidad
       que pide una serie de datos sobre fondo oscuro (OKLCH L 0,72 frente a la banda
       0,48-0,67): comprobado con el validador de paleta, no a ojo. Este pasa la banda y el
       contraste 3:1 contra --bg-surface-alt. */
    --rad-series:            #a07fe0;
    --gold:                  #dfa0c6;
    --gold-dim:              #a55f8b;
    --crimson:               #5b2a4a;

    --text-logo:             #f7f2ff;
    --text-logo-tagline:     #bcaddb;
    --text-header-account:   #ece5f8;
    --text-hero-title:       #f8f3ff;
    --text-hero-intro:       #c2b6dd;
    --text-label-strong:     #ece5f8;
    --text-label-hover:      #ffd9ee;
    --text-code:             #b6a7d6;
    --text-code-strong:      #d3c7ec;
    --text-panel-soft:       #d6cceb;
    --text-panel-bright:     #ffffff;
    --text-footer-link:      #ffdff0;
    --text-white:            #ffffff;
    --text-message:          #ecdcf2;
    --text-notice:           #ded6f0;
    --text-error:            #f5d6e0;
    --text-success:          #d9eee6;
    --text-status-success:   #7fc3a5;
    --text-status-error:     #e0798f;
    --text-status-error-strong: #cc5a75;
    --text-status-warning:   #d9b05b;

    /* Acento primario: rosa-magenta */
    --alpha-gold-08:         rgba(223, 160, 198, 0.08);
    --alpha-gold-12:         rgba(223, 160, 198, 0.12);
    --alpha-gold-16:         rgba(223, 160, 198, 0.16);
    --alpha-gold-20:         rgba(223, 160, 198, 0.20);
    --alpha-gold-24:         rgba(223, 160, 198, 0.24);
    --alpha-gold-28:         rgba(223, 160, 198, 0.28);
    --alpha-gold-32:         rgba(223, 160, 198, 0.32);
    --alpha-gold-36:         rgba(223, 160, 198, 0.36);
    --alpha-gold-42:         rgba(223, 160, 198, 0.42);
    --alpha-gold-52:         rgba(223, 160, 198, 0.52);
    --alpha-gold-64:         rgba(223, 160, 198, 0.64);

    --alpha-white-03:        rgba(255, 255, 255, 0.03);
    --alpha-white-04:        rgba(255, 255, 255, 0.04);
    --alpha-white-05:        rgba(255, 255, 255, 0.05);
    --alpha-white-06:        rgba(255, 255, 255, 0.06);
    --alpha-white-07:        rgba(255, 255, 255, 0.07);
    --alpha-white-08:        rgba(255, 255, 255, 0.08);
    --alpha-black-18:        rgba(0, 0, 0, 0.18);
    --alpha-black-22:        rgba(0, 0, 0, 0.22);
    --alpha-black-24:        rgba(0, 0, 0, 0.24);
    --alpha-black-28:        rgba(0, 0, 0, 0.28);
    --alpha-black-34:        rgba(0, 0, 0, 0.34);

    /* Neutros: lavanda */
    --alpha-silver-08:       rgba(226, 216, 248, 0.08);
    --alpha-silver-10:       rgba(226, 216, 248, 0.10);
    --alpha-silver-12:       rgba(226, 216, 248, 0.12);
    --alpha-silver-14:       rgba(226, 216, 248, 0.14);
    --alpha-silver-16:       rgba(226, 216, 248, 0.16);
    --alpha-silver-18:       rgba(226, 216, 248, 0.18);
    --alpha-silver-20:       rgba(226, 216, 248, 0.20);
    --alpha-silver-22:       rgba(226, 216, 248, 0.22);
    --alpha-silver-24:       rgba(226, 216, 248, 0.24);
    --alpha-silver-30:       rgba(226, 216, 248, 0.30);
    --alpha-silver-42:       rgba(226, 216, 248, 0.42);
    --alpha-silver-48:       rgba(226, 216, 248, 0.48);

    --alpha-silver-bright-06: rgba(247, 242, 255, 0.06);
    --alpha-silver-bright-08: rgba(247, 242, 255, 0.08);
    --alpha-silver-bright-10: rgba(247, 242, 255, 0.10);
    --alpha-silver-bright-12: rgba(247, 242, 255, 0.12);
    --alpha-silver-bright-14: rgba(247, 242, 255, 0.14);
    --alpha-silver-bright-32: rgba(247, 242, 255, 0.32);
    --alpha-silver-bright-34: rgba(247, 242, 255, 0.34);
    --alpha-silver-bright-36: rgba(247, 242, 255, 0.36);
    --alpha-silver-bright-38: rgba(247, 242, 255, 0.38);
    --alpha-silver-bright-42: rgba(247, 242, 255, 0.42);
    --alpha-silver-bright-68: rgba(247, 242, 255, 0.68);
    --alpha-silver-bright-78: rgba(247, 242, 255, 0.78);
    --alpha-silver-bright-86: rgba(247, 242, 255, 0.86);

    /* Acento secundario: amatista */
    --alpha-bronze-08:       rgba(139, 92, 214, 0.08);
    --alpha-bronze-16:       rgba(139, 92, 214, 0.16);
    --alpha-bronze-18:       rgba(139, 92, 214, 0.18);
    --alpha-bronze-20:       rgba(139, 92, 214, 0.20);
    --alpha-bronze-24:       rgba(139, 92, 214, 0.24);
    --alpha-bronze-28:       rgba(139, 92, 214, 0.28);
    --alpha-bronze-30:       rgba(139, 92, 214, 0.30);
    --alpha-bronze-32:       rgba(139, 92, 214, 0.32);
    --alpha-bronze-34:       rgba(139, 92, 214, 0.34);
    --alpha-bronze-42:       rgba(139, 92, 214, 0.42);
    --alpha-bronze-45:       rgba(139, 92, 214, 0.45);

    --surface-header-account: rgba(22, 15, 40, 0.78);
    --surface-cookie:        rgba(14, 10, 28, 0.94);
    --surface-footer-link:   rgba(222, 214, 240, 0.10);
    --surface-footer-link-hover: rgba(243, 238, 252, 0.18);
    --surface-card:          rgba(21, 14, 38, 0.82);
    --surface-card-strong:   rgba(16, 11, 30, 0.86);
    --surface-card-hover:    rgba(235, 228, 250, 0.16);
    --surface-card-soft:     rgba(226, 218, 246, 0.10);
    --surface-card-row:      rgba(41, 30, 71, 0.88);
    --surface-card-row-custom: rgba(139, 92, 214, 0.24);
    --surface-bitmask-summary: rgba(228, 220, 246, 0.12);
    --surface-bitmask-state: rgba(226, 218, 246, 0.18);
    --surface-bitmask-state-custom: rgba(105, 60, 130, 0.54);
    --surface-highlight:     rgba(228, 220, 248, 0.12);
    --surface-table-row-hover: #241a42;
    --surface-input-focus:   #2a1f4c;
    --surface-admin-sidebar-head: #2a1730;
    --surface-admin-sidebar-border: #48294c;
    --surface-admin-sidebar-item: #1b1122;
    --surface-admin-sidebar-item-hover: #2c1c35;
    --surface-sidebar-hover: #dfa0c6;
    --text-admin-sidebar:    #e8d8ea;
    --surface-silver-panel:  rgba(229, 221, 247, 0.14);
    --surface-silver-panel-strong: rgba(238, 232, 250, 0.18);
    --surface-silver-panel-soft: rgba(226, 218, 246, 0.10);
    --surface-silver-chip:   rgba(230, 222, 248, 0.14);
    --surface-silver-chip-hover: rgba(247, 242, 255, 0.24);
    --surface-silver-row:    rgba(228, 220, 248, 0.16);
    --surface-silver-state:  rgba(230, 222, 248, 0.18);
    --surface-silver-summary: rgba(230, 222, 248, 0.16);
    --border-silver-soft:    rgba(226, 218, 246, 0.24);
    --border-silver-strong:  rgba(243, 238, 252, 0.36);
    --border-custom-row:     rgba(223, 160, 198, 0.34);

    --grad-body:             linear-gradient(180deg, var(--bg-header) 0%, var(--bg-surface) 56%, var(--bg-body) 100%);
    --grad-header:           linear-gradient(135deg, #0d0819 0%, #241a44 54%, #100b21 100%);
    --grad-sidebar-card:     linear-gradient(180deg, #1a1230 0%, #110c22 100%);
    --grad-sidebar-admin:    linear-gradient(180deg, #2e1730 0%, #170d1c 100%);
    --grad-sidebar-meta:     linear-gradient(180deg, #1b1333 0%, #110c21 100%);
    --grad-sidebar-link:     linear-gradient(180deg, #2b2050 0%, #1a1334 100%);
    --grad-sidebar-link-hover: linear-gradient(180deg, #dfa0c6 0%, #8b5cd6 100%);
    --grad-primary-button:   linear-gradient(135deg, #e8aed0 0%, #b98ded 100%);
    --grad-primary-button-hover: linear-gradient(135deg, #f7cbe4 0%, #cba6f5 100%);
    --grad-secondary-button: linear-gradient(135deg, #3a2c5c 0%, #221a3c 100%);
    --grad-secondary-button-hover: linear-gradient(135deg, #dfa0c6 0%, #8b5cd6 100%);
    --grad-footer:           linear-gradient(135deg, #0c0817 0%, #221940 54%, #0e0a1d 100%);
    --grad-hero:             linear-gradient(135deg, #150f28 0%, #2a1f4c 100%);
    --grad-battle-hero:      linear-gradient(135deg, #1a1230 0%, #322549 100%);
    --grad-transparency-highlight: linear-gradient(135deg, #211838 0%, #372a5c 100%);
    --grad-delete-button:    linear-gradient(180deg, #8e3a5c 0%, #4b1c2e 100%);
    --grad-delete-button-hover: linear-gradient(180deg, #f0a8c8 0%, #b5628e 100%);
    --grad-reset-button:     linear-gradient(180deg, #3b2d5e 0%, #241b3f 100%);
    --grad-reset-button-hover: linear-gradient(180deg, #dfa0c6 0%, #8b5cd6 100%);
    --grad-register-submit:  linear-gradient(180deg, #e8aed0 0%, #8b5cd6 100%);
    --grad-register-submit-hover: linear-gradient(180deg, #f7cbe4 0%, #a878ec 100%);
    --grad-silver-panel:     linear-gradient(180deg, rgba(229, 221, 247, 0.18), rgba(186, 175, 214, 0.10));
    --grad-silver-panel-strong: linear-gradient(180deg, rgba(240, 234, 252, 0.22), rgba(196, 186, 222, 0.12));
    --grad-silver-chip:      linear-gradient(180deg, rgba(238, 231, 251, 0.18), rgba(203, 193, 227, 0.12));

    --shadow-header:         0 20px 60px var(--alpha-black-34);
    --shadow-logo:           drop-shadow(0 10px 24px var(--alpha-black-28));
    --shadow-card:           0 18px 44px var(--alpha-black-22);
    --shadow-panel:          0 18px 40px var(--alpha-black-22);
    --shadow-content:        0 25px 65px var(--alpha-black-24);
    --shadow-soft:           0 16px 40px var(--alpha-black-18);
    --shadow-pop:            0 14px 34px var(--alpha-black-18);
    --shadow-pop-strong:     0 16px 38px var(--alpha-black-24);
    --shadow-cookie:         0 24px 55px var(--alpha-black-34);
    --shadow-button-hover:   0 14px 30px var(--alpha-gold-20), 0 0 22px var(--alpha-gold-42);
    --shadow-secondary-hover: 0 12px 28px var(--alpha-gold-24), 0 0 18px var(--alpha-gold-32);
    --shadow-focus:          0 0 0 2px var(--alpha-gold-24), 0 0 16px var(--alpha-gold-36);
    --shadow-sidebar-link:   inset 0 1px 0 var(--alpha-white-08), 0 0 12px var(--alpha-silver-08), 0 0 0 transparent;
    --shadow-sidebar-link-hover: 0 0 16px var(--alpha-gold-24), 0 0 28px var(--alpha-gold-42), inset 0 0 12px var(--alpha-gold-20);
    --shadow-delete:         0 0 10px var(--alpha-gold-16);
    --shadow-delete-hover:   0 0 14px var(--alpha-gold-36), 0 0 24px var(--alpha-gold-20);
    --shadow-delete-focus:   0 0 0 2px var(--alpha-gold-20), 0 0 14px var(--alpha-gold-36);
    --shadow-state-glow:     0 0 16px var(--alpha-silver-24), 0 0 28px var(--alpha-silver-bright-12), inset 0 0 12px var(--alpha-silver-bright-12);
    --shadow-state-soft:     0 0 10px var(--alpha-gold-20), 0 0 20px var(--alpha-gold-16), inset 0 0 8px var(--alpha-gold-12);
    --shadow-state-strong:   0 0 18px var(--alpha-gold-36), 0 0 34px var(--alpha-gold-52), inset 0 0 14px var(--alpha-gold-20);

    --text-on-accent:        #1c0d20;
    --text-on-accent-strong: #120814;
    --text-on-accent-soft:   #2a1430;

    --tag-lv-u80:            #5f7fc4;
    --tag-lv-80:             #4f9873;
    --tag-lv-100:            #c19a4a;
    --tag-lv-130:            #bd6a3c;
    --tag-lv-150:            #b8455c;
    --tag-lv-any:            #6a6288;

    --state-success:         #7fc3a5;
    --state-error:           #e0798f;
    --state-error-strong:    #cc5a75;
    --state-warning:         #d9b05b;
    --state-error-bg:        #33172a;
    --state-error-border:    #7a3a55;
    --state-success-bg:      #16302c;
    --state-success-border:  #3f7a6a;
    --state-notice-bg:       #1c1836;
    --state-notice-border:   #4a4180;
    --state-message-bg:      #241a3c;
    --state-message-border:  var(--alpha-bronze-42);

    /* Tonos del mosaico de secciones de la ficha de cuenta (.pnav).
       Uno por seccion, y cada uno con su version transparente para el resplandor: el
       color y el halo tienen que ser el mismo tono, y de un hexadecimal no se puede
       sacar una version con alfa sin color-mix(), asi que van escritos los dos. */
    --tone-lilac:            #c3a6f5;
    --tone-lilac-glow:       rgba(195, 166, 245, 0.20);
    --tone-azure:            #7fb6f2;
    --tone-azure-glow:       rgba(127, 182, 242, 0.20);
    --tone-teal:             #62c9c3;
    --tone-teal-glow:        rgba(98, 201, 195, 0.20);
    --tone-amber:            #e3b062;
    --tone-amber-glow:       rgba(227, 176, 98, 0.20);
    --tone-gold:             #dbb765;
    --tone-gold-glow:        rgba(219, 183, 101, 0.20);
    --tone-rose:             #ef9ac0;
    --tone-rose-glow:        rgba(239, 154, 192, 0.20);
    --tone-mint:             #7fc3a5;
    --tone-mint-glow:        rgba(127, 195, 165, 0.20);
    --tone-indigo:           #8f9bf0;
    --tone-indigo-glow:      rgba(143, 155, 240, 0.20);
    --tone-crimson:          #e0798f;
    --tone-crimson-glow:     rgba(224, 121, 143, 0.20);
    --tone-violet:           #b48cf0;
    --tone-violet-glow:      rgba(180, 140, 240, 0.20);
    --tone-copper:           #e0a07a;
    --tone-copper-glow:      rgba(224, 160, 122, 0.20);
    --tone-silver:           #b9aed6;
    --tone-silver-glow:      rgba(185, 174, 214, 0.18);

    --grad-pnav:             linear-gradient(180deg, rgba(33, 24, 60, 0.78), rgba(15, 10, 29, 0.72));
    --grad-tile:             linear-gradient(158deg, rgba(43, 32, 76, 0.72), rgba(20, 14, 38, 0.72));
    --grad-tile-hover:       linear-gradient(158deg, rgba(56, 42, 96, 0.86), rgba(26, 18, 48, 0.82));
}

/* ── Reset / Base ──────────────────────────────────────────── */
* { box-sizing: border-box; }

html {
    height: 100%;
    overflow: hidden;
}

body {
    margin: 0;
    padding: 0;
    background:
        radial-gradient(circle at top, var(--alpha-silver-10), transparent 24%),
        radial-gradient(circle at right 18%, var(--alpha-bronze-16), transparent 32%),
        var(--grad-body);
    color: var(--text-primary);
    font-family: "Alegreya Sans", "Segoe UI Variable Text", "Gill Sans", sans-serif;
    font-size: 9pt;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: auto;
}

table {
    font-family: "Alegreya Sans", "Lucida Sans", Verdana, Tahoma, sans-serif;
    font-size: 9pt;
}

tr, td, th { vertical-align: top; }

.horizontal-table tr, .vertical-table tr, .generic-form-table tr,
.horizontal-table td, .vertical-table td, .generic-form-table td {
    vertical-align: middle;
}

.horizontal-table th, .vertical-table th, .generic-form-table th {
    vertical-align: top;
}

p { margin: 4px 0 8px 0; padding: 0; }
a img { border: 0; }

a {
    color: var(--text-link);
    text-decoration: none;
    transition: color 0.15s ease;
}
a:hover { color: var(--text-link-hover); text-decoration: underline; }

h2 {
    color: var(--text-heading);
    letter-spacing: -0.4px;
    margin: 0 0 16px;
    text-shadow: 0 0 12px var(--alpha-bronze-24);
}

h3 {
    font-weight: normal;
    font-size: 120%;
    color: var(--text-heading);
    text-transform: uppercase;
    letter-spacing: 1px;
    margin: 22px 0 10px;
}
h3:first-letter { font-weight: bold; }

.cms-download-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 10px 0 14px;
    padding: 13px 22px;
    border-radius: 16px;
    /* necROmantic 2026-07-29: el texto se confundia con el fondo del propio boton.
       Se fija un morado profundo opaco (no un token de acento, que en esta paleta
       es claro) y se marca !important porque la regla generica de <a> del tema le
       gana en la practica. El resplandor se baja: aureolaba las letras.          */
    background: var(--grad-primary-button);
    color: #1a0b26 !important;
    font-size: 10.5pt;
    font-weight: 700;
    letter-spacing: 0.3px;
    text-decoration: none !important;
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.35);
    transition: transform 0.18s ease, box-shadow 0.22s ease, border-color 0.22s ease, background 0.22s ease, color 0.22s ease;
}

.cms-download-button::before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    content: "\f019";
    color: #1a0b26;
}

.cms-download-button:hover {
    transform: translateY(-1px);
    background: var(--grad-primary-button-hover);
    color: #12061c !important;
    text-decoration: none !important;
}

.stats-page-intro {
    margin-bottom: 1.2rem;
    color: var(--text-muted);
}

.stats-filter-form,
.stats-chart-card,
.stats-table-card {
    background: var(--grad-sidebar-card);
    border-radius: 18px;
    box-shadow: var(--shadow-panel);
    padding: 1.2rem;
    margin-bottom: 1.25rem;
}

.stats-filter-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 1rem;
    align-items: end;
}

.stats-filter-grid--gm {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
}

.stats-filter-grid label {
    display: block;
}

.stats-filter-grid label span {
    display: block;
    margin-bottom: 0.45rem;
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.stats-filter-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding-bottom: 0.15rem;
}

.stats-filter-reset,
.stats-view-link,
.stats-back-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.7rem 1rem;
    border-radius: 999px;
    background: var(--alpha-gold-08);
    color: var(--text-heading);
    text-decoration: none;
    font-weight: 600;
    transition: background 0.2s ease, transform 0.2s ease;
}

.stats-filter-reset:hover,
.stats-view-link:hover,
.stats-back-link:hover {
    background: var(--alpha-gold-16);
    text-decoration: none;
    transform: translateY(-1px);
}

.stats-list-table thead th,
.stats-detail-table th {
    white-space: nowrap;
}

.stats-online-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-left: 0.55rem;
    padding: 0.16rem 0.55rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--state-success) 20%, transparent);
    color: var(--state-success);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.stats-summary-grid,
.stats-detail-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.stats-detail-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: stretch;
}

.stats-summary-card {
    background: var(--grad-sidebar-meta);
    border-radius: 18px;
    padding: 1rem 1.1rem;
    box-shadow: var(--shadow-soft);
}

.stats-summary-card__label {
    display: block;
    margin-bottom: 0.45rem;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.stats-summary-card strong {
    font-size: 1.1rem;
    color: var(--text-heading2);
}

.stats-chart-card {
    min-height: 420px;
    position: relative;
}

.stats-chart-card__header h3,
.stats-table-card h3 {
    margin-top: 0;
    margin-bottom: 0.35rem;
    color: var(--text-heading2);
}

.stats-chart-card__header p {
    margin-top: 0;
    margin-bottom: 1rem;
    color: var(--text-muted);
}

.stats-metric-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.65rem;
    margin-bottom: 1rem;
}

.stats-metric-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.42rem 0.75rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--toggle-color, var(--gold)) 16%, var(--alpha-white-03));
    color: var(--text-primary);
    font-size: 0.85rem;
    cursor: pointer;
}

.stats-metric-toggle input {
    accent-color: var(--toggle-color);
    margin: 0;
}

.stats-empty-chart {
    color: var(--text-muted);
    padding-top: 1rem;
}

.stats-back-link-row {
    margin-bottom: 1rem;
}

@media (max-width: 1080px) {
    .stats-summary-grid,
    .stats-detail-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .stats-filter-grid,
    .stats-filter-grid--gm {
        grid-template-columns: 1fr;
    }

    .stats-filter-actions {
        padding-bottom: 0;
    }
}

@media (max-width: 720px) {
    .stats-summary-grid,
    .stats-detail-grid {
        grid-template-columns: 1fr;
    }

    .stats-list-table {
        font-size: 0.9rem;
    }
}

.cms-download-button:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* ── Site Header ───────────────────────────────────────────── */
#site-header {
    background: var(--grad-header);
    padding: 22px 28px 18px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    box-shadow: var(--shadow-header);
    flex-shrink: 0;
}

#logo-link {
    display: inline-flex;
    align-items: center;
    gap: 16px;
    text-decoration: none !important;
}
#logo-link:hover { text-decoration: none !important; }

#logo-mark {
    width: 82px;
    height: 82px;
    flex: 0 0 auto;
    object-fit: contain;
    filter: var(--shadow-logo);
}

#logo-text {
    line-height: 1;
}

#logo-text .logo-nec,
#logo-text .logo-mantic {
    font-size: 36px;
    font-weight: 700;
    color: var(--text-logo);
    letter-spacing: 1px;
    text-shadow: 0 0 16px var(--alpha-silver-14);
    display: inline;
}

#logo-text .logo-ro {
    font-size: 36px;
    font-weight: 900;
    color: var(--gold);
    letter-spacing: 2px;
    text-shadow: 0 0 18px var(--alpha-silver-48), 0 0 4px var(--alpha-silver-bright-68);
    display: inline;
}

#logo-text .logo-tagline {
    display: block;
    font-size: 8.5pt;
    color: var(--text-logo-tagline);
    letter-spacing: 2.4px;
    text-transform: uppercase;
    margin-top: 7px;
    font-style: normal;
}

#header-account {
    color: var(--text-header-account);
    font-size: 9pt;
    text-align: right;
    padding: 12px 16px;
    border-radius: 18px;
    background: var(--surface-header-account);
    backdrop-filter: blur(12px);
}
#header-account strong { color: var(--text-heading); }
#header-account em { color: var(--text-primary); font-style: normal; }

.header-admin-links {
    margin-top: 4px;
}
.header-admin-links a {
    color: var(--accent-red-h);
    margin-left: 8px;
    font-size: 8pt;
}
.header-admin-links a::before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    content: "\f013";
    margin-right: 6px;
    color: var(--gold);
}
.header-admin-links a:hover { color: var(--gold); }

/* ── Site Wrapper (sidebar + content) ─────────────────────── */
#site-wrapper {
    display: flex;
    align-items: stretch;
    padding: 0px;
    gap: 20px;
    flex: 1;
    overflow: hidden;
    min-height: 0;
}

/* ── Sidebar ───────────────────────────────────────────────── */
#site-sidebar {
    width: 280px;
    padding: 15px 20px 20px 15px;
    flex-shrink: 0;
    overflow-y: auto;
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
}

.sidebar-stack {
    display: grid;
    gap: 16px;
}

.sidebar-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 18px;
    border-radius: 24px;
    background: var(--grad-sidebar-card);
    box-shadow: var(--shadow-card);
}

.sidebar-card-admin {
    margin-bottom: 14px;
    background: var(--grad-sidebar-admin);
}

.sidebar-card-meta {
    background: var(--grad-sidebar-meta);
}

.sidebar-card-legal {
    margin-top: auto;
    background: transparent;
    box-shadow: none;
}

.sidebar-card-legal .sidebar-link::before {
    display: none;
}

.sidebar-card-legal .sidebar-link__icon {
    display: inline-block;
    width: 18px;
    text-align: center;
    color: var(--gold);
    flex: 0 0 18px;
    font-size: 11pt;
}

.sidebar-card-legal .sidebar-link {
    font-size: 8.5pt;
    opacity: .82;
}

.sidebar-card-legal .sidebar-link:hover {
    opacity: 1;
}

.sidebar-legal-copy {
    margin: 6px 0 0;
    font-size: 7.5pt;
    color: var(--text-muted);
    line-height: 1.4;
}

.sidebar-card__title {
    color: var(--text-heading);
    font-size: 10px;
    letter-spacing: 1.8px;
    text-transform: uppercase;
    font-weight: bold;
}

.sidebar-links {
    display: grid;
    gap: 10px;
}

.sidebar-link {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 16px;
    background: var(--grad-sidebar-link);
    color: var(--text-primary);
    text-decoration: none;
    text-align: left;
    box-shadow: var(--shadow-sidebar-link);
    transition: color 0.22s ease, background 0.22s ease, border-color 0.22s ease, box-shadow 0.28s ease, transform 0.22s ease;
}

.sidebar-link::before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    content: "\f054";
    width: 18px;
    text-align: center;
    color: var(--gold);
    flex: 0 0 18px;
}

.sidebar-link__icon {
    display: none;
}

.sidebar-link span {
    display: block;
    width: 100%;
    text-align: left;
}

.sidebar-link:hover {
    color: var(--text-panel-bright);
    text-decoration: none;
    background: var(--grad-sidebar-link-hover);
    box-shadow: var(--shadow-sidebar-link-hover);
    transform: translateY(-1px);
    animation: sidebarOrangeGlow 1.2s ease-in-out infinite alternate;
}

.sidebar-link:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

.sidebar-meta-copy,
.sidebar-meta-note,
.sidebar-meta-language {
    color: var(--text-muted);
    font-size: 8.5pt;
    line-height: 1.5;
    text-align: center;
}

.sidebar-meta-copy {
    color: var(--text-primary);
}

.sidebar-meta-language {
    color: var(--text-heading);
    text-transform: uppercase;
    letter-spacing: 1px;
}

.footer-kicker {
    margin: 0 0 8px;
    color: var(--text-heading);
    font-size: 8pt;
    letter-spacing: 1.6px;
    text-transform: uppercase;
}

@keyframes sidebarOrangeGlow {
    from {
        box-shadow: var(--shadow-state-soft);
    }
    to {
        box-shadow: var(--shadow-state-strong);
    }
}

/* Legacy table-based sidebar – make it full-width inside the flex div */
#admin_sidebar,
#sidebar {
    width: 100%;
    margin-bottom: 12px;
    border-collapse: collapse;
    border-spacing: 0;
    background: var(--bg-sidebar);
    border-radius: 22px;
    overflow: hidden;
    box-shadow: var(--shadow-panel);
}

#admin_sidebar img, #sidebar img { display: none; } /* hide old GIF spacers */

#admin_sidebar td, #sidebar td { padding: 0; }

/* Admin sidebar header */
#admin_sidebar th.menuitem {
    display: block;
    background-color: var(--surface-admin-sidebar-head);
}
#admin_sidebar th.menuitem strong {
    display: block;
    padding: 8px 10px 6px;
    color: var(--gold);
    font-size: 9pt;
    text-align: center;
    border-bottom: none;
    letter-spacing: 2px;
    text-transform: uppercase;
}

/* Admin sidebar items */
#admin_sidebar td.menuitem {
    display: block;
}
#admin_sidebar td.menuitem a {
    display: block;
    padding: 5px 10px 5px 16px;
    color: var(--text-admin-sidebar);
    background-color: var(--surface-admin-sidebar-item);
    text-decoration: none;
    font-size: 8.5pt;
}
#admin_sidebar td.menuitem a:hover {
    color: var(--gold);
    background-color: var(--surface-admin-sidebar-item-hover);
}

/* Regular sidebar header */
#sidebar th.menuitem {
    display: block;
    background: var(--bg-sidebar-head);
    margin-top: 2px;
}
#sidebar th.menuitem strong {
    display: block;
    padding: 7px 10px 5px;
    color: var(--gold);
    font-size: 8.5pt;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 1px;
}

/* Regular sidebar items */
#sidebar td.menuitem {
    display: block;
}
#sidebar td.menuitem a {
    display: block;
    padding: 5px 10px 5px 16px;
    color: var(--text-primary);
    background-color: var(--bg-sidebar-item);
    text-decoration: none;
    font-size: 8.5pt;
    transition: background 0.12s, color 0.12s;
}
#sidebar td.menuitem a:hover {
    color: var(--gold);
    background-color: var(--surface-sidebar-hover);
}
#sidebar td.sidebar-left,
#sidebar td.sidebar-right {
    background-color: var(--bg-sidebar);
}

/* ── Main content area ─────────────────────────────────────── */
#site-content {
    flex: 1;
    min-width: 0;
    padding-top: 15px;
    padding-right: 20px;
    padding-bottom: 15px;
    overflow-y: auto;
    overflow-x: hidden;
}

/* ── Login box ─────────────────────────────────────────────── */
#loginbox {
    background: var(--bg-loginbox);
    padding: 12px 18px;
    margin-bottom: 12px;
    color: var(--text-muted);
    font-size: 8.5pt;
    box-shadow: var(--shadow-soft);
}
/* Legacy table-based loginbox override */
table#loginbox { width: 100%; border-collapse: collapse; }
table#loginbox td { background: transparent !important; border: none; padding: 4px 8px; }
table#loginbox img { display: none; } /* hide corner GIFs */

#loginbox strong a { color: var(--text-heading); }
#loginbox strong a:hover { color: var(--gold); }
#loginbox select {
    background: var(--bg-input);
    color: var(--text-primary);
}

.loginbox-admin-menu {
    padding-top: 4px;
    color: var(--accent-red-h);
}
.loginbox-admin-menu a { color: var(--accent-red-h); }
.loginbox-admin-menu a:hover { color: var(--gold); }

/* ── Content Panel ─────────────────────────────────────────── */
#content-panel {
    background: var(--bg-content);
    border-radius: 26px;
    padding: 24px 28px;
    color: var(--text-primary);
    min-height: 300px;
    box-shadow: var(--shadow-content);
}

/* Legacy #content table override */
#content {
    color: var(--text-primary);
    background: var(--bg-content);
}
#content td { background: var(--bg-content) !important; }

/* ── Forms & Inputs ────────────────────────────────────────── */
input[type=text],
input[type=email],
input[type=password],
input[type=file],
textarea {
    font-family: "Alegreya Sans", "Segoe UI Variable Text", "Gill Sans", sans-serif;
    padding: 10px 12px;
    font-size: 9pt;
    color: var(--text-primary);
    background-color: var(--bg-input);
    outline: none;
    border-radius: 14px;
}
input[type=text]:focus,
input[type=email]:focus,
input[type=password]:focus,
textarea:focus {
    background-color: var(--surface-input-focus);
    color: var(--text-heading2);
}

select {
    background-color: var(--bg-input);
    color: var(--text-primary);
    padding: 10px 12px;
    border-radius: 14px;
}

label { cursor: pointer; color: var(--text-primary); }
label:hover { color: var(--text-heading); cursor: pointer; }

.submit_button {
    display: inline-block;
    margin: 8px 4px;
    padding: 6px 14px;
    background-color: var(--bg-surface-alt);
    color: var(--text-primary);
    border-radius: 3px;
    cursor: pointer;
    font-size: 9pt;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.submit_button:hover {
    background-color: var(--accent-purple);
    color: var(--text-white);
    box-shadow: var(--shadow-secondary-hover);
}

input[type=submit] {
    background: var(--grad-primary-button);
    color: var(--text-footer-link);
    padding: 10px 16px;
    border-radius: 999px;
    cursor: pointer;
    letter-spacing: 0.4px;
    font-weight: 700;
    text-transform: uppercase;
    transition: transform 0.15s, box-shadow 0.15s, opacity 0.15s, border-color 0.15s;
}
input[type=submit]:hover {
    transform: translateY(-1px);
    background: var(--grad-primary-button-hover);
    box-shadow: var(--shadow-button-hover);
    opacity: 0.96;
}

button,
input[type=button],
input[type=reset] {
    background: var(--grad-secondary-button);
    color: var(--text-footer-link);
    padding: 10px 16px;
    border-radius: 999px;
    cursor: pointer;
    letter-spacing: 0.3px;
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s, background 0.15s;
}

button:hover,
input[type=button]:hover,
input[type=reset]:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-secondary-hover);
    background: var(--grad-secondary-button-hover);
}

button::before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    content: "\f0a4";
    margin-right: 8px;
}

/* ── Tables ────────────────────────────────────────────────── */
.horizontal-table {
    border-spacing: 0;
    border-collapse: collapse;
    width: 100%;
}
.horizontal-table th {
    padding: 6px 10px;
    background-color: var(--bg-table-head);
    color: var(--text-heading);
}
.horizontal-table td {
    padding: 5px 10px;
    background-color: var(--bg-table-row);
    color: var(--text-primary);
}
.horizontal-table tr:nth-child(even) td {
    background-color: var(--bg-table-alt);
}
.horizontal-table tr:hover td {
    background-color: var(--surface-table-row-hover);
}
.horizontal-table th, .horizontal-table td { font-size: 9pt; }

.vertical-table {
    border-spacing: 0;
    border-collapse: collapse;
}
.vertical-table th {
    padding: 5px 10px;
    background-color: var(--bg-table-head);
    color: var(--text-heading);
    text-align: right;
}
.vertical-table td {
    padding: 5px 12px;
    background-color: var(--bg-table-row);
    color: var(--text-primary);
}
.vertical-table th, .vertical-table td { font-size: 9pt; }
.vertical-table label {
    display: block;
    padding: 3px;
    color: var(--text-primary);
}
.vertical-table form { margin: 0; padding: 0; }

.generic-form-table th {
    padding: 5px 10px;
    background: var(--bg-table-head);
    color: var(--text-heading);
}
.generic-form-table td {
    padding: 5px 12px;
    background: var(--bg-table-row);
    color: var(--text-primary);
}
.generic-form-table label { color: var(--text-primary); }

/* ── Notifications / Messages ──────────────────────────────── */
.message {
    display: block;
    padding: 14px 16px;
    font-weight: bold;
    font-size: 110%;
    color: var(--text-message);
    background-color: var(--state-message-bg);
    border-radius: 18px;
    margin-bottom: 10px;
}

.notice {
    display: block;
    padding: 14px 16px;
    color: var(--text-notice);
    background-color: var(--state-notice-bg);
    border-radius: 18px;
    margin-bottom: 10px;
}

.note {
    padding: 6px 10px;
    color: var(--text-muted);
    background-color: var(--bg-surface-alt);
    font-style: italic;
    border-radius: 0 3px 3px 0;
}

.red {
    display: block;
    padding: 14px 16px;
    font-weight: bold;
    color: var(--text-error);
    background-color: var(--state-error-bg);
    border-radius: 18px;
    margin-bottom: 8px;
}

.green {
    display: block;
    padding: 10px;
    font-weight: bold;
    color: var(--text-success);
    background-color: var(--state-success-bg);
    border-radius: 4px;
    margin-bottom: 8px;
}

/* ── Submenu de modulo ─────────────────────────────────────────
   Son secciones hermanas del mismo modulo, no una jerarquia, asi
   que se presentan como barra de pestanas y no como miga de pan.
   La lista rueda en horizontal cuando no cabe (ranking tiene ocho)
   en vez de partirse en varias filas.                            */
.submenu {
    margin: 0 0 18px;
    padding-bottom: 2px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
.submenu__list {
    display: flex;
    gap: 6px;
    margin: 0;
    padding: 4px;
    list-style: none;
    width: max-content;
    min-width: 100%;
    border-radius: 16px;
    background: var(--alpha-silver-08);
}
.submenu__item { margin: 0; }

.submenu__link {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: 12px;
    white-space: nowrap;
    font-size: 9pt;
    font-weight: 600;
    color: var(--text-muted) !important;
    text-decoration: none !important;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.submenu__link:hover {
    background: var(--alpha-silver-10);
    color: var(--text-panel-soft) !important;
}
.submenu__link:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: -2px;
}
.submenu__icon {
    font-size: 0.95em;
    opacity: 0.75;
}
.submenu__link:hover .submenu__icon { opacity: 1; }

.submenu__link.is-current {
    background: var(--grad-primary-button);
    color: var(--text-on-accent) !important;
    box-shadow: var(--shadow-content);
}
.submenu__link.is-current .submenu__icon { opacity: 1; }

@media (max-width: 640px) {
    .submenu { margin-bottom: 14px; }
    .submenu__link { padding: 8px 13px; font-size: 8.5pt; }
}

/* necROmantic 2026-08-23 (WEB-01) — pestanas GRANDES.
   Variante de la misma barra para las dos paginas del personaje ("Ficha" y
   "Preferencias"): son solo dos, no compiten con nada mas en la pagina y se pidieron
   bien visibles, asi que se les da tamano de titulo pequeno en vez del cuerpo 9pt de
   una barra de ocho secciones. Todo lo demas -- colores, el degradado de la activa,
   el foco -- lo heredan de .submenu, que es de donde salen las clases.
   Se pinta desde themes/necromantic/character/_chartabs.php. */
.submenu--tabs { margin-bottom: 22px; }
.submenu--tabs .submenu__list { padding: 5px; gap: 8px; }
.submenu--tabs .submenu__link {
    padding: 13px 26px;
    font-size: 11pt;
    letter-spacing: 0.01em;
}
.submenu--tabs .submenu__icon { font-size: 1.05em; }

@media (max-width: 640px) {
    .submenu--tabs .submenu__link { padding: 11px 16px; font-size: 10pt; }
}

/* ── Acciones de la pagina ─────────────────────────────────────
   Barra secundaria bajo el submenu: son acciones sobre lo que se
   esta viendo, no navegacion, asi que se distingue en peso.      */
#pagemenu {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: -6px 0 16px;
    font-size: 8.5pt;
    color: var(--text-muted);
}
#pagemenu a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 13px;
    border-radius: 999px;
    background: var(--alpha-silver-08);
    color: var(--text-panel-soft) !important;
    text-decoration: none !important;
    font-weight: 600;
}
#pagemenu a:hover { background: var(--alpha-silver-16); color: var(--gold) !important; }
#pagemenu a::before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    content: "\f054";
    font-size: 0.72em;
    color: var(--gold);
}

/* ── Module name heading ───────────────────────────────────── */
.module-name {
    font-weight: bold;
    font-size: 12pt;
    color: var(--text-heading);
}

/* ── Server status ─────────────────────────────────────────── */
#server_status {
    border-spacing: 0;
    border-collapse: collapse;
    background-color: var(--bg-table-row);
    width: 100%;
}
#server_status th, #server_status td {
    padding: 8px 14px;
    text-align: left;
    color: var(--text-primary);
}
#server_status th {
    background: var(--bg-table-head);
    color: var(--text-heading);
}
#server_status .server { color: var(--text-primary); }
#server_status .status { text-align: center; }

/* ── Pagination ────────────────────────────────────────────── */
.pages {
    margin-top: 16px;
    padding-top: 8px;
    color: var(--text-muted);
    text-align: center;
}
.pages .page-prev, .pages .page-next { color: var(--text-link); }
.pages .page-num { padding: 0 4px; }
.pages .current-page { color: var(--gold); font-weight: bold; }

/* ── Status colors ─────────────────────────────────────────── */
.online  { color: var(--state-success); }
.offline { color: var(--text-muted); }
.up   { font-weight: bold; color: var(--state-success); text-transform: uppercase; }
.down { color: var(--state-error); text-transform: uppercase; }

.state-pending           { color: var(--state-warning); }
.state-banned            { color: var(--state-error); }
.state-permanently-banned{ font-weight: bold; color: var(--state-error-strong); }

.keyword { color: var(--gold); font-style: italic; }

/* ── Credit balance ────────────────────────────────────────── */
.credit-balance {
    float: right;
    display: inline-block;
    padding: 8px 12px;
    color: var(--text-primary);
    background-color: var(--bg-surface-alt);
    border-radius: 4px;
}
.credit-balance .balance-text {
    display: inline-block;
    margin-right: 6px;
    color: var(--text-muted);
    text-transform: uppercase;
    font-size: 8pt;
}
.credit-balance .balance-amount { font-weight: bold; color: var(--gold); }

/* ── Search form ───────────────────────────────────────────── */
.search-form, .search-form2 {
    display: none;
    margin: 0 0 10px 0;
    padding: 0;
    background: var(--bg-surface-alt);
}
.search-form p, .search-form2 p {
    margin: 0;
    padding: 5px 8px;
    color: var(--text-muted);
}
.search-form label, .search-form2 label {
    display: inline-block;
    margin: 0 0 3px;
    font-size: 8pt;
    font-style: italic;
    color: var(--text-muted);
}
.search-form input[type=text], .search-form2 input[type=text] {
    display: inline-block;
    margin: 0 0 2px;
    padding: 2px 4px;
    font-size: 8pt;
    width: 90px;
}
.search-form input[type=submit], .search-form2 input[type=submit] {
    display: inline-block;
    margin: 0 0 2px;
    font-size: 8pt;
    font-weight: bold;
}
.search-form input[type=button],  .search-form input[type=reset],
.search-form2 input[type=button], .search-form2 input[type=reset] {
    display: inline-block;
    margin: 0 0 2px;
    font-size: 8pt;
}
.search-form input[type=checkbox], .search-form2 input[type=checkbox] {
    display: inline-block;
    margin: 0 0 2px;
}
.search-form select, .search-form2 select {
    display: inline-block;
    margin: 2px 0;
}

.toggler         { font-weight: bold; font-style: italic; }
.toggler a       { color: var(--text-link); }

/* ── Info text (search results summary) ───────────────────── */
.info-text {
    margin-bottom: 6px;
    padding: 5px 10px;
    color: var(--text-muted);
    background-color: var(--bg-surface-alt);
    text-align: center;
    border-radius: 3px;
}
.info-text-total   { font-weight: bold; color: var(--text-primary); }
.info-text-results { font-weight: bold; color: var(--text-primary); }

/* ── Misc helpers ──────────────────────────────────────────── */
.center { text-align: center; }

.not-applicable { font-style: italic; color: var(--text-muted); }

.td-checkbox { text-align: center; }
.td-action   { color: var(--text-muted); text-align: center; }
.vertical-table .td-action { text-align: right; }

.sortable        { color: var(--text-primary); text-decoration: underline; }
.sortable:hover  { color: var(--gold); }

.raw-txn-log {
    padding: 10px;
    font-family: "Monaco", "Lucida Console", "Courier New", monospace;
    background-color: var(--bg-surface);
    color: var(--text-primary);
    width: 96%;
    overflow: scroll;
}

.request, .fs-path {
    display: inline-block;
    padding: 2px 4px;
    font-family: Monaco, "Lucida Console", monospace;
    font-size: 8pt;
    background-color: var(--bg-surface);
    color: var(--text-primary);
    border-radius: 2px;
}

.block {
    display: block;
    width: 80%;
    height: 40px;
}

.script-line     { font-family: Monaco, "Lucida Console", monospace; }
.script-line-num {
    display: inline-block;
    margin: 0;
    padding: 5px;
    background-color: var(--bg-surface-alt);
    color: var(--text-muted);
}
.script-line-code {
    display: inline-block;
    margin: 0;
    padding: 5px;
    color: var(--text-primary);
}

/* ── Shop table ────────────────────────────────────────────── */
.shop-table {
    width: 100%;
    color: var(--text-primary);
    border-spacing: 0 8px;
    border-collapse: separate;
}
.shop-table td {
    padding: 10px;
    background: var(--bg-surface-alt);
}

/* ── Install table ─────────────────────────────────────────── */
.install_table th, .install_table td {
    padding: 5px 10px;
    color: var(--text-primary);
}
.install_table th { background-color: var(--bg-table-head); color: var(--text-heading); }
.install_table td { width: 180px; text-align: center; background: var(--bg-table-row); }

.created { color: var(--state-success); width: 80px; }
.missing  { color: var(--state-error); width: 80px; }

/* ── Login / Register forms ────────────────────────────────── */
#register_form table td, #login_form table td { padding: 1px; }
#register_form table th label, #login_form table th label {
    display: block;
    padding: 5px;
    text-align: center;
    color: var(--text-heading);
}
#register_form input[type=text],
#register_form input[type=password],
#login_form input[type=text],
#login_form input[type=password] { width: 150px; }
#register_form select, #login_form select { width: 157px; }

/* ── Character stats widget ────────────────────────────────── */
.character-stats {
    border-spacing: 0;
    border-collapse: collapse;
}
.character-stats td {
    padding: 0 10px 5px 0;
    border: 0;
    text-align: center;
    color: var(--text-primary);
}
.character-stats .stat-name  { color: var(--text-muted); }
.character-stats .stat-value { color: var(--text-heading); font-weight: bold; }

/* ── Emblem ────────────────────────────────────────────────── */
.emblem-server {
    margin: 0 0 2px;
    padding: 0 0 2px;
    font-size: 120%;
    color: var(--text-primary);
}
.emblem-server label         { display: block; }
.emblem-server label:hover   { cursor: pointer; }

/* ── Footer ────────────────────────────────────────────────── */
#site-footer {
    background: var(--grad-footer);
    padding: 14px 18px 16px;
    text-align: left;
    font-size: 8pt;
    flex-shrink: 0;
}
.footer-topline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.footer-copy  { color: var(--text-primary); margin: 0; font-size: 9pt; }
.footer-copy a{ color: var(--text-muted); }
.footer-copy a:hover { color: var(--gold); }
.footer-info  { color: var(--text-panel-soft); margin: 10px 0 0; max-width: none; }
.footer-info strong { color: var(--text-muted); }
.footer-lang  { color: var(--text-footer); margin: 2px 0; display: inline-block; margin-left: 12px; }
.footer-lang  select { font-size: 8pt; }
.footer-lang { margin-left: 0; margin-top: 10px; }
.footer-copy,
.footer-info,
.footer-lang {
    white-space: normal;
}

.account-char-delete-form {
    margin: 0;
}

.account-char-delete-button {
    width: 100%;
    margin: 0;
    padding: 7px 10px;
    border-radius: 999px;
    background: var(--grad-delete-button);
    color: var(--text-footer-link);
    cursor: pointer;
    font-size: 8pt;
    font-weight: bold;
    text-align: center;
    box-shadow: var(--shadow-delete);
}

.account-char-delete-button:hover {
    background: var(--grad-delete-button-hover);
    box-shadow: var(--shadow-delete-hover);
}

.account-char-delete-button:focus-visible {
    outline: none;
    box-shadow: var(--shadow-delete-focus);
}
.footer-legal-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
.footer-legal-nav a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px;
    border-radius: 999px;
    background: var(--grad-silver-chip);
    color: var(--text-footer-link);
    text-decoration: none;
}

.footer-legal-nav a::before {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    color: var(--gold);
}

.footer-legal-nav a[href*="action=tos"]::before {
    content: "\f24e";
}

.footer-legal-nav a[href*="action=conduct"]::before {
    content: "\f4c4";
}

.footer-legal-nav a[href*="action=privacy"]::before {
    content: "\f21b";
}

.footer-legal-nav a[href*="action=security"]::before {
    content: "\f3ed";
}

.footer-legal-nav a[href*="action=transparency"]::before {
    content: "\f06e";
}

.footer-legal-nav a:hover {
    text-decoration: none;
    background: var(--surface-silver-chip-hover);
    color: var(--gold);
}

.footer-legal-nav i {
    display: none;
}

.cookie-notice {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 1200;
    width: min(420px, calc(100vw - 32px));
    padding: 18px 18px 16px;
    border-radius: 22px;
    background: var(--grad-silver-panel-strong);
    box-shadow: var(--shadow-cookie);
    backdrop-filter: blur(18px);
}

.cookie-notice__content strong {
    display: block;
    margin-bottom: 8px;
    color: var(--text-heading);
    font-size: 10pt;
}

.cookie-notice__content p {
    margin: 0;
    color: var(--text-panel-soft);
}

.cookie-notice__actions {
    margin-top: 14px;
}

.cookie-notice__button {
    border: 0;
    border-radius: 999px;
    padding: 10px 16px;
    background: var(--grad-primary-button);
    color: var(--text-white);
    cursor: pointer;
}

.cookie-notice__button:hover {
    opacity: 0.95;
}

.register-hero,
.legal-hero,
.about-hero,
.lgn-hero {
    margin-bottom: 20px;
    padding: 22px 24px;
    border-radius: 24px;
    background: var(--grad-hero);
    box-shadow: inset 0 1px 0 var(--alpha-white-04);
}

.register-kicker,
.legal-kicker,
.about-kicker,
.lgn-kicker {
    display: inline-block;
    padding: 6px 10px;
    border-radius: 999px;
    background: var(--grad-silver-chip);
    color: var(--gold);
    font-size: 8pt;
    letter-spacing: 1.4px;
    text-transform: uppercase;
}

.register-title,
.legal-title,
.about-title,
.lgn-title {
    margin: 14px 0 10px;
    font-size: 24px;
    line-height: 1.1;
    color: var(--text-hero-title);
    border: 0;
    padding: 0;
}

.register-intro,
.legal-intro,
.about-intro,
.lgn-intro {
    max-width: 74ch;
    color: var(--text-hero-intro);
    font-size: 10pt;
}

.battle-config-hero {
    margin-bottom: 20px;
    padding: 22px 24px;
    border-radius: 24px;
    background: var(--grad-battle-hero);
    box-shadow: inset 0 1px 0 var(--alpha-white-05);
}

.battle-config-kicker {
    display: inline-block;
    padding: 6px 10px;
    border-radius: 999px;
    background: var(--grad-silver-chip);
    color: var(--gold);
    font-size: 8pt;
    letter-spacing: 1.4px;
    text-transform: uppercase;
}

.battle-config-title {
    margin: 14px 0 10px;
    font-size: 24px;
    line-height: 1.1;
    color: var(--text-hero-title);
    border: 0;
    padding: 0;
}

.battle-config-intro {
    max-width: 82ch;
    color: var(--text-hero-intro);
    font-size: 10pt;
}

.battle-config-layout {
    display: grid;
    grid-template-columns: minmax(260px, 0.75fr) minmax(0, 2fr);
    gap: 18px;
}

.battle-config-nav-card,
.battle-config-card,
.transparency-section {
    padding: 20px 22px;
    border-radius: 22px;
    background: var(--surface-card-strong);
    box-shadow: var(--shadow-pop);
}

.battle-config-nav-card {
    position: sticky;
    top: 12px;
    align-self: start;
    background: var(--grad-silver-panel);
}

.battle-config-nav-card__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.battle-config-nav-card__header strong {
    color: var(--text-heading);
    font-size: 12pt;
}

.battle-config-nav-card__header span,
.battle-config-nav-card__note {
    color: var(--text-muted);
    line-height: 1.5;
}

.battle-config-nav-list {
    list-style: none;
    margin: 0 0 16px;
    padding: 0;
    display: grid;
    gap: 8px;
}

.battle-config-nav-item a {
    display: block;
    padding: 4px 6px;
    border-radius: 7px;
    background: var(--grad-silver-chip);
    text-decoration: none;
}

.battle-config-nav-item__title-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
}

.battle-config-nav-item.is-current a,
.battle-config-nav-item a:hover {
    background: var(--grad-sidebar-link-hover);
    text-decoration: none;
}

.battle-config-nav-item__title,
.transparency-section__title {
    display: block;
    color: var(--text-label-strong);
    font-weight: bold;
}

.battle-config-nav-item__meta,
.transparency-section__meta {
    display: inline-block;
    margin-top: 0;
    color: var(--text-muted);
    font-size: 8.5pt;
    white-space: nowrap;
}

.battle-config-sections,
.transparency-sections {
    display: grid;
    gap: 18px;
}

.battle-config-card.is-selected {
    box-shadow: var(--shadow-pop-strong);
    background: var(--alpha-bronze-08);
}

.battle-config-card__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.battle-config-card__header h3 {
    margin: 0 0 6px;
    border: 0;
    font-size: 15px;
    text-transform: none;
    letter-spacing: 0.4px;
}

.battle-config-card__header p {
    margin: 0;
    color: var(--text-muted);
}

.battle-config-card__jump {
    white-space: nowrap;
}

.battle-config-form {
    margin: 0;
}

.battle-config-table th,
.transparency-table th {
    vertical-align: middle;
}

.battle-config-table td,
.transparency-table td {
    vertical-align: top;
}

/* necROmantic 2026-08-01: celda de premio del registro de cajas misteriosas.
   Icono a la izquierda y nombre enlazado a su ficha; el ID de la columna de al
   lado lleva al mismo sitio. */
.transparency-item {
    display: flex;
    align-items: center;
    gap: 8px;
}

.transparency-item__icon {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    object-fit: contain;
    /* los iconos del cliente son de 24x24 reales: sin esto se ven emborronados */
    image-rendering: pixelated;
}

.transparency-item__icon--none {
    display: block;
    border: 1px dashed var(--border);
    border-radius: 6px;
}

.transparency-item__name { min-width: 0; }

/* El ID es enlace igual que el nombre, pero conserva su aire de dato: el <code>
   de dentro solo toma el color del enlace. */
.transparency-id-link {
    text-decoration: none;
}

.transparency-id-link .battle-config-code {
    color: var(--text-link);
}

.transparency-id-link:hover .battle-config-code,
.transparency-id-link:focus-visible .battle-config-code {
    color: var(--text-link-hover);
    text-decoration: underline;
}

.battle-config-row.is-overridden td {
    background: var(--surface-card-row-custom);
    box-shadow: inset 0 1px 0 var(--alpha-gold-12);
}

.battle-config-label {
    display: inline-block;
    color: var(--text-label-strong);
    font-weight: bold;
    cursor: help;
}

.battle-config-label:hover {
    color: var(--text-label-hover);
}

.battle-config-key,
.battle-config-code {
    display: block;
    margin-top: 4px;
    font-family: Monaco, "Lucida Console", monospace;
    font-size: 8pt;
    color: var(--text-code);
}

.battle-config-description {
    margin-top: 10px;
    padding: 10px 12px;
    border-radius: 14px;
    background: var(--surface-silver-panel-soft);
}

.battle-config-description--compact {
    margin-top: 0;
    padding: 0;
    border: 0;
    background: transparent;
}

.battle-config-description p {
    margin: 0 0 8px;
    color: var(--text-muted);
    line-height: 1.5;
}

.battle-config-description p:last-child {
    margin-bottom: 0;
}

.battle-config-value-cell {
    min-width: 180px;
}

.battle-config-input {
    width: 100%;
    min-width: 0;
}

.battle-config-input--select {
    min-width: 140px;
}

.battle-config-bitmask {
    display: grid;
    gap: 10px;
}

.battle-config-bitmask__summary {
    padding: 10px 12px;
    border-radius: 14px;
    background: var(--surface-silver-summary);
    color: var(--text-muted);
    line-height: 1.5;
}

.battle-config-bitmask__options {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 8px;
}

.battle-config-bitmask__option {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 14px;
    background: var(--surface-silver-panel);
    color: var(--text-panel-soft);
}

.battle-config-bitmask__option:hover {
    color: var(--text-footer-link);
}

.battle-config-bitmask__option input {
    margin-top: 2px;
    flex: 0 0 auto;
}

.battle-config-bitmask__option-value {
    display: inline-block;
    min-width: 48px;
    font-family: Monaco, "Lucida Console", monospace;
    font-size: 8pt;
    color: var(--text-code);
}

.battle-config-state {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 88px;
    padding: 7px 10px;
    border-radius: 999px;
    background: var(--surface-silver-state);
    color: var(--text-panel-soft);
    font-size: 8pt;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.7px;
}

.battle-config-state--custom {
    background: var(--surface-bitmask-state-custom);
    color: var(--text-footer-link);
}

.battle-config-action-cell {
    text-align: center;
}

.battle-config-reset {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    background: var(--grad-reset-button);
    color: var(--text-footer-link);
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
}

.battle-config-reset:hover {
    background: var(--grad-reset-button-hover);
    color: var(--text-panel-bright);
}

.battle-config-actions {
    margin-top: 16px;
    display: flex;
    justify-content: flex-end;
}

.battle-config-submit {
    min-width: 180px;
}

.transparency-overview {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

.transparency-overview__item {
    padding: 18px 20px;
    border-radius: 22px;
    background: var(--grad-silver-panel);
    box-shadow: var(--shadow-pop);
}

.transparency-overview__item strong {
    display: block;
    color: var(--text-label-strong);
    font-size: 22px;
}

.transparency-overview__item span {
    display: block;
    margin-top: 6px;
    color: var(--text-muted);
}

.transparency-overview__item.is-highlight {
    background: var(--grad-transparency-highlight);
}

.transparency-section {
    padding: 0;
    overflow: hidden;
}

.transparency-section summary {
    list-style: none;
    cursor: pointer;
    padding: 18px 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
}

.transparency-section summary::-webkit-details-marker {
    display: none;
}


.transparency-table {
    margin: 0;
}

@media (max-width: 980px) {
    .battle-config-layout,
    .transparency-overview {
        grid-template-columns: 1fr;
    }

    .battle-config-nav-card {
        position: static;
    }

    .transparency-section summary,
    .battle-config-card__header {
        flex-direction: column;
        align-items: flex-start;
    }
}

.register-layout,
.legal-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(260px, 0.9fr);
    gap: 18px;
}

/* Codigo de conducta: ambas columnas del mismo ancho */
.legal-grid--even {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.register-panel,
.legal-card {
    padding: 20px 22px;
    border-radius: 22px;
    /* necROmantic 2026-07-29: retirado el background var(--grad-silver-panel).
       Las tarjetas quedan sobre el fondo de la pagina y se separan solo con la sombra. */
    box-shadow: var(--shadow-pop);
}

.register-panel h3,
.legal-card h3 {
    margin-top: 0;
    border: 0;
    font-size: 15px;
    letter-spacing: 0.4px;
    text-transform: none;
}

.register-form-shell .generic-form-table,
.register-form-shell .generic-form-table tbody,
.register-form-shell .generic-form-table tr {
    width: 100%;
}

.register-form-shell .generic-form-table {
    border-collapse: separate;
    border-spacing: 0 10px;
}

.register-form-shell .generic-form-table th,
.register-form-shell .generic-form-table td {
    border: 0;
    background: transparent;
    padding: 0;
}

.register-form-shell .generic-form-table th {
    padding-bottom: 6px;
    text-align: left;
}

.register-fields-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px 16px;
}

.register-field {
    margin-bottom: 14px;
    min-width: 0;
}

.register-field--full {
    width: 100%;
}

.register-form-shell input[type="text"],
.register-form-shell input[type="email"],
.register-form-shell input[type="password"],
.register-form-shell select {
    width: 100%;
}

#register_form .register-form-shell input[type="text"],
#register_form .register-form-shell input[type="email"],
#register_form .register-form-shell input[type="password"],
#register_form .register-form-shell select {
	width: 100%;
}

.register-field label.field-label {
    display: block;
    margin-bottom: 6px;
    color: var(--text-label-strong);
    font-weight: bold;
}

.register-note-list,
.legal-list {
    margin: 0;
    padding-left: 18px;
    color: var(--text-hero-intro);
}

.register-note-list li,
.legal-list li {
    margin-bottom: 8px;
}

.register-alert {
    margin-top: 14px;
    padding: 12px 14px;
    border-radius: 18px;
    background: var(--surface-silver-panel-soft);
    color: var(--text-hero-title);
}

.avatar-choice-group {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.avatar-choice {
    flex: 1 1 180px;
    min-width: 0;
}

.avatar-choice label {
    display: block;
    padding: 14px 16px;
    border-radius: 18px;
    background: var(--surface-silver-panel);
}

.avatar-choice label:hover {
    color: var(--text-footer-link);
}

.avatar-choice small {
    display: block;
    margin-top: 6px;
    color: var(--text-muted);
}

.register-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 18px;
}

.register-actions .submit-primary {
    min-width: 180px;
    font-size: 10pt;
    font-weight: bold;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px 18px;
    border-radius: 16px;
    background: var(--grad-register-submit);
    color: var(--text-primary);
    text-align: center;
    box-shadow: inset 0 1px 0 var(--alpha-white-06), 0 0 10px var(--alpha-bronze-16), 0 0 0 transparent;
    cursor: pointer;
    transition: color 0.22s ease, background 0.22s ease, border-color 0.22s ease, box-shadow 0.28s ease, transform 0.22s ease;
}

.register-actions .submit-primary:hover {
    color: var(--text-footer-link);
    background: var(--grad-register-submit-hover);
    box-shadow: var(--shadow-delete-hover), 0 0 28px var(--alpha-bronze-16), inset 0 0 12px var(--alpha-silver-18);
    transform: translateY(-1px);
    animation: sidebarOrangeGlow 1.2s ease-in-out infinite alternate;
}

.register-actions .submit-primary:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

.register-secondary-links {
    color: var(--text-muted);
}

.legal-card p:last-child {
    margin-bottom: 0;
}

.legal-section-anchor {
    scroll-margin-top: 24px;
}

@media (max-width: 980px) {
    #site-wrapper {
        flex-direction: column;
        overflow: auto;
    }

    #logo-link {
        gap: 12px;
    }

    #logo-mark {
        width: 64px;
        height: 64px;
    }

    #site-sidebar {
        width: 100%;
    }

    .register-layout,
    .legal-grid,
    .footer-topline {
        grid-template-columns: 1fr;
        flex-direction: column;
        align-items: flex-start;
    }

    .register-fields-grid {
        grid-template-columns: 1fr;
    }

    #content-panel {
        padding: 20px 18px;
    }

    .cookie-notice {
        right: 16px;
        left: 16px;
        bottom: 16px;
        width: auto;
    }

    .footer-copy,
    .footer-info,
    .footer-lang {
        white-space: normal;
    }
}

/* ── Legacy corner GIF spacers — hide them all ─────────────── */
img[src*="content_tl"],
img[src*="content_tr"],
img[src*="content_bl"],
img[src*="content_br"],
img[src*="loginbox_tl"],
img[src*="loginbox_tr"],
img[src*="loginbox_bl"],
img[src*="loginbox_br"],
img[src*="sidebar_complete_top"],
img[src*="sidebar_complete_bottom"],
img[src*="sidebar_admin_complete_top"],
img[src*="sidebar_admin_complete_bottom"],
img[src*="sidebar_top"],
img[src*="sidebar_bottom"],
img[src*="sidebar_tl"],
img[src*="sidebar_tr"],
img[src*="sidebar_bl"],
img[src*="sidebar_br"] {
    display: none !important;
}

/* ── Scrollbar (webkit) ────────────────────────────────────── */
::-webkit-scrollbar            { width: 8px; height: 8px; }
::-webkit-scrollbar-track      { background: var(--bg-body); }
::-webkit-scrollbar-thumb      { background: var(--border); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover{ background: var(--accent-purple); }

.stats-detail-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    align-items: start;
    margin-bottom: 18px;
}

.stats-chart-card,
.stats-table-card,
.stats-summary-card {
    background: var(--bg-surface-alt);
    border-radius: 16px;
    padding: 14px 16px;
    box-sizing: border-box;
    overflow: hidden;
}

.stats-chart-card canvas {
    display: block;
    width: 100% !important;
    height: 320px !important;
    max-height: 320px;
}

.stats-summary-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

.stats-summary-card__label {
    display: block;
    margin-bottom: 6px;
    color: var(--text-muted);
    font-size: 8pt;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.stats-page-intro,
.stats-chart-card__header p,
.stats-empty-chart {
    color: var(--text-muted);
}

.stats-chart-card__header h3,
.stats-table-card h3 {
    margin-top: 0;
    margin-bottom: 6px;
}

.stats-metric-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 14px;
}

.stats-metric-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 8.5pt;
    box-sizing: border-box;
}

.stats-back-link-row {
    margin-bottom: 14px;
}

@media (max-width: 980px) {
    .stats-summary-grid,
    .stats-detail-grid {
        grid-template-columns: 1fr;
    }

    .stats-chart-card canvas {
        height: 280px !important;
        max-height: 280px;
    }
}

/* ── Stats: metric toggle panel (outside charts) ───────────── */
.stats-metric-toggles-wrap {
    background: var(--bg-surface-alt);
    border-radius: 16px;
    padding: 12px 16px;
    margin-bottom: 16px;
}

.stats-metric-toggles-wrap::before {
    content: 'Métricas a visualizar';
    display: block;
    margin-bottom: 10px;
    font-size: 8pt;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}

.stats-metric-toggle {
    cursor: pointer;
    user-select: none;
    transition: border-color 0.15s, background 0.15s;
}

.stats-metric-toggle input:checked ~ span {
    color: var(--text-heading);
}

.stats-metric-toggle:hover {
    background: var(--bg-input);
}

/* ── Server Info panels (server/info) ──────────────────────── */
.si-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
    align-items: start;
    margin-top: 1.5rem;
}
@media (max-width: 960px) {
    .si-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 580px) {
    .si-grid { grid-template-columns: 1fr; }
}

.si-card {
    background: var(--bg-surface-alt);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: var(--shadow-card);
}
.si-card-header {
    padding: 0.9rem 1.2rem 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: linear-gradient(135deg, var(--alpha-gold-08) 0%, transparent 60%);
}
.si-card-header i {
    color: var(--gold);
    font-size: 1rem;
    width: 1.1rem;
    text-align: center;
    flex-shrink: 0;
}
.si-card-header h3 {
    margin: 0;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-heading);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    line-height: 1.2;
}
.si-card-body {
    padding: 0.85rem 1.2rem 1rem;
}
.si-stat {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 0.5rem 0;
}
.si-stat:nth-child(even) { background: var(--alpha-white-03); border-radius: 8px; }
.si-stat-label {
    font-size: 0.82rem;
    color: var(--text-muted);
    flex-shrink: 0;
    padding-right: 0.75rem;
}
.si-stat-value {
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text-heading2);
    text-align: right;
}
.si-stat-value.gold { color: var(--gold); }
.si-classes-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.si-class-badge {
    background: var(--bg-table-row);
    border-radius: 5px;
    padding: 0.22rem 0.55rem;
    font-size: 0.75rem;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
    transition: border-color 0.15s, background 0.15s;
}
.si-class-badge:hover {
    background: var(--bg-table-alt);
}
.si-class-badge .si-count {
    color: var(--gold);
    font-weight: 700;
    font-size: 0.8rem;
}

/* ── Zeny chart card ───────────────────────────────────────── */
.si-chart-card {
    grid-column: 1 / -1;
    background: var(--bg-surface-alt);
    border-radius: 10px;
    overflow: hidden;
    box-shadow: var(--shadow-card);
}
.si-chart-body {
    display: flex;
    align-items: center;
    gap: 2rem;
    padding: 1.25rem 1.5rem;
}
.si-chart-canvas-wrap {
    flex: 0 0 260px;
    height: 260px;
    position: relative;
}
.si-chart-canvas-wrap canvas {
    display: block;
}
.si-chart-legend {
    flex: 1 1 0;
    min-width: 0;
}
.si-legend-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.38rem 0;
}
.si-legend-row:nth-child(even) { background: var(--alpha-white-03); border-radius: 8px; }
.si-legend-swatch {
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    border-radius: 3px;
}
.si-legend-name {
    flex: 1 1 0;
    min-width: 0;
    font-size: 0.82rem;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.si-legend-zeny {
    flex-shrink: 0;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-muted);
    text-align: right;
}
.si-legend-pct {
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--gold);
    font-weight: 700;
    min-width: 3rem;
    text-align: right;
}
@media (max-width: 700px) {
    .si-chart-body {
        flex-direction: column;
        align-items: stretch;
        gap: 1.25rem;
    }
    .si-chart-canvas-wrap {
        flex: none;
        width: 100%;
        max-width: 280px;
        margin: 0 auto;
    }
}

/* ── Contenido editorial (noticias y paginas CMS) ──────────────
   El HTML que se guarda en cp_cmsnews / cp_cmspages NO puede
   llevar estilos inline: usa exclusivamente estas clases.
   Sin bordes: la jerarquia se apoya en fondo, espacio y color.  */
.na { color: var(--text-primary); line-height: 1.6; }
.na > :first-child { margin-top: 0; }
.na > :last-child  { margin-bottom: 0; }

.na p { margin: 0 0 14px; color: var(--text-panel-soft); }
.na strong { color: var(--text-heading2); font-weight: 700; }
.na em { color: var(--text-primary); }
.na small { color: var(--text-muted); }
.na a { color: var(--gold); }
.na a:hover { color: var(--text-link-hover); }

.na code {
    font-family: Monaco, "Lucida Console", monospace;
    font-size: 0.92em;
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--alpha-white-05);
    color: var(--text-code-strong);
}

.na ol, .na ul { margin: 0 0 16px; padding-left: 20px; color: var(--text-panel-soft); }
.na li { margin-bottom: 10px; }
.na li:last-child { margin-bottom: 0; }
.na ul ul, .na ol ul, .na ol ol, .na ul ol { margin: 6px 0 0; }
.na li > p { margin: 6px 0 0; }

/* Antetitulo de bloque */
.na-eyebrow {
    margin: 0 0 8px;
    font-weight: 700;
    font-size: 0.85em;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--gold-dim);
}

/* Enfasis de texto */
.na .na-accent { color: var(--gold); }
.na .na-strong { color: var(--text-heading2); }
.na .na-muted  { color: var(--text-muted); }
.na .na-foot   { margin: 16px 0 0; color: var(--text-muted); font-size: 0.95em; }

/* Bloques destacados */
.na-box, .na-col, .na-callout {
    padding: 12px 16px;
    border-radius: 14px;
    background: var(--surface-card);
    color: var(--text-panel-soft);
}
.na-box { margin: 0 0 16px; }
.na-callout { margin: 0 0 18px; background: var(--alpha-gold-08); }
.na-box > :last-child, .na-col > :last-child, .na-callout > :last-child { margin-bottom: 0; }
.na-box .na-eyebrow, .na-col .na-eyebrow, .na-callout .na-eyebrow { color: var(--gold); }

.na-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 12px;
    margin: 0 0 18px;
}
.na-col { margin: 0; }

/* Etiqueta de nivel requerido */
.na-tag {
    display: inline-block;
    padding: 1px 9px;
    border-radius: 999px;
    font-size: 0.85em;
    font-weight: 700;
    white-space: nowrap;
    color: var(--text-white);
    background: var(--na-tag-color, var(--gold-dim));
}
.na-tag--lvu80 { --na-tag-color: var(--tag-lv-u80); }
.na-tag--lv80  { --na-tag-color: var(--tag-lv-80); }
.na-tag--lv100 { --na-tag-color: var(--tag-lv-100); color: var(--text-on-accent); }
.na-tag--lv130 { --na-tag-color: var(--tag-lv-130); }
.na-tag--lv150 { --na-tag-color: var(--tag-lv-150); }
.na-tag--lvany { --na-tag-color: var(--tag-lv-any); }

/* Valor destacado en linea */
.na-pill {
    display: inline-block;
    margin: 0 4px;
    padding: 4px 10px;
    border-radius: 8px;
    font-weight: 700;
    background: var(--grad-primary-button);
    color: var(--text-on-accent);
}

/* ── Clases de utilidad de plantilla ───────────────────────────
   Sustituyen a los estilos inline que habia en las vistas.      */
.is-hidden { display: none !important; }

.si-stat-label i { margin-right: 0.35rem; opacity: 0.6; }
.si-stat-value--sm { font-size: 0.78rem; }
.si-stat-sub { font-size: 0.72rem; opacity: 0.6; }
.si-empty { margin: 0; color: var(--text-muted); font-size: 0.85rem; }

.stats-list-table--full { width: 100%; }
.col-sprite { width: 70px; }
.td-sprite { text-align: center; vertical-align: middle; }
.sprite-thumb { object-fit: contain; }
.sprite-thumb-placeholder { font-size: 1.6rem; opacity: 0.5; }

.loginbox-server-pick { margin-left: 8px; }
.na-center { text-align: center; }
.menuitem a { cursor: pointer; }

/* ── Estado vacio de los listados ──────────────────────────────
   WoE, castillos, quien esta conectado y las tiendas pasan buena
   parte del tiempo sin filas que mostrar. Un "no hay resultados"
   seco hace pensar que el servidor esta muerto, asi que el bloque
   explica por que esta vacio y ofrece a donde ir desde ahi.

   Los iconos van como mascara CSS y no como SVG en linea: la
   salida pasa por tidy con output-xhtml, que baja a minusculas el
   atributo viewBox y deja el dibujo sin escalar. Asi ademas el
   color sigue saliendo de un token y no de un literal.           */
.emptystate {
    max-width: 64ch;
    margin: 22px auto 8px;
    padding: 34px 30px 28px;
    border-radius: 22px;
    background: var(--surface-card);
    box-shadow: var(--shadow-content);
    text-align: center;
}

.emptystate__glyph {
    display: block;
    width: 56px;
    height: 56px;
    margin: 0 auto 16px;
    background-color: var(--gold);
    opacity: 0.9;
    -webkit-mask: var(--es-glyph) center / contain no-repeat;
            mask: var(--es-glyph) center / contain no-repeat;
}
.emptystate__glyph--woe {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 21V3'/%3E%3Cpath d='M5 4h13l-2.5 3.5L18 11H5z'/%3E%3C/svg%3E");
}
.emptystate__glyph--castle {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 21h18'/%3E%3Cpath d='M5 21V9l2 1.5V6l2 1.5V4l3 2 3-2v3.5L17 6v4.5L19 9v12'/%3E%3Cpath d='M10 21v-4h4v4'/%3E%3C/svg%3E");
}
.emptystate__glyph--online {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8' r='3.2'/%3E%3Cpath d='M3.5 20a5.5 5.5 0 0 1 11 0'/%3E%3Cpath d='M16 5.6a3.2 3.2 0 0 1 0 6.3'/%3E%3Cpath d='M17.5 14.6A5.5 5.5 0 0 1 20.5 20'/%3E%3C/svg%3E");
}
.emptystate__glyph--vending {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5h17L19 4.5H5z'/%3E%3Cpath d='M5 8.5V19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8.5'/%3E%3Cpath d='M9.5 12.5h5'/%3E%3C/svg%3E");
}
.emptystate__glyph--buying {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='8.2'/%3E%3Cpath d='M12 7.4v9.2'/%3E%3Cpath d='M14.4 9.6a2.6 2.6 0 0 0-2.4-1.3c-1.5 0-2.4.8-2.4 1.9 0 2.6 4.8 1.4 4.8 4 0 1.2-1 2-2.4 2a2.7 2.7 0 0 1-2.5-1.4'/%3E%3C/svg%3E");
}

.emptystate__eyebrow {
    margin: 0 0 8px;
    font-weight: 700;
    font-size: 0.8em;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gold-dim);
}
.emptystate__title {
    margin: 0 0 12px;
    font-family: var(--font-display, inherit);
    font-size: 1.45em;
    line-height: 1.25;
    color: var(--text-heading2);
}
.emptystate__lead {
    margin: 0 auto 16px;
    max-width: 54ch;
    line-height: 1.65;
    color: var(--text-panel-soft);
}
.emptystate__lead strong { color: var(--text-heading2); }
.emptystate__lead em { color: var(--gold); font-style: normal; }

/* Datos reales que demuestran que hay un servidor detras aunque la
   tabla este vacia. Se usan div/span y no dl/dt/dd porque tidy
   reordena un <div> dentro de un <dl>.                           */
.emptystate__facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: 10px;
    margin: 0 0 20px;
    text-align: left;
}
.emptystate__fact {
    padding: 12px 14px;
    border-radius: 14px;
    background: var(--alpha-silver-08);
}
.emptystate__fact-key {
    display: block;
    margin-bottom: 4px;
    font-size: 0.76em;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.emptystate__fact-val {
    display: block;
    font-weight: 700;
    color: var(--text-heading2);
}

.emptystate__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin: 0;
}
.emptystate__cta,
.emptystate__ghost {
    display: inline-block;
    padding: 10px 20px;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.92em;
    text-decoration: none !important;
}
.emptystate__cta {
    background: var(--grad-primary-button);
    color: var(--text-on-accent) !important;
}
.emptystate__ghost {
    background: var(--alpha-silver-10);
    color: var(--text-panel-soft) !important;
}
.emptystate__ghost:hover { background: var(--alpha-silver-18); }

.emptystate__hint {
    margin: 18px 0 0;
    font-size: 0.87em;
    line-height: 1.6;
    color: var(--text-muted);
}

@media (max-width: 640px) {
    .emptystate { padding: 26px 20px 22px; border-radius: 18px; }
    .emptystate__actions { flex-direction: column; }
    .emptystate__cta, .emptystate__ghost { display: block; }
}

/* ── Listados de tiendas ───────────────────────────────────────
   Sustituyen a los estilos inline que traian las vistas de vending
   y buyingstore (negrita del vendedor y mapa en azul literal).   */
.shop-owner { font-weight: 700; }
.shop-map { color: var(--gold-dim); }
.shop-id { text-align: right; }
.shop-icon { vertical-align: middle; margin-right: 6px; }

.pagemenu__label {
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-size: 0.9em;
    color: var(--text-muted);
}
.pagemenu__label::after { content: ":"; }

/* Iconos de los estados vacios de ranking */
.emptystate__glyph--trophy {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 4h10v6a5 5 0 0 1-10 0z'/%3E%3Cpath d='M7 5.5H4.5v2A3.5 3.5 0 0 0 8 11'/%3E%3Cpath d='M17 5.5h2.5v2A3.5 3.5 0 0 1 16 11'/%3E%3Cpath d='M12 15v3'/%3E%3Cpath d='M8.5 20.5h7'/%3E%3Cpath d='M10 18h4l1 2.5H9z'/%3E%3C/svg%3E");
}
.emptystate__glyph--skull {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 11a7 7 0 1 1 14 0v3.5l-1.5 1v2.2a1.3 1.3 0 0 1-1.3 1.3H7.8a1.3 1.3 0 0 1-1.3-1.3v-2.2L5 14.5z'/%3E%3Ccircle cx='9' cy='11' r='1.6'/%3E%3Ccircle cx='15' cy='11' r='1.6'/%3E%3Cpath d='M12 14.5v2'/%3E%3C/svg%3E");
}
.emptystate__glyph--flask {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.5 3h5'/%3E%3Cpath d='M10.5 3v6L5.6 17.6A2 2 0 0 0 7.3 20.6h9.4a2 2 0 0 0 1.7-3L13.5 9V3'/%3E%3Cpath d='M8 15h8'/%3E%3C/svg%3E");
}
.emptystate__glyph--hammer {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13.5 6.5 9 11l-4.5 4.5a1.8 1.8 0 0 0 2.5 2.5L11.5 13.5 16 9'/%3E%3Cpath d='M12 5.2 15.8 9l3.6-2.2a1.4 1.4 0 0 0 .2-2.2l-1.4-1.4a1.4 1.4 0 0 0-2.2.2z'/%3E%3C/svg%3E");
}
.emptystate__glyph--paw {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cellipse cx='7' cy='9' rx='1.9' ry='2.5'/%3E%3Cellipse cx='17' cy='9' rx='1.9' ry='2.5'/%3E%3Cellipse cx='10.5' cy='5.5' rx='1.7' ry='2.2'/%3E%3Cellipse cx='14.5' cy='5.5' rx='1.7' ry='2.2'/%3E%3Cpath d='M12 13c2.6 0 4.6 1.8 4.6 4 0 1.7-1.3 2.7-3 2.7-.9 0-1.2-.4-1.6-.4s-.7.4-1.6.4c-1.7 0-3-1-3-2.7 0-2.2 2-4 4.6-4z'/%3E%3C/svg%3E");
}
.emptystate__glyph--crown {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8.5 6.8 14h10.4L20 8.5l-4.2 2.8L12 5.5l-3.8 5.8z'/%3E%3Cpath d='M6.5 17.5h11'/%3E%3C/svg%3E");
}
.emptystate__glyph--shield {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.2 5 6v6c0 4 3 7.2 7 8.8 4-1.6 7-4.8 7-8.8V6z'/%3E%3Cpath d='M9.5 11.5l1.8 1.8 3.4-3.6'/%3E%3C/svg%3E");
}
.emptystate__glyph--coins {
    --es-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cellipse cx='9' cy='7' rx='5.2' ry='2.4'/%3E%3Cpath d='M3.8 7v4c0 1.3 2.3 2.4 5.2 2.4s5.2-1.1 5.2-2.4V7'/%3E%3Cellipse cx='15' cy='15' rx='5.2' ry='2.4'/%3E%3Cpath d='M9.8 15v4c0 1.3 2.3 2.4 5.2 2.4s5.2-1.1 5.2-2.4v-4'/%3E%3C/svg%3E");
}

/* ==========================================================================
   Preferencias de privacidad del personaje  (character/prefs)
   necROmantic 2026-07-28. Sustituye a la tabla en ingles de themes/default.
   Sin bordes: la separacion la dan fondo y sombra, como en el resto del sitio.
   ========================================================================== */

.prefs-hero {
    margin-bottom: 22px;
}

.prefs-hero__kicker {
    display: inline-block;
    margin-bottom: 8px;
    font-size: 0.74rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
}

.prefs-hero__title {
    margin: 0 0 10px;
}

/* Sin `max-width` (necROmantic 2026-08-26, peticion del usuario): esta entradilla ocupa el
   ancho entero de la pagina. Las 68ch siguen puestas en .prefs-group__desc, que son lineas
   sueltas dentro de la columna y ahi la medida si ayuda a leer. */
.prefs-hero__intro {
    margin: 0;
    color: var(--text-muted);
    line-height: 1.65;
}

/* necROmantic 2026-08-04: la pagina de preferencias ya tiene dos bloques - lo que
   cambia el juego y lo que solo cambia la web - asi que cada lista de tarjetas
   necesita su encabezado. */

.prefs-group {
    margin: 0 0 12px;
}

.prefs-group + .prefs-list {
    margin-bottom: 26px;
}

.prefs-group__title {
    margin: 0 0 4px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--gold);
}

/* El h3 global lleva capitular (`h3:first-letter{font-weight:bold}`), que a este
   tamano no se lee como capitular sino como una errata. */
.prefs-group__title::first-letter {
    font-weight: inherit;
}

.prefs-group__desc {
    max-width: 68ch;
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.prefs-list {
    display: grid;
    gap: 12px;
    margin-bottom: 22px;
}

.prefs-card {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) auto;
    align-items: center;
    gap: 16px;
    padding: 18px 20px;
    border-radius: 12px;
    background: var(--bg-surface);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: background 0.18s ease, box-shadow 0.18s ease;
}

.prefs-card:hover {
    background: var(--bg-surface-alt);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
}

.prefs-card__glyph {
    display: block;
    width: 28px;
    height: 28px;
    background-color: var(--gold);
    opacity: 0.85;
    -webkit-mask: var(--pf-glyph) center / contain no-repeat;
            mask: var(--pf-glyph) center / contain no-repeat;
}

.prefs-card__glyph--online {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8' r='3.2'/%3E%3Cpath d='M3.5 20a5.5 5.5 0 0 1 11 0'/%3E%3Cpath d='M16 5.6a3.2 3.2 0 0 1 0 6.3'/%3E%3Cpath d='M17.5 14.6A5.5 5.5 0 0 1 20.5 20'/%3E%3C/svg%3E");
}

.prefs-card__glyph--map {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s6.5-5.6 6.5-10.2A6.5 6.5 0 0 0 5.5 10.8C5.5 15.4 12 21 12 21z'/%3E%3Ccircle cx='12' cy='10.5' r='2.4'/%3E%3C/svg%3E");
}

.prefs-card__glyph--coins {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cellipse cx='9' cy='7' rx='5.2' ry='2.4'/%3E%3Cpath d='M3.8 7v4c0 1.3 2.3 2.4 5.2 2.4s5.2-1.1 5.2-2.4V7'/%3E%3Cellipse cx='15' cy='15' rx='5.2' ry='2.4'/%3E%3Cpath d='M9.8 15v4c0 1.3 2.3 2.4 5.2 2.4s5.2-1.1 5.2-2.4v-4'/%3E%3C/svg%3E");
}

/* necROmantic 2026-08-04: la redireccion de conjuros. Una flecha que se desvia
   hacia una diana. Pocas piezas y grandes a proposito: a 28px cualquier detalle
   fino se convierte en suciedad. */
.prefs-card__glyph--retarget {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='14.5' cy='14.5' r='7'/%3E%3Ccircle cx='14.5' cy='14.5' r='2.2'/%3E%3Cpath d='M2.6 2.6l5.6 5.6'/%3E%3Cpath d='M8.2 4.3v3.9H4.3'/%3E%3C/svg%3E");
}

/* necROmantic 2026-08-05: la charla del mercenario / homunculo. Dos bocadillos
   de dialogo, uno contestando al otro. Igual que el de arriba: pocas piezas y
   grandes, porque a 28px el detalle fino solo ensucia. */
.prefs-card__glyph--aichat {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 4.5h11v7h-7l-4 3z'/%3E%3Cpath d='M10.5 13.5h11v7h-4l-4 3v-3h-3z'/%3E%3C/svg%3E");
}

/* necROmantic 2026-08-05: la memoria del acompanante y el consumo del dia.
   Las anchuras van por clases --wNN (de 5 en 5) y no por style="": el HTML de este
   panel no lleva estilos en linea, y una barra de progreso no es excusa para
   estrenarlos. Redondear a multiplos de 5 deja la lista en 21 clases. */
.prefs-card__glyph--memory {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5.5a4 4 0 0 0-7 2.6 3.4 3.4 0 0 0-1 4.6A3.6 3.6 0 0 0 7.5 19H12z'/%3E%3Cpath d='M12 5.5a4 4 0 0 1 7 2.6 3.4 3.4 0 0 1 1 4.6A3.6 3.6 0 0 1 16.5 19H12z'/%3E%3Cpath d='M12 5.5V19'/%3E%3C/svg%3E");
}

/* necROmantic 2026-08-09: la defensa AFK. Un escudo, que es lo que es: el personaje
   aguanta donde esta y devuelve el golpe. Mismo criterio que los de arriba -- pocas
   piezas y grandes, porque a 28px el detalle fino solo ensucia. */
.prefs-card__glyph--shield {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2.6l7.5 3v6.2c0 4.6-3.1 8.2-7.5 9.6-4.4-1.4-7.5-5-7.5-9.6V5.6z'/%3E%3Cpath d='M9 12.2l2.2 2.3L15.4 10'/%3E%3C/svg%3E");
}

.prefs-card__glyph--gauge {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 18a9 9 0 1 1 17 0'/%3E%3Cpath d='M12 18l4.5-6'/%3E%3Ccircle cx='12' cy='18' r='1.6'/%3E%3C/svg%3E");
}

.prefs-card--info {
    background: var(--bg-surface-alt);
}

.prefs-meter {
    margin-top: 0.75rem;
}

.prefs-meter__head {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 0.35rem;
}

.prefs-meter__label {
    font-size: 0.82rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.prefs-meter__value {
    font-size: 0.9rem;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.prefs-meter__track {
    height: 8px;
    border-radius: 999px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    overflow: hidden;
}

.prefs-meter__fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--gold);
    /* Una barra que salta de golpe se lee como un error de pintado. */
    transition: width 0.4s ease;
}

/* Cerca del tope el color deja de ser decorativo y pasa a ser el aviso. */
.prefs-meter__fill--alto {
    background: var(--accent-purple);
}

.prefs-meter__foot {
    margin: 0.45rem 0 0;
    font-size: 0.85rem;
    color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
    .prefs-meter__fill { transition: none; }
}

.prefs-meter__fill--w0 { width: 0%; }
.prefs-meter__fill--w5 { width: 5%; }
.prefs-meter__fill--w10 { width: 10%; }
.prefs-meter__fill--w15 { width: 15%; }
.prefs-meter__fill--w20 { width: 20%; }
.prefs-meter__fill--w25 { width: 25%; }
.prefs-meter__fill--w30 { width: 30%; }
.prefs-meter__fill--w35 { width: 35%; }
.prefs-meter__fill--w40 { width: 40%; }
.prefs-meter__fill--w45 { width: 45%; }
.prefs-meter__fill--w50 { width: 50%; }
.prefs-meter__fill--w55 { width: 55%; }
.prefs-meter__fill--w60 { width: 60%; }
.prefs-meter__fill--w65 { width: 65%; }
.prefs-meter__fill--w70 { width: 70%; }
.prefs-meter__fill--w75 { width: 75%; }
.prefs-meter__fill--w80 { width: 80%; }
.prefs-meter__fill--w85 { width: 85%; }
.prefs-meter__fill--w90 { width: 90%; }
.prefs-meter__fill--w95 { width: 95%; }
.prefs-meter__fill--w100 { width: 100%; }

/* necROmantic 2026-08-05: el pasado que el jugador escribe y la memoria que puede leer. */
.prefs-card__glyph--scroll {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 3.5h11a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2h-11a2 2 0 0 1-2-2v-13a2 2 0 0 1 2-2z'/%3E%3Cpath d='M8 8h8'/%3E%3Cpath d='M8 12h8'/%3E%3Cpath d='M8 16h5'/%3E%3C/svg%3E");
}

/* La tarjeta del pasado no lleva interruptor a la derecha, asi que el texto ocupa el ancho. */
.prefs-card__text--full {
    flex: 1 1 100%;
}

.prefs-textarea {
    display: block;
    width: 100%;
    margin-top: 0.6rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-input);
    color: var(--text-primary);
    font: inherit;
    line-height: 1.5;
    resize: vertical;
}

.prefs-textarea:focus {
    outline: none;
    border-color: var(--gold);
}

.prefs-code {
    padding: 0.1em 0.4em;
    border-radius: 4px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.9em;
    /* Sin esto, una frase de ejemplo larga desborda la tarjeta en un movil. */
    overflow-wrap: anywhere;
}

.prefs-memo {
    margin-top: 0.8rem;
    border-top: 1px solid var(--border-light);
    padding-top: 0.6rem;
}

.prefs-memo__summary {
    cursor: pointer;
    font-size: 0.9rem;
    color: var(--gold);
}

.prefs-memo__block {
    margin-top: 0.7rem;
    padding: 0.6rem 0.7rem;
    border-radius: 6px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
}

.prefs-memo__who {
    margin: 0 0 0.35rem;
    font-size: 0.9rem;
    color: var(--text-heading2);
}

.prefs-memo__kind,
.prefs-memo__size {
    margin-left: 0.5rem;
    font-size: 0.8rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.prefs-memo__text {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--text-muted);
    /* Es un volcado de conversacion: si crece, que haga scroll dentro y no estire la pagina. */
    max-height: 18rem;
    overflow-y: auto;
    overflow-wrap: anywhere;
}

/* necROmantic 2026-08-06: caja de memoria vacia y boton de borrarla. */
.prefs-memo__text--vacia {
    font-style: italic;
    opacity: 0.75;
}

.prefs-memo__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.8rem;
    margin: 0.8rem 0 0;
}

.prefs-memo__clear {
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-input);
    color: var(--text-primary);
    font: inherit;
    font-size: 0.9rem;
    cursor: pointer;
}

.prefs-memo__clear:hover,
.prefs-memo__clear:focus-visible {
    border-color: var(--gold);
    color: var(--gold);
}

.prefs-memo__hint {
    flex: 1 1 14rem;
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* necROmantic 2026-08-06: apodos como etiquetas. */
.prefs-card__glyph--tag {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 11.5V4.5h7l9.5 9.5-7 7z'/%3E%3Ccircle cx='7.5' cy='8.5' r='1.4'/%3E%3C/svg%3E");
}

.prefs-tags {
    margin-top: 0.6rem;
}

.prefs-tags__list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.prefs-tags__list:not(:empty) {
    margin-bottom: 0.5rem;
}

.prefs-tags__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.35rem 0.2rem 0.6rem;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-input);
    font-size: 0.88rem;
    color: var(--text-primary);
}

.prefs-tags__x {
    border: 0;
    background: none;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.15rem;
    cursor: pointer;
}

.prefs-tags__x:hover,
.prefs-tags__x:focus-visible {
    color: var(--gold);
}

.prefs-tags__input,
.prefs-tags__write {
    display: block;
    width: 100%;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-input);
    color: var(--text-primary);
    font: inherit;
}

.prefs-tags__input:focus,
.prefs-tags__write:focus {
    outline: none;
    border-color: var(--gold);
}

/* Sin JS este campo se queda a la vista y funciona como toda la vida: comas a mano. */
.prefs-tags__input--oculto {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================================
   LOS ACOMPAÑANTES, DE UNO EN UNO (necROmantic 2026-08-29, encargo del usuario:
   "esta demasiado saturado al tener a los 4 en columnas ... que se mostrasen de
   1 en 1, por medio de pestañas").

   AQUI ESTABA `.prefs-companions`, un `grid` de `auto-fit` con columnas de 17rem
   minimo. Se retira: con cuatro familias -- el Compañero entro el 2026-08-27 --
   caben tres columnas a 1280px y la cuarta baja sola a una segunda fila, asi que
   ademas de estrecho quedaba descuadrado. Y el contenido de cada una no es una
   ficha corta: es un pasado de 1.024 caracteres, los apodos, el idioma y la lista
   de frases por momento.

   El reparto de ahora: la tira de pestañas manda, el panel ocupa TODO el ancho y
   por dentro se parte en dos -- el pasado a la izquierda, los dos campos cortos a
   la derecha -- con las frases debajo, que es lo unico que crece sin tope.

   El `display:none` de los paneles apagados cuelga de `.cmt--js`: esa clase la
   pone el guion al arrancar, de modo que sin JavaScript se ven los cuatro y no
   una caja con tres cuartas partes del contenido inalcanzables.
   ============================================================================ */
.cmt {
    margin-bottom: 1.5rem;
}

.cmt__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
    margin: 0 0 1rem;
}

/* `flex: 1 1 11rem` y no un ancho fijo: las cuatro se reparten la fila a partes
   iguales cuando caben, y cuando no, bajan de dos en dos sin dejar una sola
   pestaña huerfana a lo ancho de toda la caja. */
.cmt__tab {
    flex: 1 1 11rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-width: 0;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
    color: var(--text-muted);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}

.cmt__tab:hover {
    border-color: var(--border-light);
    background: var(--bg-surface-alt);
    color: var(--text-primary);
}

.cmt__tab:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

/* La activa NO se distingue solo por el color: lleva ademas el galon de la
   izquierda y el fondo mas claro. Un unico indicio cromatico se pierde para
   quien no separa bien estos dos morados. */
.cmt__tab.is-on {
    border-color: var(--gold-dim);
    background: var(--bg-surface-alt);
    color: var(--text-heading2);
    box-shadow: inset 3px 0 0 var(--gold);
}

/* ⚠️ `.cmt__tab .cmt__tab-glyph` Y NO `.cmt__tab-glyph` A SECAS. El mismo <span> lleva
   tambien `.prefs-comp__glyph`, que es quien pinta la silueta (la mascara) y que esta
   definida MAS ABAJO en este fichero con su `background-color: var(--gold)` y sus 24px.
   A igual especificidad gana la de abajo, asi que a secas esto no cambiaria nada. */
.cmt__tab .cmt__tab-glyph {
    width: 22px;
    height: 22px;
    background-color: currentColor;
    opacity: 0.75;
}

.cmt__tab.is-on .cmt__tab-glyph {
    background-color: var(--gold);
    opacity: 1;
}

.cmt__tab-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}

.cmt__tab-name {
    font-size: 0.98rem;
    font-weight: 600;
}

/* De quien es. Se recorta con puntos suspensivos en vez de partirse: la pestaña
   tiene que conservar su altura pase lo que pase con el nombre de un mercenario
   de dieciocho letras. */
.cmt__tab-note {
    font-size: 0.78rem;
    color: var(--text-muted);
    opacity: 0.9;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cmt__tab.is-on .cmt__tab-note {
    color: var(--gold-dim);
    opacity: 1;
}

/* Sin guion, los cuatro paneles a la vista y separados. Con guion, solo el
   encendido. El `.is-on` gana por especificidad (0,3,0 contra 0,2,0), no por
   orden: escribirlo al reves con la misma especificidad dejaria la seccion en
   blanco y el motivo no se veria en el marcado. */
.cmt__panel + .cmt__panel {
    margin-top: 1rem;
}

.cmt--js .cmt__panel {
    display: none;
}

.cmt--js .cmt__panel.is-on {
    display: flex;
    margin-top: 0;
}

/* Mismo motivo que en el glifo: `.prefs-comp` trae su propio `padding` y se declara
   despues. */
.cmt__panels .cmt__panel {
    padding: 1.1rem 1.3rem 1.3rem;
}

.cmt__panel .prefs-comp__title {
    font-size: 1.15rem;
}

/* Las dos columnas de dentro. `minmax(0, …)` en las dos para que un <select> o
   una etiqueta larga no puedan empujar la rejilla mas alla del panel: sin ese
   minimo, la columna toma como suelo el ancho de su contenido mas ancho. */
.cmt__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    gap: 0.2rem 1.8rem;
    align-items: start;
}

.cmt__col {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Con el panel a todo lo ancho el recuadro del pasado ya no tiene que ser una
   rendija: cinco lineas eran las que cabian en una columna de 17rem. */
.cmt__col--pasado .prefs-textarea {
    min-height: 10.5rem;
}

.cmt__frases {
    margin-top: 1.2rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--border-light);
}

/* La primera etiqueta de cada columna no necesita el margen de separacion que
   llevan las siguientes: arriba solo tiene el borde de la cabecera. */
.cmt__col > .prefs-comp__label:first-child,
.cmt__frases > .prefs-comp__label:first-child {
    margin-top: 0;
}

/* Por debajo de 900px las dos columnas no caben sin estrangular el recuadro del
   pasado, que es justo el problema del que se venia. Se apilan. */
@media (max-width: 900px) {
    .cmt__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 0;
    }

    .cmt__col--datos {
        margin-top: 0.9rem;
    }
}

@media (max-width: 620px) {
    .cmt__tab {
        flex: 1 1 100%;
    }

    .cmt__panels .cmt__panel {
        padding: 0.9rem 1rem 1.1rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cmt__tab {
        transition: none;
    }
}

.prefs-comp {
    display: flex;
    flex-direction: column;
    padding: 1rem 1.1rem 1.2rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
    min-width: 0;
}

.prefs-comp__head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding-bottom: 0.7rem;
    margin-bottom: 0.9rem;
    border-bottom: 1px solid var(--border-light);
}

.prefs-comp__title {
    margin: 0;
    font-size: 1.05rem;
    color: var(--text-heading2);
}

.prefs-comp__glyph {
    display: block;
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
    background-color: var(--gold);
    opacity: 0.9;
    -webkit-mask: var(--pf-glyph) center / contain no-repeat;
            mask: var(--pf-glyph) center / contain no-repeat;
}

/* Una espada, un frasco de alquimista, una huella y un escudo con alguien dentro.
   Siluetas simples: a 24px cualquier detalle fino se convierte en suciedad. */
.prefs-comp__glyph--mercenary {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 3.5l-9 9'/%3E%3Cpath d='M15.5 3.5H19v3.5'/%3E%3Cpath d='M10 12.5l-2.5 2.5'/%3E%3Cpath d='M4.5 20.5l4-4'/%3E%3Ccircle cx='6.5' cy='18.5' r='2.6'/%3E%3C/svg%3E");
}

.prefs-comp__glyph--homunculus {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.5 3.5h5'/%3E%3Cpath d='M10.5 3.5v5L6 17a3.2 3.2 0 0 0 2.8 4.5h6.4A3.2 3.2 0 0 0 18 17l-4.5-8.5v-5'/%3E%3Cpath d='M7.5 14.5h9'/%3E%3C/svg%3E");
}

.prefs-comp__glyph--pet {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cellipse cx='12' cy='16' rx='4.6' ry='4'/%3E%3Cellipse cx='5.5' cy='10' rx='2.1' ry='2.6'/%3E%3Cellipse cx='18.5' cy='10' rx='2.1' ry='2.6'/%3E%3Cellipse cx='9.5' cy='5.5' rx='2' ry='2.4'/%3E%3Cellipse cx='15' cy='5.5' rx='2' ry='2.4'/%3E%3C/svg%3E");
}

/* necROmantic 2026-08-27: el Companero. Escudo con alguien dentro, que es lo que es -- una
   persona que te guarda las espaldas -- y ademas el mismo icono con el que se le nombra en la
   ficha de personaje (fa-user-shield), para que se le reconozca entre las dos pantallas. */
.prefs-comp__glyph--companion {
    --pf-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2.5l7.5 2.9v5.4c0 4.7-3.1 8.4-7.5 10.7C7.6 19.2 4.5 15.5 4.5 10.8V5.4z'/%3E%3Ccircle cx='12' cy='10' r='2.2'/%3E%3Cpath d='M8.4 17c0.5-2 1.9-3 3.6-3s3.1 1 3.6 3'/%3E%3C/svg%3E");
}

.prefs-comp__label {
    display: block;
    margin-top: 0.6rem;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.prefs-comp__desc {
    margin: 0.25rem 0 0;
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.prefs-comp__foot {
    margin: 0.35rem 0 0.5rem;
    font-size: 0.8rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* necROmantic 2026-08-06: "Saber más".
   La pagina explica mucho y esta bien que lo haga, pero de golpe se lee como un muro.
   Lo esencial se queda a la vista y el detalle entra aqui. <details> nativo: sin JS,
   con teclado y accesible de serie. */
.prefs-more {
    margin-top: 0.5rem;
}

.prefs-more__summary {
    display: inline-block;
    cursor: pointer;
    font-size: 0.85rem;
    letter-spacing: 0.03em;
    color: var(--gold);
    padding: 0.15rem 0;
}

.prefs-more__summary::marker,
.prefs-more__summary::-webkit-details-marker {
    color: var(--gold);
}

.prefs-more__summary:hover {
    text-decoration: underline;
}

.prefs-more__body {
    margin-top: 0.4rem;
    padding-left: 0.8rem;
    border-left: 2px solid var(--border-light);
}

.prefs-more__body > .prefs-card__desc:first-child,
.prefs-more__body > .prefs-comp__desc:first-child {
    margin-top: 0;
}

/* necROmantic 2026-08-06: las frases aprendidas de la mascota. */
.prefs-lines {
    margin-top: 0.6rem;
}

.prefs-lines__head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    margin: 0 0 0.3rem;
    font-size: 0.85rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.prefs-lines__count {
    font-variant-numeric: tabular-nums;
    text-transform: none;
    letter-spacing: 0;
}

.prefs-lines__empty {
    margin: 0;
    font-size: 0.85rem;
    font-style: italic;
    opacity: 0.7;
    color: var(--text-muted);
}

.prefs-lines__list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.prefs-lines__item {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    padding: 0.25rem 0;
    border-bottom: 1px solid var(--border-light);
}

.prefs-lines__item:last-child {
    border-bottom: 0;
}

.prefs-lines__text {
    flex: 1 1 auto;
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

/* La frase es editable. Se pinta como texto y no como caja hasta que la tocas: una lista
   de diez recuadros pesa mucho, y aqui lo normal es leer, no escribir. */
.prefs-lines__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.2rem 0.35rem;
    border: 1px solid transparent;
    border-radius: 4px;
    background: transparent;
    color: var(--text-primary);
    font: inherit;
    font-size: 0.88rem;
    line-height: 1.45;
}

.prefs-lines__input:hover {
    border-color: var(--border-light);
}

.prefs-lines__input:focus {
    outline: none;
    border-color: var(--gold);
    background: var(--bg-input);
}

.prefs-lines__x {
    flex: 0 0 auto;
    border: 0;
    background: none;
    color: var(--text-muted);
    font-size: 1.05rem;
    line-height: 1.2;
    padding: 0 0.2rem;
    cursor: pointer;
}

.prefs-lines__x:hover,
.prefs-lines__x:focus-visible {
    color: var(--gold);
}

.prefs-card__text {
    min-width: 0;
}

.prefs-card__title {
    display: block;
    margin-bottom: 4px;
    font-weight: 600;
    color: var(--text-label-strong);
    cursor: pointer;
}

.prefs-card__desc {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-muted);
}

/* necROmantic 2026-08-04: las tarjetas pueden llevar mas de un parrafo. */
.prefs-card__desc + .prefs-card__desc {
    margin-top: 8px;
}

/* Aviso puntual dentro de una tarjeta (por ejemplo: "el cambio se aplica al
   volver a entrar"). No es un error, solo una condicion que conviene leer. */
.prefs-card__note {
    margin: 10px 0 0;
    padding-left: 10px;
    border-left: 2px solid var(--gold);
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* --- Interruptor ---------------------------------------------------------
   El <input> real se mantiene en el flujo (no display:none) para que siga
   siendo alcanzable con el teclado; se oculta visualmente sobre la pista.   */

.prefs-switch {
    position: relative;
    display: inline-block;
    width: 46px;
    height: 26px;
    flex: 0 0 auto;
}

.prefs-switch__input {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 2;
}

.prefs-switch__track {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border-radius: 999px;
    background: var(--bg-input);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.45);
    transition: background 0.18s ease;
}

.prefs-switch__thumb {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--text-panel-bright);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    transition: transform 0.18s ease, background 0.18s ease;
}

.prefs-switch__input:checked ~ .prefs-switch__track {
    background: var(--gold);
}

.prefs-switch__input:checked ~ .prefs-switch__track .prefs-switch__thumb {
    transform: translateX(20px);
    background: var(--bg-content);
}

.prefs-switch__input:focus-visible ~ .prefs-switch__track {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

/* --- Acciones ----------------------------------------------------------- */

.prefs-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
}

/* necROmantic 2026-08-26: EL AVISO DEL AUTOGUARDADO.
   Preferencias ya no tiene boton: cada control se guarda solo al cambiarlo. Este es el acuse, y va
   PEGADO A CADA CONTROL y no al final del formulario -- son cuatro plegables de alto, y un aviso
   ahi abajo le quedaria al jugador fuera de la pantalla justo cuando necesita verlo.

   `:empty` no ocupa: el aviso se crea vacio y solo abulta cuando tiene algo que decir, asi que no
   deja un hueco reservado en cada fila. */
.prefs-auto {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.78em;
    vertical-align: middle;
    transition: opacity 0.2s;
}

.prefs-auto:empty { display: none; }

.prefs-auto--wait { color: var(--text-muted); }

.prefs-auto--ok {
    color: var(--text-success);
    background: var(--bg-surface-alt);
}

/* El fallo NO se va solo (asi lo pinta el guion) y por eso se le da su propia linea: un aviso de
   error que hay que buscar entre dos controles es medio aviso. */
.prefs-auto--err {
    display: block;
    margin: 4px 0 0;
    color: var(--accent-red-h, var(--tone-rose));
    background: var(--bg-surface-alt);
}

/* El aviso de <noscript>, encima del boton que solo ve quien no tiene JavaScript. */
.prefs-actions__note {
    margin: 0 0 8px;
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* necROmantic 2026-08-26: preferencias vive ahora DENTRO de la ficha, en plegables.
   Dos retoques que solo hacen falta ahi, y por eso van acotados a `.fold` en vez de tocar las
   reglas de base -- que siguen sirviendo a quien las use en otro sitio.

   1) El boton de guardar quedaba pegado al ultimo plegable, sin aire. Se le da el mismo hueco que
      separa dos plegables entre si (34px), para que se lea como "esto cierra el bloque de arriba"
      y no como parte de el. */
.fold__body ~ .prefs-actions,
.fold + .prefs-actions {
    margin-top: 34px;
}

/* 2) El parrafo de entrada de cada bloque heredaba `max-width: 68ch`, que esta pensado para el
      ancho de la pagina vieja. Dentro del cuerpo de un plegable -- que ya viene acotado y con su
      propio relleno -- esas 68ch rompen la linea mucho antes de tiempo y dejan media caja vacia.
      Se suelta el tope SOLO ahi dentro. */
.fold__body > .prefs-group__desc,
.fold__body .prefs-group > .prefs-group__desc {
    max-width: none;
}

/* necROmantic 2026-08-09: los interruptores se guardan solos al cambiarlos, y entre el clic y la
   recarga hay una peticion de verdad. Sin senal, el interruptor parece que no ha hecho nada y se
   vuelve a pulsar. Se atenua el formulario entero y se bloquea el raton: recargando, cualquier
   segundo cambio se perderia igual. */
.prefs-form--guardando {
    opacity: 0.55;
    pointer-events: none;
    transition: opacity 120ms ease-out;
}

.prefs-save {
    padding: 11px 26px;
    border: 0;
    border-radius: 8px;
    background: var(--gold);
    color: var(--bg-content);
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: filter 0.18s ease, transform 0.18s ease;
}

.prefs-save:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
}

.prefs-back {
    font-size: 0.9rem;
    color: var(--text-muted);
}

.prefs-back:hover {
    color: var(--gold);
}

@media (max-width: 640px) {
    .prefs-card {
        grid-template-columns: 28px minmax(0, 1fr);
        grid-template-areas:
            "glyph text"
            "switch switch";
        row-gap: 14px;
    }
    .prefs-card__glyph { grid-area: glyph; }
    .prefs-card__text  { grid-area: text; }
    .prefs-switch      { grid-area: switch; justify-self: start; }
}

/* ==========================================================================
   Buscador del almacen en la ficha de cuenta  (account/view)
   necROmantic 2026-07-28. El listado va de 25 en 25; esto es el filtro.
   ========================================================================== */

.storage-search {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px;
    padding: 14px 16px;
    border-radius: 10px;
    background: var(--bg-surface);
}

.storage-search__label {
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.storage-search__input {
    flex: 1 1 240px;
    min-width: 0;
    padding: 9px 12px;
    border: 0;
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
}

.storage-search__submit {
    padding: 9px 20px;
    border: 0;
    border-radius: 8px;
    background: var(--gold);
    color: var(--bg-content);
    font-weight: 600;
    cursor: pointer;
    transition: filter 0.18s ease;
}

.storage-search__submit:hover {
    filter: brightness(1.08);
}

.storage-search__clear {
    font-size: 0.88rem;
    color: var(--text-muted);
}

.storage-search__clear:hover {
    color: var(--gold);
}

/* ==========================================================================
   Reportes de jugadores  (modules/report)
   necROmantic 2026-07-28. Formulario + columna de ayuda. Sin bordes.
   ========================================================================== */

.report-hero {
    margin-bottom: 22px;
}

.report-hero__kicker {
    display: inline-block;
    margin-bottom: 8px;
    font-size: 0.74rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
}

.report-hero__title {
    margin: 0 0 10px;
}

.report-hero__intro {
    max-width: 70ch;
    margin: 0;
    color: var(--text-muted);
    line-height: 1.65;
}

.report-errors {
    margin-bottom: 20px;
    padding: 16px 18px;
    border-radius: 10px;
    background: var(--surface-silver-panel-soft, var(--bg-surface));
    box-shadow: inset 3px 0 0 var(--text-error);
}

.report-errors__title {
    margin: 0 0 8px;
    font-weight: 600;
    color: var(--text-error);
}

.report-errors__list {
    margin: 0;
    padding-left: 20px;
    color: var(--text-muted);
    line-height: 1.6;
}

.report-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 24px;
    align-items: start;
}

.report-form {
    display: grid;
    gap: 18px;
    padding: 22px 24px;
    border-radius: 12px;
    background: var(--bg-surface);
}

.report-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

.report-field {
    display: grid;
    gap: 7px;
    min-width: 0;
}

.report-label {
    font-size: 0.82rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-label-strong);
}

.report-optional {
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-muted);
}

.report-input,
.report-select,
.report-textarea {
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font: inherit;
}

.report-textarea {
    min-height: 220px;
    line-height: 1.6;
    resize: vertical;
    border-radius: 0 0 8px 8px;
}

.report-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px;
    border-radius: 8px 8px 0 0;
    background: var(--bg-surface-alt);
}

.report-tool {
    padding: 5px 12px;
    border: 0;
    border-radius: 6px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-size: 0.82rem;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.report-tool:hover {
    background: var(--gold);
    color: var(--bg-content);
}

.report-file {
    padding: 10px 0;
    color: var(--text-muted);
}

.report-hint {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.report-hint--ok  { color: var(--text-success); }
.report-hint--bad { color: var(--text-error); }

/* necROmantic 2026-08-01: casilla de aceptación, en reportes y en sugerencias.
   Va en su propio recuadro justo encima del botón: es lo último que se lee
   antes de enviar, que es cuando importa. */
.report-consent {
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface-alt);
}

.report-consent__box {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    cursor: pointer;
}

.report-consent__check {
    flex: 0 0 auto;
    /* alineada con la primera línea del texto, no con el centro del bloque */
    margin-top: 2px;
    width: 17px;
    height: 17px;
    accent-color: var(--gold);
    cursor: pointer;
}

.report-consent__text {
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-primary);
}

.report-consent__mail {
    font-family: Monaco, "Lucida Console", monospace;
    font-size: 0.86em;
    color: var(--text-code-strong);
}

.report-consent__warn {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 10px 0 0;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    font-size: 0.86rem;
    color: var(--text-muted);
}

.report-consent__warn i { color: var(--accent-red); }

.report-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
}

.report-submit {
    padding: 12px 30px;
    border: 0;
    border-radius: 8px;
    background: var(--gold);
    color: var(--bg-content);
    font-weight: 600;
    cursor: pointer;
    transition: filter 0.18s ease, transform 0.18s ease;
}

.report-submit:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
}

.report-privacy {
    font-size: 0.84rem;
    color: var(--text-muted);
}

.report-aside {
    padding: 20px 22px;
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

.report-aside__title {
    margin: 0 0 12px;
    font-size: 1rem;
}

.report-aside__list {
    margin: 0 0 14px;
    padding-left: 18px;
    font-size: 0.9rem;
    line-height: 1.65;
    color: var(--text-muted);
}

.report-aside__list li + li {
    margin-top: 8px;
}

.report-aside__note {
    margin: 0;
    font-size: 0.84rem;
    line-height: 1.55;
    color: var(--text-notice);
}

@media (max-width: 900px) {
    .report-layout { grid-template-columns: minmax(0, 1fr); }
    .report-row    { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   Referidos: nivel, barra de experiencia y ventajas  (account/view)
   necROmantic 2026-07-28. El ancho de la barra va por clase --pNN y no por
   estilo en linea, en coherencia con el resto del sitio.
   ========================================================================== */

.referral-panel {
    margin-bottom: 26px;
    padding: 22px 24px;
    border-radius: 12px;
    background: var(--bg-surface);
}

.referral-head {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 16px;
}

.referral-badge {
    flex: 0 0 auto;
    padding: 10px 18px;
    border-radius: 999px;
    background: var(--gold);
    color: var(--bg-content);
    font-weight: 700;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.referral-head__text { min-width: 0; }

.referral-head__title {
    margin: 0 0 4px;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text-label-strong);
}

.referral-head__sub {
    margin: 0;
    font-size: 0.9rem;
    color: var(--text-muted);
}

/* --- Barra de experiencia --- */

.referral-bar {
    position: relative;
    height: 22px;
    border-radius: 999px;
    background: var(--bg-input);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.45);
    overflow: hidden;
}

.referral-bar__fill {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    padding-right: 8px;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
    transition: width 0.4s ease;
}

.referral-bar__value {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--bg-content);
}

.referral-bar__fill--p0   { width: 0;    padding-right: 0; }
.referral-bar__fill--p5   { width: 5%;   }
.referral-bar__fill--p10  { width: 10%;  }
.referral-bar__fill--p15  { width: 15%;  }
.referral-bar__fill--p20  { width: 20%;  }
.referral-bar__fill--p25  { width: 25%;  }
.referral-bar__fill--p30  { width: 30%;  }
.referral-bar__fill--p35  { width: 35%;  }
.referral-bar__fill--p40  { width: 40%;  }
.referral-bar__fill--p45  { width: 45%;  }
.referral-bar__fill--p50  { width: 50%;  }
.referral-bar__fill--p55  { width: 55%;  }
.referral-bar__fill--p60  { width: 60%;  }
.referral-bar__fill--p65  { width: 65%;  }
.referral-bar__fill--p70  { width: 70%;  }
.referral-bar__fill--p75  { width: 75%;  }
.referral-bar__fill--p80  { width: 80%;  }
.referral-bar__fill--p85  { width: 85%;  }
.referral-bar__fill--p90  { width: 90%;  }
.referral-bar__fill--p95  { width: 95%;  }
.referral-bar__fill--p100 { width: 100%; }

.referral-bar__legend {
    display: flex;
    justify-content: space-between;
    margin: 6px 2px 18px;
    font-size: 0.78rem;
    color: var(--text-muted);
}

/* --- Ventajas del nivel --- */

.referral-perks {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}

.referral-perk {
    display: grid;
    gap: 4px;
    padding: 14px 16px;
    border-radius: 10px;
    background: var(--bg-surface-alt);
    text-align: center;
}

.referral-perk__value {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--gold);
}

.referral-perk__label {
    font-size: 0.82rem;
    line-height: 1.4;
    color: var(--text-muted);
}

.referral-rules {
    margin: 0 0 18px;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.referral-table { width: 100%; }

.referral-yes { color: var(--text-success); font-weight: 600; }
.referral-no  { color: var(--text-notice); }

@media (max-width: 760px) {
    .referral-perks { grid-template-columns: minmax(0, 1fr); }
    .referral-head  { flex-wrap: wrap; }
}

/* ==========================================================================
   Fichas de participacion  (account/view)
   necROmantic 2026-07-29. Verde cubierta, azul protegida, rojo fallada.
   ========================================================================== */

.ticket-card {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0 12px;
}

.ticket {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 7px;
    background: var(--bg-input);
    color: var(--bg-content);
    font-size: 0.76rem;
    font-weight: 700;
}

.ticket--green { background: var(--text-success); }
.ticket--blue  { background: var(--accent-purple); }
.ticket--red   { background: var(--text-error); }

.ticket-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0 0 18px;
    font-size: 0.84rem;
    color: var(--text-muted);
}

.ticket-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.ticket-legend .ticket {
    width: 15px;
    height: 15px;
    border-radius: 4px;
}

.streak-history {
    margin: 0 0 18px;
    padding-left: 18px;
    font-size: 0.88rem;
    line-height: 1.7;
    color: var(--text-muted);
}

/* ==========================================================================
   Cartilla de sellos  (account/view)  ·  necROmantic 2026-07-29
   Paginas de 30 dias contadas desde el inicio de la racha, agrupadas en
   semanas de 7. Verde perfecta, azul si algun fallo quedo protegido, rojo si
   hubo fallo sin proteger.
   ========================================================================== */

.stampcard {
    margin: 4px 0 14px;
    padding: 16px 18px;
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

.stampcard__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px 16px;
    margin-bottom: 14px;
}

.stampcard__page {
    font-weight: 700;
    color: var(--text-label-strong);
}

.stampcard__range {
    font-size: 0.84rem;
    color: var(--text-muted);
}

.stampcard__nav {
    display: flex;
    gap: 12px;
    margin-left: auto;
    font-size: 0.84rem;
}

.stampcard__arrow { color: var(--gold); }
.stampcard__arrow:hover { filter: brightness(1.15); }
.stampcard__arrow.is-off { color: var(--text-muted); opacity: 0.45; }

/* --- Semana: UN solo elemento (nombre + contador + progreso de fondo) ------ */

.stampweek {
    display: grid;
    grid-template-columns: 128px minmax(0, 1fr);
    align-items: center;
    gap: 14px;
    padding: 5px 8px;
    border-radius: 9px;
}

.stampweek--current {
    background: var(--bg-surface);
    box-shadow: inset 2px 0 0 var(--gold);
}

.stampweek__label {
    position: relative;
    display: block;
    padding: 6px 11px;
    border-radius: 999px;
    background: var(--bg-input);
    overflow: hidden;
}

.stampweek__fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    border-radius: 999px;
    background: var(--bg-input);
    transition: width 0.3s ease;
}

/* necROmantic 2026-07-31: la barra de cada semana usa la paleta --stamp-* (definida
   mas abajo, en el bloque "Sellos de la cartilla: colores de verdad" del 2026-07-30),
   igual que los sellos sueltos. Se quedo sin migrar en aquella pasada y seguia tirando
   de tokens de TEXTO: --text-success (#d9eee6) y --text-error (#f5d6e0) son pasteles
   casi blancos que como fondo no se distinguian entre si, y el azul ni siquiera era
   azul, era el violeta del tema (--accent-purple).
   El estado ya lo calcula Flux_Participation::buildCard() y significa exactamente esto:
     red    -> hay algun fallo sin proteger en la semana (manda sobre todo lo demas)
     blue   -> se gasto al menos un protector y NO queda ningun fallo
     green  -> semana impecable
     future -> semana sin empezar
   Las variables CSS se resuelven al calcular el valor, no por orden de aparicion, asi
   que no importa que el :root con los --stamp-* venga despues en el fichero. */
.stampweek__label--green  .stampweek__fill { background: var(--stamp-green); }
.stampweek__label--blue   .stampweek__fill { background: var(--stamp-blue); }
.stampweek__label--red    .stampweek__fill { background: var(--stamp-red); }
.stampweek__label--future .stampweek__fill { background: var(--stamp-void); }

/* Una semana sin empezar tiene progreso 0, o sea que su relleno mide 0 y no se ve:
   el color "por venir" hay que ponerlo en la PISTA o el estado future no se
   distinguiria de una semana empezada y aun a cero. */
.stampweek__label--future { background: var(--stamp-void); }

.stampweek__text {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: 0.72rem;
    font-weight: 700;
    /* necROmantic 2026-07-31: blanco. Antes era naranja #ff9400 (decision del 2026-07-29,
       cuando los rellenos eran pasteles casi blancos y hacia falta algo que se viera).
       Con la paleta --stamp-* saturada el blanco contrasta bien sobre los cuatro estados
       y sobre la pista vacia, asi que ya no hace falta el naranja ni las tres reglas que
       lo repetian para las semanas rellenas. La sombra es para el verde y el azul, que
       son tonos medios. */
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}

.stampweek__count { font-weight: 600; opacity: 0.85; }

/* --- Sello -----------------------------------------------------------------
   Rejilla fija de 7 columnas: las semanas cortas (la ultima pagina son 30 dias,
   no 28) dejan sus huecos alineados en lugar de descolocar la fila.          */

.stampweek__stamps {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 6px;
    max-width: 380px;
}

.stamp {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 700;
    transition: transform 0.15s ease;
}

.stamp:hover { transform: translateY(-2px); z-index: 3; }

.stamp--green   { background: var(--text-success);  color: var(--bg-content); }
.stamp--blue    { background: var(--accent-purple); color: var(--bg-content); }
.stamp--red     { background: var(--text-error);    color: var(--bg-content); }
.stamp--empty   { background: var(--text-error);    color: var(--bg-content); opacity: 0.55; }
.stamp--pending { background: var(--gold);          color: var(--bg-content); }
.stamp--future  { background: var(--bg-input);      color: var(--text-muted); opacity: 0.5; }

.stamp--today { box-shadow: 0 0 0 2px var(--gold); }
.stamp--goal  { box-shadow: inset 0 0 0 2px var(--gold); }
.stamp--today.stamp--goal { box-shadow: 0 0 0 2px var(--gold), inset 0 0 0 2px var(--gold); }

.stamp__goal {
    position: absolute;
    top: -3px;
    right: -3px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gold);
}

.stamp__index { line-height: 1; }

/* --- Tooltip propio --------------------------------------------------------
   NO se usa el atributo title: el tema carga unitip, que engancha los title y
   los repinta con su propia caja (la que salia rota). Con data-tip el plugin
   no se entera y el globo es enteramente nuestro.                            */

.stamp[data-tip] { cursor: help; }

.stamp[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 20;
    padding: 7px 10px;
    border-radius: 7px;
    background: var(--bg-content);
    color: var(--text-primary);
    font-size: 0.72rem;
    font-weight: 500;
    line-height: 1.35;
    white-space: nowrap;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.12s ease;
    pointer-events: none;
}

.stamp[data-tip]:hover::after { opacity: 1; visibility: visible; }

/* Los de los extremos se pegan al borde para no salirse de la tarjeta. */
.stampweek__stamps .stamp:nth-child(-n+2)[data-tip]::after { left: 0; transform: none; }
.stampweek__stamps .stamp:nth-child(n+6)[data-tip]::after  { left: auto; right: 0; transform: none; }

/* --- Cartilla y ayuda en dos columnas -------------------------------------- */

.stampcard-layout {
    display: grid;
    grid-template-columns: minmax(450px, 1fr) minmax(50%, 450px);
    gap: 18px;
    align-items: start;
}

.stampcard-aside {
    padding: 16px 18px;
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

.stampcard-aside__title {
    margin: 0 0 10px;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--gold);
}

.stampcard-aside__title + .ticket-legend { margin-top: 0; }
.stampcard-aside .referral-rules { margin-bottom: 14px; font-size: 0.85rem; }
.stampcard-aside .referral-rules:last-child { margin-bottom: 0; }

/* Leyenda compacta: la muestra es pequena, no un sello a tamano real. */
.stampcard-aside .ticket-legend {
    display: grid;
    gap: 7px;
    margin-bottom: 18px;
    font-size: 0.82rem;
}

.ticket-legend__item { display: flex; align-items: center; gap: 9px; }

.ticket-legend .stamp {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    border-radius: 5px;
    font-size: 0;
}

.ticket-legend .stamp:hover { transform: none; }
/* "Por venir" es casi del color del fondo: se le marca el contorno. */
.ticket-legend .stamp--future { box-shadow: inset 0 0 0 1px var(--text-muted); opacity: 0.7; }

/* Aviso dentro de un bloque de reglas (tope de protectores, etc). */
.referral-rules--warn {
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--bg-surface);
    box-shadow: inset 3px 0 0 var(--text-notice);
}

@media (max-width: 1100px) {
    .stampcard-layout { grid-template-columns: minmax(0, 1fr); }
    .stampcard-aside .ticket-legend { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
    .stampweek { grid-template-columns: minmax(0, 1fr); gap: 8px; }
    .stampweek__label { justify-self: start; min-width: 128px; }
    .stampcard-aside .ticket-legend { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   Invitaciones y referidos en una sola tabla  ·  necROmantic 2026-07-29
   Antes eran dos tablas con las mismas personas repetidas. Ahora cada fila es
   una invitacion y arrastra, si fue usada, el progreso del invitado.
   ========================================================================== */

.invites-table td { vertical-align: middle; }

.invites-code {
    display: block;
    font-family: monospace;
    font-size: 0.95rem;
    letter-spacing: 0.06em;
    color: var(--text-label-strong);
}

.invites-sub {
    display: block;
    margin-top: 3px;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.invites-pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--bg-content);
}

.invites-pill--used    { background: var(--text-muted); }
.invites-pill--open    { background: var(--gold); }
.invites-pill--expired { background: var(--bg-input); color: var(--text-muted); }
.invites-pill--valid   { background: var(--text-success); }
.invites-pill--pending { background: var(--text-notice); }

/* necROmantic 2026-08-03: el permanente (90+ o renacido) no es lo mismo que el
   activo -no tiene cuenta atras-, y se distingue con su propio color.

   OJO: aqui NO se puede usar --lvl-accent. Ese token no esta en :root, esta
   declarado dentro del bloque .lvl (la seccion de nivel de jugador), y esta tabla
   cuelga de otro sitio: la variable no resolvia, el degradado entero quedaba
   invalido y la pastilla salia SIN FONDO mientras las demas si lo tenian. Se usan
   dos tokens globales de la paleta. */
.invites-pill--perm {
    background: linear-gradient(135deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
}

/* Insignia Gold: racha de una semana o mas, vale el doble. */
.invites-gold {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 6px;
    padding: 3px 9px 3px 7px;
    border: 1px solid var(--rb-gold-glow);
    border-radius: 999px;
    background: linear-gradient(135deg, var(--rb-gold-soft), transparent);
    box-shadow: 0 0 14px var(--rb-gold-soft);
    vertical-align: middle;
}

.invites-gold i    { font-size: 0.72rem; color: var(--rb-gold); }
.invites-gold b    { font-size: 0.66rem; font-weight: 800; letter-spacing: 0.1em; color: var(--rb-gold); }
.invites-gold em   { font-style: normal; font-size: 0.72rem; font-weight: 700; color: var(--text-heading2); }

/* Progreso del invitado hacia el nivel que se le exige. */
.invites-progress { display: block; min-width: 140px; }

.invites-progress__bar {
    display: block;
    height: 6px;
    border-radius: 999px;
    background: var(--bg-input);
    overflow: hidden;
}

.invites-progress__fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--accent-purple);
    transition: width 0.3s ease;
}

.invites-progress__fill.is-done { background: var(--text-success); }

/* ==========================================================================
   Tablas a ancho completo y centradas  ·  necROmantic 2026-07-29
   Invitaciones, personajes y objetos del almacen.
   ========================================================================== */

table.vertical-table.invites-table {
    width: 100%;
}

table.vertical-table.invites-table th,
table.vertical-table.invites-table td,
table.vertical-table.chars-table th,
table.vertical-table.chars-table td,
table.vertical-table.storage-table th,
table.vertical-table.storage-table td {
    text-align: center;
    vertical-align: middle;
}

/* Los bloques de dentro (codigo, pastillas, barras) tienen que centrarse ellos
   tambien: text-align no alinea un elemento de bloque. */
table.vertical-table.invites-table .invites-progress {
    margin: 0 auto;
}

table.vertical-table.chars-table img,
table.vertical-table.storage-table img {
    display: inline-block;
    vertical-align: middle;
}

/* ==========================================================================
   Guia de invitaciones  ·  necROmantic 2026-07-29
   Cuatro pasos numerados + la advertencia de que la validez se recalcula.
   ========================================================================== */

.invite-guide {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin: 0 0 18px;
    padding: 18px 20px;
    border-radius: 12px;
    background: var(--bg-surface);
}

.invite-guide__step {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 12px;
    align-items: start;
}

.invite-guide__num {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--gold);
    color: var(--bg-content);
    font-weight: 700;
    font-size: 0.86rem;
}

.invite-guide__title {
    margin: 3px 0 5px;
    font-size: 0.92rem;
    color: var(--text-label-strong);
}

.invite-guide__step p {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.invite-guide__note {
    grid-column: 1 / -1;
    margin: 4px 0 0;
    padding: 11px 14px;
    border-radius: 8px;
    background: var(--bg-surface-alt);
    box-shadow: inset 3px 0 0 var(--text-notice);
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--text-muted);
}

@media (max-width: 820px) {
    .invite-guide { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   Pagina de descargas  ·  necROmantic 2026-07-29
   Acordeones nativos (details/summary, sin JS) en dos columnas en pantallas
   grandes y una sola por debajo de 900px.
   ========================================================================== */

.dl-hero {
    margin-bottom: 22px;
    padding: 22px 24px;
    border-radius: 14px;
    background: var(--bg-surface);
    text-align: center;
}

.dl-hero__lead {
    max-width: 70ch;
    margin: 0 auto 16px;
    line-height: 1.65;
    color: var(--text-muted);
}

/* necROmantic 2026-07-29: se limita el ancho para que el boton y su linea de detalle no se
   estiren a lo largo de toda la pagina de descargas. */
p.dl-hero__cta {
    margin: 0;
    max-width: 70ch;
}

.dl-hero__meta {
    display: block;
    margin-top: 6px;
    font-size: 0.8rem;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.dl-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    align-items: start;
}

.dl-card {
    border-radius: 12px;
    background: var(--bg-surface);
    overflow: hidden;
    transition: background 0.18s ease, box-shadow 0.18s ease;
}

.dl-card[open] {
    background: var(--bg-surface-alt);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
}

.dl-card__head {
    display: grid;
    grid-template-columns: 38px minmax(0, 1fr) 16px;
    align-items: center;
    gap: 14px;
    padding: 16px 18px;
    cursor: pointer;
    list-style: none;
}

.dl-card__head::-webkit-details-marker { display: none; }

/* Flecha propia, en la tercera columna. */
.dl-card__head::after {
    content: "";
    width: 9px;
    height: 9px;
    border-right: 2px solid var(--gold);
    border-bottom: 2px solid var(--gold);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform 0.2s ease;
}

.dl-card[open] .dl-card__head::after {
    transform: rotate(-135deg) translate(-3px, -3px);
}

.dl-card__icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background-color: var(--gold);
    -webkit-mask: var(--dl-icon) center / 20px no-repeat;
            mask: var(--dl-icon) center / 20px no-repeat;
}

.dl-card__icon--install { --dl-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v11'/%3E%3Cpath d='M7.5 10.5 12 15l4.5-4.5'/%3E%3Cpath d='M4 18.5h16'/%3E%3C/svg%3E"); }
.dl-card__icon--shield  { --dl-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l7 3v6c0 4-3 7-7 9-4-2-7-5-7-9V6z'/%3E%3Cpath d='M9.5 12l1.8 1.8 3.4-3.6'/%3E%3C/svg%3E"); }
.dl-card__icon--wrench  { --dl-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 4.5a4.5 4.5 0 0 0-5.9 5.6L4 15.3V20h4.7l5.2-5.2a4.5 4.5 0 0 0 5.6-5.9l-2.7 2.7-2.8-.7-.7-2.8z'/%3E%3C/svg%3E"); }
.dl-card__icon--display { --dl-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='12' rx='1.6'/%3E%3Cpath d='M9 20h6'/%3E%3Cpath d='M12 16.5V20'/%3E%3C/svg%3E"); }

.dl-card__titles { min-width: 0; }

.dl-card__title {
    display: block;
    font-weight: 700;
    color: var(--text-label-strong);
}

.dl-card__sub {
    display: block;
    margin-top: 2px;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.dl-card__body {
    padding: 0 18px 18px 70px;
    font-size: 0.9rem;
    line-height: 1.7;
    color: var(--text-muted);
}

.dl-card__body > p:first-child { margin-top: 0; }

.dl-steps {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: dlstep;
}

.dl-steps li {
    position: relative;
    counter-increment: dlstep;
    padding: 0 0 12px 30px;
}

.dl-steps li::before {
    content: counter(dlstep);
    position: absolute;
    top: 1px;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--bg-input);
    color: var(--gold);
    font-size: 0.72rem;
    font-weight: 700;
}

.dl-steps li:last-child { padding-bottom: 0; }

.dl-defs { margin: 0; }

.dl-defs dt {
    margin-top: 12px;
    font-weight: 700;
    color: var(--text-label-strong);
}

.dl-defs dt:first-child { margin-top: 0; }
.dl-defs dd { margin: 3px 0 0; }

.dl-card__body code {
    padding: 2px 6px;
    border-radius: 5px;
    background: var(--bg-input);
    color: var(--text-code-strong);
    font-size: 0.86em;
}

@media (max-width: 900px) {
    .dl-grid { grid-template-columns: minmax(0, 1fr); }
    .dl-card__body { padding-left: 18px; }
}

/* necROmantic 2026-07-29: el bloque de estado de sesion se retira de todas las
   paginas. El aviso "Has iniciado sesion como X" ya se quito de la plantilla
   (themes/necromantic/main/loginbox.php); esto oculta el contenedor entero. */
#loginbox {
    display: none;
}

/* necROmantic 2026-07-29: el bloque de titulos de cada acordeon de descargas,
   resaltado sobre su propio fondo. Se declara como span.dl-card__titles para
   ganar en especificidad a la regla generica .dl-card__titles de mas arriba. */
span.dl-card__titles {
    padding: 5px;
    background-color: #241a44;
    border-radius: 5px;
    margin-top: 4px !important;
    display: inline-block;
    cursor: pointer;
}

/* ==========================================================================
   Portada: recompensas por constancia y por invitar  ·  necROmantic 2026-07-29
   Dos tarjetas con su escalera de hitos, y debajo las ventajas del nivel.
   ========================================================================== */

.rewards-head { text-align: center; margin-bottom: 26px; }

.rewards-kicker {
    display: inline-block;
    margin-bottom: 10px;
    font-size: 0.74rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--gold);
}

.rewards-title { margin: 0 0 12px; }

.rewards-lead {
    max-width: 66ch;
    margin: 0 auto;
    line-height: 1.7;
    color: var(--text-muted);
}

.rewards-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
    margin-bottom: 22px;
}

.reward-card {
    position: relative;
    padding: 26px 24px 22px;
    border-radius: 14px;
    background: var(--bg-surface);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.26);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.reward-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 16px 38px rgba(0, 0, 0, 0.34);
}

.reward-card__icon {
    display: block;
    width: 42px;
    height: 42px;
    margin-bottom: 14px;
    background-color: var(--gold);
    -webkit-mask: var(--rw-icon) center / contain no-repeat;
            mask: var(--rw-icon) center / contain no-repeat;
}

.reward-card__icon--daily  { --rw-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.2' y='5' width='17.6' height='16' rx='2'/%3E%3Cpath d='M8 3v4M16 3v4M3.2 10h17.6'/%3E%3Cpath d='M9 15.5l2 2 4-4'/%3E%3C/svg%3E"); }
.reward-card__icon--invite { --rw-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='8' r='3.4'/%3E%3Cpath d='M3 20a6 6 0 0 1 12 0'/%3E%3Cpath d='M18 7.5v6M15 10.5h6'/%3E%3C/svg%3E"); }

.reward-card__title { margin: 0 0 10px; font-size: 1.12rem; }

.reward-card__text {
    margin: 0 0 16px;
    line-height: 1.65;
    color: var(--text-muted);
}

.reward-ladder {
    margin: 0 0 16px;
    padding: 0;
    list-style: none;
}

.reward-ladder li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
    font-size: 0.88rem;
}

.reward-ladder li + li { box-shadow: inset 0 1px 0 var(--alpha-silver-10); }

.reward-ladder__when { color: var(--text-muted); }

.reward-ladder__what {
    flex: 0 0 auto;
    font-weight: 700;
    color: var(--gold);
}

.reward-card__foot {
    margin: 0;
    padding-top: 14px;
    font-size: 0.84rem;
    line-height: 1.6;
    color: var(--text-muted);
    box-shadow: inset 0 1px 0 var(--alpha-silver-10);
}

.rewards-perks {
    padding: 22px 24px;
    border-radius: 14px;
    background: var(--bg-surface-alt);
    text-align: center;
}

.rewards-perks__title {
    margin: 0 0 16px;
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--gold);
}

.rewards-perks__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
}

.rewards-perk {
    display: grid;
    gap: 5px;
    padding: 16px 14px;
    border-radius: 10px;
    background: var(--bg-surface);
}

.rewards-perk__value {
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--gold);
}

.rewards-perk__label {
    font-size: 0.83rem;
    line-height: 1.45;
    color: var(--text-muted);
}

@media (max-width: 900px) {
    .rewards-grid { grid-template-columns: minmax(0, 1fr); }
    .rewards-perks__grid { grid-template-columns: minmax(0, 1fr); }
}

/* necROmantic 2026-07-29: las noticias largas no estiran el carrusel de la
   portada; cada diapositiva se limita en alto y hace scroll por dentro. */
article.news-slide {
    max-height: min(560px, 100vh);
    overflow-y: scroll;
}

/* necROmantic 2026-07-29: cuerpo de la tarjeta de noticia, con tope de alto y
   scroll propio para que una noticia larga no descuadre la rejilla. */
.news-card__body {
    font-size: 9pt;
    color: var(--text-primary);
    line-height: 1.55;
    max-height: min(660px, 100vh);
    overflow-y: scroll;
}

/* necROmantic 2026-07-29: contador de referidos de segundo nivel. */
.referral-second {
    margin: 6px 0 0;
    padding: 8px 12px;
    border-radius: 8px;
    background: var(--bg-surface-alt);
    font-size: 0.84rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.referral-second__num {
    font-weight: 700;
    color: var(--gold);
}

/* necROmantic 2026-07-29: el listado de objetos del almacen, a ancho completo. */
table.vertical-table.storage-table {
    width: 100%;
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-29 — Etiqueta de la invitacion
   El servidor es privado y se entra presentado por alguien. El mismo
   mensaje aparece en cuatro sitios con cuatro tonos: consejo aqui,
   recordatorio en el alta, condicion en el aviso legal y conducta
   sancionable en el codigo de conducta.
   ══════════════════════════════════════════════════════════════ */
.invite-etiquette {
    position: relative;
    margin: 0 0 18px;
    /* El hueco de la derecha es el que ocupa Ebel: ver .mob-aside--ebel. */
    padding: 18px 186px 18px 20px;
    border-radius: 12px;
    background: var(--bg-surface);
}

/* --------------------------------------------------------------------------------------
   Zona de peligro: la eliminacion completa de la cuenta (2026-08-04).

   Sale de la tabla de privacidad porque no es un dato mas: es un formulario irreversible con
   su boton rojo y su lista de bloqueos. A ancho completo, con el borde en el tono de aviso y
   una franja a la izquierda -- el mismo recurso que ya usa .invite-etiquette__warn -- para que
   se lea distinto de las tarjetas de al lado sin gritar.
   -------------------------------------------------------------------------------------- */
.danger-zone {
    margin: 0 0 22px;
    padding: 16px 20px 18px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--aq-ember, #b4453a);
    border-radius: 12px;
    background:
        radial-gradient(120% 200% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        var(--bg-surface);
}

.danger-zone__title {
    margin: 0 0 10px;
    font-size: 0.92rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--text-label-strong);
}

.danger-zone__body > small,
.danger-zone__body > strong { display: block; }

.danger-zone__body small {
    display: block;
    margin-bottom: 10px;
    line-height: 1.55;
    color: var(--text-muted);
}

/* El formulario ya no esta dentro de una celda estrecha, asi que el boton puede respirar. */
.danger-zone .privacy-form { margin: 0; }

.danger-zone .privacy-blockers { margin-top: 12px; }

/* --------------------------------------------------------------------------------------
   Sprites de acompanamiento a la derecha de un bloque de texto (2026-08-04). Mismo patron
   que .aq__mascot y por el mismo motivo: posicion absoluta, asi el texto no se mueve ni un
   pixel si algun dia se cambia el sprite o se quita. El hueco lo abre el padding del
   contenedor, que es lo unico que estos bloques le piden.
   -------------------------------------------------------------------------------------- */
.mob-aside {
    position: absolute;
    right: 14px;
    bottom: 10px;
    margin: 0;
    line-height: 0;
    pointer-events: none;
    opacity: 0.96;
    filter: drop-shadow(0 6px 14px var(--alpha-black-28));
}

.mob-aside img {
    display: block;
    width: 100%;
    height: auto;
    /* Arte por pixeles: el suavizado de las pantallas densas lo emborrona. */
    image-rendering: pixelated;
}

.mob-aside--ebel   { width: 158px; }

/* Solo la fila del correo se estrecha: es la unica que convive con Papila. Las de abajo
   -- descarga de datos y la zona de peligro -- ocupan el ancho entero. */
table.vertical-table.privacy-table tr.privacy-row--aside { position: relative; }
table.vertical-table.privacy-table tr.privacy-row--aside td { padding-right: 140px; }

/* Va pegada al borde derecho de SU fila, y medida para caber dentro de ella: cualquier cosa
   mas alta se derramaria sobre la fila siguiente, que es justo lo que se queria evitar. */
.mob-aside--papila {
    width: 118px;
    top: 50%;
    right: 10px;
    bottom: auto;
    transform: translateY(-50%);
}

/* Estrechos: antes que estrujar el texto contra el sprite, se retira y se recupera el ancho. */
@media (max-width: 860px) {
    .mob-aside { display: none; }
    .invite-etiquette { padding-right: 20px; }
    table.vertical-table.privacy-table tr.privacy-row--aside td { padding-right: 12px; }
}

.invite-etiquette__title {
    margin: 0 0 8px;
    font-size: 0.92rem;
    color: var(--text-label-strong);
}

.invite-etiquette p {
    margin: 0 0 10px;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.invite-etiquette p:last-child { margin-bottom: 0; }

/* La consecuencia va destacada: es la unica frase con sancion concreta. */
.invite-etiquette__warn {
    padding: 11px 14px;
    border-radius: 8px;
    background: var(--bg-surface-alt);
    box-shadow: inset 3px 0 0 var(--accent-red-h);
    color: var(--text-notice) !important;
}

/* Nota bajo un campo del formulario de alta. */
.field-hint {
    margin: 8px 0 0;
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--bg-surface-alt);
    box-shadow: inset 3px 0 0 var(--gold);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--text-muted);
}

/* necROmantic 2026-07-29 — Ficha de cuenta a dos columnas
   La tabla de datos de la cuenta pasa de una pareja etiqueta/valor por fila a DOS. Sin
   anchos fijos las cuatro columnas se reparten segun el contenido y quedan desiguales,
   asi que se fijan aqui: las etiquetas estrechas y los valores repartiendose el resto. */
table.vertical-table.account-summary { width: 100%; table-layout: fixed; }
table.vertical-table.account-summary th { width: 18%; }
table.vertical-table.account-summary td { width: 32%; word-break: break-word; }

/* En pantallas estrechas no caben cuatro columnas: cada pareja vuelve a su propia linea. */
@media (max-width: 720px) {
    table.vertical-table.account-summary,
    table.vertical-table.account-summary tbody,
    table.vertical-table.account-summary tr { display: block; width: 100%; }
    table.vertical-table.account-summary th,
    table.vertical-table.account-summary td { display: block; width: auto; text-align: left; }
}

/* necROmantic 2026-07-29 — Estado del servidor cuando no hay nadie conectado.
   El aro que normalmente lleva el numero pasa a llevar un icono, y el texto explica
   por que estar vacio no significa lo mismo aqui que en un servidor grande. */
.status-players__ring--quiet {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 1.6rem;
}
.status-players--quiet .status-players__label span {
    display: block;
    max-width: 42ch;
    line-height: 1.5;
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-29 — Resumen del código de conducta
   El código completo son 9 apartados y 60+ puntos con el mismo peso visual.
   Este bloque va delante y concentra lo que de verdad expulsa a alguien, con
   jerarquía real: número grande, frase corta en negrita, matiz detrás.
   ══════════════════════════════════════════════════════════════ */
.conduct-tldr {
    margin: 0 0 26px;
    padding: 24px 28px;
    border-radius: 18px;
    background: var(--bg-surface);
    box-shadow: var(--shadow-card);
}

.conduct-tldr__title {
    margin: 0 0 16px;
    font-family: var(--font-display, inherit);
    font-size: 1.05rem;
    color: var(--gold);
}

.conduct-tldr__list {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: tldr;
    display: grid;
    gap: 12px;
}

/* OJO: aqui NO se puede usar display:grid en el <li>. Cada hijo -incluidos los nodos de
   texto sueltos entre <strong> y el resto de la frase- se convierte en un item de la
   rejilla, y la frase acaba partida palabra a palabra en columnas de 34px. El numero va
   en posicion absoluta y el texto se queda en flujo normal. */
.conduct-tldr__list li {
    counter-increment: tldr;
    position: relative;
    padding-left: 48px;
    min-height: 34px;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.conduct-tldr__list li::before {
    content: counter(tldr);
    position: absolute;
    left: 0;
    top: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--alpha-gold-12, rgba(255, 200, 90, 0.12));
    color: var(--gold);
    font-weight: 700;
    font-size: 0.95rem;
}

.conduct-tldr__list li strong { color: var(--text-label-strong); }

.conduct-tldr__foot {
    margin: 18px 0 0;
    padding-top: 14px;
    box-shadow: inset 0 1px 0 var(--alpha-white-05, rgba(255,255,255,0.06));
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--text-muted);
}

@media (max-width: 640px) {
    .conduct-tldr { padding: 18px 18px; }
    .conduct-tldr__list li { padding-left: 40px; }
    .conduct-tldr__list li::before { width: 28px; height: 28px; font-size: 0.85rem; }
}

/* necROmantic 2026-07-29 — Subtítulos dentro de los apartados legales.
   Los apartados 1 y 3 tenían 11 y 12 puntos seguidos, todos con el mismo peso visual:
   un muro donde nadie encuentra nada. Estos subtítulos los agrupan por tema. */
.legal-subhead {
    margin: 18px 0 8px;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gold);
}
.legal-subhead:first-of-type { margin-top: 12px; }
.legal-card .legal-list + .legal-subhead { margin-top: 20px; }

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-30 — Sellos de la cartilla: colores de verdad
   ══════════════════════════════════════════════════════════════
   Antes los rellenos usaban tokens de TEXTO (--text-success #d9eee6,
   --text-error #f5d6e0): pasteles casi blancos que como fondo no se
   distinguian entre si. Aqui van colores saturados y propios.

   Y el rojo queda SOLO para el fallo confirmado. Antes 'empty' -un dia
   pasado sin registro- compartia el mismo rojo, asi que la cartilla se
   veia mucho peor de lo que era. 'empty' pasa a un gris de aviso: no ha
   fichado, pero el sistema aun no lo ha dado por perdido.
   ══════════════════════════════════════════════════════════════ */
:root {
    --stamp-green:  #29a35f;   /* cubierta        */
    --stamp-blue:   #3b7fe0;   /* protegida       */
    --stamp-red:    #d32f2f;   /* fallada  <- el unico rojo */
    --stamp-amber:  #e8971a;   /* hoy, en curso   */
    --stamp-idle:   #4b3f6b;   /* sin fichar aun  */
    --stamp-void:   #241a44;   /* por venir       */
    --stamp-goal:   #ffd166;   /* objetivo de nivel */
    --stamp-ink:    #10061c;   /* texto sobre relleno claro */
}

.stamp--green   { background: var(--stamp-green);  color: #ffffff; opacity: 1; }
.stamp--blue    { background: var(--stamp-blue);   color: #ffffff; opacity: 1; }
.stamp--red     { background: var(--stamp-red);    color: #ffffff; opacity: 1; }
.stamp--pending { background: var(--stamp-amber);  color: var(--stamp-ink); opacity: 1; }

/* Sin fichar: gris violaceo con borde marcado. Se lee como "pendiente",
   no como "has fallado". */
.stamp--empty {
    background: var(--stamp-idle);
    color: #d8cfe8;
    opacity: 1;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}

/* Por venir: hueco de verdad, sin color. */
.stamp--future {
    background: var(--stamp-void);
    color: var(--text-muted);
    opacity: 1;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.10);
}

/* ── Hoy y objetivo: dos marcas que tienen que distinguirse entre si ──
   Antes las dos eran del mismo color dorado, una por fuera y otra por
   dentro, asi que sobre un relleno claro no se apreciaba ninguna.
   Ahora: HOY = anillo exterior blanco. OBJETIVO = anillo interior ambar
   grueso + punto en la esquina, que se ve encima de cualquier relleno. */
.stamp--today {
    box-shadow: 0 0 0 2px #ffffff, 0 0 10px rgba(255, 255, 255, 0.35);
    z-index: 2;
}

.stamp--goal {
    box-shadow: inset 0 0 0 3px var(--stamp-goal);
}
.stamp--goal::after {
    content: "";
    position: absolute;
    top: 3px;
    right: 3px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--stamp-goal);
    box-shadow: 0 0 4px var(--stamp-goal);
}

.stamp--today.stamp--goal {
    box-shadow: inset 0 0 0 3px var(--stamp-goal), 0 0 0 2px #ffffff, 0 0 10px rgba(255,255,255,0.35);
}

/* En la leyenda la muestra es diminuta: el anillo del objetivo se afina un
   poco para que no se coma la casilla, y se mantiene el punto. */
.ticket-legend .stamp--future {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
    opacity: 1;
}
.ticket-legend .stamp--goal {
    box-shadow: inset 0 0 0 2px var(--stamp-goal);
}
.ticket-legend .stamp--goal::after { top: 2px; right: 2px; width: 4px; height: 4px; }

/* ── Sobre mi ───────────────────────────────────────────────────
   La pagina reutiliza .about-hero/.about-kicker/.about-title/.about-intro
   (agrupados arriba con .legal-*) y las tarjetas .legal-card. Aqui solo va
   lo propio: la tira de datos del encabezado y la nota de cierre.
   Sin bordes, como el resto del sitio: separan fondo y sombra.          */

/* El encabezado ocupa el ancho del panel, asi que la entradilla puede respirar mas que
   la de una pagina legal (74ch) sin quedarse en una columna estrecha con medio hueco. */
.about-intro { max-width: 92ch; }

/* Tarjetas cortas a ancho completo, fuera de .legal-grid. */
.about-card-wide { margin-bottom: 18px; }
.legal-grid + .about-card-wide { margin-top: 18px; margin-bottom: 0; }

/* Lista de cierre: al ir a ancho completo, dos columnas evitan renglones larguisimos. */
.legal-list--pairs {
    columns: 2;
    column-gap: 32px;
}

.legal-list--pairs li { break-inside: avoid; }

/* Mismo corte que .legal-grid (980px): en estrecho, una sola columna. */
@media (max-width: 980px) {
    .legal-list--pairs { columns: 1; }
}

/* Tarjeta "yo tambien juego aqui": el sprite de Aurel va flotado y el texto le rodea
   la silueta, no el recuadro. El titular queda fuera de este bloque, a ancho completo.
   Como el sprite puede ser mas alto que el texto, hace falta cerrar el flotado para
   que la tarjeta no se quede corta. */
/* ── Sprites del cliente sueltos por la web ─────────────────────────
   Piezas animadas sacadas con tools/render_char.py del cliente. Reglas comunes
   a todas: tamaño natural del render (son pixel art, cualquier escalado no
   entero las emborrona) y `pixelated` para las pantallas de alta densidad,
   donde el navegador las amplia. La animacion es un webp; el <picture> sirve un
   PNG del primer marco a quien pide prefers-reduced-motion, porque un webp
   animado no se puede parar desde CSS.                                     */
.feature-card__sprite img,
.na-sprite img,
.rewards-head__sprite img,
.dl-hero__sprite img,
.about-widget__mob img,
.battle-config-hero__sprite img,
.register-hero__sprite img,
.about-play__sprite img,
.lgn-hero__sprite img {
    display: block;
    image-rendering: pixelated;
}

/* Ficha de portada con bicho: dos columnas, con el sprite centrado en vertical
   frente al icono, el titular y el texto juntos. */
.feature-card--sprite {
    display: flex;
    align-items: center;
    gap: 18px;
}

.feature-card__body { min-width: 0; }

.feature-card__sprite {
    display: block;
    flex: 0 0 auto;
    width: 98px;
    height: 106px;
}

@media (max-width: 720px) {
    .feature-card--sprite { flex-direction: column; gap: 12px; }
}

/* Fila de contenido editorial (componente .na, o sea HTML guardado en la BD) con
   un sprite al lado. El sprite se centra en vertical frente a todo el bloque de
   texto, que puede llevar varias columnas .na-col apiladas. */
.na-sprite-row {
    display: flex;
    align-items: center;
    gap: 22px;
}

.na-sprite-row__text { min-width: 0; flex: 1 1 auto; }

.na-sprite {
    display: block;
    flex: 0 0 auto;
}

/* Randgris es un sprite de jefe y mide bastante mas que un personaje. Ancho fijo
   a proposito: encogerlo con un porcentaje daria una escala no entera y el pixel
   art sale con pixeles de distinto tamaño. Lo que se hace en estrecho es bajarlo
   debajo del texto, no reducirlo. */
.na-sprite--randgris {
    width: 356px;
    height: 300px;
}

@media (max-width: 860px) {
    .na-sprite-row { flex-direction: column; }
    .na-sprite--randgris { margin: 0 auto; }
}

/* Fila de bichos dentro de una noticia: tres columnas iguales, los tres dibujos
   a la MISMA altura y apoyados en la misma linea de suelo (`align-items: end`).
   Los lienzos vienen de tamaños muy distintos (el mandoble del Raydric ocupa el
   doble que la Drosera), asi que la altura comun la fija el CSS y la escala de
   cada render se elige para que el navegador solo tenga que AMPLIAR: reducir
   pixel art tira filas enteras y se pierden detalles, ampliar solo deja los
   pixeles de tamaño desigual. Con NA_MOBS_H = 204px: Kobold Archer a escala 3
   (204 px, exacto), Drosera a escala 2 (174 -> x1.17) y Raydric a escala 1
   (168 -> x1.21). Si se cambia esa altura hay que rehacer la cuenta. */
.na-mobs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    align-items: end;
    justify-items: center;
    gap: 26px;
    margin: 22px 0 8px;
}

.na-mob {
    min-width: 0;
    max-width: 100%;
    text-align: center;
}

/* `display: block` explicito en el <picture>: es inline de suyo, y envolver una
   imagen en bloque con una caja inline descuadra la linea. */
.na-mob picture { display: block; }

/* Doble clase a proposito: el carrusel de portada trae
   `.news-slide__body img { height: auto }` en modern.css, que se carga DESPUES
   de esta hoja y con la misma especificidad (0,1,1) le ganaria la altura fija.
   Con `.na .na-mob img` (0,2,1) mandamos nosotros. Lo mismo en .na-figure. */
.na .na-mob img {
    display: block;
    margin: 0 auto 10px;
    height: 204px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
    object-position: bottom center;
    image-rendering: pixelated;
}

.na-mob__name {
    display: block;
    color: var(--text-heading2);
    font-weight: 700;
}

.na-mob__meta {
    display: block;
    color: var(--text-muted);
    font-size: 0.88em;
}

/* Por debajo de ~820px las tres columnas ya no caben (la mas ancha es la del
   Raydric, 242px a la altura comun) y los dibujos empezarian a encogerse dentro
   de su hueco, con lo que dejarian de medir lo mismo. Antes que eso, uno por
   fila: la altura se mantiene. */
@media (max-width: 820px) {
    .na-mobs {
        grid-template-columns: 1fr;
        gap: 18px;
    }
}

/* Ilustracion a lo ancho con su pie. Nada de <figure>/<figcaption>: la salida
   pasa por tidy (OutputCleanHTML) y no esta comprobado que los respete, asi que
   se compone con div + p, que si sobreviven seguro. */
.na-figure {
    margin: 22px 0 18px;
    text-align: center;
}

.na .na-figure img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0 auto;
    border-radius: 12px;
}

.na-figure__cap {
    margin: 10px auto 0;
    max-width: 62ch;
    color: var(--text-muted);
    font-size: 0.92em;
}

/* Ktullanux en el widget de portada. El widget ya es un flex centrado, asi que
   el bicho solo necesita no encogerse; queda entre la marca y el texto. */
.about-widget__mob {
    display: block;
    flex: 0 0 auto;
    width: 304px;
    height: 348px;
}

/* Encabezado de las paginas de transparencia con bicho al lado. Mismo criterio
   que en el resto: columna, no rodeo, porque el intro es un parrafo ancho. */
.battle-config-hero--sprite {
    display: flex;
    align-items: center;
    gap: 24px;
}

.battle-config-hero__text { min-width: 0; flex: 1 1 auto; }

.battle-config-hero__sprite {
    display: block;
    flex: 0 0 auto;
}

/* Las tres paginas de transparencia comparten altura y cada bicho se queda con
   el ancho que le toque. Es la unica escala no entera del sitio, y por eso los
   ficheros estan elegidos para que el navegador siempre AMPLIE, nunca reduzca:
   ampliando con pixelated los pixeles quedan de tamaño desigual pero no se
   pierde nada, mientras que reduciendo se tiran filas enteras y los detalles
   finos (las cadenas de Atroce) desaparecen. Por eso Atroce se exporta a escala
   1 y los otros dos a escala 2: asi los tres factores son mayores que 1. */
.battle-config-hero__sprite img {
    height: 220px;
    width: auto;
}

/* Encabezado de la pagina de alta, mismo patron. Aqui el sprite si va a escala
   entera: es el unico y no tiene que igualar altura con nada. */
.register-hero--sprite {
    display: flex;
    align-items: center;
    gap: 24px;
}

.register-hero__text { min-width: 0; flex: 1 1 auto; }

.register-hero__sprite {
    display: block;
    flex: 0 0 auto;
    width: 152px;
    height: 110px;
}

/* En estrecho todos los bichos bajan debajo del texto en vez de reducirse. */
@media (max-width: 860px) {
    .battle-config-hero--sprite,
    .register-hero--sprite { flex-direction: column; }

    .battle-config-hero__sprite,
    .register-hero__sprite { margin: 0 auto; }
}

@media (max-width: 720px) {
    .about-widget__mob { margin: 0 auto; }
}

/* Papryka en el bloque de recompensas: fila de dos columnas centrada como
   conjunto, para no descuadrar un encabezado que va centrado. */
.rewards-head--sprite {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 26px;
}

.rewards-head__text { min-width: 0; }

.rewards-head__sprite {
    display: block;
    flex: 0 0 auto;
    width: 102px;
    height: 168px;
}

@media (max-width: 720px) {
    .rewards-head--sprite { flex-direction: column; gap: 14px; }
}

/* Deathbringer andando junto al bloque de descarga, mismo criterio que Papryka:
   el hero va centrado, asi que el sprite es una segunda columna y no un flotado. */
.dl-hero--sprite {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 26px;
    text-align: left;
}

.dl-hero__text { min-width: 0; }

/* El lead y el pie del hero van centrados dentro de su columna cuando esta solo;
   con sprite al lado, alineados a la izquierda leen mejor contra el dibujo. */
.dl-hero--sprite .dl-hero__lead,
.dl-hero--sprite .dl-hero__cta { margin-left: 0; }

/* Dos personajes, uno a cada lado del texto: Eutanasia (la sacerdotisa de
   Papryka) andando hacia la derecha y Deathbringer hacia la izquierda, o sea las
   dos mirando al bloque de descarga. Mismo paso y misma escala.
   Eutanasia va exportada con --sin-capa y --sin-tocado medio superior a
   proposito: la capa (Wing of Eutaxy) ocupaba mas que ella, y de los tocados
   solo se queda la peluca de orejas de gato. Por eso mide 102 y no 164. */
.dl-hero__sprite {
    display: block;
    flex: 0 0 auto;
    width: 100px;
    height: 218px;
}

.dl-hero__sprite--izquierda {
    width: 102px;
    height: 222px;
}

@media (max-width: 720px) {
    .dl-hero--sprite { flex-direction: column; gap: 14px; text-align: center; }
    .dl-hero--sprite .dl-hero__lead { margin-left: auto; }
}

.about-play::after {
    content: "";
    display: block;
    clear: both;
}

/* shape-outside solo funciona sobre un flotado, y la forma sale de aurel-silueta.png,
   que es la union del alfa de los cuatro marcos: fija, asi que el texto no tiembla al
   cambiar de marco. El umbral deja fuera el halo mas tenue del tocado; el margen es
   para que las letras no lleguen a tocar el dibujo. */
.about-play__sprite {
    /* display block explicito: <picture> es inline de suyo, y al quitarle el flotado
       en movil volveria a serlo, ignorando el ancho y el margin auto que lo centran. */
    display: block;
    float: left;
    width: 144px;
    height: 204px;
    line-height: 0;
    shape-outside: url("/assets/personajes/aurel-silueta.png");
    shape-image-threshold: 0.4;
    shape-margin: 10px;
    margin-right: 4px;
}

/* Sin escalado: la imagen mide justo 144x204 (el render va a x2) y se sirve a tamano
   natural. image-rendering pixelated es para las pantallas de alta densidad, donde el
   navegador la amplia: sin el, el pixel art sale emborronado. */
.about-play__sprite img {
    display: block;
    width: 144px;
    height: 204px;
    image-rendering: pixelated;
}

/* Mismo corte que .legal-grid: cuando la tarjeta pasa a ancho completo de movil, el
   sprite se pone encima del texto y centrado. Ahi no se rodea nada: en una columna
   estrecha el texto rodeando la silueta queda en renglones de tres palabras. */
@media (max-width: 980px) {
    .about-play__sprite {
        float: none;
        shape-outside: none;
        margin: 0 auto 14px;
    }
}

.about-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 18px 0 0;
    padding: 0;
    list-style: none;
}

.about-fact {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 180px;
    padding: 10px 14px;
    border-radius: 16px;
    background: var(--alpha-gold-08);
    box-shadow: inset 0 1px 0 var(--alpha-white-05);
}

.about-fact__value {
    color: var(--gold);
    font-size: 11pt;
    font-weight: 700;
    letter-spacing: 0.2px;
}

.about-fact__label {
    color: var(--text-muted);
    font-size: 8.5pt;
}

/* Cierre del bloque de limites: mismo texto, un peso visual algo mayor que un
   parrafo normal para que no se lea como una coletilla. */
/* necROmantic 2026-07-30: la nota late, porque es lo que mas interesa que se lea
   de toda la pagina. Late el FONDO, nunca el texto: el color de la letra no se
   toca y el fondo solo va de --alpha-bronze-16 a --alpha-bronze-34, que sobre el
   panel son dos violetas translucidos muy proximos. Asi el contraste apenas se
   mueve y el texto se lee igual en cualquier momento del ciclo. Nada de animar
   opacidad ni filter: eso si se llevaria la letra por delante.
   9 segundos y ease-in-out para que respire y no parpadee. */
.about-note {
    margin: 16px 0 0;
    padding: 12px 16px;
    border-radius: 16px;
    background: var(--alpha-bronze-16);
    color: var(--text-panel-soft);
    box-shadow: inset 0 1px 0 var(--alpha-white-04);
    animation: about-note-latido 9s ease-in-out infinite;
}

@keyframes about-note-latido {
    0%, 100% {
        background-color: var(--alpha-bronze-16);
        box-shadow: inset 0 1px 0 var(--alpha-white-04);
    }
    50% {
        background-color: var(--alpha-bronze-34);
        box-shadow: inset 0 1px 0 var(--alpha-white-08);
    }
}

/* Quien pide menos movimiento se queda con la nota quieta y en el punto alto,
   que es el que mas destaca: pierde el latido, no el enfasis. */
@media (prefers-reduced-motion: reduce) {
    .about-note {
        animation: none;
        background: var(--alpha-bronze-34);
    }
}

/* ── Pie de version de los documentos legales ──────────────── */
/* necROmantic 2026-07-30: lo pinta service/legal_meta.php al final del aviso legal,
   privacidad, seguridad y codigo de conducta. Va fuera de .legal-grid a proposito:
   es un dato del documento entero, no una tarjeta mas, asi que no debe entrar en el
   reparto de columnas ni llevar la sombra de .legal-card. */
.legal-meta {
    margin: 26px auto 0;
    padding-top: 16px;
    max-width: 720px;
    border-top: 1px solid var(--border);
    text-align: center;
    font-size: 8pt;
    color: var(--text-muted);
}

.legal-meta__line {
    margin: 0 0 4px;
}

.legal-meta__label {
    color: var(--text-heading);
    letter-spacing: 0.4px;
    text-transform: uppercase;
}

.legal-meta__version {
    color: var(--gold);
    /* la cadena de version no se parte a mitad en pantallas estrechas */
    white-space: nowrap;
}

.legal-meta__note {
    margin: 10px 0 0;
    color: var(--text-code);
    line-height: 1.5;
}

/* necROmantic 2026-07-31: capturas dentro de las tarjetas de descargas.
   Las instrucciones de SmartScreen se entienden mucho mejor viendo el diálogo
   exacto, con el sitio donde hay que pulsar ya señalado en la imagen. */
/* necROmantic 2026-08-01: la captura pasa a ser una miniatura. Ocupaba media
   tarjeta y rompía la lectura de los pasos, cuando lo que hace falta es poder
   mirarla un momento y seguir leyendo. Al pasar por encima aparece la lupa y al
   pulsar se abre a pantalla completa (ver .dl-lightbox más abajo). */
.dl-shot {
    margin: 12px 0 0;
    max-width: 190px;
}

.dl-shot img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 8px;
    border: 1px solid var(--alpha-bronze-24);
}

/* El <picture> es el que recibe el clic y el foco: es el único elemento del
   grupo que admite pseudo-elementos (el <img> es reemplazado y no los pinta),
   así que el velo con la lupa cuelga de él. */
.dl-shot picture {
    position: relative;
    display: block;
    border-radius: 8px;
    overflow: hidden;
    cursor: zoom-in;
}

.dl-shot > img { cursor: zoom-in; }

.dl-shot picture::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--alpha-black-34);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f7f2ff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.4 15.4 20 20'/%3E%3Cpath d='M10.5 7.8v5.4'/%3E%3Cpath d='M7.8 10.5h5.4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 32px 32px;
    opacity: 0;
    transition: opacity 0.16s ease;
}

.dl-shot picture:hover::after,
.dl-shot picture:focus-visible::after {
    opacity: 1;
}

.dl-shot picture:focus-visible {
    outline: 2px solid var(--border-accent);
    outline-offset: 2px;
}

.dl-shot figcaption {
    margin-top: 6px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

/* Dos capturas seguidas: van una al lado de otra, porque son los dos pasos
   consecutivos del mismo diálogo. Con la miniatura pequeña caben juntas casi
   en cualquier ancho, así que se usa flex y no una rejilla que las estire. */
.dl-shots {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 12px;
}

.dl-shots .dl-shot { margin-top: 0; }

/* ── Visor a pantalla completa de las capturas ────────────────
   necROmantic 2026-08-01: lo monta modern.js al vuelo, no vive en el HTML de
   la página (que se guarda en la base de datos y conviene dejar limpio).
   La imagen se enseña a su tamaño real: sin ampliar, sin recortar y sin
   deformar. Sólo se encoge —manteniendo la proporción— si no cabe en la
   ventana, que es lo único que puede pasar en un móvil. */
.dl-lightbox {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(6, 4, 14, 0.78);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    /* Se cierra pulses donde pulses, también sobre la propia imagen. */
    cursor: zoom-out;
    opacity: 0;
    transition: opacity 0.18s ease;
}

.dl-lightbox[hidden] { display: none; }

.dl-lightbox.is-open { opacity: 1; }

.dl-lightbox__img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    border: 0;
    border-radius: 0;
}

.dl-lightbox__close {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--alpha-silver-24);
    border-radius: 50%;
    background: var(--alpha-black-34);
    color: var(--text-primary);
    cursor: pointer;
    transition: background-color 0.16s ease, border-color 0.16s ease;
}

.dl-lightbox__close:hover,
.dl-lightbox__close:focus-visible {
    background: var(--alpha-silver-16);
    border-color: var(--border-accent);
}

.dl-lightbox__close::before,
.dl-lightbox__close::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 18px;
    height: 2px;
    margin: -1px 0 0 -9px;
    border-radius: 2px;
    background: currentColor;
}

.dl-lightbox__close::before { transform: rotate(45deg); }
.dl-lightbox__close::after  { transform: rotate(-45deg); }

/* Con el visor abierto la página de detrás no se desplaza. */
.dl-lightbox-open,
.dl-lightbox-open body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
    .dl-lightbox,
    .dl-shot picture::after { transition: none; }
}

/* Aviso destacado dentro de una tarjeta (lo que NO hay que hacer). */
.dl-note {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-left: 3px solid var(--accent-red);
    border-radius: 0 6px 6px 0;
    background: var(--alpha-black-18);
}

.dl-note > :first-child { margin-top: 0; }
.dl-note > :last-child { margin-bottom: 0; }

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Rampa dorada
   ══════════════════════════════════════════════════════════════
   Nacio dentro de .aq (la cuota diaria) y se subio a :root al empezar a usarla tambien
   la etiqueta de "equipado" del inventario: una variable declarada en .aq solo resuelve
   dentro de .aq, fuera se queda sin valor y la regla se descarta en silencio.

   No se toca --gold del tema: en esta piel ese token es rosa-magenta (conserva ese
   nombre por compatibilidad) y repintarlo cambiaria la web entera. Esto es oro de
   verdad, y ademas oro VIEJO: toda la rampa lleva rojo de base, de bronce oscuro a oro
   calido, sin pasar por el amarillo limon de la primera version (#e6c25a), que quedaba
   plana.
   ══════════════════════════════════════════════════════════════ */
:root {
    --aq-gold-deep:   #5c2f0b;
    --aq-gold-mid:    #a5601c;
    --aq-gold:        #cf8b38;
    --aq-gold-light:  #eebd76;
    --aq-gold-glow:   rgba(207, 139, 56, 0.38);
    --aq-gold-soft:   rgba(207, 139, 56, 0.16);
    --aq-amber-deep:  #8a4a12;
    --aq-amber:       #d98324;
    /* Se acaba: cobre/brasa, para seguir en la familia calida del oro en vez de saltar
       al rosa del tema (--accent-red), que ahi desentonaba. */
    --aq-ember-deep:  #5e2410;
    --aq-ember:       #b8492a;
    --aq-ember-light: #e0714a;
}

/* ============================================================
   Cuota diaria de automatizacion (@autoplay / @helpme)
   Marcado en themes/default/account/view.php, datos en
   modules/account/view.php ($autoQuota).

   El relleno de la barra representa lo que QUEDA, no lo gastado, y su
   ancho viene de una clase .aq__fill--pN en pasos de 5 porque en esta web
   no se usan estilos en linea (ni siquiera para un ancho calculado).
   ============================================================ */

.aq {
    /* La rampa dorada (--aq-gold-*) vive en :root, ver mas abajo. */

    position: relative;
    margin: 0 0 22px;
    padding: 20px 22px 16px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 160% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28), inset 0 1px 0 var(--alpha-white-06);
    overflow: hidden;
}

/* Filo superior de color: cambia con el estado, es lo que da el "golpe de vista". */
.aq::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--aq-gold-deep), var(--aq-gold-light) 50%, var(--aq-gold-mid));
    opacity: 0.95;
}

.aq--warn::before  { background: linear-gradient(90deg, var(--aq-amber-deep), var(--aq-gold)); }
.aq--low::before,
.aq--empty::before { background: linear-gradient(90deg, var(--aq-ember-deep), var(--aq-ember-light) 50%, var(--aq-ember)); }

/* --- Cabecera --- */

.aq__head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 18px;
}

.aq__icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid var(--border-light);
    background: radial-gradient(circle at 30% 25%, var(--aq-gold-soft), var(--bg-input));
    box-shadow: inset 0 1px 0 var(--alpha-white-08), 0 0 14px var(--aq-gold-soft);
    font-size: 1.25rem;
    line-height: 1;
    color: var(--aq-gold);
}

.aq--low .aq__icon,
.aq--empty .aq__icon { color: var(--aq-ember-light); }

.aq__titles {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

.aq__title {
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--text-label-strong);
}

.aq__sub {
    font-size: 0.86rem;
    color: var(--text-muted);
}

.aq__sub code {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--alpha-black-22);
    color: var(--text-code-strong);
    font-size: 0.92em;
}

/* Pastilla del multiplicador de cuenta (#AUTOQUOTA_MULT). */
.aq__mult {
    flex: 0 0 auto;
    padding: 7px 15px;
    border-radius: 999px;
    background: linear-gradient(150deg, var(--aq-gold-light), var(--aq-gold) 45%, var(--aq-gold-mid));
    border: 1px solid var(--aq-gold-light);
    color: #331603;
    font-weight: 700;
    letter-spacing: 0.04em;
    white-space: nowrap;
    text-shadow: 0 1px 0 rgba(255, 236, 210, 0.4);
    box-shadow: 0 0 18px var(--aq-gold-glow), inset 0 1px 0 rgba(255, 255, 255, 0.45);
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 6px 16px;
}

.aq__mult i {
    font-style: normal;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: 0.7;
}

.aq__mult b { font-size: 1.28rem; line-height: 1; }

/* Desglose "30 de bienvenida + 180 por tu nivel = 210 al dia". Existe para que el
   jugador pueda SUMARLO, que es justo lo que no se podia hacer con un "x7" pelado:
   el multiplicador del emulador es nivel+1 y no cuadraba con el nivel que ve. */
.aq__math {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}

.aq__math-part {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.aq__math-part b {
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-heading2);
}

.aq__math-part i {
    font-style: normal;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

/* El total se lleva el oro: es la cifra que se quiere recordar. */
.aq__math-part--total {
    border-color: var(--aq-gold-mid);
    background: linear-gradient(180deg, var(--aq-gold-soft), transparent);
}

.aq__math-part--total b { color: var(--aq-gold-light); }
.aq__math-part--total i { color: var(--aq-gold); }

.aq__math-op {
    align-self: center;
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--aq-gold-mid);
}

/* --- Medidor: barra ancha + total fijo a la derecha --- */

.aq__gauge {
    display: flex;
    align-items: center;
    gap: 18px;
}

.aq__track {
    position: relative;
    flex: 1 1 auto;
    height: 34px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-body), var(--bg-input));
    box-shadow: inset 0 2px 6px var(--alpha-black-34);
    overflow: hidden;
}

/* Marcas cada 10% para que se lea la escala sin poner numeros. */
.aq__ticks {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(
        90deg,
        transparent 0,
        transparent calc(10% - 1px),
        var(--alpha-white-07) calc(10% - 1px),
        var(--alpha-white-07) 10%
    );
}

.aq__fill {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    padding-right: 14px;
    border-radius: 999px;
    /* Oro pulido: sombra abajo, luz arriba y filo claro al final del recorrido. */
    background: linear-gradient(
        180deg,
        var(--aq-gold-light) 0%,
        var(--aq-gold) 38%,
        var(--aq-gold-mid) 62%,
        var(--aq-gold-deep) 100%
    );
    box-shadow: 0 0 20px var(--aq-gold-glow), inset 0 1px 0 rgba(255, 255, 255, 0.45);
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.aq--warn .aq__fill {
    background: linear-gradient(180deg, var(--aq-gold) 0%, var(--aq-amber) 60%, var(--aq-amber-deep) 100%);
}
.aq--low .aq__fill {
    background: linear-gradient(180deg, var(--aq-ember-light) 0%, var(--aq-ember) 55%, var(--aq-ember-deep) 100%);
    box-shadow: 0 0 20px rgba(184, 73, 42, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.32);
}
.aq--empty .aq__fill { background: none; box-shadow: none; }

/* Barrido de brillo: el toque "epico", puramente decorativo. */
.aq__fill::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    /* 'background-repeat: no-repeat' es OBLIGATORIO y es justo lo que faltaba: el
       atajo 'background:' reinicia el repeat a su valor inicial (repeat), asi que con
       un tamano mayor que el elemento el degradado se TESELABA. Entraba un segundo
       destello por el otro lado mientras el primero seguia cruzando, y ademas el ciclo
       (3.36 anchos de recorrido) era mas largo que el mosaico (2.2 anchos), asi que al
       reiniciar pegaba un salto visible. De ahi que pareciera rota. */
    background-image: linear-gradient(
        105deg,
        transparent 34%,
        rgba(255, 231, 199, 0.5) 50%,
        transparent 66%
    );
    background-repeat: no-repeat;
    background-size: 300% 100%;
    /* De 100% a 0% la imagen (3 anchos) se desplaza hacia la DERECHA, asi que la banda
       clara cruza la barra de izquierda a derecha UNA sola vez por ciclo. El ease-in-out
       hace que la entrada y la salida (fuera de cuadro) sean lo lento, y el cruce, vivo. */
    animation: aq-sweep 3.6s ease-in-out infinite;
    pointer-events: none;
}

.aq--empty .aq__fill::before { animation: none; background-image: none; }

@keyframes aq-sweep {
    from { background-position: 100% 0; }
    to   { background-position: 0 0; }
}

/* Etiqueta del tiempo disponible: viaja pegada al borde del relleno. */
.aq__value {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: baseline;
    gap: 5px;
    white-space: nowrap;
    color: #331603;
    text-shadow: 0 1px 0 rgba(255, 236, 210, 0.45);
}

.aq__value b { font-size: 0.95rem; font-weight: 700; }
.aq__value i { font-size: 0.74rem; font-style: normal; opacity: 0.82; }

/* Con poco relleno la etiqueta no cabe dentro: se saca a su derecha y se
   recolorea sobre el fondo oscuro de la pista. */
.aq__fill--tight .aq__value {
    /* 100% = ancho de la propia etiqueta; +26px = los 14px de padding-right del
       relleno que hay que deshacer, mas 12px de aire real hasta su borde. */
    transform: translateX(calc(100% + 26px));
    color: var(--text-primary);
    text-shadow: none;
}

.aq__total {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.15;
    border-left: 1px solid var(--border);
    padding: 2px 0 2px 16px;
}

.aq__total b {
    font-size: 1.08rem;
    font-weight: 700;
    color: var(--text-heading2);
}

.aq__total i {
    font-size: 0.72rem;
    font-style: normal;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* Cuenta atras hasta la recarga de medianoche. */
.aq__refill {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 16px;
    padding: 10px 16px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: linear-gradient(90deg, var(--aq-gold-soft), transparent 70%);
    font-size: 0.92rem;
    color: var(--text-panel-soft);
}

.aq__refill b {
    font-weight: 700;
    color: var(--aq-gold-light);
    white-space: nowrap;
}

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

/* Punto latiendo: la unica pieza que sugiere "esto corre solo". */
.aq__refill-dot {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--aq-gold);
    box-shadow: 0 0 0 0 var(--aq-gold-glow);
    animation: aq-pulse 2.4s ease-out infinite;
}

.aq--low .aq__refill-dot,
.aq--empty .aq__refill-dot {
    background: var(--aq-ember-light);
    box-shadow: 0 0 0 0 rgba(224, 113, 74, 0.4);
}

@keyframes aq-pulse {
    0%   { box-shadow: 0 0 0 0 var(--aq-gold-glow); }
    70%  { box-shadow: 0 0 0 9px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

/* El Gerente de la Torre del Reloj (mob 1270) a la derecha del panel de cuota (2026-08-04).
   Va en posicion absoluta y no en el flujo a proposito: asi ni una sola de las lineas de texto
   cambia de sitio si algun dia se cambia el sprite o se quita. El hueco lo abre el
   padding-right de .aq--mascot, que es lo unico que este bloque le pide al panel.
   pointer-events: none para que no robe ningun clic; el panel lleva overflow: hidden, asi que
   la peana queda recortada contra el borde inferior y parece apoyado en el. */
.aq__mascot {
    position: absolute;
    right: 14px;
    bottom: -6px;
    width: 113px;
    margin: 0;
    line-height: 0;
    pointer-events: none;
    opacity: 0.96;
    filter: drop-shadow(0 6px 14px var(--alpha-black-28));
}

.aq__mascot img {
    display: block;
    width: 100%;
    height: auto;
    /* Es arte por pixeles: en pantallas de alta densidad el suavizado lo emborrona. */
    image-rendering: pixelated;
}

.aq--mascot { padding-right: 150px; }

/* La mitad de arriba -- cabecera y medidor -- recupera casi todo el hueco que .aq--mascot
   reserva a la derecha (usuario 2026-08-04). El Gerente ocupa la mitad de abajo, asi que
   estrujar tambien el titulo y la barra era regalar ancho a cambio de nada: el margen negativo
   devuelve 120 de los 150 px y deja 30 de aire, que es lo que separa la barra del borde.

   Va por margen negativo y no bajando el padding de la tarjeta porque ese hueco SI lo necesitan
   los parrafos de abajo, que son los que conviven con el sprite. */
.aq__top { margin-right: -120px; }

/* Y sin margen negativo donde no hay sprite: por debajo de 760px .aq--mascot ya lo retira. */
@media (max-width: 760px) {
    .aq__top { margin-right: 0; }
}

/* Por debajo de esto el texto se quedaria en una columna ridicula peleando con el sprite:
   antes que estrujarlo, se retira. */
@media (max-width: 760px) {
    .aq__mascot { display: none; }
    .aq--mascot { padding-right: 22px; }
}

/* Goteo de la regeneracion (2026-08-04). Va pegado a la pildora del relleno y con menos peso
   que ella: el numero de arriba es cuanto falta para estar LLENA, y esto es la letra pequena
   que explica que mientras tanto va volviendo sola cada media hora. La sangria lo alinea con
   el texto de la pildora, que lleva el punto latiendo delante. */
.aq__drip {
    margin: 8px 2px 0;
    padding-left: 19px;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.aq__drip b {
    font-weight: 700;
    color: var(--aq-gold-light);
    white-space: nowrap;
}

/* La cuenta atras del proximo tramo: mismo parrafo, un peldano mas de peso, porque es el
   numero que se mira cuando uno esta esperando a que vuelva algo de tiempo. */
.aq__drip-next {
    display: block;
    margin-top: 4px;
    color: var(--text-primary);
}

/* Y su contrario: cuando el reloj todavia no ha arrancado no hay cifra, solo el aviso. */
.aq__drip-wait {
    display: block;
    margin-top: 4px;
    font-style: italic;
}

.aq__foot {
    margin: 14px 0 0;
    font-size: 0.86rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.aq__foot strong { color: var(--text-primary); }

/* Aviso del consumo simultaneo. Se saca del parrafo general porque es la regla que
   mas sorprende al jugador: la cuota se gasta por herramienta activa, no por reloj. */
.aq__note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 12px 0 0;
    padding: 11px 14px;
    border: 1px solid var(--aq-gold-mid);
    border-radius: 10px;
    background: linear-gradient(180deg, var(--aq-gold-soft), transparent);
    font-size: 0.86rem;
    line-height: 1.55;
    color: var(--text-panel-soft);
}

.aq__note strong { color: var(--aq-gold-light); }

.aq__note code {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--alpha-black-22);
    color: var(--text-code-strong);
    font-size: 0.92em;
}

.aq__note-icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin-top: 1px;
    border-radius: 50%;
    background: var(--aq-gold);
    color: #331603;
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
}

/* Variante "sin cuota": no hay barra que mostrar. */
.aq--free .aq__head { margin-bottom: 0; }
.aq--free .aq__icon { font-size: 1.6rem; }

/* Anchos del relleno (pasos de 5). */
.aq__fill--p0   { width: 0;    padding-right: 0; box-shadow: none; }
.aq__fill--p5   { width: 5%;   }
.aq__fill--p10  { width: 10%;  }
.aq__fill--p15  { width: 15%;  }
.aq__fill--p20  { width: 20%;  }
.aq__fill--p25  { width: 25%;  }
.aq__fill--p30  { width: 30%;  }
.aq__fill--p35  { width: 35%;  }
.aq__fill--p40  { width: 40%;  }
.aq__fill--p45  { width: 45%;  }
.aq__fill--p50  { width: 50%;  }
.aq__fill--p55  { width: 55%;  }
.aq__fill--p60  { width: 60%;  }
.aq__fill--p65  { width: 65%;  }
.aq__fill--p70  { width: 70%;  }
.aq__fill--p75  { width: 75%;  }
.aq__fill--p80  { width: 80%;  }
.aq__fill--p85  { width: 85%;  }
.aq__fill--p90  { width: 90%;  }
.aq__fill--p95  { width: 95%;  }
.aq__fill--p100 { width: 100%; }

@media (max-width: 620px) {
    .aq { padding: 16px 16px 14px; }
    .aq__head { flex-wrap: wrap; gap: 10px; }
    .aq__gauge { flex-direction: column; align-items: stretch; gap: 10px; }
    .aq__track { height: 30px; }
    .aq__math { flex-direction: column; gap: 6px; }
    .aq__math-op { align-self: flex-start; padding-left: 14px; }
    .aq__total {
        flex-direction: row;
        align-items: baseline;
        justify-content: flex-end;
        gap: 6px;
        border-left: 0;
        padding: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .aq__fill { transition: none; }
    .aq__fill::before { animation: none; }
    .aq__refill-dot { animation: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Panel de nivel de jugador y referidos
   ══════════════════════════════════════════════════════════════
   Marcado en themes/default/account/view.php (bloque .lvl).

   Sustituye al antiguo .referral-panel de esta seccion, que mezclaba el nivel de
   JUGADOR y el de REFERIDOS en la misma cabecera y cuya barra media solo dentro del
   tramo del nivel actual: con 2 referidos de los 4 que pide el siguiente nivel
   marcaba "0%" porque el tramo empezaba en 2. Ahora la barra va de CERO al objetivo.

   Paleta LAVANDA/VIOLETA a proposito: el oro esta reservado para la cuota diaria de
   automatizacion, y dos bloques dorados seguidos se pisarian.
   ══════════════════════════════════════════════════════════════ */

.lvl {
    --lvl-accent:      #a97bf0;
    --lvl-accent-soft: rgba(169, 123, 240, 0.16);
    --lvl-accent-glow: rgba(169, 123, 240, 0.34);
    --lvl-accent-deep: #4a2d7a;

    position: relative;
    margin: 0 0 22px;
    padding: 22px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 160% at 100% 0%, var(--lvl-accent-soft), transparent 62%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28), inset 0 1px 0 var(--alpha-white-06);
    overflow: hidden;
}

.lvl::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--lvl-accent-deep), var(--lvl-accent) 55%, var(--accent-purple-h));
}

/* --- Cabecera con la medalla --- */

.lvl__hero {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-bottom: 20px;
}

.lvl__medal {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 78px;
    height: 78px;
    border-radius: 50%;
    border: 2px solid var(--lvl-accent);
    background: radial-gradient(circle at 32% 26%, var(--lvl-accent-soft), var(--bg-input) 70%);
    box-shadow: 0 0 22px var(--lvl-accent-glow), inset 0 1px 0 var(--alpha-white-08);
}

.lvl__medal i {
    font-style: normal;
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.lvl__medal b {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-heading2);
}

.lvl__hero-text { min-width: 0; }

.lvl__hero-title {
    margin: 0 0 4px;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text-label-strong);
}

.lvl__hero-sub {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
}

/* --- Desglose sumable del nivel --- */

.lvl__breakdown {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 8px;
    padding-bottom: 20px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--border);
}

.lvl__part {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 13px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.lvl__part b {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-muted);
}

.lvl__part i {
    font-style: normal;
    font-size: 0.71rem;
    letter-spacing: 0.03em;
    color: var(--text-muted);
}

/* Un sumando que aporta algo se enciende; los que estan a cero se quedan apagados,
   asi se ve de un vistazo por donde se esta subiendo y por donde no. */
.lvl__part.is-on b { color: var(--text-heading2); }
.lvl__part.is-on   { border-color: var(--border-light); }

.lvl__part--total {
    border-color: var(--lvl-accent);
    background: linear-gradient(180deg, var(--lvl-accent-soft), transparent);
}

.lvl__part--total b { color: var(--lvl-accent); font-size: 1.2rem; }
.lvl__part--total i { color: var(--accent-purple-h); }

.lvl__op {
    align-self: center;
    font-size: 1rem;
    font-weight: 700;
    color: var(--border-accent);
}

/* --- Escalera de referidos: la barra --- */

.lvl__quest-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.lvl__quest-title {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.lvl__quest-step {
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--text-primary);
}

.lvl__quest-step em {
    font-style: normal;
    font-weight: 400;
    color: var(--text-muted);
}

.lvl__track {
    position: relative;
    display: flex;
    align-items: center;
    height: 30px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-body), var(--bg-input));
    box-shadow: inset 0 2px 6px var(--alpha-black-34);
    overflow: hidden;
}

.lvl__fill {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    padding-right: 12px;
    border-radius: 999px;
    background: linear-gradient(180deg, var(--accent-purple-h) 0%, var(--lvl-accent) 45%, var(--lvl-accent-deep) 100%);
    box-shadow: 0 0 18px var(--lvl-accent-glow), inset 0 1px 0 var(--alpha-white-08);
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.lvl__fill-value {
    font-size: 0.86rem;
    font-weight: 700;
    color: #170a2b;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.32);
    white-space: nowrap;
}

/* Con el relleno corto la cifra no cabe dentro: se saca a su derecha, igual que en la
   barra de cuota. El +24px deshace el padding-right del relleno y deja 12 de aire. */
.lvl__fill--tight .lvl__fill-value {
    transform: translateX(calc(100% + 24px));
    color: var(--text-primary);
    text-shadow: none;
}

/* "faltan N" pegado al extremo derecho: lo que queda por hacer, siempre a la vista. */
.lvl__rest {
    position: absolute;
    right: 14px;
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--text-muted);
    white-space: nowrap;
}

.lvl__scale {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin: 7px 4px 0;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.lvl__quest-foot {
    margin: 12px 0 0;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.lvl__quest-foot strong { color: var(--text-primary); }

/* --- De donde sale el total ponderado --- */

.lvl__counts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 10px;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
}

.lvl__count {
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.lvl__count b {
    display: block;
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--text-heading2);
}

.lvl__count b span {
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--text-muted);
}

.lvl__count i {
    display: block;
    margin-top: 3px;
    font-style: normal;
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.lvl__count--total {
    border-color: var(--lvl-accent);
    background: linear-gradient(180deg, var(--lvl-accent-soft), transparent);
}

.lvl__count--total b { color: var(--lvl-accent); }

/* necROmantic 2026-08-03: con tres generaciones mas la casilla de Gold son cinco
   fichas. El minmax de 200px las partia en dos filas descompensadas (3 + 2), asi
   que aqui se pide un minimo menor y se deja que quepan las cinco de una tirada
   cuando hay sitio. */
.lvl__counts--four {
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
}

/* El token --gold del tema es en realidad el rosa-magenta del acento primario, asi
   que un referido "Gold" pintado con el no se leeria como oro. Se define aqui un
   ambar propio, emparentado con --text-status-warning, que ya vive en la paleta. */
.lvl__counts,
.invites-table,
.rb {
    --rb-gold:      #d9b05b;
    --rb-gold-soft: rgba(217, 176, 91, 0.16);
    --rb-gold-glow: rgba(217, 176, 91, 0.32);
}

.lvl__count--gold {
    border-color: var(--rb-gold);
    background: linear-gradient(180deg, var(--rb-gold-soft), transparent);
}

.lvl__count--gold b {
    color: var(--rb-gold);
    text-shadow: 0 0 18px var(--rb-gold-glow);
}

/* --- Ventajas del nivel --- */

.lvl__perks {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 10px;
    margin-top: 10px;
}

.lvl__perk {
    padding: 14px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: linear-gradient(180deg, var(--alpha-silver-08), transparent);
    text-align: center;
}

.lvl__perk b {
    display: block;
    font-size: 1.45rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--lvl-accent);
}

.lvl__perk i {
    display: block;
    margin-top: 4px;
    font-style: normal;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.lvl__perk code {
    padding: 1px 4px;
    border-radius: 4px;
    background: var(--alpha-black-22);
    color: var(--text-code-strong);
    font-size: 0.92em;
}

.lvl__rules {
    margin: 16px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 0.83rem;
    line-height: 1.6;
    color: var(--text-muted);
}

@media (max-width: 620px) {
    .lvl { padding: 16px; }
    .lvl__hero { gap: 14px; }
    .lvl__medal { width: 64px; height: 64px; }
    .lvl__medal b { font-size: 1.6rem; }
    .lvl__breakdown { flex-direction: column; gap: 6px; }
    .lvl__op { align-self: flex-start; padding-left: 13px; }
    .lvl__quest-head { flex-direction: column; align-items: flex-start; gap: 4px; }
    .lvl__rest { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .lvl__fill { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Ficha de cuenta: cabecera, secciones y privacidad
   ══════════════════════════════════════════════════════════════ */

/* --- Separacion entre secciones -------------------------------------------
   La ficha de cuenta encadena ocho bloques (privacidad, cuota, participacion,
   nivel, invitaciones, personajes, storage...) y todos empezaban con un <h3>
   suelto pegado al bloque anterior, asi que se leian como una lista continua.
   Cada cabecera de seccion se apoya ahora en una linea con un acento de color y
   respira por arriba: se ve donde acaba una cosa y empieza otra. */

.sec-title {
    position: relative;
    margin: 46px 0 16px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
    font-size: 1.12rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--text-heading2);
}

/* Marca corta de color montada sobre la linea, a la altura del titulo. */
.sec-title::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    width: 56px;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
}

/* La primera seccion de la pagina no necesita separarse de nada. */
.sec-title:first-of-type {
    margin-top: 26px;
    padding-top: 0;
    border-top: 0;
}

.sec-title:first-of-type::before { display: none; }

/* --- Cabecera de la ficha -------------------------------------------------- */

.acchead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 18px;
    margin-bottom: 6px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--border);
}

.acchead__eyebrow {
    margin: 0 0 2px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.acchead__title {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--text-heading2);
}

.acchead__id {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.acchead__avatar {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1;
    overflow: hidden;
}

.acchead__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* La imagen y su "Quitar imagen" van en columna: el enlace queda DEBAJO de la foto,
   no colgando del nombre de la cuenta. */
.acchead__avatar-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
}

.acchead__avatar-form { margin: 0; padding: 0; }

/* El input de fichero no se puede esconder con display:none sin perder el foco por
   teclado, asi que se saca de la vista pero se deja enfocable. */
.acchead__avatar-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.acchead__avatar--editable { cursor: pointer; }

/* La pista solo aparece al señalar (o al enfocar con teclado): en reposo se ve la
   imagen limpia, y en cuanto el raton pasa por encima queda claro que ahi se pulsa. */
.acchead__avatar-hint {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    background: rgba(10, 7, 19, 0.72);
    color: var(--text-white);
    opacity: 0;
    transition: opacity 0.18s ease;
}

.acchead__avatar--editable:hover .acchead__avatar-hint,
.acchead__avatar-input:focus + .acchead__avatar-hint,
.acchead__avatar-form:focus-within .acchead__avatar-hint { opacity: 1; }

.acchead__avatar-hint-icon { font-size: 0.95rem; line-height: 1; }

.acchead__avatar-hint-text {
    font-size: 0.46rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: center;
    line-height: 1.1;
}

/* Anillo al señalar, para que el circulo entero se lea como un boton. */
.acchead__avatar--editable::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    box-shadow: inset 0 0 0 0 var(--border-accent);
    transition: box-shadow 0.18s ease;
    pointer-events: none;
}

.acchead__avatar--editable:hover::after { box-shadow: inset 0 0 0 2px var(--text-white); }

.acchead__avatar-drop { margin: 0; padding: 0; line-height: 1; }

.acchead__avatar-drop button {
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.7rem;
    text-decoration: underline;
    cursor: pointer;
}

.acchead__avatar-drop button:hover { color: var(--accent-red); }

.acchead__meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    min-height: 44px;
    line-height: 1.25;
}

.acchead__meta b {
    font-size: 0.98rem;
    font-weight: 700;
    color: var(--text-primary);
}

.acchead__meta i {
    font-style: normal;
    font-size: 0.74rem;
    color: var(--text-muted);
}

/* --- Tabla de datos de la cuenta ------------------------------------------
   Sigue siendo una tabla (los datos son pares etiqueta/valor y eso es lo que
   son), pero deja de parecer una hoja de calculo: sin fondos de bloque, con
   lineas finas de separacion y las etiquetas en versalitas alineadas a la
   izquierda, que es como se leen las fichas de verdad. */

table.vertical-table.account-summary {
    margin-top: 4px;
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--bg-surface);
}

table.vertical-table.account-summary th,
table.vertical-table.account-summary td {
    padding: 13px 16px;
    background: transparent;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

table.vertical-table.account-summary tr:last-child th,
table.vertical-table.account-summary tr:last-child td { border-bottom: 0; }

table.vertical-table.account-summary th {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: left;
    color: var(--text-muted);
    white-space: nowrap;
}

table.vertical-table.account-summary td {
    font-size: 0.92rem;
    color: var(--text-primary);
}

/* Separador vertical entre las dos parejas etiqueta/valor de cada fila. */
table.vertical-table.account-summary th + th,
table.vertical-table.account-summary td + th { border-left: 1px solid var(--border); }

/* --- Privacidad y control de cuenta ---------------------------------------
   De tabla de dos columnas a tarjetas apiladas: cada apartado (email, descarga,
   eliminacion) es una decision independiente y se lee mejor separado que en
   celdas contiguas. */

table.vertical-table.privacy-table {
    display: block;
    width: 100%;
    margin-top: 4px;
}

table.vertical-table.privacy-table tbody { display: block; }

table.vertical-table.privacy-table tr {
    display: block;
    margin-bottom: 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background:
        radial-gradient(120% 200% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        var(--bg-surface);
    overflow: hidden;
}

table.vertical-table.privacy-table th,
table.vertical-table.privacy-table td {
    display: block;
    width: auto;
    background: transparent;
    text-align: left;
}

table.vertical-table.privacy-table th {
    padding: 13px 18px 0;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--gold);
}

table.vertical-table.privacy-table td {
    padding: 8px 18px 16px;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text-primary);
}

table.vertical-table.privacy-table small {
    display: block;
    margin-top: 5px;
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.privacy-form { margin-top: 12px; }

.privacy-btn {
    padding: 9px 18px;
    border: 1px solid var(--border-light);
    border-radius: 9px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.privacy-btn:hover {
    border-color: var(--border-accent);
    background: var(--bg-surface-alt);
    color: var(--text-label-hover);
}

/* Accion irreversible: se marca en rojo, pero apagada hasta que se apunta a ella.
   Un boton rojo permanente en una ficha de cuenta invita a pulsarlo. */
.privacy-btn--danger {
    border-color: var(--crimson);
    color: var(--accent-red);
}

.privacy-btn--danger:hover {
    border-color: var(--accent-red);
    background: var(--crimson);
    color: var(--accent-red-h);
}

.privacy-blockers {
    margin-top: 12px;
    padding: 11px 14px;
    border-left: 3px solid var(--accent-red);
    border-radius: 0 8px 8px 0;
    background: var(--alpha-black-22);
    font-size: 0.86rem;
    color: var(--text-muted);
}

.privacy-blockers strong { color: var(--text-primary); }
.privacy-blockers ul { margin: 6px 0 0; padding-left: 20px; }

@media (max-width: 620px) {
    .acchead { gap: 12px; }
    .acchead__title { font-size: 1.32rem; }
    .sec-title { margin-top: 34px; padding-top: 20px; }
    table.vertical-table.account-summary th + th,
    table.vertical-table.account-summary td + th { border-left: 0; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Personajes: rejilla de fichas
   ══════════════════════════════════════════════════════════════
   Sustituye a la tabla de 12 columnas (.chars-table), que con gremio y las cuatro
   acciones no cabia y obligaba a barrer en horizontal. Las acciones viven ahora en
   un <details>, el desplegable nativo: se abre al pulsar, sin JavaScript, y funciona
   con teclado. Aviso conocido de esa solucion: al no haber JS, el menu NO se cierra
   al pulsar fuera; se cierra volviendo a pulsar el boton (o abriendo otro, no).
   ══════════════════════════════════════════════════════════════ */

.chargrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: 14px;
    margin-top: 4px;
}

.chc {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background:
        radial-gradient(130% 120% at 100% 0%, var(--alpha-silver-08), transparent 58%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 20px var(--alpha-black-24);
    transition: border-color 0.2s ease, background 0.2s ease;
}

/* Al señalar NO se mueve nada: solo se ilumina. Un desplazamiento en hover dentro de una
   rejilla obliga al ojo a recolocarse en cada pasada del raton, y aqui no aporta nada. */
.chc:hover {
    border-color: var(--border-accent);
    background:
        radial-gradient(130% 120% at 100% 0%, var(--alpha-silver-16), transparent 58%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

/* Un personaje conectado se marca con un filo lateral, no con otro color de fondo:
   asi se distingue de un vistazo sin romper la rejilla. */
.chc--online { box-shadow: 0 8px 20px var(--alpha-black-24), inset 3px 0 0 var(--accent-purple); }

.chc__top {
    display: flex;
    align-items: center;
    gap: 8px;
}

.chc__slot {
    padding: 3px 9px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.chc__state {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-right: auto;
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--text-muted);
}

.chc__state i {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--text-muted);
}

.chc--online .chc__state { color: var(--accent-purple-h); }
.chc--online .chc__state i {
    background: var(--accent-purple);
    box-shadow: 0 0 8px var(--accent-purple);
}

/* --- Menu contextual de acciones (details/summary nativo) --- */

.chc__menu { position: relative; }

.chc__menu-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-size: 0.74rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;                 /* quita el triangulito por defecto */
    transition: border-color 0.2s ease, color 0.2s ease;
}

.chc__menu-btn::-webkit-details-marker { display: none; }   /* idem en WebKit */

.chc__menu-btn:hover,
.chc__menu[open] .chc__menu-btn {
    border-color: var(--border-accent);
    color: var(--text-label-hover);
}

.chc__menu-btn-text { letter-spacing: 0.02em; }

.chc__menu-panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + 7px);
    right: 0;
    min-width: 236px;
    padding: 6px;
    border: 1px solid var(--border-light);
    border-radius: 11px;
    background: var(--bg-surface-alt);
    box-shadow: 0 14px 32px var(--alpha-black-34);
}

.chc__menu-item {
    display: flex;
    flex-direction: column;
    gap: 1px;
    width: 100%;
    padding: 8px 11px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.87rem;
    font-weight: 600;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.chc__menu-item em {
    font-style: normal;
    font-size: 0.73rem;
    font-weight: 400;
    line-height: 1.35;
    color: var(--text-muted);
}

.chc__menu-item:hover {
    background: var(--bg-input);
    color: var(--text-label-hover);
}

.chc__menu-form { margin: 0; padding: 0; }

/* Por que NO se puede borrar, en lugar de un boton que iba a fallar. */
.chc__menu-note {
    margin: 4px 0 0;
    padding: 9px 11px 4px;
    border-top: 1px solid var(--border);
    font-size: 0.73rem;
    line-height: 1.4;
    color: var(--text-muted);
}

/* La accion destructiva se separa del resto y solo se enciende al apuntarla. */
.chc__menu-item--danger {
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    border-radius: 0 0 8px 8px;
    color: var(--accent-red);
}

.chc__menu-item--danger:hover { background: var(--crimson); color: var(--accent-red-h); }

/* --- Identidad --- */

/* Identidad: icono de clase + nombre y profesion */
.chc__id {
    display: flex;
    align-items: center;
    gap: 11px;
}

.chc__id-text { min-width: 0; }

.chc__jobicon {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    object-fit: contain;
    /* Son 25x25 de pixel art: al escalar hay que conservar el pixel, no suavizarlo. */
    image-rendering: pixelated;
    filter: drop-shadow(0 1px 3px var(--alpha-black-34));
}

.chc__name {
    margin: 0;
    font-size: 1.18rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--text-heading2);
}

.chc__name a { color: inherit; text-decoration: none; }
.chc__name a:hover { color: var(--text-link-hover); }

.chc__job {
    margin: 2px 0 0;
    font-size: 0.82rem;
    letter-spacing: 0.03em;
    color: var(--text-muted);
}

/* --- Cifras --- */

.chc__stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.chc__stat {
    padding: 9px 11px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--alpha-black-22);
}

.chc__stat--wide { grid-column: 1 / -1; }

.chc__stat b {
    display: block;
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1.15;
    color: var(--text-primary);
}

.chc__stat i {
    display: block;
    margin-top: 2px;
    font-style: normal;
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* --- Gremio --- */

.chc__guild {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-top: auto;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    font-size: 0.85rem;
}

.chc__emblem { width: 24px; height: 24px; image-rendering: pixelated; }
.chc__guild-name a { color: var(--text-link); }
.chc__guild-none { color: var(--text-muted); font-style: italic; }

/* --- Pie de la rejilla --- */

.chargrid__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 14px;
    padding: 13px 16px;
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--alpha-black-22);
}

.chargrid__total {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin: 0;
}

.chargrid__total span {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.chargrid__total b { font-size: 1.2rem; font-weight: 700; color: var(--gold); }

.chargrid__note {
    flex: 1 1 260px;
    margin: 0;
    font-size: 0.8rem;
    line-height: 1.5;
    text-align: right;
    color: var(--text-muted);
}

.chargrid__empty { color: var(--text-muted); }

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Cuenta atras del regalo diario
   ══════════════════════════════════════════════════════════════
   Vive al final de la rejilla de personajes y solo aparece cuando el regalo de
   hoy ya se ha cobrado. Usa la rampa --aq-gold-*, la misma del boton de reclamo
   y del bloque de cuota, para que la ficha de cuenta tenga una sola identidad
   dorada. Recuerda: --gold NO sirve aqui, en esta piel es rosa-magenta.

   Las cifras las escribe JavaScript con textContent; el ancho de los huecos lo
   fija ch + tabular-nums para que no bailen al cambiar de segundo.
   ══════════════════════════════════════════════════════════════ */
.gcd {
    /* Fila propia dentro del pie, que es un flex con space-between. */
    flex: 1 0 100%;
    position: relative;
    overflow: hidden;
    margin: 4px 0 2px;
    padding: 16px 18px 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background:
        radial-gradient(120% 160% at 0% 0%, var(--aq-gold-soft), transparent 62%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: inset 0 1px 0 var(--alpha-white-06);
    text-align: center;
}

/* Filo dorado superior: el mismo golpe de vista que .aq */
.gcd::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--aq-gold-deep), var(--aq-gold-light) 50%, var(--aq-gold-mid));
    opacity: 0.95;
}

.gcd__eyebrow {
    margin: 0 0 6px;
    color: var(--aq-gold);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.gcd__claimed {
    margin: 0 0 2px;
    color: var(--text-panel-soft);
    font-size: 0.9rem;
}

.gcd__who { color: var(--aq-gold-light); font-weight: 700; }

.gcd__lead {
    margin: 0 0 10px;
    color: var(--text-muted);
    font-size: 0.82rem;
}

.gcd__clock {
    display: inline-flex;
    align-items: flex-start;
    justify-content: center;
    gap: 8px;
}

.gcd__unit {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
}

.gcd__num {
    display: block;
    min-width: 2.6ch;
    padding: 9px 12px;
    border: 1px solid var(--aq-gold-mid);
    border-radius: 10px;
    background: var(--alpha-black-28);
    box-shadow: inset 0 1px 0 var(--alpha-white-06), 0 0 20px var(--aq-gold-soft);
    color: var(--aq-gold-light);
    font-size: 1.85rem;
    font-weight: 700;
    line-height: 1;
    /* Cifras de ancho fijo: sin esto el reloj tiembla en cada segundo. */
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 14px var(--aq-gold-glow);
}

.gcd__unit i {
    font-style: normal;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* Los dos puntos se alinean con las cifras, no con las etiquetas de abajo. */
.gcd__sep {
    align-self: flex-start;
    padding-top: 12px;
    color: var(--aq-gold-mid);
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
}

.gcd__foot {
    margin: 10px 0 0;
    color: var(--aq-gold-light);
    font-size: 0.88rem;
    font-weight: 700;
}

@media (max-width: 620px) {
    .chargrid { grid-template-columns: minmax(0, 1fr); }
    .chc__menu-btn-text { display: none; }
    .chc__menu-panel { right: auto; left: 0; min-width: 210px; }
    .chargrid__note { text-align: left; }

    .gcd { padding: 14px 12px 12px; }
    .gcd__clock { gap: 5px; }
    .gcd__num { min-width: 2.4ch; padding: 8px 9px; font-size: 1.5rem; }
    .gcd__sep { padding-top: 10px; font-size: 1.2rem; }
}

@media (prefers-reduced-motion: reduce) {
    .chc { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Almacen de la cuenta
   ══════════════════════════════════════════════════════════════
   De 11 columnas a 3. Se fueron "Identificado", "Roto", "Random options" y "Extra"
   -las tres primeras repetian "No"/"None" en casi todas las filas- y las cuatro
   columnas de cartas se juntaron en una sola que las enumera.
   ══════════════════════════════════════════════════════════════ */

.stg {
    margin-top: 4px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--bg-surface);
    overflow: hidden;
}

/* --- Barra de filtros --- */

.stg__bar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0;
    padding: 18px;
    border-bottom: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-surface-alt), transparent);
}

.stg__search { flex: 1 1 320px; min-width: 0; }

.stg__label {
    display: block;
    margin-bottom: 7px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.stg__field {
    display: flex;
    align-items: center;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-input);
    overflow: hidden;
    transition: border-color 0.2s ease;
}

.stg__field:focus-within { border-color: var(--border-accent); }

.stg__field-icon {
    padding: 0 4px 0 13px;
    color: var(--text-muted);
    font-size: 0.95rem;
    line-height: 1;
}

.stg__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 10px 12px;
    border: 0;
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.92rem;
}

.stg__input:focus { outline: none; }
.stg__input::placeholder { color: var(--text-muted); }

.stg__submit {
    flex: 0 0 auto;
    padding: 10px 20px;
    border: 0;
    border-left: 1px solid var(--border);
    background: var(--bg-surface-alt);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}

.stg__submit:hover { background: var(--accent-purple); color: var(--bg-content); }

.stg__aside {
    display: flex;
    align-items: flex-end;
    gap: 16px;
    flex-wrap: wrap;
}

.stg__clear {
    padding: 8px 13px;
    border: 1px dashed var(--border-light);
    border-radius: 9px;
    color: var(--text-muted);
    font-size: 0.8rem;
    text-decoration: none;
}

.stg__clear:hover { border-color: var(--accent-red); color: var(--accent-red-h); }

.stg__count { margin: 0; text-align: right; }
.stg__count b {
    display: block;
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-heading2);
}
.stg__count i {
    font-style: normal;
    font-size: 0.7rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* --- Tabla --- */

/* Variante de la barra sin buscador: la ficha de personaje solo ensena el recuento y
   el "mostrando X-Y de Z", asi que no necesita el campo de busqueda ni su columna. */
.stg__bar--plain {
    align-items: baseline;
    padding-bottom: 14px;
}

.stg__bar--plain .stg__count { text-align: left; }
.stg__bar--plain .stg__meta { padding: 0; }

.stg__meta { padding: 12px 18px 0; }
.stg__meta .info-text { margin: 0; font-size: 0.8rem; color: var(--text-muted); }

/* La tabla se desplaza dentro de su propia caja: la pagina nunca hace scroll lateral. */
.stg__scroll { overflow-x: auto; padding: 12px 6px 0; }

.stg__table {
    width: 100%;
    border-collapse: collapse;
}

.stg__table thead th {
    padding: 9px 14px;
    background: transparent;
    border-bottom: 1px solid var(--border);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: left;
    color: var(--text-muted);
    white-space: nowrap;
}

.stg__table tbody td {
    padding: 11px 14px;
    background: transparent;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.stg__table tbody tr:last-child td { border-bottom: 0; }
.stg__table tbody tr:hover td { background: var(--alpha-white-03); }

/* El .stg__col-num a secas (0,1,0) lo pisaba ".stg__table thead th" (0,2,1), que alinea
   a la izquierda: por eso el rotulo "Cantidad" no seguia a su columna. Hace falta el
   selector con la misma raiz para ganar la especificidad. */
.stg__col-num,
.stg__table thead th.stg__col-num { text-align: right; }

/* --- Celda del objeto --- */

/* OJO: el flex va en .stg__item-row, no en el <td>. Un display:flex sobre una celda
   la saca del algoritmo de tabla -deja de generar una caja table-cell- y la fila se
   descuadra: las celdas afectadas se apilan y las que quedan intactas se van a un lado.
   Fue exactamente el sintoma que tuvo esta tabla ("dos columnas una encima de otra y la
   tercera a la derecha"). */
.stg__item-row { display: flex; align-items: center; gap: 12px; }

.stg__icon {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    object-fit: contain;
    image-rendering: pixelated;
}

.stg__icon--none {
    display: block;
    border: 1px dashed var(--border);
    border-radius: 6px;
}

.stg__item-text { min-width: 0; }

.stg__name {
    display: block;
    font-size: 0.94rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--text-primary);
}

.stg__refine { color: var(--gold); }
.stg__slots { color: var(--text-muted); font-weight: 400; }

.stg__tags {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
}

.stg__id { font-size: 0.72rem; color: var(--text-muted); }
.stg__id a { color: var(--text-muted); text-decoration: none; }
.stg__id a:hover { color: var(--text-link-hover); }

/* Etiquetas de EXCEPCION: solo aparecen cuando hay algo que decir. */
.stg__tag {
    padding: 1px 7px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-muted);
}

.stg__tag--warn { border-color: var(--gold-dim); color: var(--gold); }
.stg__tag--bad  { border-color: var(--crimson); color: var(--accent-red); }

/* --- Celda de cartas --- */

.stg__cards-row { display: flex; flex-wrap: wrap; gap: 6px; }

.stg__card {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 3px 9px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--alpha-black-22);
    font-size: 0.78rem;
}

.stg__card a { color: var(--text-link); text-decoration: none; }
.stg__card a:hover { color: var(--text-link-hover); }
.stg__card b { font-size: 0.72rem; color: var(--gold); }

.stg__none { color: var(--text-muted); }

/* Listas de objetos y monstruos: tipo/subtipo y elemento/nivel en dos lineas. */
.stg__kind {
    display: block;
    font-size: 0.88rem;
    color: var(--text-primary);
}

.stg__kind-sub {
    display: block;
    margin-top: 2px;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.stg__where { font-size: 0.82rem; color: var(--text-muted); }

/* El retrato de un monstruo no es un icono de 32: se le deja mas caja y NO se pixela,
   porque son gif ya renderizados, no pixel art de interfaz. */
.stg__icon--mob {
    width: 46px;
    height: 46px;
    image-rendering: auto;
}

.stg__tag--mvp {
    border-color: var(--aq-gold-mid);
    background: linear-gradient(150deg, var(--aq-gold-light), var(--aq-gold) 45%, var(--aq-gold-mid));
    color: #331603;
    font-weight: 800;
    letter-spacing: 0.06em;
    padding: 1px 7px;
    border-radius: 999px;
    border-width: 1px;
    border-style: solid;
    font-size: 0.62rem;
    vertical-align: middle;
}

.stg__amount {
    display: inline-block;
    min-width: 44px;
    padding: 3px 10px;
    border-radius: 7px;
    background: var(--alpha-black-22);
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--text-primary);
}

/* necROmantic 2026-08-04: variante apagada para la cifra que acompana a otra y no es
   el dato principal (en el bestiario, las muertes de media al lado del porcentaje).
   Sin fondo para que el porcentaje siga siendo lo que salta a la vista. */
.stg__amount--soft {
    background: transparent;
    font-weight: 600;
    color: var(--text-muted);
}

/* --- Paginacion --- */

.stg__pager {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 18px;
    padding: 14px 18px 18px;
}

.pages,
.stg__pager .pages {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
    font-size: 0;                       /* se come los separadores de texto del paginador */
    /* La regla base .pages (mas arriba en este mismo fichero) trae margin-top:16px y
       padding-top:8px, pensados para cuando el paginador cuelga suelto debajo de una
       tabla. Aqui vive dentro de .stg__pager, que ya pone su propio espaciado, asi que
       esos 24px solo servian para bajar los numeros de pagina 24px respecto al salto de
       pagina que tienen al lado: se veian desalineados. Se anulan en el origen, en vez
       de compensarlos empujando el otro elemento hacia abajo con la misma cantidad. */
    margin-top: 0;
    padding-top: 0;
}

.pages a,
.stg__pager .pages a {
    min-width: 34px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-link);
    font-size: 0.84rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.pages a:hover,
.stg__pager .pages a:hover {
    border-color: var(--border-accent);
    background: var(--bg-surface-alt);
    color: var(--text-link-hover);
}

.pages .current-page,
.stg__pager .pages .current-page {
    border-color: var(--accent-purple);
    background: var(--accent-purple);
    color: var(--bg-content);
    cursor: default;
}

/* --- Salto de pagina ---
   El marcado lo genera Flux_Paginator::getHTML(). Se estiliza aqui globalmente (no
   colgando de .stg) porque el mismo paginador lo usan otros modulos y no tiene sentido
   que se vea moderno en el almacen y arcaico en el resto. */
.jump-to-page {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.jump-to-page__label {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.jump-to-page__input {
    width: 62px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    transition: border-color 0.2s ease;
}

.jump-to-page__input:focus {
    outline: none;
    border-color: var(--border-accent);
}

.jump-to-page__input::placeholder { color: var(--text-muted); font-weight: 400; }

.jump-to-page__hint { font-size: 0.78rem; color: var(--text-muted); }

.stg__empty { padding: 22px 18px; margin: 0; color: var(--text-muted); }

/* ==========================================================================
   Incineradora y Protegidos (.ipol) -- necROmantic 2026-08-11
   ==========================================================================
   Las dos listas por tipo de objeto de la ficha de personaje y las tres pestanas que las
   contienen junto al inventario de siempre. Vive pegado al bloque .stg porque la pestana
   de Inventario ES una .stg: aqui solo esta lo que la rodea.

   OJO CON [hidden]: en este panel se usa el atributo para esconder los menus, los
   resultados y el mensaje, y varias de esas piezas llevan `display: flex` o `display:
   grid` puestos por su clase. Una declaracion de display SIEMPRE gana a la regla de
   agente de usuario `[hidden] { display: none }`, asi que sin la regla de abajo el
   atributo no esconderia nada. Va acotada a .ipol para no cambiarle el comportamiento al
   resto del sitio. */

.ipol [hidden] { display: none !important; }

.ipol { margin-top: 4px; }

.ipol__scope {
    margin: 0 0 12px;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.ipol__scope b { color: var(--text-primary); }

/* --- Pestanas --- */

.ipol__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 14px;
}

.ipol__tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.ipol__tab:hover { border-color: var(--border-accent); color: var(--text-primary); }

.ipol__tab.is-on {
    border-color: var(--accent-purple);
    background: var(--bg-surface-alt);
    color: var(--text-primary);
}

.ipol__num {
    min-width: 20px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--alpha-black-22);
    font-size: 0.72rem;
    font-weight: 700;
    text-align: center;
}

.ipol__panel--off { display: none; }

/* --- Sub-pestanas dentro de una pestana (necROmantic 2026-08-23, WEB-08) ---
   Hoy solo las tiene la Incineradora: "Se incineraran" y "Ya incinerados". Se distinguen de las
   grandes a proposito -- mas pequenas, cuadradas y sin fondo propio -- porque si se parecieran
   el jugador no sabria cual de los dos conmutadores acaba de tocar. */

.ipol__subtabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}

.ipol__subtab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 13px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.ipol__subtab:hover { color: var(--text-primary); }

.ipol__subtab.is-on {
    border-color: var(--border-accent);
    background: var(--alpha-black-22);
    color: var(--text-primary);
}

.ipol__sub--off { display: none; }

/* --- Pestanas por TIPO de objeto de los dos almacenes (necROmantic 2026-08-25) ---
   Un tercer nivel de conmutador, y por eso NO se parece a los otros dos: las de arriba son
   pastillas grandes y las sub-pestanas son texto; estas son fichas pequenas que se envuelven en
   varias lineas si hace falta. Nueve etiquetas con su numero no caben en una fila en un movil, y
   apretarlas hasta que quepan las haria ilegibles. */

.ipol__cats {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 14px;
}

.ipol__cat {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.ipol__cat:hover { border-color: var(--border-accent); color: var(--text-primary); }

.ipol__cat.is-on {
    border-color: var(--border-accent);
    background: var(--alpha-black-22);
    color: var(--text-primary);
}

/* La pestana sin nada dentro se queda en su sitio, apagada. Sigue siendo pulsable a proposito:
   quien la pulsa lee "no tienes nada de esa categoria", que es una respuesta; una pestana que no
   responde al clic parece rota. */
.ipol__cat--empty { opacity: 0.45; }

.ipol__cat i { font-size: 0.72rem; }

/* --- Mensaje de la ultima orden --- */

.ipol__msg {
    margin: 0 0 12px;
    padding: 9px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
    font-size: 0.84rem;
    color: var(--text-muted);
}

.ipol__msg--ok  { border-color: var(--border-accent); color: var(--text-primary); }
.ipol__msg--bad { border-color: var(--crimson); color: var(--accent-red); }

/* --- Cabecera de una lista --- */

.ipol__head { margin-bottom: 14px; }

.ipol__title {
    margin: 0 0 4px;
    font-size: 1rem;
    color: var(--text-primary);
}

.ipol__intro {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.ipol__intro b { color: var(--text-primary); }

/* --- Buscador para anadir lo que aun no se tiene --- */

.ipol__add { position: relative; margin-bottom: 16px; }

.ipol__results {
    position: absolute;
    z-index: 30;
    left: 0;
    right: 0;
    max-height: 340px;
    margin-top: 6px;
    padding: 6px;
    overflow-y: auto;
    border: 1px solid var(--border-accent);
    border-radius: 12px;
    background: var(--bg-surface);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}

.ipol__hit {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 9px;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
}

.ipol__hit:hover:not(:disabled) { background: var(--alpha-white-03); }

/* Un resultado que no se puede añadir a esta lista. Se enseña igualmente, con el motivo escrito
   al lado: que desapareciera dejaba al jugador buscando algo que existe y no aparece. */
.ipol__hit--off { opacity: 0.5; cursor: default; }

.ipol__hit-text { display: flex; flex-direction: column; min-width: 0; }
.ipol__hit-text b { font-size: 0.86rem; font-weight: 600; }
.ipol__hit-text i { font-size: 0.74rem; font-style: normal; color: var(--text-muted); }

/* --- Un resultado con DOS destinos (necROmantic 2026-08-25) ---
   En Autostore un resultado de busqueda no se puede añadir de un solo clic: hay dos sitios donde
   puede ir y elegir por el jugador seria elegir mal la mitad de las veces. Asi que ahi la fila deja
   de ser un boton y pasa a llevar dos. */
.ipol__hit--dual { cursor: default; }
.ipol__hit--dual:hover { background: transparent; }

.ipol__hit-acts {
    flex: 0 0 auto;
    display: flex;
    gap: 6px;
    margin-left: auto;
}

.ipol__dest {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.74rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.ipol__dest--store:hover { border-color: var(--tone-mint); color: var(--tone-mint); }
.ipol__dest--sub:hover   { border-color: var(--tone-violet); color: var(--tone-violet); }

/* La leyenda de los dos colores, dentro del parrafo que explica la pestana: si el reparto se
   cuenta con palabras hay que poder ver AHI MISMO de que color es cada cosa. */
.ipol__key {
    padding: 1px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.78rem;
    white-space: nowrap;
}

.ipol__key--store { border-color: var(--tone-mint); color: var(--tone-mint); }
.ipol__key--sub   { border-color: var(--tone-violet); color: var(--tone-violet); }

/* --- Las tarjetas de una lista --- */

.ipol__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 10px;
}

.ipol__card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: 12px;
    background: var(--bg-surface);
}

.ipol__card--burn  { border-left-color: var(--accent-red); }
.ipol__card--prot  { border-left-color: var(--tone-azure); }
.ipol__card--store { border-left-color: var(--tone-mint); }
/* El subalmacen (necROmantic 2026-08-25). El color del borde izquierdo es lo unico que distingue
   una tarjeta de autostore de otra, asi que es el que lleva el peso de los "dos colores". */
.ipol__card--sub   { border-left-color: var(--tone-violet); }

/* --- La tarjeta de un EJEMPLAR: inventario y los dos almacenes (necROmantic 2026-08-25) ---
   Es la misma .ipol__card que las cuatro listas, con dos diferencias que vienen de lo que lleva
   dentro. Aqui no hay TIPOS de objeto sino ejemplares: cada uno con su cantidad, su refinamiento y
   puede que una fila de cartas debajo del nombre. Por eso el contenido se alinea ARRIBA -- con
   todo centrado, una tarjeta con cartas dejaria el icono flotando a media altura mientras la de al
   lado no --, y por eso el nombre puede partirse en dos lineas.

   Y por eso NO se envuelve la tarjeta (`nowrap`): sin esto, un nombre largo empujaba el icono y el
   boton de opciones a una linea propia y cada tarjeta de la rejilla salia con el menu en un sitio
   distinto. Lo que se parte es el texto de dentro, que es lo unico que tiene sentido partir. */
.ipol__card--item {
    align-items: flex-start;
    flex-wrap: nowrap;
}

.ipol__card--inv { border-left-color: var(--border-light); }
.ipol__card--inv.is-equipped { border-left-color: var(--tone-gold); }

/* El nombre de un ejemplar no es una linea suelta: lleva dentro el refinamiento, el prefijo de
   forjado y las ranuras, cada uno en su propio <span>. Por eso aqui se deshace el nowrap de
   .ipol__card-text b -- un "+9 Very Strong Muramasa [1]" recortado con puntos suspensivos no dice
   nada -- y se deja partir en dos lineas. */
.ipol__card--item .ipol__card-text b {
    display: block;
    white-space: normal;
    overflow: visible;
}

/* En LINEA y no en bloque: .stg__name es un bloque en la tabla del almacen, y ahi esta bien --
   ocupa su fila --, pero aqui detras va la cantidad, y con el nombre en bloque el "x21" caia solo
   en la linea siguiente. Asi el nombre y la cantidad son un solo parrafo que se parte donde le
   toque. */
.ipol__card--item .stg__name { display: inline; }

.ipol__card--item .stg__tags { margin-top: 3px; }
.ipol__card--item .stg__cards-row { margin-top: 6px; }

/* El boton de opciones nunca se encoge ni se descuelga: la rejilla se lee de un vistazo porque
   todos los menus estan en el mismo sitio. */
.ipol__card--item .ipol__menu { flex: 0 0 auto; }

/* La cantidad va pegada al nombre y en el tono de las cifras: es el dato que en la tabla tenia
   columna propia, y sin destacarla se pierde entre las etiquetas. Inline, no un item flex aparte:
   asi acompana al nombre cuando este se parte en dos lineas en vez de quedarse solo arriba a la
   derecha. */
.ipol__amount {
    margin-left: 8px;
    font-size: 0.8rem;
    font-weight: 700;
    white-space: nowrap;
    color: var(--text-muted);
}

.ipol__card-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }

.ipol__card-text b {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ipol__card-text i {
    margin-top: 2px;
    font-size: 0.74rem;
    font-style: normal;
    color: var(--text-muted);
}

.ipol__x {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.ipol__x:hover { border-color: var(--crimson); color: var(--accent-red); }

.ipol__empty {
    margin: 0;
    padding: 22px 4px;
    color: var(--text-muted);
    font-size: 0.88rem;
}

/* --- Filtrar dentro de la lista (necROmantic 2026-08-24) ---
   Con la incineradora en 1200 objetos, la rejilla necesita un colador propio. No es el buscador
   de .ipol__add: aquel abre un desplegable de resultados del servidor y por eso lleva
   position:relative; este solo escribe en una variable y repinta.
   El [hidden] va explicito porque el atributo solo esconde mientras nadie declare `display` en la
   regla, y eso es justo lo que se olvida al retocar el bloque despues. */

.ipol__filter { margin-bottom: 14px; }
.ipol__filter[hidden] { display: none; }

.ipol__total {
    margin: 0 0 10px;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.ipol__total[hidden] { display: none; }

/* --- Paginacion propia de las dos listas ---
   No reutiliza .stg__pager porque aquel son ENLACES que recargan la pagina
   (Flux_Paginator); estas dos listas se paginan en el navegador sobre datos que ya estan
   aqui, asi que son botones. Con el mismo aspecto: para el jugador es el mismo gesto. */

.ipol__pager {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
    padding: 14px 0 2px;
}

.ipol__pagebtn {
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-link);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
}

.ipol__pagebtn:hover:not(:disabled) { border-color: var(--border-accent); color: var(--text-link-hover); }
.ipol__pagebtn:disabled { opacity: 0.45; cursor: default; }

.ipol__page { font-size: 0.8rem; color: var(--text-muted); }

/* --- Historial de lo ya incinerado (necROmantic 2026-08-23, WEB-08) ---
   Un bloque por DIA y, dentro, la misma .ipol__grid de .ipol__card que usan las tres listas: son
   objetos ensenados igual, y darles otra tarjeta habria sido inventar un segundo lenguaje para
   decir lo mismo. Lo unico propio es la cabecera del dia y el boton de vuelta. */

.ipol__wallet {
    margin: 0 0 10px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.ipol__days { display: flex; flex-direction: column; gap: 22px; }

/* Las tarjetas del historial llevan un tercer bloque que las de las listas no tienen -- el boton
   de recuperar, con su precio dentro --, asi que a 280px el nombre del objeto se quedaba en
   "Jel...". Se les da mas columna y se les deja partir: si el boton no cabe al lado del texto,
   baja a su propia linea en vez de estrujarlo. */
.ipol__day .ipol__grid { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); }
.ipol__day .ipol__card { flex-wrap: wrap; }

.ipol__day-head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 10px;
    padding-bottom: 7px;
    border-bottom: 1px solid var(--border);
}

.ipol__day-head b {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--text-primary);
}

.ipol__day-head i {
    font-size: 0.78rem;
    font-style: normal;
    color: var(--text-muted);
}

/* Lo ya devuelto se queda a la vista -- la fila no se borra al recuperar --, apagado y sin
   boton: es historial, no una oferta. */
.ipol__card--done { opacity: 0.55; }

.ipol__done {
    margin-top: 2px;
    font-size: 0.74rem;
    font-style: normal;
    color: var(--tone-mint);
}

/* De donde salio la fila (necROmantic 2026-08-26). Esta pantalla ya no es solo de la
   incineradora: tambien recoge lo que se vende a mano desde el almacen y el subalmacen, y una
   tarjeta que no diga cual de las dos cosas fue deja al jugador pensando que el servidor le ha
   quemado algo por su cuenta.

   Es una pastilla y no una linea mas de texto porque tiene que leerse ANTES que el pie: va justo
   debajo del nombre y con su propio color.

   EL SELECTOR VA COMPUESTO Y NO SUELTO: `.ipol__card-text i` (mas arriba) es una clase MAS un
   elemento, o sea que le gana en especificidad a `.ipol__from` a secas y le pisaria el color y el
   tamano sin que nada avise. */
.ipol__card-text .ipol__from {
    align-self: flex-start;
    margin-top: 3px;
    padding: 1px 7px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.68rem;
    font-style: normal;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--tone-crimson);
    background: var(--tone-crimson-glow);
}

/* Vendido a mano: el azul del panel, para que no se confunda con el rojo de lo destruido. */
.ipol__card-text .ipol__from--sell {
    color: var(--tone-azure);
    background: var(--tone-azure-glow);
}

.ipol__back {
    flex: 0 0 auto;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-link);
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}

.ipol__back:hover:not(:disabled) { border-color: var(--border-accent); color: var(--text-link-hover); }
.ipol__back:disabled { opacity: 0.4; cursor: not-allowed; }

/* Armado: el primer clic pide confirmacion en el propio boton y el segundo cobra. El color de
   aviso es el mismo oro de .ipol__gate, que en este panel ya significa "para y lee". */
.ipol__back--arm {
    border-color: var(--gold);
    background: var(--alpha-black-22);
    color: var(--gold);
}

/* --- Boton de hamburguesa de cada fila del inventario ---
   Vive en la ULTIMA columna de la tabla, a la derecha de Cantidad (petición del usuario,
   2026-08-11). La columna se queda con lo justo que ocupa el botón. */

.stg__col-menu,
.stg__table thead th.stg__col-menu {
    width: 1%;
    padding-left: 6px;
    text-align: right;
    white-space: nowrap;
}

.ipol__menu { position: relative; display: inline-block; }

.ipol__burger {
    width: 30px;
    height: 30px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.ipol__burger:hover { border-color: var(--border-accent); color: var(--text-primary); }

/* EL ICONO, CENTRADO EN EL BOTON (necROmantic 2026-09-02, peticion del usuario: "los botones de
   menu de hamburguesa no estan centrados vertical y horizontalmente con su icono").

   No estaba mal la caja: estaba mal lo que le entra de fuera. Mas arriba en esta misma hoja, el
   tema viejo trae una regla generica

       button, input[type=button], input[type=reset] { padding: 10px 16px; ... }

   que se cuela en TODO <button> que no ponga el suyo. Con 16 px a cada lado, un boton declarado de
   30 px de ancho se queda en 34 -- ni siquiera cuadrado --, y el icono, que es contenido en linea,
   empieza DESPUES de ese relleno: sale bajo y a la derecha. Medido en la pagina servida: caja de
   34x30 con el contenido arrancando en (17, 11).

   Se arregla en los DOS botones cuadrados de una tarjeta y no solo en el de hamburguesa: la «x» es
   la misma caja con el mismo problema, y desde hoy los dos pueden salir en la misma rejilla -- la
   incineradora ensena hamburguesa a quien puede configurar precios y «x» a quien no --, asi que
   uno centrado y el otro no se notaria a la primera.

   `inline-flex` + centrado en los dos ejes y no un relleno calculado a mano: la caja de un `<i>` de
   Font Awesome no mide lo mismo que su dibujo, y cada icono tiene su propia anchura. Centrando la
   caja da igual que glifo lleve dentro. `line-height: 1` quita el hueco que el interlineado le
   sumaria por debajo. */
.ipol__burger,
.ipol__x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    padding: 0;
    line-height: 1;
}

.ipol__pop {
    position: absolute;
    z-index: 40;
    top: calc(100% + 6px);
    right: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    width: 260px;
    padding: 8px;
    border: 1px solid var(--border-accent);
    border-radius: 12px;
    background: var(--bg-surface);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
    /* La celda que lo contiene lleva `white-space: nowrap` para que el boton no parta linea, y
       eso se HEREDA: sin devolverlo a normal aqui, el motivo y la confirmacion salen en una sola
       linea recortada por el borde del menu. */
    white-space: normal;
    text-align: left;
}

/* Hacia arriba cuando abajo no cabe: la tabla vive en un contenedor con overflow, asi que un
   menu de las ultimas filas se quedaria recortado. Lo decide el JS midiendo (ver haciaArriba). */
.ipol__pop--up {
    top: auto;
    bottom: calc(100% + 6px);
}

.ipol__opt {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.84rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.ipol__opt:hover  { border-color: var(--border-accent); }
.ipol__opt--burn  { border-color: var(--crimson); color: var(--accent-red); }
.ipol__opt--prot  { border-color: var(--tone-azure); color: var(--tone-azure); }
.ipol__opt--store { border-color: var(--tone-mint); color: var(--tone-mint); }
/* Los dos de 2026-08-25: el subalmacen (violeta, el mismo de su tarjeta) y vender (oro, que en
   este panel ya es el color del dinero). */
.ipol__opt--sub   { border-color: var(--tone-violet); color: var(--tone-violet); }
.ipol__opt--sell  { border-color: var(--tone-gold); color: var(--tone-gold); }
.ipol__opt--off   { color: var(--text-muted); }

/* El destino que el objeto YA tiene: se pinta igual que los demas pero apagado y con una marca,
   para que el menu diga donde esta sin cambiar de forma. `cursor: default` porque un boton
   deshabilitado que sigue enseñando la manita promete un clic que no existe. */
.ipol__opt--now { opacity: 0.55; cursor: default; }

/* El "¿cuantos?" del menu de los almacenes. Vive DENTRO del desplegable, con la consecuencia
   escrita debajo, en vez de en un prompt() del navegador: un prompt() se lee fuera de contexto y no
   puede decir de que objeto habla ni cuanto va a costar. */
.ipol__qty {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.ipol__qty input {
    flex: 1 1 auto;
    min-width: 0;
    width: 100%;
    padding: 5px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.82rem;
    font-family: inherit;
}

/* ---------------------------------------------------------------------------------------------
   EL PRECIO AL VENDER DESDE EL ALMACEN (necROmantic 2026-09-02, peticion del usuario)

   Antes las dos cifras -- unitario y total -- iban dentro de una frase corrida, y la que de verdad
   importa (lo que te van a pagar) quedaba en mitad de un parrafo. Aqui van en su propia caja, con
   la etiqueta a la izquierda y el numero a la derecha, alineados en tabular para que al cambiar la
   cantidad no bailen las columnas.
   --------------------------------------------------------------------------------------------- */
.ipol__sell {
    margin: 0 0 8px;
    padding: 8px 10px;
    border: 1px solid var(--gold-dim);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.ipol__sell-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.ipol__sell-row + .ipol__sell-row { margin-top: 4px; }

.ipol__sell-v {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
}

/* El total es la cifra que decide, asi que es la unica grande y en oro. */
.ipol__sell-row--total .ipol__sell-v {
    font-size: 1.02rem;
    color: var(--gold);
}

.ipol__sell-row--total { padding-top: 4px; border-top: 1px solid var(--border); }

/* El campo de la tarifa. Solo lo ven scripttab y el staff. */
.ipol__tariff {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 8px 0 0;
    padding-top: 8px;
    border-top: 1px solid var(--border);
    font-size: 0.76rem;
    color: var(--text-muted);
}

/* La etiqueta no parte: partida en dos lineas dejaba el campo del ancho de un boton. */
.ipol__tariff > span:first-child { white-space: nowrap; }

.ipol__tariff input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 5px 8px;
    border: 1px solid var(--gold-dim);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.82rem;
    font-family: inherit;
    font-variant-numeric: tabular-nums;
}

.ipol__tariff-note {
    margin: 6px 0 0;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.ipol__tariff-note b { color: var(--gold); }

/* La NORMA de precio (necROmantic 2026-09-02). El selector y los dos juegos de campos, de los que
   solo se ve el que corresponde al modo elegido.

   `display: none` por CLASE y no con el atributo `hidden`: la caja lleva `display: grid`, y una
   regla de display siempre gana a `[hidden]`. Es la trampa de [[project_web_hidden_display]], que
   ya mordio dos veces en este mismo panel. */
.ipol__rule {
    display: grid;
    gap: 4px;
    margin-top: 6px;
}

.ipol__rule.is-off { display: none; }

/* Dentro de la norma las etiquetas SI pueden partir y el campo puede encogerse: son mas largas que
   las de fuera y el desplegable solo tiene 260 px. Sin esto el input se salia de la caja. */
.ipol__rule .ipol__tariff > span:first-child { white-space: normal; }
.ipol__rule .ipol__tariff input { min-width: 0; width: 100%; }

/* El campo de tarifa suelto se apaga cuando manda una norma: sigue a la vista para que se entienda
   que existe, pero deja de prometer que se va a usar. */
.ipol__tariff.is-off { opacity: 0.45; }

.ipol__rule-pick select {
    flex: 1 1 auto;
    min-width: 0;
    padding: 5px 8px;
    border: 1px solid var(--gold-dim);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.78rem;
    font-family: inherit;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   CONFIGURAR PRECIOS (necROmantic 2026-09-02, peticion del usuario)
   ══════════════════════════════════════════════════════════════════════════════════════════

   Pantalla propia dentro del desplegable de un objeto, separada de la de vender. Reutiliza el
   molde de la venta (.ipol__sell, .ipol__tariff, .ipol__rule) a proposito: es el mismo formulario
   que estaba dentro de aquella, y darle una caja distinta habria sido inventar un segundo aspecto
   para lo mismo. Lo unico propio es la cabecera y el registro de cambios. */

.ipol__price { display: block; }

.ipol__price-head {
    margin: 0 0 8px;
    font-size: 0.74rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.ipol__price-head b { color: var(--text-primary); }

/* ── El registro de cambios ────────────────────────────────────────────────────────────────
   Una lista, no una tabla: son tres datos por linea y en un desplegable de 260 px una tabla de
   cuatro columnas se estruja hasta ser ilegible. Cada linea es una rejilla de dos filas -- que
   cambio y de cuanto a cuanto arriba, quien y cuando debajo --, que es el orden en que se lee. */

.ipol__log {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}

.ipol__log-head {
    display: block;
    margin-bottom: 6px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.ipol__log-empty {
    display: block;
    font-style: normal;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.ipol__log-rows {
    /* Se desplaza dentro de si misma: con doce cambios la lista es mas alta que la pantalla, y un
       desplegable que crece sin fin empuja el boton de guardar fuera de la vista. */
    max-height: 190px;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    list-style: none;
}

.ipol__log-rows li {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0 8px;
    padding: 5px 0;
    border-top: 1px solid var(--alpha-silver-08);
}

.ipol__log-rows li:first-child { border-top: 0; }

.ipol__log-rows b {
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--text-primary);
}

/* La pareja "de cuanto a cuanto" es el dato del registro, asi que va en cifras tabulares y con el
   color del dinero de este panel: es lo que se busca al abrirlo. */
.ipol__log-v {
    font-size: 0.74rem;
    font-weight: 700;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--tone-gold);
}

.ipol__log-rows i {
    grid-column: 1 / -1;
    font-style: normal;
    font-size: 0.68rem;
    color: var(--text-muted);
}

/* La opcion de menu. Oro apagado y no el oro de vender: son vecinas en el mismo desplegable y la
   que mueve objetos y dinero tiene que seguir siendo la que mas destaca. */
.ipol__opt--price { border-color: var(--gold-dim); color: var(--tone-gold); }

/* ── EL PRECIO UNITARIO EN DORADO Y NEGRITA (peticion del usuario) ─────────────────────────
   En las tarjetas de «Se incineraran» y de «Ya incinerado o vendido». `--tone-gold` y no la rampa
   `--aq-gold-*`: en ESTE panel el oro del dinero ya es este -- es el de la opcion «Vender al NPC»
   --, y meter un segundo dorado a dos centimetros del primero se lee como un error, no como un
   matiz. Tampoco vale `--gold`, que en esta piel es rosa-magenta y conserva ese nombre solo por
   compatibilidad.

   El selector va COMPUESTO (`.ipol__card-text .ipol__zeny`) porque `.ipol__card-text i` es una
   clase mas un elemento y ganaria a una clase suelta, dejando el precio del color del resto del
   pie sin que nada avise. Es la misma trampa que ya documenta .ipol__from aqui al lado. */
.ipol__card-text .ipol__zeny {
    font-weight: 700;
    color: var(--tone-gold);
    font-variant-numeric: tabular-nums;
}

/* ── El precio en la tarjeta del INVENTARIO (peticion del usuario) ─────────────────────────
   Mismo aspecto que el pie de las demas tarjetas. Se le da clase propia en vez de dejarlo como un
   `<i>` suelto porque el JS lo busca por ella para reescribir la cifra cuando alguien acaba de
   cambiar el precio, sin recargar la pagina. */
.ipol__card-foot {
    margin-top: 2px;
    font-size: 0.74rem;
    font-style: normal;
    color: var(--text-muted);
}

/* El aviso de que lo vendido por un GM no sale al mercado. */
.ipol__sell-hidden {
    margin: 6px 0 0;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--tone-violet);
}

/* El aviso de "esto necesita nivel de referido N". No es un error: es una puerta, y por eso no
   va en rojo. */
.ipol__gate {
    margin: 8px 0 0;
    padding: 8px 12px;
    border: 1px solid var(--gold-dim);
    border-radius: 10px;
    background: var(--alpha-black-22);
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.ipol__gate b { color: var(--gold); }
.ipol__gate i { margin-right: 6px; color: var(--gold); }

.ipol__note {
    margin: 0;
    padding: 2px 4px 4px;
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-muted);
}

/* Texto que solo leen los lectores de pantalla: el boton es un icono, y un boton sin
   nombre accesible es un boton que no existe para quien no ve el dibujo. */
.ipol__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --- Las tres etiquetas nuevas del inventario ---
   El azul-plata de "protegido", el rojo fuego de "a la incineradora" y el verde del almacen.
   Son .stg__tag, asi que heredan de alli la forma; aqui solo cambia el color, que es lo que las
   distingue de un vistazo. */

.stg__tag--prot {
    border-color: var(--tone-azure);
    background: linear-gradient(150deg, var(--tone-silver-glow), var(--alpha-black-22));
    color: var(--tone-azure);
}

.stg__tag--burn {
    border-color: var(--crimson);
    background: var(--alpha-black-22);
    color: var(--accent-red);
}

.stg__tag--store {
    border-color: var(--tone-mint);
    background: linear-gradient(150deg, var(--tone-mint-glow), var(--alpha-black-22));
    color: var(--tone-mint);
}

/* El violeta del subalmacen (necROmantic 2026-08-25, peticion del usuario: "en dos colores uno
   para los que se envian al Storage y otro para los que se envian al Substorage"). Es un tono
   distinto y no una variante del verde a proposito: los dos destinos tienen que distinguirse de un
   vistazo, y dos verdes parecidos se distinguen leyendo, que es lo contrario de lo que se pidio. */
.stg__tag--sub {
    border-color: var(--tone-violet);
    background: linear-gradient(150deg, var(--tone-violet-glow), var(--alpha-black-22));
    color: var(--tone-violet);
}

.stg__tag--prot i,
.stg__tag--burn i,
.stg__tag--store i,
.stg__tag--sub i { font-size: 0.66rem; }

/* El hueco de la etiqueta existe siempre (lo rellena el JS), y vacio no debe abrir un
   espacio en la fila de etiquetas: sin esto, el gap de .stg__tags deja un salto delante
   de nada en todos los objetos sin marcar. */
.ipol__slot:empty { display: none; }

@media (max-width: 620px) {
    /* El menu emergente ocupa el ancho de la tarjeta: a 260px fijos se sale de la pantalla
       por la derecha, que es justo el lado al que esta anclado. */
    .ipol__pop { width: min(260px, calc(100vw - 48px)); }
    .ipol__grid { grid-template-columns: 1fr; }

    /* "Recuperar por 1.250.000 z" no cabe en una columna estrecha sin empujar el nombre del
       objeto fuera de la tarjeta: aqui se le deja partir en dos lineas. */
    .ipol__back { white-space: normal; }
    .ipol__subtabs { gap: 4px; }

    /* Los dos botones de destino no caben al lado del nombre en una columna estrecha: bajan a su
       propia linea y se reparten el ancho. */
    .ipol__hit--dual { flex-wrap: wrap; }
    .ipol__hit-acts { width: 100%; margin-left: 0; }
    .ipol__dest { flex: 1 1 0; justify-content: center; }
}

@media (max-width: 620px) {
    .stg__pager { gap: 12px; }
    .stg__bar { flex-direction: column; align-items: stretch; }
    .stg__aside { justify-content: space-between; }
    .stg__count { text-align: left; }
    /* Al desapilar hay que convertir TODOS los niveles (table, tbody, tr, td), no solo
       las celdas: dejar el tbody como table-row-group con hijos de bloque obliga al
       navegador a inventarse celdas anonimas y el resultado es impredecible. */
    .stg__table { display: block; }
    .stg__table thead { display: none; }
    .stg__table tbody { display: block; }
    .stg__table tbody td { display: block; width: auto; border-bottom: 0; padding: 4px 14px; }
    .stg__table tbody tr { display: block; border-bottom: 1px solid var(--border); padding: 10px 0; }
    .stg__col-num { text-align: left; }
    /* Desapilada, la columna del menu deja de ser una columna: es una linea mas de la ficha, y
       el boton se pone a la izquierda con todo lo demas en vez de solo en su renglon. */
    .stg__col-menu,
    .stg__table thead th.stg__col-menu { width: auto; text-align: left; padding-left: 14px; }
    /* Con el thead oculto, una celda numerica se queda sin nombre. Las que llevan
       data-label se lo ponen delante ellas mismas. */
    .stg__table tbody td[data-label]::before {
        content: attr(data-label) ": ";
        color: var(--text-muted);
        font-weight: 600;
    }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Participación e invitaciones
   ══════════════════════════════════════════════════════════════
   Acento VERDE/TEAL: el oro es de la cuota y el violeta del nivel de jugador, así que
   la constancia se lleva su propio color y las tres secciones se distinguen de un
   vistazo al bajar por la página.
   ══════════════════════════════════════════════════════════════ */

.part {
    --part-accent: #3fbf87;
    --part-soft:   rgba(63, 191, 135, 0.15);
    --part-glow:   rgba(63, 191, 135, 0.30);
    --part-deep:   #1d6b4b;

    position: relative;
    margin: 0 0 22px;
    padding: 22px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 150% at 0% 0%, var(--part-soft), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28), inset 0 1px 0 var(--alpha-white-06);
    overflow: hidden;
}

.part::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--part-deep), var(--part-accent) 60%, #8ee7bf);
}

.part__hero {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-bottom: 18px;
}

.part__medal {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 84px;
    height: 84px;
    border-radius: 50%;
    border: 2px solid var(--part-accent);
    background: radial-gradient(circle at 32% 26%, var(--part-soft), var(--bg-input) 70%);
    box-shadow: 0 0 22px var(--part-glow), inset 0 1px 0 var(--alpha-white-08);
    text-align: center;
}

.part__medal b {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-heading2);
}

.part__medal i {
    margin-top: 2px;
    font-style: normal;
    font-size: 0.55rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.part__today { flex: 1 1 auto; min-width: 0; }

.part__today-title {
    margin: 0 0 6px;
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--text-label-strong);
}

.part__today-title b { color: var(--part-accent); }

.part__today--done .part__today-title { color: var(--part-accent); }

.part__today-sub {
    margin: 6px 0 0;
    font-size: 0.85rem;
    color: var(--text-muted);
}

.part__today-track {
    height: 12px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-body), var(--bg-input));
    box-shadow: inset 0 2px 5px var(--alpha-black-34);
    overflow: hidden;
}

.part__today-fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(180deg, #8ee7bf, var(--part-accent) 55%, var(--part-deep));
    box-shadow: 0 0 14px var(--part-glow);
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.part__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
    padding-bottom: 20px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border);
}

.part__stat {
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.part__stat b {
    display: block;
    font-size: 1.28rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-heading2);
}

.part__stat i {
    display: block;
    margin-top: 3px;
    font-style: normal;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* necROmantic 2026-08-09: el "/11" del nivel de racha, más pequeño que la cifra para que
   el nivel se lea de un vistazo y el tope no compita con él. */
.part__stat-of {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-muted);
}

/* Días fallados. Sólo se pinta cuando hay alguno, y en rojo: es la cifra que explica por
   qué el nivel de racha no es el que daría la escalera de días. */
.part__stat--bad { border-color: var(--crimson); }
.part__stat--bad b { color: var(--accent-red); }

/* --- Cupo de invitaciones --- */

.inv {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: 16px;
    align-items: stretch;
    margin: 4px 0 22px;
}

.inv__quota,
.inv__cta {
    padding: 18px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

.inv__quota-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.inv__quota-label {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.inv__quota-left { text-align: right; }
.inv__quota-left b {
    display: block;
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1;
    color: var(--gold);
}
.inv__quota-left i {
    font-style: normal;
    font-size: 0.68rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* La barra mide lo CONSUMIDO, no lo que queda: aquí gastar cupo es avanzar. */
.inv__track {
    height: 14px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-body), var(--bg-input));
    box-shadow: inset 0 2px 5px var(--alpha-black-34);
    overflow: hidden;
}

.inv__fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.inv__legend {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin: 8px 2px 0;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.inv__legend b { color: var(--text-primary); }

.inv__note {
    margin: 10px 0 0;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.inv__cta {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 10px;
    text-align: center;
}

.inv__cta form { margin: 0; padding: 0; }

.inv__btn {
    width: 100%;
    padding: 13px 18px;
    border: 1px solid var(--border-accent);
    border-radius: 10px;
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
    font-family: inherit;
    font-size: 0.94rem;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.2s ease, transform 0.2s ease;
}

.inv__btn:hover { filter: brightness(1.12); transform: translateY(-1px); }

.inv__cta-note {
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.inv__cta-note strong { color: var(--text-primary); }

@media (max-width: 720px) {
    .inv { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 620px) {
    .part { padding: 16px; }
    .part__hero { flex-direction: column; align-items: flex-start; gap: 14px; }
    .part__today { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
    .part__today-fill,
    .inv__fill { transition: none; }
    .inv__btn:hover { transform: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Ficha de personaje (/character/<id>/)
   ══════════════════════════════════════════════════════════════
   Reutiliza a proposito .acchead, .sec-title y todo el bloque .stg del almacen: es la
   misma web y las mismas cosas (una cabecera, secciones, y tablas de objetos), asi que
   no tiene sentido inventar componentes paralelos que luego se desincronicen.
   Lo propio de esta pagina es .chv.
   ══════════════════════════════════════════════════════════════ */

.chv__jobicon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    object-fit: contain;
    image-rendering: pixelated;         /* 25x25 de pixel art */
    filter: drop-shadow(0 1px 3px var(--alpha-black-34));
}

.chv {
    position: relative;
    margin: 0 0 22px;
    padding: 22px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 150% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28), inset 0 1px 0 var(--alpha-white-06);
    overflow: hidden;
}

.chv::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
}

/* --- Barras de HP y SP --- */

.chv__vitals {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin-bottom: 18px;
}

.chv__bar-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.chv__bar-label {
    flex: 0 0 auto;
    width: 26px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}

.chv__bar {
    flex: 1 1 auto;
    height: 16px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-body), var(--bg-input));
    box-shadow: inset 0 2px 5px var(--alpha-black-34);
    overflow: hidden;
}

.chv__bar-fill {
    height: 100%;
    border-radius: 999px;
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.chv__bar-fill--hp { background: linear-gradient(180deg, #7fe0a8, #29a35f 60%, #17603a); }
.chv__bar-fill--sp { background: linear-gradient(180deg, #8fc4ff, #3b7fe0 60%, #204a86); }

/* necROmantic 2026-08-28 (peticion del usuario): "las barras de HP y SP tambien ambas en la misma
   linea" y, debajo, las dos de experiencia igual.

   .chv__bar-pair es solo el envoltorio: mete DOS .chv__bar-row en una fila y les da la misma
   anchura. El `min-width: 0` no es decorativo -- sin el, un hijo flex nunca se encoge por debajo
   de su contenido y la cifra de la derecha empujaria la barra fuera de la caja.

   Las mismas clases las usa el panel del Companero. Son la misma pagina y la misma barra; darle un
   segundo juego de nombres a un componente identico es como acaban existiendo dos componentes que
   se parecen y ya no se pueden cambiar a la vez. */
.chv__bar-pair {
    display: flex;
    gap: 18px;
    align-items: center;
}

.chv__bar-pair > .chv__bar-row {
    flex: 1 1 0;
    min-width: 0;
}

/* La barra de experiencia dice un porcentaje, no una fraccion de cuatro cifras, asi que su hueco
   de texto es la cuarta parte. Con el min-width de 130px de .chv__bar-num, dos barras de exp en
   una fila dejaban a la barra en si menos sitio que a su etiqueta. */
.chv__bar-num--pct {
    min-width: 62px;
}

/* "Base" y "Clase" no caben en los 26px pensados para "HP" y "SP". Se deja que la etiqueta mida lo
   suyo en vez de subir el ancho fijo: con un ancho fijo mayor, las filas de HP/SP heredarian un
   hueco vacio a la izquierda solo para que cupiera una palabra de otra fila. */
.chv__bar-label--wide {
    width: auto;
    white-space: nowrap;
}

/* Las dos barras de experiencia del panel del Compañero. Solo el hueco: la barra en si es la misma
   que la de la ficha, y por eso aqui no se redefine ni un color ni una altura. */
.compa__exp {
    margin: 14px 0 4px;
}

.chv__bar-fill--exp  { background: linear-gradient(180deg, #ffd98a, #e0a531 60%, #8a5f14); }
.chv__bar-fill--jexp { background: linear-gradient(180deg, #d8b6ff, #8b5cd6 60%, #4d2f7d); }

.chv__bar-num {
    flex: 0 0 auto;
    min-width: 130px;
    text-align: right;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-primary);
}

/* --- Cifras principales --- */

.chv__tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 10px;
    padding-bottom: 18px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--border);
}

.chv__tile {
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.chv__tile b {
    display: block;
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-heading2);
}

.chv__tile i {
    display: block;
    margin-top: 3px;
    font-style: normal;
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.chv__tile em {
    display: block;
    margin-top: 4px;
    font-style: normal;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.chv__on  { color: var(--accent-purple) !important; font-size: 1.05rem !important; }
.chv__off { color: var(--text-muted) !important;    font-size: 1.05rem !important; }

/* --- Los seis atributos --- */

.chv__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
    gap: 8px;
}

.chv__stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 10px 8px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: linear-gradient(180deg, var(--alpha-silver-08), transparent);
}

.chv__stat i {
    font-style: normal;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--text-muted);
}

.chv__stat b {
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--text-primary);
}

.chv__points {
    margin: 16px 0 0;
    font-size: 0.85rem;
    color: var(--text-muted);
}

.chv__points strong { color: var(--gold); }

/* --- Vinculos --- */

.chv__bonds {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px;
    margin-bottom: 22px;
}

.chv__bond {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--bg-surface);
}

.chv__bond-emblem { width: 28px; height: 28px; image-rendering: pixelated; }

.chv__bond i {
    display: block;
    font-style: normal;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.chv__bond b { font-size: 0.95rem; font-weight: 600; color: var(--text-primary); }
.chv__bond b a { color: var(--text-link); text-decoration: none; }
.chv__bond b a:hover { color: var(--text-link-hover); }

.chv__bond em {
    display: block;
    margin-top: 2px;
    font-style: normal;
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* --- Homunculo y mascota --- */

.chv__mates {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 12px;
    margin-bottom: 22px;
}

.chv__mate {
    padding: 15px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

.chv__mate header b { display: block; font-size: 1.05rem; color: var(--text-heading2); }
.chv__mate header span { font-size: 0.78rem; color: var(--text-muted); }

.chv__mate-bars {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin: 11px 0;
    font-size: 0.82rem;
    color: var(--text-primary);
}

.chv__mate-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.chv__mate-stats b { color: var(--text-primary); }

.chv__mate footer {
    margin-top: 11px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    font-size: 0.78rem;
    color: var(--text-muted);
}

/* --- El Companero (mercenario renacido) ---
   Bloque .compa de la ficha de personaje. Habla el mismo idioma visual que .chv__mate y
   .chv__tile de aqui arriba a proposito: es una criatura mas de la ficha, no una pantalla
   aparte. Todo con los tokens de :root, ni un color escrito a mano. */

.compa {
    margin-bottom: 22px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

.compa__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 13px;
    padding-bottom: 13px;
    border-bottom: 1px solid var(--border);
}

.compa__icon { width: 34px; height: 34px; image-rendering: pixelated; flex: none; }

.compa__ident { flex: 1 1 auto; min-width: 0; }

.compa__eyebrow {
    margin: 0;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--gold);
}

.compa__name {
    display: block;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-heading2);
    overflow-wrap: anywhere;
}

.compa__class { font-size: 0.78rem; color: var(--text-muted); }

.compa__flags { flex: none; display: flex; flex-wrap: wrap; gap: 6px; }

.compa__flag {
    display: inline-block;
    padding: 3px 9px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.compa__flag--on  { border-color: var(--gold); color: var(--gold); }
.compa__flag--off { color: var(--text-muted); opacity: 0.75; }

.compa__tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 9px;
    margin: 14px 0;
}

.compa__tile {
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
    text-align: center;
}

.compa__tile b {
    display: block;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text-primary);
}

.compa__tile i {
    display: block;
    margin-top: 2px;
    font-style: normal;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.compa__birth,
.compa__warn,
.compa__empty,
.compa__note {
    margin: 0 0 12px;
    font-size: 0.85rem;
    color: var(--text-muted);
}

.compa__birth b { color: var(--gold); font-weight: 600; }
.compa__warn { color: var(--text-primary); }

.compa__note {
    margin: 14px 0 0;
    padding-top: 11px;
    border-top: 1px solid var(--border);
    font-size: 0.78rem;
}

.compa__subtitle {
    margin: 16px 0 9px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* La linea del tiempo del linaje. Es una <ol> de verdad -- el orden ES el dato -- pero sin
   numeracion: la marca de cada paso es el punto de la izquierda. */
.compa__line {
    margin: 0;
    padding: 0 0 0 17px;
    list-style: none;
    border-left: 1px solid var(--border);
}

/* necROmantic 2026-08-27 (informe del usuario: "este tipo de cosas del companero se
   visualizan muy mal, muy rotas").

   EL PASO DEL LINAJE SE LLAMABA `.compa__step` Y ESE NOMBRE YA ESTABA COGIDO. Mas abajo, en el
   bloque "lo EDITABLE" del 2026-08-25, `.compa__step` se volvio a declarar para OTRA cosa: el
   botoncito cuadrado de +/- de caracteristicas, con `width: 28px; height: 28px;
   display: inline-flex`. Dos componentes distintos con el mismo nombre; el que va despues gana,
   asi que cada `<li>` de la historia pasaba a ser una caja de 28x28 en fila, con la fecha, los
   oficios y los niveles amontonados unos encima de otros dentro. La <ol> no estaba rota: estaba
   siendo pintada como una hilera de botones.

   Se renombra ESTE (que se usa en un solo sitio) y no el boton (que se usa en muchos y va a
   seguir usandose en el planificador). `hito` porque es lo que es: un hito del linaje. */
.compa__hito {
    position: relative;
    margin: 0 0 12px;
    padding: 0;
}

.compa__hito:last-child { margin-bottom: 0; }

.compa__hito::before {
    content: "";
    position: absolute;
    left: -21px;
    top: 6px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--gold);
}

.compa__when {
    display: block;
    font-size: 0.7rem;
    color: var(--text-muted);
}

.compa__jobs {
    display: block;
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text-primary);
}

.compa__meta {
    display: block;
    font-style: normal;
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* --- El Companero: lo EDITABLE (necROmantic 2026-08-25) ---
   Mismo BEM que el bloque de arriba (.compa__*) y los mismos tokens de :root. Nada aqui
   pinta un color a mano, y no hay ni un estilo en linea en la plantilla: la ficha ya ha
   pagado ese error antes.

   Cada formulario es un POST de toda la vida, sin JavaScript, asi que estas clases solo
   tienen que vestir controles nativos. */

.compa__hint {
    margin: 6px 0 14px;
    font-size: 0.76rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.compa__count {
    margin: 0 0 10px;
    font-size: 0.82rem;
    color: var(--text-primary);
}

.compa__held {
    display: inline-block;
    margin-left: 6px;
    font-size: 0.76rem;
    color: var(--gold-dim);
}

/* La cola de peticiones. Es una lista de hechos, no un adorno: si hay algo aqui es que el
   juego todavia no lo ha aplicado. */
.compa__queue {
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
}

.compa__qrow {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 7px 11px;
    margin-bottom: 6px;
    border: 1px dashed var(--border-light);
    border-radius: 9px;
    background: var(--bg-surface);
}

.compa__qwhat { font-size: 0.85rem; font-weight: 600; color: var(--text-primary); }
.compa__qwhen { font-style: normal; font-size: 0.72rem; color: var(--text-muted); }

/* Lo que el motor YA contesto. Misma caja que la cola de arriba, pero con el borde SOLIDO
   -- lo de arriba todavia puede cambiar, esto ya no -- y una barra de color a la izquierda
   que dice de un vistazo si colo o no. El veredicto va en su propia linea (flex-basis del
   100%) porque son frases enteras, no etiquetas: partirlas en dos columnas las dejaria
   ilegibles en el movil. */
.compa__answers {
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
}

.compa__arow {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 7px 11px;
    margin-bottom: 6px;
    border: 1px solid var(--border-light);
    border-left: 3px solid var(--border-light);
    border-radius: 9px;
    background: var(--bg-surface);
}

.compa__arow--ok { border-left-color: var(--text-success); }
.compa__arow--no { border-left-color: var(--text-error); }

.compa__averdict {
    flex: 1 1 100%;
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--text-primary);
}

.compa__adetail {
    flex: 1 1 100%;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.compa__form { margin: 0 0 10px; }

.compa__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 7px;
}

/* Los corchetes son texto FIJO a los lados del campo, no parte de lo que se escribe: son
   la marca infalsificable y el jugador no puede ponerlos ni quitarlos. */
.compa__bracket {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--gold);
}

.compa__input,
.compa__select,
.compa__num {
    padding: 6px 9px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.88rem;
    font-family: inherit;
}

.compa__input  { flex: 1 1 190px; min-width: 0; }
.compa__select { flex: 0 1 240px; }
.compa__num    { width: 68px; text-align: right; }

.compa__input:focus,
.compa__select:focus,
.compa__num:focus { outline: 1px solid var(--border-accent); }

.compa__btn {
    padding: 6px 13px;
    border: 1px solid var(--border-light);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}

.compa__btn:hover {
    border-color: var(--gold);
    color: var(--gold);
}

.compa__btn--small { padding: 3px 9px; font-size: 0.72rem; }

/* necROmantic 2026-08-26 (peticion del usuario: "los botones de subir bajar").
   El par -/+ de las habilidades. Cuadrado y con el signo centrado, para que se lea como pareja y
   no como dos botones sueltos; el texto de que hace cada uno vive en su `title`/`aria-label`. */
.compa__btn--step {
    min-width: 28px;
    padding: 3px 0;
    font-size: 0.95rem;
    line-height: 1;
    font-weight: 700;
    text-align: center;
}

/* Las seis caracteristicas. Cada una es su propio <form> porque cada una lleva su cantidad. */
.compa__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 8px;
    margin: 0 0 14px;
}

.compa__stat {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 7px;
    padding: 8px 11px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-surface);
}

.compa__statname {
    flex: none;
    width: 34px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    color: var(--text-muted);
}

.compa__statval {
    flex: none;
    min-width: 42px;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
}

/* Lo que ya esta pedido y sin aplicar se ensena aparte del valor real: sumarlo al numero
   seria decir que ya lo tiene. */
.compa__statheld { font-style: normal; font-size: 0.76rem; color: var(--gold-dim); }

.compa__statnote {
    flex: 1 1 100%;
    font-style: normal;
    font-size: 0.71rem;
    color: var(--text-muted);
}

/* --- El Companero: PESTANAS (2026-08-26, peticion del usuario) ---
   Cinco arriba y una fila de sub-pestanas dentro de Habilidades, una por oficio del linaje.
   Hablan el mismo idioma visual que .cpan__tab del panel de asistencia a proposito: son la misma
   idea en la misma ficha, y dos formas distintas de pintar una pestana se notan.

   SIN JAVASCRIPT SE VEN TODAS SEGUIDAS, y esta bien asi: --off solo lo pone el guion. */

.compa__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 15px;
    padding-bottom: 11px;
    border-bottom: 1px solid var(--border);
}

.compa__tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-surface);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.8rem;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.compa__tab i { font-size: 0.78rem; }
.compa__tab:hover { color: var(--text-primary); background: var(--bg-table-alt); }

.compa__tab.is-on {
    border-color: var(--gold-dim);
    background: var(--bg-surface-alt);
    color: var(--gold);
    font-weight: 600;
}

/* --- MERCENARIO V2: la pestana DESACTIVADA (necROmantic 2026-09-02, D-6, §6.1-ter) ---

   PIEZA 3 DE 4. Las otras tres son el `disabled` nativo del boton, el cuerpo del panel que NO se
   emite, y el rechazo del modulo. Esta solo hace que se VEA lo que ya es.

   Que la pestana siga ahi es deliberado: una que desaparece deja al jugador preguntandose si su
   mercenario tiene equipo o si el panel esta roto; una tachada le dice que existe y que no es para
   el. Tokens los que ya hay -- nada de colores nuevos --, `cursor: not-allowed`, y sin `:hover`.

   ⚠️ EL `:hover` HAY QUE APAGARLO A MANO Y CON MAS PESO, y esta es la parte que se olvida: `:hover`
   sigue casando sobre un elemento `disabled`, asi que `.compa__tab:hover` (0,2,0) le encenderia el
   color a una pestana muerta. `.compa__tab.is-off:hover` vale (0,3,0) y gana. Y el `box-shadow: 0`
   no es de adorno: la hoja base trae un `button:hover` global con un resplandor de 28 px que
   tambien alcanza a esto. Es exactamente la trampa que ya documenta este fichero mas abajo para
   .compa__btn. */

.compa__tab.is-off,
.compa__tab.is-off:hover,
.compa__tab.is-off:focus {
    border-color: var(--border);
    background: var(--bg-surface);
    color: var(--text-muted);
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
    font-weight: 400;
}

.compa__tab.is-off i { opacity: 0.8; }

/* --- MERCENARIO V2: las secciones propias del panel --------------------------------

   `.compa__h4` existia como nombre en el marcado y NO como regla: en Caracteristicas el trabajo lo
   hacia `.compa__caract-h`, que es de esa seccion. Se escribe aqui para que un titulillo de seccion
   se vea igual en las tres pantallas nuevas sin tener que colgarse de la clase de otra. */

.compa__h4 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 12px;
}

.compa__h4 i { opacity: 0.75; }

/* La lealtad y el disfraz son secciones DENTRO de una pestana, no pestanas: se separan de lo de
   arriba con la misma linea con la que Caracteristicas se separa de las barras. */
.compa__merc {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

/* Las tres clases contratables. Es la misma lista de `.compa__locked` -- lo que no se puede coger
   todavia, con su motivo -- pero cada fila lleva ademas su boton, asi que el boton se va al final
   de la linea en vez de quedarse pegado al texto. */
.compa__merclist .compa__lockrow {
    align-items: center;
    gap: 6px 12px;
}

.compa__merclist .compa__todo-form { margin-left: auto; }

.compa__panel--off,
.compa__subpanel--off { display: none; }

.compa__subtabs {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin: 0 0 12px;
}

.compa__subtab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-surface);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.75rem;
    cursor: pointer;
}

.compa__subtab:hover { color: var(--text-primary); }

.compa__subtab.is-on {
    border-color: var(--accent-purple);
    color: var(--text-primary);
    background: var(--bg-surface-alt);
}

/* Cuantas habilidades trae ese oficio. Es lo que evita abrir cuatro pestanas para descubrir
   que en tres no hay nada. */
.compa__subtab-n {
    font-size: 0.68rem;
    color: var(--text-muted);
    background: var(--bg-input);
    border-radius: 999px;
    padding: 0 6px;
}

/* Lo que contesta el servidor cuando se pide algo sin recargar. Nace oculto: `hidden` solo
   funciona si nada le pone `display`, asi que la regla va escrita. */
.compa__msg {
    margin: 0 0 12px;
    padding: 9px 13px;
    border-radius: 9px;
    border: 1px solid var(--border);
    font-size: 0.8rem;
    line-height: 1.5;
}

.compa__msg[hidden] { display: none; }
.compa__msg--ok { border-color: var(--gold-dim); background: var(--bg-surface-alt); color: var(--text-primary); }
.compa__msg--no { border-color: var(--danger, #a33); background: var(--bg-surface-alt); color: var(--text-primary); }

/* Mientras una peticion esta en vuelo. No se bloquea nada: solo se dice que esta pasando algo. */
.compa.is-busy { opacity: 0.72; }
.compa.is-busy .compa__btn,
.compa.is-busy .compa__step { pointer-events: none; }

/* --- Caracteristicas: subir Y BAJAR --- */

.compa__statctl {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: none;
}

.compa__step {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.compa__step:hover:not(:disabled) { border-color: var(--gold-dim); color: var(--gold); }
.compa__step:disabled { opacity: 0.35; cursor: not-allowed; }
.compa__step--down:hover:not(:disabled) { border-color: var(--accent-purple); color: var(--accent-purple); }

/* --- Habilidades: una tarjeta por habilidad --- */

.compa__skills {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
    gap: 8px;
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
    max-height: 460px;
    overflow-y: auto;
}

.compa__skill {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 9px 11px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
}

/* LOS CUATRO ESTADOS DE UNA HABILIDAD (necROmantic 2026-08-28, petición del usuario).
 *
 * El relieve crece con lo que la tarjeta significa, y el ORDEN DE LAS REGLAS ES EL ORDEN DEL
 * RELIEVE: bloqueada < aprendible < aprendida < al máximo. Escritas así, la que gana es siempre la
 * de más abajo, y añadir un estado nuevo es meterlo en su sitio de la escalera en vez de pelearse
 * con especificidades.
 *
 * La base (sin modificador) es la BLOQUEADA, y es la única que debe verse apagada: le faltan
 * requisitos, así que decir "todavía no" es exactamente su trabajo. Hasta hoy TODAS las no
 * aprendidas se veían así, incluidas las que se podían aprender en ese mismo momento. */
.compa__skill {
    opacity: 0.62;                     /* bloqueada: apagada a propósito */
    transition: opacity 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

/* APRENDIBLE YA: a plena luz y con un filo dorado tenue que invita a pulsar. Sin sombra todavía --
   la sombra es de las que ya se tienen --, para que no compita con ellas. */
.compa__skill--open {
    opacity: 1;
    border-color: var(--gold-dim);
    background: var(--bg-surface);
    box-shadow: inset 0 0 0 1px var(--alpha-gold-12, rgba(212, 175, 55, 0.12));
}

/* APRENDIDA: relieve de verdad. Sombra proyectada corta y borde de oro pleno. */
.compa__skill--known {
    opacity: 1;
    background: var(--bg-surface-alt);
    border-color: var(--gold);
    box-shadow: 0 2px 6px var(--alpha-black-34), inset 0 1px 0 var(--alpha-gold-12, rgba(212, 175, 55, 0.14));
}

/* AL MÁXIMO: el más fuerte. Sombra más larga, borde de dos píxeles y un halo exterior que la
   despega de la rejilla. El `padding` se compensa para que el borde grueso NO mueva la tarjeta:
   sin esa resta, subir la última habilidad al tope daría un salto de un píxel en toda la fila. */
.compa__skill--max {
    opacity: 1;
    background: var(--bg-surface-alt);
    border: 2px solid var(--gold);
    padding: 8px 10px;
    box-shadow: 0 3px 10px var(--alpha-black-34), 0 0 0 1px var(--alpha-gold-12, rgba(212, 175, 55, 0.22));
}

/* De dónde sale, no cuánto se tiene: se acumula con cualquiera de los cuatro. */
.compa__skill--plat  { border-style: dashed; }

.compa__skhead {
    display: flex;
    align-items: center;   /* necROmantic 2026-08-26: `baseline` descuadraba el icono nuevo */
    gap: 8px;
}

/* necROmantic 2026-08-26 (peticion del usuario: "quiero que se vea el icono").
   Tamano fijo y `flex: none` para que la fila no baile entre una habilidad con icono y otra sin
   el -- hay 356 sin icono en el GRF, asi que las dos cosas conviven en el mismo arbol. */
.compa__skicon {
    flex: none;
    width: 24px;
    height: 24px;
    object-fit: contain;
    image-rendering: pixelated;   /* son sprites de 24px: sin esto el navegador los emborrona */
}

.compa__skname { flex: 1 1 auto; font-size: 0.83rem; color: var(--text-primary); }

.compa__sklv {
    flex: none;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--gold);
}

.compa__sknote {
    font-style: normal;
    font-size: 0.71rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.compa__sknote--wait { color: var(--gold-dim); }

/* Lo que se caeria al olvidarla. Va en otro color porque es una advertencia, no una nota. */
.compa__skfall {
    font-style: normal;
    font-size: 0.7rem;
    line-height: 1.45;
    color: var(--accent-purple);
}

.compa__skform {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    margin-top: auto;
}

/* --- Planificar el arbol entero y mandarlo de golpe (necROmantic 2026-08-26) ---
   El selector de niveles vive dentro de la tarjeta pero PERTENECE al formulario del final
   (atributo `form`), asi que aqui solo se viste: no hay nada que hacer con el anidamiento.
   Y no hay ni un estilo inline en la vista -- todo lo que cambia el guion son numeros y
   clases, nunca `style`. */

.compa__skplan {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: auto;      /* pega el bloque al pie de la tarjeta, como .compa__skform */
}

.compa__skplan-lb {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

/* Mas estrecho que el de caracteristicas: aqui el numero mas grande que cabe son dos cifras. */
.compa__num--plan { width: 56px; }

.compa__skplan-room {
    font-size: 0.7rem;
    color: var(--text-muted);
}

/* La nota de "marca antes el requisito". Va en el color de aviso y no en el de nota gris porque
   es lo unico que separa una casilla que se puede rellenar de una que el motor va a rechazar. */
.compa__sknote--req { color: var(--accent-purple); }

/* El pie de la pestana: presupuesto y UN solo boton. */
.compa__batch {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 4px 0 12px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface-alt);
}

.compa__batch-count {
    flex: 1 1 220px;
    margin: 0;
    font-size: 0.82rem;
    color: var(--text-primary);
}

.compa__batch-count b { color: var(--gold); }

/* Pasarse de puntos se ve ANTES de pulsar: el numero cambia de color y el boton se apaga. */
.compa__batch.is-over { border-color: var(--accent-purple); }
.compa__batch.is-over .compa__batch-count b { color: var(--accent-purple); }

.compa__batch-over {
    flex: 1 1 100%;
    order: 3;
    font-style: normal;
    font-size: 0.74rem;
    color: var(--accent-purple);
}

/* ⚠️ El `display` explicito para `[hidden]`: sin el, el `display: block` de la regla de arriba
   gana al del navegador y el aviso se queda visible con el atributo puesto. Ya mordio dos veces
   en este panel. */
.compa__batch-over[hidden] { display: none; }

.compa__btn--send:disabled { opacity: 0.4; cursor: not-allowed; }

/* El texto largo de debajo del boton ocupa la fila entera. */
.compa__batch .compa__hint {
    flex: 1 1 100%;
    order: 4;
    margin: 0;
}

.compa__badge {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.66rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.compa__badge--plat {
    background: var(--bg-input);
    border: 1px solid var(--gold-dim);
    color: var(--gold);
}

.compa__btn--off {
    border-color: var(--border);
    color: var(--text-muted);
    background: var(--bg-input);
}

.compa__btn--off:hover { color: var(--text-primary); }
.compa__btn--on { border-color: var(--gold-dim); color: var(--gold); }
.compa__btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* --- Los cambios de clase que todavia no le tocan --- */

.compa__locked {
    margin: 10px 0 0;
    padding: 0;
    list-style: none;
}

.compa__lockrow {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.79rem;
}

.compa__lockrow:last-child { border-bottom: 0; }
.compa__lockrow b { color: var(--text-primary); }
.compa__lockrow em { font-style: normal; font-size: 0.73rem; color: var(--text-muted); }

/* --- Equipamiento: el maniqui y la mochila, los dos en rejilla --- */

.compa__warn--bad {
    border-left: 3px solid var(--accent-purple);
    padding-left: 10px;
}

/* Las dos acciones que valen para el Companero ENTERO, no para una ranura (2026-08-28):
   desequipar todo y restablecer el aspecto. Van en fila debajo de la rejilla; cada boton es su
   propio formulario porque cada uno manda un `op` distinto, y sin el flex saldrian uno por linea
   como dos parrafos sueltos. */
.compa__todo {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 8px;
}

.compa__todo-form {
    margin: 0;
}

.compa__gear {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 8px;
    margin: 0 0 16px;
}

.compa__slot {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 9px 11px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
    min-height: 78px;
}

/* Un hueco vacio tambien es informacion: se ve que esta y que no lleva nada. */
.compa__slot--free { background: transparent; border-style: dashed; }
.compa__slot--bad  { border-color: var(--accent-purple); }

.compa__slot-where {
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.compa__slot-body {
    display: flex;
    align-items: flex-start;
    gap: 9px;
}

.compa__slot-icon {
    width: 28px;
    height: 28px;
    flex: none;
    image-rendering: pixelated;
    object-fit: contain;
}

.compa__slot-icon--none {
    border: 1px dashed var(--border);
    border-radius: 6px;
}

.compa__slot-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 0.79rem;
}

.compa__slot-text b { font-weight: 500; color: var(--text-primary); }

.compa__slot-note {
    font-style: normal;
    font-size: 0.71rem;
    color: var(--text-muted);
}

.compa__slot-bad {
    font-style: normal;
    font-size: 0.71rem;
    color: var(--accent-purple);
}

.compa__slot-form { margin-top: auto; }

.compa__filter {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    padding: 7px 11px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-input);
}

.compa__filter-icon { color: var(--text-muted); font-size: 0.78rem; }

.compa__filter-input {
    flex: 1 1 auto;
    border: 0;
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.82rem;
    outline: none;
}

.compa__bag {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 8px;
    margin: 0 0 12px;
    max-height: 460px;
    overflow-y: auto;
}

.compa__card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 9px 11px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
}

/* necROmantic 2026-08-26: la pestana de inventario (mandar objetos entre las dos mochilas).
   Todo lo de aqui vive DENTRO de .compa__card, que ya existia: son piezas que se le anaden a la
   tarjeta, no una tarjeta nueva. */

/* La cantidad de una pila, arriba a la derecha del icono. */
.compa__amount {
    align-self: flex-start;
    font-size: 0.74rem;
    font-weight: 700;
    color: var(--gold);
}

/* Los dos botones de una misma pieza ("ponerselo" y "recuperar") en la misma linea. */
.compa__cardacts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

/* El selector de cuantas unidades. Solo sale con pilas de mas de una, asi que la etiqueta va
   pegada al numero y no encima: en una tarjeta estrecha, un rotulo por linea propia empuja el
   boton fuera de la vista. */
.compa__amountbox {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-right: 6px;
}

.compa__num {
    width: 68px;
    padding: 2px 6px;
    font-size: 0.78rem;
    color: var(--text-primary);
    background: var(--bg-input, var(--bg-surface));
    border: 1px solid var(--border);
    border-radius: 6px;
}

.compa__card[hidden] { display: none; }

.compa__to {
    font-size: 0.68rem;
    opacity: 0.8;
    margin-left: 5px;
}

.compa__prot {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.68rem;
    color: var(--gold);
}

/* Lo que NO le vale. Se cuenta y se puede desplegar: "no aparece" y "aparece y dice por que"
   no son lo mismo. */
.compa__rest {
    margin: 6px 0 0;
    padding: 9px 12px;
    border: 1px dashed var(--border);
    border-radius: 9px;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.compa__rest summary { cursor: pointer; }

.compa__restlist {
    margin: 9px 0 0;
    padding: 0;
    list-style: none;
    max-height: 260px;
    overflow-y: auto;
}

.compa__restlist li {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}

.compa__restlist li:last-child { border-bottom: 0; }
.compa__restlist b { font-weight: 500; color: var(--text-secondary, var(--text-primary)); }
.compa__restlist em { font-style: normal; color: var(--text-muted); }

/* El pie: la cola. Fuera de las pestanas a proposito -- una peticion de una pestana y otra de
   otra esperan en la misma fila. */
.compa__foot {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

/* necROmantic 2026-08-26: el pie paso a ser un <details> plegable (peticion del usuario). Su
   <summary> tiene que parecer un titulo pulsable, no una linea de texto con una flecha delante. */
.compa__foot > summary {
    cursor: pointer;
    list-style: none;          /* fuera el triangulo por defecto: lo pinta ::before */
    display: flex;
    align-items: center;
    gap: 8px;
}

.compa__foot > summary::-webkit-details-marker { display: none; }

.compa__foot > summary::before {
    content: "\25B8";          /* triangulo a la derecha; gira al abrirse */
    font-size: 0.8em;
    color: var(--gold);
    transition: transform 0.15s ease;
}

.compa__foot[open] > summary::before { transform: rotate(90deg); }

/* El boton de limpiar, separado de la lista para que no se lea como parte de la primera fila. */
.compa__clearform {
    margin: 10px 0 6px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   necROmantic 2026-08-26: EL COMPANERO -- CUADRAR LOS CONTROLES Y DARLES ESTADO
   (peticion del usuario: "mejora tambien la interactividad y que cada boton este
   perfectamente alineado sin descuadres")

   Va AL FINAL de la seccion .compa__ a proposito. Lo que corrige se escribio arriba
   en tandas distintas -- las cinco pestanas viejas por un lado y las dos nuevas
   (Inventario y Disfraces) por otro -- y la unica forma de cuadrarlo sin tocar el
   marcado, que ahora mismo esta en otras manos, es ganar por ORDEN en la cascada.
   Ni un color escrito a mano: todo sale de los tokens de :root.
   ═══════════════════════════════════════════════════════════════════════════ */

/* UNA sola altura para todo lo pequeno del panel, y el descuadre de fondo era este: un
   <button> se mide por su padding y su fuente, y un <input type="number"> por las suyas,
   que no son las mismas. Dos vecinos de la misma fila -- los -/+ y la casilla de cantidad --
   no coincidian nunca. Con una altura comun dejan de depender de la tipografia. */
.compa { --compa-ctl: 28px; }

.compa__num { height: var(--compa-ctl); }

.compa__btn--small,
.compa__btn--step { min-height: var(--compa-ctl); }   /* min- y no height: si el rotulo parte
                                                          en dos lineas, que crezca en vez de
                                                          recortarse */

.compa__step {
    width: var(--compa-ctl);
    height: var(--compa-ctl);
}

/* La casilla del planificador de la tanda volvia a medir 68px: `.compa__num--plan` se escribio
   ANTES del segundo bloque de `.compa__num`, que repite `width` con la misma especificidad y
   gana por ir despues. Se vuelve a poner aqui, que ya es el final de la seccion. */
.compa__num--plan { width: 56px; }

/* El boton por dentro. Era un `inline-block` con el contenido colgado de la linea base, asi que
   la escoba de "limpiar" y el "a: Cabeza" de "ponerselo" se sentaban a distinta altura que su
   propio rotulo. Centrado en los dos ejes se acaba, y de paso el signo del par -/+ queda en el
   centro del cuadrado sin depender del `line-height`. */
.compa__btn {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /* Solo color y `transform`. NUNCA `width`/`height`: eso obliga al navegador a recalcular
       la fila entera en cada fotograma. */
    transition: color 0.15s, border-color 0.15s, background-color 0.15s, opacity 0.15s, transform 0.15s;
}

/* El hueco ya lo pone el `gap` de arriba; el margen suelto lo sumaba dos veces. */
.compa__btn > .compa__to { margin-left: 0; }

/* El par -/+ de Habilidades medía distinto que el de Caracteristicas: el MISMO par en dos
   tamanos. Y como el "-" y el "+" no ocupan lo mismo, el boton se encogia segun el signo y
   corria de sitio al de al lado. Cuadrado y fijo: los dos pares se leen ya como un solo
   control, que es lo que dice el comentario de arriba que tenian que ser. */
.compa__btn--step {
    width: var(--compa-ctl);
    min-width: var(--compa-ctl);
    padding: 0;
    /* Con un ancho fijo, `wrap` heredado de .compa__btn dejaria el signo en una segunda linea
       si el tema base le colara un ::before. Aqui dentro solo hay un caracter: que no parta. */
    flex-wrap: nowrap;
}

/* --- Estados: raton, teclado, pulsacion y apagado -------------------------- */

.compa__step,
.compa__subtab { transition: color 0.15s, border-color 0.15s, background-color 0.15s, opacity 0.15s, transform 0.15s; }

/* `:focus-visible` no es un adorno aqui: el panel se REPINTA ENTERO por AJAX despues de cada
   accion, asi que quien navega con teclado necesita ver donde ha quedado el foco cuando el
   contenido vuelve. Mismo anillo que .gift-btn, para no inventar un segundo idioma. */
.compa__btn:focus-visible,
.compa__step:focus-visible,
.compa__tab:focus-visible,
.compa__subtab:focus-visible,
.compa__foot > summary:focus-visible,
.compa__rest > summary:focus-visible {
    outline: 2px solid var(--border-accent);
    outline-offset: 2px;
}

/* El acuse de recibo de la pulsacion. Un pixel basta, y con `transform` no se reserva sitio:
   el vecino no se entera. */
.compa__btn:active:not(:disabled),
.compa__step:active:not(:disabled) { transform: translateY(1px); }

/* Un boton apagado tiene que verse apagado TAMBIEN con el raton encima. `:hover` sigue casando
   sobre un `disabled`, asi que `.compa__btn--off:hover` le encendia el color a un boton que no
   hace nada. Estas ganan por especificidad (0,3,0 contra 0,2,0). */
.compa__btn:disabled,
.compa__btn:disabled:hover {
    border-color: var(--border);
    color: var(--text-muted);
    cursor: not-allowed;
    transform: none;
}

/* ...pero el boton de la opcion VIGENTE (el genero que ya tiene) no esta apagado: esta elegido.
   Sale `disabled` para no volver a pedir lo que ya se tiene, y con la opacidad general del
   disabled la opcion en vigor acababa siendo lo mas palido de la pantalla, justo al reves de
   lo que hay que leer. */
.compa__btn--on:disabled,
.compa__btn--on:disabled:hover {
    opacity: 1;
    cursor: default;
    border-color: var(--gold-dim);
    color: var(--gold);
}

/* ⚠️ TRAMPA GORDA DE LA HOJA BASE, y es la que peor se veia de todo el panel.
   Mucho mas arriba (la parte heredada de flux.css) hay un `button:hover` global que trae
   `background: var(--grad-secondary-button-hover)` -- un degradado ROSA-MORADO -- y
   `box-shadow: var(--shadow-secondary-hover)`, un resplandor de 28px. Ese selector vale
   (0,1,1) y `.compa__btn` vale (0,1,0): gana el global. Como el hover del panel solo
   declaraba borde y color, al posar el raton el boton se pintaba de rosa y el rotulo -- que
   en esta piel TAMBIEN es rosa, porque var(--gold) es rosa-magenta -- se perdia dentro del
   fondo. Se declara aqui el fondo y la sombra en el estado hover para taparlo. No hay ningun
   color nuevo: es el mismo fondo que ya tiene el control en reposo, y el aviso de "estas
   encima" sigue siendo el borde y el texto dorados, como se penso. */
.compa__btn:hover,
.compa__step:hover,
.compa__tab:hover,
.compa__subtab:hover { box-shadow: none; }

.compa__btn:hover     { background: var(--bg-surface-alt); }
.compa__btn--off:hover{ background: var(--bg-input); }
.compa__step:hover    { background: var(--bg-input); }
.compa__subtab:hover  { background: var(--bg-surface-alt); }


/* --- Las filas de botones de las tarjetas ---------------------------------- */

/* UN <form> ES `block`. En Inventario y Disfraces cada accion es su propio formulario, y dentro
   conviven la casilla de cantidad y el boton: al ser una caja de bloque, sus hijos se colocaban
   como si fueran texto -- alineados por la LINEA BASE -- y dos controles que no miden lo mismo
   quedaban a distinta altura. En fila flexible y centrados, cuadran. */
.compa__card form,
.compa__slot-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

/* El hueco lo pone el `gap` de la fila. El margen suelto lo duplicaba y ademas separaba la
   etiqueta "Cantidad" del numero al que pertenece. */
.compa__amountbox { margin-right: 0; }
.compa__amountbox .compa__held { margin-left: 0; }

/* --- Los botones, anclados ABAJO en las rejillas --------------------------- */

/* .compa__bag y .compa__gear son rejillas: las tarjetas de una misma fila se estiran a la altura
   de la mas alta, pero su contenido no. Con un nombre de objeto de dos lineas al lado de otro de
   una, el boton de la corta se quedaba a media tarjeta y ninguna fila cuadraba. `margin-top: auto`
   se come el sobrante por ARRIBA y deja la accion al pie -- que es lo que ya hacia
   .compa__slot-form y aqui solo se termina de aplicar al resto. */
.compa__card > form,
.compa__card > .compa__cardacts { margin-top: auto; }

/* DOS `margin-top: auto` en la misma tarjeta NO anclan: el sobrante se REPARTE entre los dos, asi
   que el planificador de niveles y la fila -/+ se quedaban los dos flotando a media altura. Basta
   con anclar el primero: todo lo que va detras baja con el, en bloque. */
.compa__skplan ~ .compa__skform { margin-top: 0; }

/* --- Los dos plegables del panel ------------------------------------------- */

/* El pie ya se peina solo (triangulo dorado propio); el de "lo que no le vale" se quedo con el
   triangulo del navegador, asi que dos plegables de la misma pantalla se abrian con dos flechas
   distintas. Y el margen de .compa__subtitle -- pensado para un titulo suelto -- dejaba el rotulo
   del plegable descentrado dentro de su propia caja. */
.compa__rest > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
}

.compa__rest > summary::-webkit-details-marker { display: none; }

.compa__rest > summary::before {
    content: "\25B8";
    font-size: 0.8em;
    color: var(--gold);
    transition: transform 0.15s ease;
}

.compa__rest[open] > summary::before { transform: rotate(90deg); }

.compa__foot > summary.compa__subtitle,
.compa__rest > summary.compa__subtitle { margin: 0; }

/* --- La caja del filtro ---------------------------------------------------- */

/* El campo lleva `outline: none` para que la caja se lea como una sola pieza; el precio era que
   con el teclado no se veia DONDE estabas. La pista la da ahora la caja entera, que es
   exactamente lo que el jugador ve como "el campo". */
.compa__filter:focus-within { outline: 1px solid var(--border-accent); }

/* --- Mientras el juego aplica la orden ------------------------------------- */

/* Con `pointer-events: none` los botones dejaban de responder pero el raton seguia ensenando la
   manita: parecia colgado en vez de ocupado. */
.compa.is-busy { cursor: progress; }

/* --- necROmantic 2026-08-26: "Aplicando en el juego, un momento..." ---------
   El aviso que sale mientras el guion sondea si el juego ya ha aplicado la orden. El marcado
   lo pone otra tarea; el estilo se escribe aqui para que no salga sin pintar.

   Es un AVISO, no un estado de la pagina: una linea discreta al lado de lo que se acaba de
   pulsar, del tamano de una nota y con los mismos grises. NADA de bloque de color: para lo
   que hay que leer si o si ya esta .compa__msg, y si este aviso gritara, competiria con el.

   NACE OCULTO. El panel se repinta entero por AJAX y el aviso viaja en el marcado tambien
   cuando no esta pasando nada: si naciera visible, la ficha diria "aplicando..." en reposo. */
.compa__live { display: none; }

/* Encendido. `flex` y no `inline-flex`: ocupa su propia linea, que es lo que evita que al
   aparecer empuje de lado a lo que tiene al lado. El guion lo cuelga como PRIMER hijo de
   [data-compa-body], o sea justo encima de la tarjeta del panel, asi que el hueco va debajo. */
.compa__live--on {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 8px;
    font-style: normal;
    font-size: 0.74rem;
    line-height: 1.4;
    color: var(--gold-dim);
}

/* ⚠️ `hidden` NO oculta nada en cuanto algo le pone un `display`, y aqui se lo acabamos de
   poner: el guion pone el atributo Y la clase, asi que sin esta linea un aviso apagado con
   `hidden` seguiria viendose por culpa de `.compa__live--on`. Es la trampa clasica y en este
   mismo panel ya ha mordido dos veces (.compa__msg y .compa__batch-over la llevan escrita).
   Gana siempre, este donde este: `[hidden]` cuenta como clase (0,2,0 contra 0,1,0). */
.compa__live[hidden] { display: none; }

/* El icono que gira. Solo `transform`: girar no repinta geometria ni mueve al vecino. */
.compa__live-icon {
    flex: none;
    font-size: 0.78rem;
    color: var(--gold);
    animation: compa-live-giro 1.6s linear infinite;
}

.compa__live-text { min-width: 0; }

@keyframes compa-live-giro {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* Mientras se sondea, los botones se atenuan un poco: dicen "lo de antes todavia esta en el
   aire" sin mentir. NO se bloquea NADA -- ni `pointer-events` ni `disabled` -- porque el
   sondeo puede durar 15 segundos y en ese rato el jugador tiene derecho a seguir pidiendo
   cosas; el que decide lo que se puede y lo que no es el modulo, no la opacidad. */
.compa__body--live .compa__btn:not(:disabled),
.compa__body--live .compa__step:not(:disabled) { opacity: 0.7; }

/* Quien pide menos movimiento no pierde ninguna pista: el aviso sigue diciendo lo mismo con su
   texto y su color, solo que quieto. El icono puede estar girando 15 segundos seguidos, asi que
   aqui esto no es un detalle. */
@media (prefers-reduced-motion: reduce) {
    .compa__btn,
    .compa__step,
    .compa__subtab,
    .compa__rest > summary::before { transition: none; }

    .compa__btn:active:not(:disabled),
    .compa__step:active:not(:disabled) { transform: none; }

    .compa__live-icon { animation: none; }
}



/* --- Grupo y amigos --- */

.chv__people {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 9px;
    margin-bottom: 22px;
}

.chv__person {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 13px;
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--bg-surface);
}

.chv__person img { width: 28px; height: 28px; image-rendering: pixelated; }
.chv__person > div { min-width: 0; flex: 1 1 auto; }
.chv__person b { display: block; font-size: 0.92rem; }
.chv__person b a { color: var(--text-primary); text-decoration: none; }
.chv__person b a:hover { color: var(--text-link-hover); }

.chv__person i {
    display: block;
    font-style: normal;
    font-size: 0.73rem;
    color: var(--text-muted);
}

.chv__person-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
    opacity: 0.5;
}

.chv__person.is-online { border-color: var(--border-accent); }
.chv__person.is-online .chv__person-dot {
    background: var(--accent-purple);
    box-shadow: 0 0 8px var(--accent-purple);
    opacity: 1;
}

/* Objeto equipado: la señal es la ETIQUETA dorada, no un fondo de fila. Tintar la fila
   entera competia con el hover de la tabla y ensuciaba la lectura de la columna de
   cartas; la etiqueta dice lo mismo y solo ocupa lo que ocupa. */
.stg__tag--on {
    border-color: var(--aq-gold-mid);
    background: linear-gradient(150deg, var(--aq-gold-light), var(--aq-gold) 45%, var(--aq-gold-mid));
    color: #331603;
    font-weight: 700;
    text-shadow: 0 1px 0 rgba(255, 236, 210, 0.4);
}

@media (max-width: 620px) {
    .chv { padding: 16px; }
    .chv__bar-num { min-width: 0; font-size: 0.74rem; }
    .chv__mate-stats { grid-template-columns: repeat(2, 1fr); }

    /* En movil las dos barras de una fila se apilan: a media pantalla cada una se quedaba en un
       dedo de ancho y dejaba de decir nada. Se deshace el emparejado, no se esconde ninguna. */
    .chv__bar-pair {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 9px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .chv__bar-fill { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Buscador de las listas (.flt)
   ══════════════════════════════════════════════════════════════
   Sustituye a .search-form, que era un <p> tras otro con label, select e input sueltos
   separados por "..." literales, y encima escondido detras de un toggleSearchForm() en
   JavaScript. Ahora la fila principal esta SIEMPRE visible (nombre, id y un par de
   filtros: lo que se busca casi siempre) y el resto de criterios viven en un <details>
   nativo, que ademas se abre solo si alguno esta puesto — si la lista viene filtrada,
   el filtro tiene que estar a la vista o no se entiende el resultado.
   ══════════════════════════════════════════════════════════════ */

.flt {
    margin: 0 0 18px;
    padding: 18px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 160% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 22px var(--alpha-black-24);
}

.flt__main {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
}

.flt__field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.flt__field--grow { flex: 1 1 240px; }
.flt__field--id   { flex: 0 0 110px; }

.flt__field label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.flt__field input[type="text"],
.flt__field select {
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.9rem;
    transition: border-color 0.2s ease;
}

.flt__field input[type="text"]:focus,
.flt__field select:focus { outline: none; border-color: var(--border-accent); }
.flt__field input::placeholder { color: var(--text-muted); }

.flt__actions { display: flex; align-items: center; gap: 10px; }

.flt__go {
    padding: 11px 26px;
    border: 1px solid var(--border-accent);
    border-radius: 10px;
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.2s ease;
}

.flt__go:hover { filter: brightness(1.12); }

.flt__reset {
    padding: 11px 16px;
    border: 1px dashed var(--border-light);
    border-radius: 10px;
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
}

.flt__reset:hover { border-color: var(--accent-red); color: var(--accent-red-h); }

/* --- Filtros avanzados --- */

.flt__more { margin-top: 14px; }

.flt__more > summary {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}

.flt__more > summary::-webkit-details-marker { display: none; }

.flt__more > summary::before {
    /* Una sola barra: en CSS "\\25B8" es una barra invertida ESCAPADA seguida del texto
       25B8, que es justo lo que se veia en pantalla. El escape de un punto de codigo
       lleva una sola barra. */
    content: "\25B8";
    display: inline-block;
    transition: transform 0.2s ease;
}

.flt__more[open] > summary::before { transform: rotate(90deg); }

.flt__more > summary:hover,
.flt__more[open] > summary { border-color: var(--border-accent); color: var(--text-label-hover); }

.flt__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 12px;
    margin-top: 14px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

/* Operador + valor: el select manda lo justo y el numero se lleva el resto. */
.flt__pair { display: flex; gap: 6px; }
.flt__pair select { flex: 0 0 42%; min-width: 0; }
.flt__pair input  { flex: 1 1 auto; min-width: 0; }

@media (max-width: 620px) {
    .flt { padding: 14px; }
    .flt__field--grow, .flt__field--id { flex: 1 1 100%; }
    .flt__actions { width: 100%; }
    .flt__go { flex: 1 1 auto; }
}

@media (prefers-reduced-motion: reduce) {
    .flt__more > summary::before { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-07-31 — Fichas de objeto y de monstruo (.dtl)
   ══════════════════════════════════════════════════════════════
   Las dos eran vertical-table de 14-15 filas donde todo pesaba lo mismo: el id de la
   base de datos ocupaba tanto como el ataque, y media tabla repetia "None". Ahora las
   cifras que se miran van arriba y grandes, el resto es una lista que SOLO pinta lo que
   existe, y las tablas de drops y habilidades usan el .stg del resto del panel.
   ══════════════════════════════════════════════════════════════ */

.dtl__icon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    object-fit: contain;
    image-rendering: pixelated;
    filter: drop-shadow(0 1px 3px var(--alpha-black-34));
}

.dtl__icon--mob { width: 52px; height: 52px; image-rendering: auto; }

.dtl {
    position: relative;
    margin: 0 0 22px;
    padding: 22px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 150% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28), inset 0 1px 0 var(--alpha-white-06);
    overflow: hidden;
}

.dtl::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
}

.dtl__top {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    align-items: flex-start;
    margin-bottom: 20px;
}

/* El arte del objeto/monstruo, sobre un tablero para que se lea igual sea claro u
   oscuro y tenga o no fondo transparente. */
.dtl__art {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 152px;
    min-height: 152px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background:
        linear-gradient(180deg, var(--alpha-silver-08), transparent),
        var(--bg-input);
}

.dtl__art img { max-width: 100%; height: auto; }
.dtl__art--mob img { image-rendering: auto; }

.dtl__side { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 12px; }

.dtl__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
    gap: 9px;
}

.dtl__stat {
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
}

.dtl__stat b {
    display: block;
    font-size: 1.22rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-heading2);
}

.dtl__stat i {
    display: block;
    margin-top: 3px;
    font-style: normal;
    font-size: 0.67rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.dtl__prices {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 9px;
}

.dtl__price {
    padding: 10px 13px;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: linear-gradient(180deg, var(--alpha-silver-08), transparent);
}

.dtl__price i {
    display: block;
    font-style: normal;
    font-size: 0.66rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.dtl__price b { font-size: 1rem; font-weight: 700; color: var(--text-primary); }

.dtl__price--shop { border-color: var(--aq-gold-mid); }
.dtl__price--shop b { color: var(--aq-gold-light); }

.dtl__attrs { margin-bottom: 18px; }

/* --- Lista de detalle: solo lo que existe --- */

.dtl__rows {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0 22px;
    margin: 0;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}

.dtl__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
}

.dtl__key {
    flex: 0 0 auto;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.dtl__val {
    text-align: right;
    font-size: 0.9rem;
    color: var(--text-primary);
}

/* --- Descripcion, comportamiento y scripts --- */

.dtl__desc {
    margin-top: 18px;
    padding: 14px 16px;
    border-left: 3px solid var(--accent-purple);
    border-radius: 0 10px 10px 0;
    background: var(--alpha-black-22);
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--text-panel-soft);
}

.dtl__desc h4,
.dtl__modes h4 {
    margin: 0 0 8px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.dtl__modes { margin-top: 18px; }

.dtl__mode {
    display: inline-block;
    margin: 0 5px 5px 0;
    padding: 4px 11px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--alpha-black-22);
    font-size: 0.76rem;
    color: var(--text-panel-soft);
}

/* Los scripts son para quien sabe leerlos: plegados por defecto. */
.dtl__script { margin-top: 10px; }

.dtl__script > summary {
    display: inline-block;
    padding: 6px 13px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    color: var(--text-muted);
    font-size: 0.76rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}

.dtl__script > summary::-webkit-details-marker { display: none; }
.dtl__script > summary:hover { border-color: var(--border-accent); color: var(--text-label-hover); }

.dtl__script > div {
    margin-top: 9px;
    padding: 13px 15px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-body);
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 0.78rem;
    line-height: 1.6;
    color: var(--text-code);
    overflow-x: auto;
}

.dtl__rate { color: var(--aq-gold-light); }

@media (max-width: 620px) {
    .dtl { padding: 16px; }
    .dtl__top { gap: 14px; }
    .dtl__art { width: 100%; min-height: 0; }
    .dtl__row { flex-direction: column; align-items: flex-start; gap: 2px; }
    .dtl__val { text-align: left; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Páginas de listado: WoE, castillos, tiendas y conectados
   ══════════════════════════════════════════════════════════════
   OJO: estas cinco paginas NO se sirven desde themes/default. El tema activo es la
   cadena necromantic-modern -> necromantic -> default, y hay override en
   themes/necromantic/ para woe, castle, vending, buyingstore, character/online, los
   siete rankings y sobre-mi. Editar la version de default para estas rutas no tiene
   ningun efecto.
   El estado VACIO de las cinco ya estaba resuelto con el componente .emptystate (glifo,
   eyebrow, titulo, lead y datos), asi que aqui solo se reescribe el estado CON
   contenido, que seguia siendo tablas con rowspan y estilo en linea.
   ══════════════════════════════════════════════════════════════ */

/* --- WoE: franjas de guerra --- */

.woe__intro, .woe__foot {
    margin: 4px 0 18px;
    font-size: 0.92rem;
    line-height: 1.65;
    color: var(--text-muted);
}

.woe__foot { margin: 20px 0 0; }
.woe__foot strong { color: var(--text-primary); }

.woe {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
    margin-bottom: 22px;
}

.woe__slot {
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background:
        radial-gradient(120% 130% at 100% 0%, var(--alpha-silver-08), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 20px var(--alpha-black-24);
}

.woe__day {
    display: block;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent-purple);
}

.woe__hours {
    display: flex;
    align-items: baseline;
    gap: 9px;
    margin-top: 7px;
}

.woe__hours b { font-size: 1.28rem; font-weight: 700; color: var(--text-heading2); }
.woe__hours i { font-style: normal; font-size: 0.74rem; color: var(--text-muted); }

.woe__spill {
    display: block;
    margin-top: 6px;
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* --- WoE: las ciudades de cada tanda, dentro de la tarjeta de la franja --- */

.woe { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.woe__zones {
    margin-top: 13px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

.woe__zones-label,
.woecity__key {
    display: block;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.woe__zone { margin-top: 10px; }
.woe__zone:first-of-type { margin-top: 7px; }

.woe__zone-city {
    display: block;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-heading2);
}

.woe__zone-city i {
    font-style: normal;
    font-weight: 400;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.woe__zone-tier {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 9px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.72rem;
    color: var(--accent-purple);
}

.woe__zone-castles,
.woecity__castles,
.woecity__sessions {
    margin: 6px 0 0;
    padding: 0;
    list-style: none;
}

.woe__zone-castles li,
.woecity__castles li,
.woecity__sessions li {
    font-size: 0.82rem;
    line-height: 1.75;
    color: var(--text-primary);
}

.woe__zone-castles li span,
.woecity__castles li span {
    font-size: 0.72rem;
    color: var(--text-muted);
}

.woecity__sessions li b { color: var(--text-heading2); }

/* --- WoE: una fortaleza y quien la tiene --- */

.woecity__castle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 5px 0;
    border-bottom: 1px solid var(--alpha-silver-08);
}

.woecity__castle:last-child { border-bottom: 0; }

.woecity__castle-name {
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--text-heading2);
}

.woecity__holder {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.woecity__holder b {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.woecity__emblem {
    width: 20px;
    height: 20px;
    object-fit: contain;
    image-rendering: pixelated;
}

.woecity__emblem--plain {
    font-size: 0.9rem;
    line-height: 1;
    color: var(--text-muted);
}

/* Sin dueño: el asta vacia. Se apaga el nombre del gremio que no hay, no el del castillo --
   la fortaleza sigue siendo lo importante de la linea. */
.woecity__castle--free .woecity__castle-name { color: var(--text-primary); }

.woecity__holder--free i {
    font-style: italic;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.woecity__staff {
    font-size: 0.9rem;
    line-height: 1;
    color: var(--accent-purple);
    opacity: 0.55;
}

.woecity__count {
    float: right;
    letter-spacing: 0.04em;
    text-transform: none;
    color: var(--text-primary);
}

/* --- WoE: las seis ciudades, con o sin asedio --- */

.woecity { margin-top: 30px; }

.woecity__title {
    margin: 0;
    font-size: 1.12rem;
    color: var(--text-heading2);
}

.woecity__lead {
    margin: 6px 0 16px;
    font-size: 0.92rem;
    line-height: 1.65;
    color: var(--text-muted);
}

.woecity__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 12px;
}

.woecity__card {
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

/* Una ciudad sin tanda programada se ve apagada, pero se LEE igual de bien: lo que
   cambia es el realce, no el contraste del texto. */
.woecity__card--idle { background: var(--bg-surface); }

.woecity__name {
    margin: 0;
    font-size: 1.02rem;
    color: var(--text-heading2);
}

.woecity__region {
    margin: 2px 0 0;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.woecity__tier {
    margin: 10px 0 12px;
    padding: 8px 11px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface-alt);
}

.woecity__tier span {
    display: block;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.woecity__tier b {
    font-size: 0.92rem;
    color: var(--accent-purple);
}

.woecity__key { margin: 12px 0 0; }

.woecity__idle {
    margin: 12px 0 0;
    font-size: 0.86rem;
    font-weight: 700;
    color: var(--text-heading2);
}

.woecity__idle-lead {
    margin: 4px 0 0;
    font-size: 0.82rem;
    line-height: 1.6;
    color: var(--text-muted);
}

/* --- Castillos --- */

.cst {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 12px;
    margin-bottom: 22px;
}

.cst__card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 20px var(--alpha-black-24);
}

/* Un castillo libre se marca en el borde: es la informacion que se busca de un vistazo. */
.cst__card--free { border-style: dashed; border-color: var(--border-light); }

.cst__head { display: flex; align-items: center; gap: 11px; }

.cst__emblem { width: 32px; height: 32px; image-rendering: pixelated; flex: 0 0 auto; }

.cst__emblem--none {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dashed var(--border-light);
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 0.95rem;
    image-rendering: auto;
}

.cst__title b { display: block; font-size: 1rem; font-weight: 600; color: var(--text-heading2); }
.cst__title i { font-style: normal; font-size: 0.72rem; color: var(--text-muted); }

.cst__owner-label {
    display: block;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.cst__owner-name { font-size: 0.95rem; color: var(--text-primary); }
.cst__owner-name a { color: var(--text-link); text-decoration: none; }
.cst__owner-name a:hover { color: var(--text-link-hover); }
.cst__free { color: var(--text-muted); font-style: italic; }

.cst__eco {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: auto;
    padding-top: 11px;
    border-top: 1px solid var(--border);
    font-size: 0.72rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.cst__eco b { font-size: 1.05rem; text-transform: none; color: var(--gold); }

/* --- Puestos de venta y de compra --- */

.shop__meta { padding: 0 0 12px; }

.shop {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 12px;
}

.shop__card {
    display: flex;
    flex-direction: column;
    gap: 11px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 20px var(--alpha-black-24);
}

.shop__head { display: flex; align-items: flex-start; gap: 11px; }
.shop__sign { width: 26px; height: 26px; flex: 0 0 auto; image-rendering: pixelated; }

.shop__title { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.35; color: var(--text-heading2); }
.shop__title a { color: inherit; text-decoration: none; }
.shop__title a:hover { color: var(--text-link-hover); }

.shop__owner { margin: 0; display: flex; align-items: baseline; gap: 8px; }

.shop__owner span {
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.shop__owner b { font-size: 0.92rem; color: var(--text-primary); }

.shop__where {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: auto;
    padding-top: 11px;
    border-top: 1px solid var(--border);
    font-size: 0.78rem;
}

.shop__map {
    padding: 2px 9px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--alpha-black-22);
    color: var(--text-primary);
}

.shop__pos { color: var(--text-muted); }
.shop__go { margin-left: auto; color: var(--text-link); text-decoration: none; font-weight: 600; }
.shop__go:hover { color: var(--text-link-hover); }

/* --- Quien esta conectado --- */

.onl {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
    gap: 10px;
}

/* necROmantic 2026-08-25: la ficha paso a ser una COLUMNA -- la fila de identidad de
   siempre y, debajo, la barra de cuota de automatizacion que solo ve el staff. Por eso la
   fila va envuelta en .onl__row: sin envoltorio la barra se colocaria AL LADO del nombre,
   que es lo que hace la direccion 'row' de un flex. Las fichas sin barra tienen un unico
   hijo y se ven exactamente igual que antes. */
.onl__card {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

.onl__row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.onl__icon { width: 34px; height: 34px; flex: 0 0 auto; image-rendering: pixelated; object-fit: contain; }
.onl__icon--none { border: 1px dashed var(--border); border-radius: 8px; }

.onl__text { flex: 1 1 auto; min-width: 0; }
.onl__name { margin: 0; font-size: 1rem; font-weight: 600; }
.onl__name a { color: var(--text-heading2); text-decoration: none; }
.onl__name a:hover { color: var(--text-link-hover); }

.onl__job { margin: 1px 0 0; font-size: 0.76rem; color: var(--text-muted); }

.onl__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 5px 0 0;
    font-size: 0.74rem;
}

.onl__guild { display: inline-flex; align-items: center; gap: 5px; color: var(--text-muted); }
.onl__guild img { width: 16px; height: 16px; image-rendering: pixelated; }
.onl__guild a { color: var(--text-link); text-decoration: none; }

.onl__map {
    padding: 1px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    color: var(--text-muted);
}

.onl__dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent-purple);
    box-shadow: 0 0 9px var(--accent-purple);
}

.onl__hidden {
    margin: 16px 0 0;
    font-size: 0.82rem;
    color: var(--text-muted);
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Clasificaciones (.rnk)
   ══════════════════════════════════════════════════════════════
   Marcado compartido en themes/necromantic/ranking/_tabla.php. Podio para los tres
   primeros y lista para el resto, en lugar de la tabla de 8-9 columnas que ademas
   pintaba filas vacias hasta llegar al tope configurado.
   ══════════════════════════════════════════════════════════════ */

.rnk__podium {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px;
    margin: 4px 0 16px;
}

.rnk__step {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 26px 18px 20px;
    border: 1px solid var(--border);
    border-radius: 16px;
    text-align: center;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28);
    overflow: hidden;
}

/* Filo de color por metal: es lo que distingue los tres puestos de un vistazo. */
.rnk__step::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 4px;
}

.rnk__step--oro::before    { background: linear-gradient(90deg, var(--aq-gold-deep), var(--aq-gold-light) 50%, var(--aq-gold-mid)); }
.rnk__step--plata::before  { background: linear-gradient(90deg, #6b7280, #d5dae3 50%, #8b93a1); }
.rnk__step--bronce::before { background: linear-gradient(90deg, #5c2f18, #c88a5a 50%, #8a5330); }

/* El primero se levanta un poco sobre los otros dos: es un podio, no tres tarjetas. */
.rnk__step--oro {
    border-color: var(--aq-gold-mid);
    box-shadow: 0 14px 34px var(--alpha-black-34), 0 0 26px var(--aq-gold-soft);
}

.rnk__pos {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--border-light);
    background: var(--alpha-black-22);
    font-size: 0.95rem;
    font-weight: 800;
    color: var(--text-muted);
}

.rnk__step--oro .rnk__pos {
    border-color: var(--aq-gold);
    background: linear-gradient(150deg, var(--aq-gold-light), var(--aq-gold) 45%, var(--aq-gold-mid));
    color: #331603;
}

.rnk__step--plata .rnk__pos  { border-color: #b6bcc7; color: #d5dae3; }
.rnk__step--bronce .rnk__pos { border-color: #a97048; color: #d5a179; }

.rnk__icon { width: 42px; height: 42px; object-fit: contain; image-rendering: pixelated; }

.rnk__name { margin: 2px 0 0; font-size: 1.08rem; font-weight: 700; color: var(--text-heading2); }
.rnk__name a { color: inherit; text-decoration: none; }
.rnk__name a:hover { color: var(--text-link-hover); }

.rnk__sub { margin: 0; font-size: 0.76rem; color: var(--text-muted); }

.rnk__guild {
    display: flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    font-size: 0.76rem;
    color: var(--text-muted);
}

.rnk__guild img { width: 16px; height: 16px; image-rendering: pixelated; }
.rnk__guild a { color: var(--text-link); text-decoration: none; }

.rnk__value {
    /* necROmantic 2026-08-25: "auto" arriba en vez de 10px. La ficha es una columna
       flex, asi que esto empuja la cifra al fondo y las tres del podio quedan a la
       misma altura aunque una tenga gremio y otra no, o mas pastillas debajo. Cuando no
       sobra sitio el auto vale 0 y manda el gap de 6px de la ficha. */
    margin: auto 0 0;
    padding-top: 12px;
    width: 100%;
    border-top: 1px solid var(--border);
}

.rnk__value b { display: block; font-size: 1.5rem; font-weight: 700; line-height: 1.1; color: var(--text-primary); }
.rnk__step--oro .rnk__value b { color: var(--aq-gold-light); }

.rnk__value i {
    font-style: normal;
    font-size: 0.66rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* --- Del cuarto en adelante --- */

.rnk__list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 22px;
}

.rnk__row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--bg-surface);
    transition: border-color 0.2s ease, background 0.2s ease;
}

.rnk__row:hover { border-color: var(--border-accent); background: var(--bg-surface-alt); }

.rnk__rowpos {
    flex: 0 0 auto;
    min-width: 30px;
    font-size: 0.86rem;
    font-weight: 700;
    text-align: right;
    color: var(--text-muted);
}

.rnk__rowicon { width: 28px; height: 28px; flex: 0 0 auto; object-fit: contain; image-rendering: pixelated; }
.rnk__rowicon--none { border: 1px dashed var(--border); border-radius: 7px; }

.rnk__rowtext { flex: 1 1 auto; min-width: 0; }
.rnk__rowname { margin: 0; font-size: 0.95rem; font-weight: 600; color: var(--text-primary); }
.rnk__rowname a { color: inherit; text-decoration: none; }
.rnk__rowname a:hover { color: var(--text-link-hover); }

.rnk__rowsub {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 2px 0 0;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.rnk__rowguild { display: inline-flex; align-items: center; gap: 5px; }
.rnk__rowguild img { width: 15px; height: 15px; image-rendering: pixelated; }
.rnk__rowguild a { color: var(--text-link); text-decoration: none; }

.rnk__rowvalue { flex: 0 0 auto; text-align: right; }
.rnk__rowvalue b { display: block; font-size: 1rem; font-weight: 700; color: var(--text-primary); }
.rnk__rowvalue i { font-style: normal; font-size: 0.64rem; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-muted); }

/* --- Linea de apoyo opcional ('extra' de ranking/_tabla.php) ---
   Hoy solo la usa el ranking de MVP: las pastillas con los jefes que ha abatido cada
   personaje. En el podio van centradas y en la lista alineadas a la izquierda, que es la
   unica diferencia entre las dos variantes. */

.rnk__extra {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 5px;
    margin: 6px 0 0;
}

.rnk__extra--row {
    justify-content: flex-start;
    margin-top: 4px;
}

.rnk__kill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.7rem;
    line-height: 1.5;
    color: var(--text-muted);
    background: var(--bg-surface-alt);
    white-space: nowrap;
}

.rnk__kill a { color: inherit; text-decoration: none; }
.rnk__kill a:hover { color: var(--text-link-hover); }
.rnk__kill b { font-weight: 700; color: var(--text-primary); }
.rnk__kill--more { border-style: dashed; }

@media (max-width: 620px) {
    .rnk__podium { grid-template-columns: minmax(0, 1fr); }
    .rnk__rowvalue i { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .rnk__row { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Los buscadores que quedan (.search-form / .search-form2)
   ══════════════════════════════════════════════════════════════
   Quedan una docena de paginas con el buscador antiguo: hermandades, lista de
   personajes, buscador de cuentas y los nueve registros de GM (cplog/*, logdata/*).
   Reescribir doce plantillas a mano para el mismo resultado no compensa, asi que se
   reescribe el COMPONENTE: mismas reglas visuales que el .flt nuevo, aplicadas al
   marcado que ya existe (un <p> con label/input/select sueltos).

   Se quita ademas el "display:none" de la regla original: esos formularios nacian
   OCULTOS y solo aparecian pulsando un enlace "Buscar..." que llamaba a un slideToggle
   de jQuery. Un buscador escondido detras de otro clic no lo encuentra nadie. El enlace
   .toggler se deja funcionando -sigue plegando y desplegando- pero ya no hace falta
   para ver el formulario.
   ══════════════════════════════════════════════════════════════ */

.search-form,
.search-form2 {
    display: block;
    margin: 0 0 18px;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background:
        radial-gradient(120% 160% at 0% 0%, var(--alpha-silver-08), transparent 60%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 22px var(--alpha-black-24);
}

/* El marcado antiguo mete todo en un <p>: se convierte en una rejilla flexible para que
   cada pareja etiqueta/campo caiga donde quepa en vez de irse a una linea kilometrica. */
.search-form p,
.search-form2 p {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 14px;
    margin: 0;
    padding: 0;
    color: var(--text-muted);
}

.search-form p + p,
.search-form2 p + p { margin-top: 12px; }

.search-form label,
.search-form2 label {
    display: inline-block;
    margin: 0;
    font-size: 0.68rem;
    font-style: normal;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.search-form input[type=text],
.search-form input[type=number],
.search-form select,
.search-form2 input[type=text],
.search-form2 input[type=number],
.search-form2 select {
    width: auto;
    min-width: 130px;
    margin: 0;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.88rem;
    transition: border-color 0.2s ease;
}

.search-form input[type=text]:focus,
.search-form select:focus,
.search-form2 input[type=text]:focus,
.search-form2 select:focus { outline: none; border-color: var(--border-accent); }

.search-form input[type=submit],
.search-form2 input[type=submit] {
    margin: 0;
    padding: 10px 22px;
    border: 1px solid var(--border-accent);
    border-radius: 9px;
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
    font-family: inherit;
    font-size: 0.86rem;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.2s ease;
}

.search-form input[type=submit]:hover,
.search-form2 input[type=submit]:hover { filter: brightness(1.12); }

.search-form input[type=button],
.search-form input[type=reset],
.search-form2 input[type=button],
.search-form2 input[type=reset] {
    margin: 0;
    padding: 10px 16px;
    border: 1px dashed var(--border-light);
    border-radius: 9px;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.84rem;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.search-form input[type=button]:hover,
.search-form input[type=reset]:hover,
.search-form2 input[type=button]:hover,
.search-form2 input[type=reset]:hover { border-color: var(--accent-red); color: var(--accent-red-h); }

.search-form input[type=checkbox],
.search-form2 input[type=checkbox] { margin: 0 4px 0 0; accent-color: var(--accent-purple); }

/* El "..." literal que separaba los campos en el marcado antiguo: se apaga sin tocar
   las plantillas. Es texto suelto dentro del <p>, asi que no se puede seleccionar por
   CSS; lo que si se puede es darle el mismo color que el fondo para que desaparezca.
   No se hace: mejor dejarlo tenue y legible que jugar a esconder texto. */
.search-form p,
.search-form2 p { font-size: 0.78rem; }

/* El enlace "Buscar..." ya no hace falta para VER el formulario (ahora nace visible),
   pero se deja usable como plegable. */
.toggler {
    margin: 0 0 10px;
    font-size: 0.78rem;
}

.toggler a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 13px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    color: var(--text-muted);
    font-weight: 600;
    text-decoration: none;
}

.toggler a:hover { border-color: var(--border-accent); color: var(--text-label-hover); }

@media (max-width: 620px) {
    .search-form p,
    .search-form2 p { gap: 6px 10px; }
    .search-form input[type=text],
    .search-form select,
    .search-form2 input[type=text],
    .search-form2 select { flex: 1 1 100%; min-width: 0; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — "Sobre mí"
   ══════════════════════════════════════════════════════════════
   Segunda vuelta. La primera dejó seis tarjetas redondeadas idénticas apiladas: al
   bajar por la página no pasaba nada, todo tenía el mismo peso y la misma silueta.
   Ahora cada sección tiene SU forma, y ninguna se repite:

     claim   declaración a ancho completo, sin caja, tipografía grande
     skills  mosaico de piezas numeradas
     why     lista numerada grande sobre fondo hundido
     play    banda destacada, la única con imagen
     rules   columna estrecha con filo lateral, como una carta
     misc    cierre ligero a dos columnas, sin caja

   TODO cuelga de .about: las tarjetas ya no usan .legal-card, pero el ancla se mantiene
   por si algo hereda de las páginas legales.

   Es una pasada de PRESENTACIÓN. El texto no se toca: la página tiene un criterio
   escrito sobre lo que puede y no puede contener y eso no es cosa del CSS.
   ══════════════════════════════════════════════════════════════ */

.about { --ab-accent: var(--gold); }

/* --- Portada --- */

.about .about-hero {
    position: relative;
    margin-bottom: 8px;
    padding: 44px 40px 36px;
    border: 1px solid var(--border);
    border-radius: 24px;
    overflow: hidden;
}

.about .about-hero::before {
    content: "";
    position: absolute;
    top: -170px;
    right: -130px;
    width: 440px;
    height: 440px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--alpha-silver-14), transparent 68%);
    pointer-events: none;
}

.about .about-hero::after {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--accent-purple), var(--ab-accent) 55%, transparent);
}

.about .about-kicker {
    position: relative;
    padding: 7px 14px;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.18em;
}

.about .about-title {
    position: relative;
    margin: 18px 0 14px;
    font-size: clamp(1.7rem, 3.4vw, 2.4rem);
    font-weight: 600;
    line-height: 1.12;
    letter-spacing: -0.01em;
}

.about .about-intro {
    position: relative;
    max-width: 70ch;
    font-size: 1rem;
    line-height: 1.75;
}

/* Las cuatro cifras: cada pareja valor+etiqueta es una PIEZA CERRADA. Antes eran
   columnas separadas solo por una línea vertical y el conjunto se leía como una lista
   corrida de ocho renglones sueltos, sin saber qué etiqueta iba con qué valor. */
.about .about-facts--tiles {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
    margin: 30px 0 0;
    padding: 0;
    list-style: none;
    border: 0;
}

.about .about-facts--tiles .about-fact {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--alpha-black-22);
}

.about .about-facts--tiles .about-fact__value {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ab-accent);
}

.about .about-facts--tiles .about-fact__label {
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* --- Rejilla común de las secciones --- */

.about .ab__sec { margin: 34px 0; }

.about .ab__eyebrow {
    margin: 0 0 8px;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.about .ab__h {
    margin: 0 0 16px;
    padding: 0;
    border: 0;
    font-size: 1.3rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--text-heading2);
}

.about .ab__sec p {
    font-size: 0.96rem;
    line-height: 1.78;
    color: var(--text-panel-soft);
}

.about .ab__sec strong { color: var(--text-primary); }

/* --- 1. Declaración: sin caja, tipografía grande, filo a la izquierda --- */

.about .ab__sec--claim {
    padding-left: 26px;
    border-left: 2px solid var(--ab-accent);
}

.about .ab__sec--claim .ab__h { font-size: 1.5rem; }

.about .ab__sec--claim p {
    max-width: 68ch;
    font-size: 1.05rem;
    line-height: 1.8;
}

/* --- 2. Terrenos: mosaico de piezas numeradas --- */

.about .ab__skills {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 10px;
    margin: 18px 0 0;
    padding: 0;
    list-style: none;
}

.about .ab__skill {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 15px 17px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    font-size: 0.9rem;
    line-height: 1.65;
    color: var(--text-panel-soft);
}

.about .ab__skill-n {
    flex: 0 0 auto;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    line-height: 1.9;
    color: var(--ab-accent);
    opacity: 0.75;
}

/* --- 3. Argumentario: numeración grande sobre fondo hundido --- */

.about .ab__sec--why {
    padding: 30px 32px;
    border-radius: 20px;
    background: var(--bg-body);
    box-shadow: inset 0 2px 14px var(--alpha-black-34);
}

.about .ab__args {
    counter-reset: ab;
    margin: 20px 0 0;
    padding: 0;
    list-style: none;
}

.about .ab__args li {
    counter-increment: ab;
    position: relative;
    margin: 0 0 16px;
    padding-left: 52px;
    font-size: 0.94rem;
    line-height: 1.7;
    color: var(--text-panel-soft);
}

.about .ab__args li::before {
    content: counter(ab, decimal-leading-zero);
    position: absolute;
    left: 0;
    top: -2px;
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1;
    color: var(--accent-purple);
    opacity: 0.55;
}

.about .ab__args li:last-child { margin-bottom: 0; }

/* --- 4. Aurel: banda destacada, la única con imagen --- */

.about .ab__sec--play {
    position: relative;
    padding: 30px 32px;
    border: 1px solid var(--border-light);
    border-radius: 20px;
    background:
        radial-gradient(110% 130% at 0% 0%, var(--alpha-silver-14), transparent 62%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 14px 34px var(--alpha-black-34), inset 0 1px 0 var(--alpha-white-06);
    overflow: hidden;
}

.about .ab__sec--play::after {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, transparent, var(--accent-purple) 40%, var(--ab-accent));
}

/* --- 5. Límites: columna estrecha, como una carta --- */

.about .ab__sec--rules {
    padding: 26px 30px;
    border: 1px dashed var(--border-light);
    border-radius: 18px;
    background: var(--alpha-black-18);
}

.about .about-note {
    margin: 18px 0 0;
    padding: 14px 18px;
    border-left: 3px solid var(--ab-accent);
    border-radius: 0 12px 12px 0;
    background: var(--alpha-black-24);
    font-size: 0.93rem;
    line-height: 1.7;
}

/* --- 5 y 6 emparejados: los limites a la izquierda, el cierre a la derecha --- */

.about .ab__duo {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 20px;
    align-items: start;
}

/* Dentro de la pareja pierden el margen vertical propio: lo pone la rejilla. */
.about .ab__duo > .ab__sec { margin: 34px 0 0; }

/* --- 6. Cierre: ligero, sin caja --- */

.about .ab__sec--misc {
    padding-top: 26px;
    border-top: 1px solid var(--border);
}

.about .legal-list--pairs {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
    margin: 14px 0 0;
    padding: 0;
    list-style: none;
}

.about .legal-list--pairs li {
    position: relative;
    margin: 0;
    padding: 9px 0 9px 22px;
    font-size: 0.92rem;
    line-height: 1.7;
    color: var(--text-panel-soft);
}

.about .legal-list--pairs li::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 1.35em;
    width: 7px;
    height: 7px;
    border-radius: 2px;
    background: linear-gradient(135deg, var(--accent-purple), var(--ab-accent));
    transform: rotate(45deg);
}

@media (max-width: 720px) {
    .about .about-hero { padding: 30px 22px 26px; }
    .about .ab__sec { margin: 26px 0; }
    .about .ab__sec--claim { padding-left: 18px; }
    .about .ab__sec--why,
    .about .ab__sec--play { padding: 22px 20px; }
    .about .ab__sec--rules { padding: 20px 20px; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Reportar un problema (.rep)
   ══════════════════════════════════════════════════════════════
   El cambio de fondo es el tipo de problema: eran ocho opciones dentro de un <select>,
   la PRIMERA decisión del formulario, y había que abrirlo y leerlas de una en una.
   Ahora son fichas elegibles: se ven las ocho a la vez. Por debajo siguen siendo radios
   con el mismo name, así que el módulo no cambia y funciona sin JavaScript.
   ══════════════════════════════════════════════════════════════ */

.rep__intro {
    max-width: 74ch;
    margin: 4px 0 20px;
    font-size: 0.96rem;
    line-height: 1.7;
    color: var(--text-muted);
}

/* --- Tipo de problema --- */

.rep__choices {
    margin: 0 0 22px;
    padding: 0;
    border: 0;
}

.rep__choices > .report-label { padding: 0; margin-bottom: 10px; }

.rep__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 10px;
}

.rep__choice { display: block; cursor: pointer; }

/* El radio se saca de la vista pero se deja enfocable: sin él no hay navegación por
   teclado ni lectura por voz. La ficha reacciona vía :checked y :focus-visible. */
.rep__choice input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.rep__choice-box {
    display: flex;
    align-items: center;
    gap: 11px;
    height: 100%;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--alpha-black-22);
    font-size: 0.88rem;
    line-height: 1.4;
    color: var(--text-primary);
    transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}

.rep__choice-box i {
    flex: 0 0 auto;
    width: 20px;
    text-align: center;
    font-size: 1rem;
    color: var(--text-muted);
    transition: color 0.18s ease;
}

.rep__choice:hover .rep__choice-box { border-color: var(--border-accent); }

.rep__choice input:checked + .rep__choice-box {
    border-color: var(--accent-purple);
    background: linear-gradient(180deg, var(--alpha-silver-12), transparent);
    color: var(--text-heading2);
    box-shadow: 0 0 18px var(--alpha-silver-18);
}

.rep__choice input:checked + .rep__choice-box i { color: var(--accent-purple); }

/* El foco tiene que verse: es la única pista para quien navega con teclado. */
.rep__choice input:focus-visible + .rep__choice-box {
    outline: 2px solid var(--border-accent);
    outline-offset: 2px;
}

/* --- Ayuda lateral --- */

.rep__aside {
    position: sticky;
    top: 96px;
    align-self: start;
}

.rep__aside-title {
    margin: 0 0 14px;
    padding: 0;
    border: 0;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.rep__tips {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rep__tips li {
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--text-muted);
}

.rep__tips li:last-child { border-bottom: 0; }

.rep__tip-k {
    display: block;
    margin-bottom: 3px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent-purple);
}

.rep__warn {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 16px 0 0;
    padding: 13px 15px;
    border: 1px solid var(--crimson);
    border-radius: 11px;
    background: var(--alpha-black-24);
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--text-panel-soft);
}

.rep__warn i { color: var(--accent-red); margin-top: 2px; }
.rep__warn strong { color: var(--accent-red-h); }

.rep__aside-note {
    margin: 14px 0 0;
    font-size: 0.8rem;
    line-height: 1.6;
    color: var(--text-muted);
}

@media (max-width: 900px) {
    .rep__aside { position: static; }
}

@media (prefers-reduced-motion: reduce) {
    .rep__choice-box,
    .rep__choice-box i { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Subida de capturas del reporte (.rup)
   ══════════════════════════════════════════════════════════════
   El campo de antes era un <input type="file"> desnudo con una línea de texto debajo
   contando megas: no se veía qué habías elegido, no se podía quitar una imagen suelta
   (solo vaciarlo entero) y no había forma de arrastrar ni de pegar.

   El <input> sigue siendo quien envía. Todo esto es una capa por encima que se activa
   sola con .rup--js: si el JavaScript no corre, se ve el campo de siempre y el
   formulario funciona igual.
   ══════════════════════════════════════════════════════════════ */

.rup { margin-top: 4px; }

/* --- Zona de arrastre --- */

.rup__drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 30px 22px;
    border: 2px dashed var(--border-light);
    border-radius: 16px;
    background:
        radial-gradient(90% 130% at 50% 0%, var(--alpha-silver-08), transparent 65%),
        var(--alpha-black-22);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.18s ease, background 0.18s ease;
}

.rup__drop:hover { border-color: var(--accent-purple); }

/* Mientras se arrastra algo encima. */
.rup--encima .rup__drop {
    border-color: var(--accent-purple);
    border-style: solid;
    background: var(--alpha-silver-14);
}

.rup__drop-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    margin-bottom: 6px;
    border-radius: 50%;
    border: 1px solid var(--border-light);
    background: var(--bg-input);
    font-size: 1.25rem;
    color: var(--accent-purple);
}

.rup__drop-main { font-size: 1rem; font-weight: 600; color: var(--text-heading2); }
.rup__drop-sub  { font-size: 0.86rem; color: var(--text-muted); }
.rup__drop-sub b { color: var(--text-link); }

.rup__drop-meta {
    margin-top: 4px;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.rup__drop kbd {
    padding: 1px 6px;
    border: 1px solid var(--border-light);
    border-radius: 5px;
    background: var(--bg-input);
    font-family: inherit;
    font-size: 0.78em;
    color: var(--text-primary);
}

/* El input nativo: visible sin JS (es el respaldo), fuera de la vista con JS —pero
   enfocable, para no perder el acceso por teclado. */
.rup__input { margin-top: 10px; }

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

/* --- Lo que ya se ha elegido --- */

.rup__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 8px;
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
}

.rup__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface);
}

.rup__thumb {
    width: 46px;
    height: 46px;
    flex: 0 0 auto;
    border-radius: 8px;
    object-fit: cover;
    background: var(--bg-input);
}

.rup__item-text { min-width: 0; flex: 1 1 auto; }

.rup__item-text b {
    display: block;
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rup__item-text i {
    font-style: normal;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.rup__remove {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.rup__remove:hover,
.rup__remove:focus-visible {
    border-color: var(--accent-red);
    background: var(--crimson);
    color: var(--accent-red-h);
}

/* --- Peso acumulado --- */

.rup__bar { margin-top: 12px; }

.rup__bar-track {
    height: 8px;
    border-radius: 999px;
    background: var(--bg-body);
    box-shadow: inset 0 1px 3px var(--alpha-black-34);
    overflow: hidden;
}

.rup__bar-fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
    transition: width 0.25s ease;
}

/* Pasado el límite el color avisa antes que el texto. */
.rup__bar-fill.is-over { background: linear-gradient(90deg, var(--crimson), var(--accent-red)); }

.rup__bar-text {
    margin: 7px 0 0;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.rup__error {
    margin: 10px 0 0;
    padding: 10px 13px;
    border-left: 3px solid var(--accent-red);
    border-radius: 0 9px 9px 0;
    background: var(--alpha-black-24);
    font-size: 0.84rem;
    line-height: 1.6;
    color: var(--accent-red-h);
}

/* Con imágenes ya elegidas la zona de arrastre se encoge: deja de ser lo importante. */
.rup--con-archivos .rup__drop { padding: 18px 22px; }
.rup--con-archivos .rup__drop-icon { width: 38px; height: 38px; font-size: 1rem; margin-bottom: 2px; }
.rup--con-archivos .rup__drop-meta { display: none; }

@media (prefers-reduced-motion: reduce) {
    .rup__drop,
    .rup__bar-fill,
    .rup__remove { transition: none; }
}

/* Capturas que ya están en el servidor (sobrevivieron a un envío fallido). Se
   distinguen de las recién elegidas: estas no se pueden quitar con un clic sin más,
   se marcan y se van al enviar. */
.rup__list--guardadas { margin-bottom: 8px; }

.rup__item--guardada {
    border-style: dashed;
    border-color: var(--border-light);
    background: var(--alpha-black-22);
}

.rup__thumb--saved {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 1.05rem;
}

.rup__drop-saved {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    padding: 5px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 0.76rem;
    color: var(--text-muted);
    cursor: pointer;
}

.rup__drop-saved:hover { border-color: var(--accent-red); color: var(--accent-red-h); }
.rup__drop-saved input { accent-color: var(--accent-red); }

/* Estado "subiendo": la zona se atenúa mientras el servidor recibe. */
.rup--subiendo .rup__drop { opacity: 0.55; pointer-events: none; }
.rup--subiendo .rup__drop-main::after { content: " · subiendo…"; color: var(--accent-purple); }
.rup__remove[disabled] { opacity: 0.4; cursor: default; }

/* ===========================================================================
   necROmantic 2026-08-01: configurador del regalo diario (/regalos/)
   Cuatro fichas, una por slot, con su tabla de candidatos. Los tres formularios
   de la pagina van declarados vacios y los campos se enganchan con form=, asi
   que .gcf__ghost solo tiene que sacarlos del flujo sin ocultarlos del todo
   (display:none en un <form> no impide enviarlo, pero si molesta al layout).
   =========================================================================== */
.gcf__ghost { display: contents; }

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

.gcf__intro {
    max-width: 70ch;
    margin: 0 0 .6rem;
    color: var(--text-panel-soft);
    line-height: 1.6;
}
.gcf__intro--muted {
    color: var(--text-muted);
    font-size: .93em;
    margin-bottom: 1.6rem;
}

.gcf__errors {
    margin: 0 0 1.4rem;
    padding: .8rem 1rem;
    border: 1px solid var(--accent-red);
    border-left-width: 4px;
    border-radius: 6px;
    background: rgba(201, 111, 158, .12);
}
.gcf__errors p { margin: .2rem 0; color: var(--accent-red-h); }

/* --- Ficha de slot ------------------------------------------------------- */
.gcf-slot {
    margin: 0 0 1.8rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
    overflow: hidden;
}

.gcf-slot__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .8rem 1.4rem;
    padding: .9rem 1.1rem;
    background: var(--bg-surface-alt);
    border-bottom: 1px solid var(--border);
}

.gcf-slot__title { display: flex; align-items: baseline; gap: .7rem; }
.gcf-slot__title h3 { margin: 0; color: var(--text-heading2); font-size: 1.15rem; }

.gcf-slot__num {
    padding: .12rem .5rem;
    border: 1px solid var(--border-accent);
    border-radius: 999px;
    color: var(--accent-purple);
    font-size: .74rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.gcf-slot__empty { display: flex; align-items: center; gap: .5rem; margin-left: auto; }
.gcf-slot__empty label { color: var(--text-muted); font-size: .9rem; white-space: nowrap; }
.gcf-slot__empty-field { display: inline-flex; align-items: center; gap: .25rem; }
.gcf-slot__empty-field em { color: var(--text-muted); font-style: normal; }

.gcf-slot__meta {
    flex-basis: 100%;
    margin: 0;
    color: var(--text-muted);
    font-size: .85rem;
}

.gcf-slot__none {
    margin: 0;
    padding: 1.2rem 1.1rem;
    color: var(--accent-red-h);
}

/* --- Tabla de candidatos -------------------------------------------------- */
/* El scroll horizontal vive aqui dentro: la pagina nunca se desplaza a lo ancho. */
.gcf-table__wrap { overflow-x: auto; }

.gcf-table { width: 100%; border-collapse: collapse; font-size: .93rem; }
.gcf-table th {
    padding: .5rem .7rem;
    background: var(--bg-table-head);
    color: var(--text-heading);
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}
.gcf-table td {
    padding: .38rem .7rem;
    border-top: 1px solid var(--border);
    vertical-align: middle;
}
.gcf-table tbody tr:nth-child(odd) { background: var(--bg-table-row); }
.gcf-table tbody tr:nth-child(even) { background: var(--bg-table-alt); }

.gcf-table__id   { width: 5.5rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.gcf-table__icon { width: 2.6rem; }
.gcf-table__type { width: 8rem; color: var(--text-muted); }
.gcf-table__amt,
.gcf-table__w,
.gcf-table__pct  { width: 5.5rem; text-align: right; font-variant-numeric: tabular-nums; }
.gcf-table__act  { width: 5rem; text-align: right; }

.gcf-cell__icon { width: 24px; height: 24px; image-rendering: pixelated; vertical-align: middle; }
.gcf-cell__glyph { color: var(--gold); font-size: 1.1rem; }
.gcf-cell__dash { color: var(--text-muted); }
.gcf-cell__name a { color: var(--text-link); text-decoration: none; }
.gcf-cell__name a:hover { color: var(--text-link-hover); text-decoration: underline; }
.gcf-cell__costume { color: var(--gold); font-weight: 600; }

/* La fila del pool de costumes no es un objeto suelto: se marca para que no se
   la confunda con uno. Y peso 0 significa apagada, no borrada. */
.gcf-row--costume td { background: rgba(223, 160, 198, .07); }
.gcf-row--off { opacity: .45; }

/* --- Alta y guardado ------------------------------------------------------ */
.gcf-add {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .8rem 1.1rem;
    border-top: 1px solid var(--border);
    background: var(--bg-surface-alt);
}
.gcf-add__label { color: var(--text-muted); font-size: .9rem; margin-right: .2rem; }
.gcf-add__id  { width: 7rem; }
.gcf-add__amt { width: 5rem; }
.gcf-add__w   { width: 5rem; }

.gcf-slot input[type="number"],
.gcf-add input[type="number"] {
    padding: .3rem .5rem;
    border: 1px solid var(--border-light);
    border-radius: 5px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}
.gcf-table__w input[type="number"] { width: 100%; text-align: right; }
.gcf-slot input[type="number"]:focus,
.gcf-add input[type="number"]:focus {
    outline: none;
    border-color: var(--border-accent);
}

.gcf-btn {
    padding: .34rem .8rem;
    border: 1px solid var(--border-light);
    border-radius: 5px;
    background: var(--bg-surface);
    color: var(--text-primary);
    font-size: .88rem;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
.gcf-btn:hover { border-color: var(--border-accent); color: var(--text-label-hover); }
.gcf-btn--del:hover { border-color: var(--accent-red); color: var(--accent-red-h); }
.gcf-btn--add { border-color: var(--border-accent); }

.gcf-save { margin: 1.6rem 0 2.4rem; }
.gcf-btn--save {
    padding: .6rem 1.5rem;
    border-color: var(--border-accent);
    background: var(--bg-surface-alt);
    color: var(--text-heading2);
    font-size: 1rem;
}
.gcf-save__note {
    margin: .6rem 0 0;
    color: var(--text-muted);
    font-size: .87rem;
}

@media (max-width: 720px) {
    .gcf-slot__empty { margin-left: 0; }
    .gcf-table { font-size: .86rem; }
}

/* --- /regalos/: pestañas, buscador y paginación (2026-08-01) -------------- */
.gcf-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin: 0 0 -1px;
}

.gcf-tab {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 9.5rem;
    padding: .55rem .9rem;
    border: 1px solid var(--border);
    border-bottom-color: transparent;
    border-radius: 8px 8px 0 0;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    text-decoration: none;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.gcf-tab:hover { background: var(--bg-table-alt); color: var(--text-primary); }

/* La activa se funde con la ficha de abajo: mismo fondo y sin borde inferior. */
.gcf-tab--on {
    background: var(--bg-surface);
    border-color: var(--border-accent);
    border-bottom-color: var(--bg-surface);
    color: var(--text-heading2);
}

.gcf-tab__num {
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--accent-purple);
}
.gcf-tab--on .gcf-tab__num { color: var(--gold); }
.gcf-tab__name { font-weight: 600; }
.gcf-tab__count { font-size: .78rem; color: var(--text-muted); }

/* La ficha del slot cuelga de las pestañas: esquina superior izquierda recta. */
.gcf-tabs + .gcf-slot {
    border-color: var(--border-accent);
    border-top-left-radius: 0;
}

.gcf-search {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem 1rem;
    padding: .7rem 1.1rem;
    border-bottom: 1px solid var(--border);
}
.gcf-search__form { display: flex; align-items: center; gap: .5rem; margin: 0; flex: 1 1 20rem; }
.gcf-search__box {
    flex: 1 1 auto;
    min-width: 0;
    padding: .34rem .6rem;
    border: 1px solid var(--border-light);
    border-radius: 5px;
    background: var(--bg-input);
    color: var(--text-primary);
}
.gcf-search__box:focus { outline: none; border-color: var(--border-accent); }
.gcf-search__clear { color: var(--text-muted); font-size: .87rem; white-space: nowrap; }
.gcf-search__clear:hover { color: var(--text-link-hover); }
.gcf-search__result { margin: 0; color: var(--text-muted); font-size: .87rem; }

.gcf-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    padding: .8rem 1.1rem;
    border-top: 1px solid var(--border);
}
.gcf-pager__num,
.gcf-pager__step {
    padding: .28rem .6rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text-link);
    text-decoration: none;
    font-size: .88rem;
    font-variant-numeric: tabular-nums;
}
.gcf-pager__num:hover,
.gcf-pager__step:hover { border-color: var(--border-accent); color: var(--text-link-hover); }
.gcf-pager__num--on {
    border-color: var(--border-accent);
    background: var(--bg-surface-alt);
    color: var(--text-heading2);
    font-weight: 600;
}
.gcf-pager__step--off { opacity: .35; }
.gcf-pager__gap { color: var(--text-muted); padding: 0 .15rem; }

@media (max-width: 720px) {
    .gcf-tab { min-width: 0; flex: 1 1 8rem; }
}

/* ===========================================================================
   necROmantic 2026-08-01: regalo diario en la ficha de cuenta
   =========================================================================== */
.chc__gift { margin: .7rem 0 0; }
.chc__gift-note { margin: 0; color: var(--text-muted); font-size: .82rem; font-style: italic; }

/* necROmantic 2026-08-01: el reclamo del regalo diario pasa a la rampa dorada.
   Es la accion mas apetecible de la ficha de cuenta y tiene que verse desde lejos.
   Se calca el tratamiento de .aq__mult (la insignia de nivel de la cuota de
   automatizacion): mismo degradado, mismo filo claro y el mismo par resplandor +
   brillo interior.

   Se usan los tokens --aq-gold-*, NO --gold: en esta piel --gold es rosa-magenta y
   conserva ese nombre solo por compatibilidad, asi que el hover de antes tiraba a
   rosa en vez de a oro. El texto va en #331603, el mismo de .aq__mult, ya
   comprobado legible sobre esta rampa. */
.gift-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    width: 100%;
    padding: .7rem 1rem;
    border: 1px solid var(--aq-gold-light);
    border-radius: 7px;
    background: linear-gradient(150deg, var(--aq-gold-light), var(--aq-gold) 45%, var(--aq-gold-mid));
    color: #331603;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .02em;
    text-shadow: 0 1px 0 rgba(255, 236, 210, .4);
    cursor: pointer;
    /* Latido lento: llama la atención sin marearte si dejas la pestaña abierta. */
    animation: gift-latido 2.6s ease-in-out infinite;
    transition: transform .12s ease, border-color .15s ease, background .18s ease, box-shadow .18s ease;
}

.gift-btn:hover {
    transform: translateY(-2px);
    background: linear-gradient(150deg, #f7cf8e, var(--aq-gold-light) 45%, var(--aq-gold));
    border-color: #f7cf8e;
    color: #2a1202;
    box-shadow: 0 0 30px var(--aq-gold-glow), inset 0 1px 0 rgba(255, 255, 255, .55);
}

.gift-btn:active { transform: translateY(0); }

/* Que quien navega con teclado reciba la misma pista que quien usa el raton. */
.gift-btn:focus-visible {
    outline: 2px solid var(--aq-gold-light);
    outline-offset: 3px;
}

@keyframes gift-latido {
    0%, 100% { box-shadow: 0 0 0 0 var(--aq-gold-glow), inset 0 1px 0 rgba(255, 255, 255, .45); }
    50%      { box-shadow: 0 0 18px 4px var(--aq-gold-soft), inset 0 1px 0 rgba(255, 255, 255, .45); }
}

/* Quien pide menos movimiento se queda con el boton dorado, pero quieto. */
@media (prefers-reduced-motion: reduce) {
    .gift-btn { animation: none; transition: none; }
    .gift-btn:hover { transform: none; }
}

.gift-state {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin: 1rem 0 0;
    padding: .7rem 1rem;
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: 7px;
    background: var(--bg-surface);
    color: var(--text-panel-soft);
    font-size: .92rem;
}
.gift-state--done    { border-left-color: var(--accent-purple); }
.gift-state--blocked { border-left-color: var(--accent-red); }
.gift-state--pending { border-left-color: var(--gold); }

/* --- El gacha ------------------------------------------------------------- */
body.gacha-abierto { overflow: hidden; }

/* EL ARMAZÓN DE VENTANA MODAL, COMPARTIDO (necROmantic 2026-08-31).
   Estas reglas eran solo del gacha. Al hacer la ventana de confirmación de "Donar mis minutos
   al gremio" se AGRUPARON en vez de copiarse: una sola ventana modal en toda la web, que se
   retoca en un sitio. `.gacha` conserva exactamente los mismos valores que tenía. */
.gacha, .nmodal { position: fixed; inset: 0; z-index: 900; display: grid; place-items: center; }
.gacha[hidden], .nmodal[hidden] { display: none; }

.gacha__backdrop, .nmodal__backdrop { position: absolute; inset: 0; background: rgba(6, 4, 12, .88); }

.gacha__panel, .nmodal__panel {
    position: relative;
    width: min(30rem, calc(100vw - 2rem));
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    padding: 1.6rem 1.4rem 1.2rem;
    border: 1px solid var(--border-accent);
    border-radius: 12px;
    background: var(--bg-surface);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .7);
    text-align: center;
}

.gacha__title, .nmodal__title {
    margin: 0 0 1rem;
    color: var(--gold);
    font-size: 1.05rem;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* Al morir, la caja acaba transparente: la escena se retira entera con [hidden]
   (display:none) en vez de dejarla invisible, o quedaria un hueco vacio de su tamano
   justo encima de los premios. */
.gacha__stage { display: grid; place-items: center; }
.gacha__stage[hidden] { display: none; }

/* Es un <button>: hay que quitarle la piel de boton para dejar solo el sprite. */
.gacha__box {
    width: 157px;
    height: 142px;
    /* Ojo: el sprite va con scale(1.15) y la escala no ocupa sitio en el layout, asi
       que se sale ~11px por arriba y por abajo. El hueco visible acaba siendo menor
       que estos 25px. */
    margin-top: 25px;
    margin-bottom: 25px;
    padding: 0;
    border: 0;
    background-color: transparent;
    background-repeat: no-repeat;
    /* Pixel art: la tira se sirve a 1x y la escala el navegador sin suavizar. */
    image-rendering: pixelated;
    transform: scale(1.15);
    cursor: pointer;
    transition: transform .15s ease, filter .15s ease;
}
.gacha__box:hover:not(:disabled) { transform: scale(1.22); filter: brightness(1.12); }
.gacha__box:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 6px;
}
/* Mientras revienta ya no se puede volver a pulsar, y el cursor lo dice. */
.gacha__box:disabled { cursor: default; transform: scale(1.15); filter: none; }

.gacha__hint {
    margin: .6rem 0 0;
    color: var(--gold);
    font-size: .92rem;
    letter-spacing: .04em;
    /* Respira despacio para que se lea como "pulsa aqui" sin necesidad de decirlo. */
    animation: gacha-respira 1.8s ease-in-out infinite;
}
@keyframes gacha-respira {
    0%, 100% { opacity: .55; }
    50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .gacha__hint { animation: none; opacity: 1; }
}

.gacha__loot-head {
    margin: .2rem 0 1rem;
    color: var(--text-heading2);
    font-size: 1.08rem;
    font-weight: 700;
}

.gacha__items { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: .5rem; }

.gacha__item {
    opacity: 0;
    animation: gacha-entra .45s ease forwards;
}
@keyframes gacha-entra {
    from { opacity: 0; transform: translateY(10px) scale(.94); }
    to   { opacity: 1; transform: none; }
}

.gacha__item a {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: .5rem .8rem;
    border: 1px solid var(--border-light);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-primary);
    text-decoration: none;
    transition: border-color .15s ease, transform .12s ease;
}
.gacha__item a:hover { border-color: var(--gold); transform: translateX(2px); }

.gacha__item-icon { width: 28px; height: 28px; image-rendering: pixelated; flex: none; }
.gacha__item-name { flex: 1 1 auto; text-align: left; }
.gacha__item-amount { color: var(--gold); font-variant-numeric: tabular-nums; }

.gacha__loot-note { margin: 0; color: var(--text-muted); font-size: .84rem; }

.gacha__error {
    margin: 1rem 0 0;
    padding: .7rem 1rem;
    border: 1px solid var(--accent-red);
    border-radius: 7px;
    color: var(--accent-red-h);
}

.gacha__close {
    margin-top: 1.2rem;
    padding: .45rem 1.4rem;
    border: 1px solid var(--border-light);
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.gacha__close:hover { border-color: var(--border-accent); color: var(--text-primary); }

/* Quien haya pedido menos movimiento se queda sin latido ni entradas animadas.
   La animación de la caja no se toca: es el contenido, no un adorno. */
@media (prefers-reduced-motion: reduce) {
    .gift-btn { animation: none; }
    .gacha__item { opacity: 1; animation: none; }
}

/* --- Modo pruebas del regalo diario (2026-08-01) --------------------------- */
/* Chillón a propósito: mientras esto se vea, nadie debe creer que ha recibido algo. */
.gift-state--sandbox {
    align-items: flex-start;
    border-color: var(--gold);
    border-left-color: var(--gold);
    background: rgba(223, 160, 198, .08);
    color: var(--text-panel-soft);
}
.gift-state--sandbox i { margin-top: .2rem; color: var(--gold); }
.gift-state--sandbox code {
    padding: .05rem .3rem;
    border-radius: 3px;
    background: var(--bg-input);
    color: var(--text-code-strong);
    font-size: .9em;
}

.gift-btn--test {
    background: linear-gradient(160deg, var(--bg-surface-alt), var(--bg-sidebar-head));
    border-color: var(--gold-dim);
    animation: none;   /* sin latido: esto no es una recompensa, es una herramienta */
}
.gift-btn--test:hover { border-color: var(--gold); }

.gacha__loot-note--sandbox {
    padding: .55rem .8rem;
    border: 1px dashed var(--gold-dim);
    border-radius: 6px;
    color: var(--text-panel-soft);
}

/* ═══════════════════════════════════════════════════════════════════════
   necROmantic 2026-08-01 — Panel de asistencia automatica (.cpan)
   Cuatro pestanas en la ficha de personaje: Autoplay, Helpme, Mercenario
   y Homunculo. Usa la paleta violeta del tema y la rampa dorada (--aq-gold-*)
   solo para el acento de la pestana activa y el boton de guardar.
   ═══════════════════════════════════════════════════════════════════════ */

.cpan {
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1.1rem 1.2rem 1.3rem;
    margin-bottom: 1.6rem;
}

.cpan__intro {
    color: var(--text-muted);
    font-size: .9rem;
    line-height: 1.55;
    margin: 0 0 .9rem;
}
.cpan__live { color: var(--aq-gold-light); }

.cpan__note {
    font-size: .85rem;
    padding: .5rem .75rem;
    border-radius: 6px;
    margin: 0 0 .9rem;
}
.cpan__note--wait {
    background: var(--aq-gold-soft);
    border: 1px solid var(--aq-gold-mid);
    color: var(--aq-gold-light);
}

/* ── Pestanas ───────────────────────────────────────────────────────── */
.cpan__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: .7rem;
    margin-bottom: 1.1rem;
}
.cpan__tab {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .5rem .95rem;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 7px;
    color: var(--text-muted);
    font-size: .9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}
.cpan__tab:hover { background: var(--bg-table-alt); color: var(--text-primary); }
.cpan__tab--on {
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-table-alt));
    border-color: var(--aq-gold-mid);
    color: var(--text-heading2);
    box-shadow: 0 0 12px var(--aq-gold-soft);
}
.cpan__tab-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 .3rem;
    border-radius: 5px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    font-size: .72rem;
    letter-spacing: .02em;
}
.cpan__tab--on .cpan__tab-mark {
    border-color: var(--aq-gold);
    color: var(--aq-gold-light);
}

/* ── Paneles ────────────────────────────────────────────────────────── */
.cpan__panel--off { display: none; }

.cpan__blurb {
    color: var(--text-muted);
    font-size: .88rem;
    line-height: 1.55;
    margin: 0 0 1rem;
}

.cpan__state {
    font-size: .88rem;
    color: var(--text-muted);
    margin: 0 0 1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}
.cpan__on  { color: #7fd6a0; }
.cpan__off { color: var(--text-muted); }
.cpan__hint { flex: 1 1 100%; font-size: .8rem; }
.cpan__hint code {
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: .05rem .3rem;
}

.cpan__sub {
    font-size: .82rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--text-heading);
    margin: 1.4rem 0 .7rem;
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--border);
}

/* ── Selectores de modo ─────────────────────────────────────────────── */
.cpan__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: .9rem;
}
/* El desplegable y su «Saber más…», en una sola celda de la rejilla (necROmantic 2026-08-10). */
.cpan__field-wrap { display: flex; flex-direction: column; }
/* Y la MISMA pareja de la nota de aquí abajo, por el mismo motivo: `data-needs-any` se mudó a este
   envoltorio, así que es él quien recibe [hidden] y su display:flex se lo comería. */
.cpan__field-wrap[hidden] { display: none; }
.cpan__field { display: flex; flex-direction: column; gap: .35rem; }
/* necROmantic 2026-08-07: un ajuste que solo aplica con algo encendido se retira con
   [hidden] desde el JS del panel (refreshDeps). Sin esta regla no se iria: el display:flex
   de la linea de arriba gana al display:none que el navegador le da a [hidden]. Es la misma
   pareja que ya tienen .pnav__tile y .gacha en este mismo fichero. */
.cpan__field[hidden] { display: none; }
.cpan__field-label {
    font-size: .85rem;
    font-weight: 600;
    color: var(--text-primary);
}
.cpan__field-help { font-size: .78rem; color: var(--text-muted); line-height: 1.45; }
.cpan__select {
    width: 100%;
    padding: .5rem .6rem;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: .87rem;
}
.cpan__select:focus { outline: none; border-color: var(--aq-gold); }

/* ── Interruptores ──────────────────────────────────────────────────── */
.cpan__switches {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: .55rem;
}
/* La TARJETA de una función (necROmantic 2026-08-10). El fondo, el borde y el relleno se mudaron
   aquí desde `.cpan__switch` al meter el «Saber más…»: el desplegable tiene que quedar DENTRO de la
   tarjeta pero FUERA de la etiqueta, porque un <summary> dentro de un <label> hace que abrir la
   ayuda marque el interruptor. */
.cpan__fn {
    display: flex;
    flex-direction: column;
    padding: .6rem .7rem;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 7px;
    transition: border-color .15s, background .15s;
}
.cpan__fn:hover { background: var(--bg-table-alt); border-color: var(--border-light); }

/* «Saber más…» (necROmantic 2026-08-10, petición del usuario): TODA la ayuda del panel, plegada.
   Deliberadamente discreto -- es un enlace, no un botón: lo que tiene que destacar es el control,
   y la explicación está ahí para quien la busque. */
.cpan__more { margin-top: .4rem; }
.cpan__more > summary {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .74rem;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
    padding: .15rem 0;
}
.cpan__more > summary::-webkit-details-marker { display: none; }
.cpan__more > summary::before {
    content: "\25B8";
    display: inline-block;
    transition: transform .2s ease;
}
.cpan__more[open] > summary::before { transform: rotate(90deg); }
.cpan__more > summary:hover { color: var(--text-label-hover); }
.cpan__more-body {
    margin-top: .35rem;
    padding-left: .8rem;
    border-left: 2px solid var(--border);
    font-size: .78rem;
    line-height: 1.55;
    color: var(--text-muted);
}
.cpan__more-body b { color: var(--text-primary); font-weight: 600; }
.cpan__grid .cpan__more { margin-bottom: .5rem; }
.cskl .cpan__more { margin-bottom: .8rem; }

/* Aire y línea antes de una sección que empieza tema nuevo -- «Objetos» tras «Habilidades»
   (necROmantic 2026-08-10, petición del usuario): las dos comparten tarjeta, y sin esto la segunda
   se leía como la cola de la primera. */
.cpan__sub--gap {
    margin-top: 2.2rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--border);
}
.cpan__switch {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    cursor: pointer;
}
.cpan__switch-input { position: absolute; opacity: 0; width: 0; height: 0; }
/* El interruptor y su icono, en UNA sola columna (necROmantic 2026-08-10, decisión del usuario).
   En columna aparte el icono empujaba el texto y las tres piezas competían por la vista; apilado,
   la izquierda es "el control" de un vistazo y el texto sigue empezando donde empezaba. El ancho
   lo fija el propio interruptor, así que el icono queda centrado bajo él sin números a mano. */
.cpan__switch-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 0 0 auto;
}
/* Tamaño y separación dados por el usuario (2026-08-10). La separación va como `margin-bottom` del
   icono y no como `gap` de la columna a propósito: así el número que se pidió es el que se ve, sin
   sumarle otro por detrás. */
.cpan__ico {
    font-size: 31px;
    margin-bottom: 7px;
    line-height: 1;
    color: var(--text-muted);
    transition: color .18s;
}
/* Encendido, el icono acompaña al interruptor en vez de quedarse apagado encima de algo vivo. Se
   usa el mismo oro que la pastilla, no un color propio: son la misma pieza.

   Va con `:has()` y no con el combinador de hermanos porque el icono está DELANTE de la casilla, y
   `~` solo mira hacia adelante. Donde `:has()` no exista, el icono se queda del color apagado: se
   ve peor, pero nada se rompe. */
.cpan__switch:has(.cpan__switch-input:checked) .cpan__ico { color: var(--aq-gold-light); }
.cpan__switch-track {
    position: relative;
    flex: 0 0 auto;
    width: 2.3rem;
    height: 1.25rem;
    margin-top: .1rem;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    transition: background .18s, border-color .18s;
}
.cpan__switch-knob {
    position: absolute;
    top: 50%;
    left: .15rem;
    width: .9rem;
    height: .9rem;
    margin-top: -.45rem;
    background: var(--text-muted);
    border-radius: 50%;
    transition: left .18s, background .18s;
}
.cpan__switch-input:checked + .cpan__switch-track {
    background: var(--aq-gold-soft);
    border-color: var(--aq-gold);
}
.cpan__switch-input:checked + .cpan__switch-track .cpan__switch-knob {
    left: calc(100% - 1.05rem);
    background: var(--aq-gold-light);
}
.cpan__switch-input:focus-visible + .cpan__switch-track {
    box-shadow: 0 0 0 2px var(--aq-gold-glow);
}
.cpan__switch-text { display: flex; flex-direction: column; gap: .15rem; }
.cpan__switch-text b { font-size: .87rem; color: var(--text-primary); font-weight: 600; }
.cpan__switch-text span { font-size: .78rem; color: var(--text-muted); line-height: 1.45; }

.cpan__locked {
    margin-top: .8rem;
    padding: .6rem .75rem;
    background: var(--bg-table-row);
    border: 1px dashed var(--border-light);
    border-radius: 7px;
}
.cpan__locked p { margin: .2rem 0; font-size: .8rem; color: var(--text-muted); line-height: 1.5; }
.cpan__locked b { color: var(--text-primary); }

/* ── Listas de monstruos ────────────────────────────────────────────── */
.cpan__lists {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: .9rem;
}
.cpan__list {
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: .8rem .85rem;
}
.cpan__list-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}
.cpan__list-head b { font-size: .88rem; color: var(--text-primary); }
.cpan__count {
    font-size: .75rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.cpan__list-help {
    margin: .3rem 0 .6rem;
    font-size: .77rem;
    color: var(--text-muted);
    line-height: 1.45;
}

/* Interruptor que vive DENTRO de una tarjeta de lista ("Huir de todos los bosses").
   Una sola columna siempre: la tarjeta ya es estrecha y el auto-fit de .cpan__switches
   la partiria en dos con cualquier ancho. El fondo sube un escalon porque la tarjeta ya
   usa --bg-table-row y sin eso el interruptor se fundiria con ella. */
.cpan__switches--in-list {
    grid-template-columns: 1fr;
    margin: 0 0 .6rem;
}
.cpan__switches--in-list .cpan__fn { background: var(--bg-table-alt); }
.cpan__switches--in-list .cpan__fn:hover { background: var(--bg-input); }

/* ── Habilidades de la IA del homúnculo (necROmantic 2026-08-26) ────────────────
   Un interruptor por habilidad, repartidos por criatura. NO hay rejilla propia: se
   reutiliza .cpan__switches, que ya es la rejilla de tarjetas de este panel y ya se
   adapta al ancho. Aquí solo van los dos títulos del reparto, la marca de las seis
   que vienen apagadas de serie y la nota de Bio Explosion. */
.hskl__tier {
    margin: 1.5rem 0 .2rem;
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--text-heading);
}
.hskl__grupo {
    margin: .85rem 0 .45rem;
    font-size: .8rem;
    font-weight: 600;
    color: var(--text-muted);
}
/* LA MARCA DE LAS SEIS QUE NACEN APAGADAS. Es un tono, no un candado: se pueden
   encender igual que las demás, y al lado va escrito a cambio de qué. Se usa la rampa
   dorada que ya usa el aviso de "Heredar de" (.cpan__inherit-warn) en este mismo
   panel, para que "ojo con esto" se vea siempre del mismo color. */
.hskl__fn--riesgo {
    background: var(--aq-gold-soft);
    border-color: var(--aq-gold-mid);
}
.hskl__fn--riesgo:hover {
    background: var(--aq-gold-soft);
    border-color: var(--aq-gold);
}
.hskl__fn--riesgo .cpan__ico,
.hskl__fn--riesgo .cpan__switch-text b { color: var(--aq-gold-light); }

.hskl__nota {
    margin: 1.3rem 0 0;
    padding: .5rem .7rem;
    background: var(--bg-table-alt);
    border-left: 2px solid var(--border-light);
    border-radius: 0 5px 5px 0;
    font-size: .76rem;
    line-height: 1.5;
    color: var(--text-muted);
}
.hskl__nota b { color: var(--text-primary); }
.hskl__nota .fa-circle-info { margin-right: .35rem; }

.cpan__search { display: flex; gap: .4rem; }
.cpan__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: .45rem .6rem;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: .85rem;
}
.cpan__input:focus { outline: none; border-color: var(--aq-gold); }

.cpan__results {
    margin-top: .4rem;
    max-height: 14rem;
    overflow-y: auto;
    border: 1px solid var(--border-light);
    border-radius: 6px;
    background: var(--bg-surface-alt);
}
.cpan__hit {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    width: 100%;
    padding: .45rem .6rem;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--border);
    color: var(--text-primary);
    text-align: left;
    font-size: .84rem;
    cursor: pointer;
}
.cpan__hit:last-child { border-bottom: 0; }
.cpan__hit:hover { background: var(--bg-table-alt); }
.cpan__hit span { font-size: .74rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* necROmantic 2026-08-04: alto maximo y scroll propio.
   Es la unica parte de la tarjeta que crece sin freno -- las listas admiten 256
   monstruos y "Agregar tipicos" mete 50 de una tacada -- y sin tope empujaba
   "Heredar de" fuera de la pantalla y estiraba la fila entera del grid, porque las
   tres tarjetas se igualan a la mas alta.

   El tope va AQUI y no en .cpan__list a proposito: si scrollara la tarjeta entera, el
   buscador y los botones de "Agregar tipicos"/"Eliminar todos" se irian de la vista
   justo cuando la lista es larga, que es cuando mas se usan. Asi la cabecera, el
   contador y los botones se quedan siempre puestos y solo se mueven las fichas.
   El desplegable del buscador ya tenia su propio tope de 14rem. */
.cpan__chips {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: .35rem;
    margin-top: .6rem;
    max-height: 15rem;
    overflow-y: auto;
    /* Al llegar al final, la rueda no sigue arrastrando la pagina de debajo. */
    overscroll-behavior: contain;
    /* Hueco para la barra y para que el foco de las fichas no quede recortado. */
    padding-right: .2rem;

    /* Que se NOTE que hay mas. Cortar sin avisar es peor que no cortar: la tarjeta
       parece tener 14 monstruos cuando tiene 50, y solo el contador de la cabecera
       lo desmiente. Dos pistas, por si una falla:

       1. La barra, con el pulgar en claro para que se vea sobre la tarjeta (la global
          de :root usa --border, que sobre --bg-table-row casi no se distingue).
       2. Un degradado arriba y abajo que aparece SOLO cuando queda contenido en esa
          direccion. Sin JavaScript: las dos capas "tapa" van con background-attachment
          local (se desplazan con el contenido y por tanto cubren la sombra al llegar
          al tope) y las dos de sombra con scroll (se quedan pegadas al borde). */
    scrollbar-width: thin;
    scrollbar-color: var(--border-light) transparent;
    background:
        linear-gradient(var(--bg-table-row) 35%, transparent) center top,
        linear-gradient(transparent, var(--bg-table-row) 65%) center bottom,
        radial-gradient(farthest-side at 50% 0,   var(--alpha-black-22), transparent) center top,
        radial-gradient(farthest-side at 50% 100%, var(--alpha-black-22), transparent) center bottom;
    background-repeat: no-repeat;
    background-size: 100% 1.6rem, 100% 1.6rem, 100% .5rem, 100% .5rem;
    background-attachment: local, local, scroll, scroll;
}
.cpan__chips::-webkit-scrollbar-thumb { background: var(--border-light); }
.cpan__chips::-webkit-scrollbar-thumb:hover { background: var(--aq-gold-mid); }
.cpan__chips::-webkit-scrollbar-track { background: transparent; }
.cpan__chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .25rem .3rem .25rem .55rem;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    font-size: .78rem;
}
.cpan__chip b { color: var(--text-primary); font-weight: 600; }
.cpan__chip i {
    font-style: normal;
    color: var(--text-muted);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
}
.cpan__chip-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    background: none;
    border: 0;
    border-radius: 50%;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.cpan__chip-x:hover { background: var(--accent-red); color: #fff; }

.cpan__empty { margin: .2rem 0; font-size: .78rem; color: var(--text-muted); font-style: italic; }

/* ── Pie: guardar / descartar / mensajes ────────────────────────────── */
.cpan__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    margin-top: 1.3rem;
    padding-top: .9rem;
    border-top: 1px solid var(--border);
}
.cpan__btn {
    padding: .5rem .95rem;
    border-radius: 6px;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
    transition: filter .15s, background .15s, border-color .15s;
}
.cpan__btn:disabled { opacity: .55; cursor: default; }
.cpan__btn--save {
    background: linear-gradient(180deg, var(--aq-gold), var(--aq-gold-mid));
    border: 1px solid var(--aq-gold-light);
    color: #2a1503;
    box-shadow: 0 0 14px var(--aq-gold-soft);
}
.cpan__btn--save:hover:not(:disabled) { filter: brightness(1.1); }
.cpan__btn--ghost {
    background: var(--bg-table-row);
    border: 1px solid var(--border-light);
    color: var(--text-muted);
}
.cpan__btn--ghost:hover:not(:disabled) { background: var(--bg-table-alt); color: var(--text-primary); }

.cpan__msg { font-size: .83rem; color: var(--text-muted); }
.cpan__msg--ok   { color: #7fd6a0; }
.cpan__msg--bad  { color: var(--accent-red); }
.cpan__msg--wait { color: var(--aq-gold-light); }

/* ── Pantallas estrechas ────────────────────────────────────────────── */
@media (max-width: 640px) {
    .cpan { padding: .85rem .8rem 1rem; }
    .cpan__tab { flex: 1 1 8rem; justify-content: center; }
    .cpan__lists,
    .cpan__switches,
    .cpan__grid { grid-template-columns: 1fr; }
    .cpan__foot .cpan__btn { flex: 1 1 auto; }
}

@media (prefers-reduced-motion: reduce) {
    .cpan__tab,
    .cpan__switch,
    .cpan__switch-track,
    .cpan__switch-knob,
    .cpan__btn { transition: none; }
}

/* ── necROmantic 2026-08-01 (v2): retratos de monstruo, acciones de lista y
      el interruptor de encendido del autoplay ────────────────────────────── */

/* Retrato del monstruo. Los gif de data/monsters/ son ~37x36 con transparencia;
   se dejan a tamaño fijo para que las fichas no bailen de altura entre unas y
   otras, y con image-rendering nítido porque son sprites pequeños. */
.cpan__mob-img {
    flex: 0 0 auto;
    width: 1.7rem;
    height: 1.7rem;
    object-fit: contain;
    image-rendering: -webkit-optimize-contrast;
}

.cpan__chip { padding-left: .3rem; }
.cpan__chip .cpan__mob-img { width: 1.5rem; height: 1.5rem; }

.cpan__hit {
    flex-direction: row;
    align-items: center;
    gap: .5rem;
}
.cpan__hit .cpan__mob-img { width: 2rem; height: 2rem; }
.cpan__hit-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }

/* Acciones bajo el buscador de cada lista. */
.cpan__list-acts {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .4rem;
}
.cpan__btn--mini {
    padding: .3rem .6rem;
    font-size: .76rem;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-light);
    color: var(--text-muted);
}
.cpan__btn--mini:hover:not(:disabled) { background: var(--bg-table-alt); color: var(--text-primary); }
.cpan__btn--danger:hover:not(:disabled) {
    background: var(--accent-red);
    border-color: var(--accent-red);
    color: #fff;
}

/* ── Tácticas avanzadas (beta) ──────────────────────────────────────────
      Vive al final de "Asistencia automática", fuera de las pestañas. Se
      distingue de las tarjetas normales sin gritar: borde discontinuo, que es
      el idioma que ya usa .cpan__locked para "esto no es configuración
      corriente". Cuando no se tiene el permiso baja el contraste, porque
      entonces es informativo y no accionable. ── */
.cpan__tac {
    margin: 1.6rem 0 0;
    padding: .9rem 1rem 1rem;
    background: var(--bg-table-row);
    border: 1px dashed var(--aq-gold-mid);
    border-radius: 9px;
}
.cpan__tac--locked { border-color: var(--border-light); }

.cpan__tac-head {
    display: flex;
    align-items: center;
    gap: .55rem;
    flex-wrap: wrap;
}
/* El .cpan__sub trae margen y subrayado para separar secciones; dentro de esta
   tarjeta no hay nada de lo que separarse. */
.cpan__tac-head .cpan__sub {
    margin: 0;
    padding: 0;
    border-bottom: 0;
}
.cpan__beta {
    padding: .1rem .45rem;
    background: var(--aq-gold-soft);
    border: 1px solid var(--aq-gold-mid);
    border-radius: 999px;
    color: var(--aq-gold-light);
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
}
.cpan__tac--locked .cpan__beta {
    background: transparent;
    border-color: var(--border-light);
    color: var(--text-muted);
}

.cpan__tac-text {
    margin: .7rem 0 0;
    font-size: .84rem;
    color: var(--text-muted);
    line-height: 1.6;
}

/* El aviso de responsabilidad. Barra lateral en vez de recuadro completo: se lee
   como una nota al margen del párrafo anterior, que es lo que es, y no compite
   con el botón por la atención. */
.cpan__tac-warn {
    margin: .75rem 0 0;
    padding: .55rem .75rem;
    background: var(--alpha-gold-08);
    border-left: 3px solid var(--text-status-warning);
    border-radius: 0 6px 6px 0;
    font-size: .81rem;
    color: var(--text-panel-soft);
    line-height: 1.6;
}
.cpan__tac-warn b { color: var(--text-primary); }
.cpan__tac-warn--off {
    background: transparent;
    border-left-color: var(--border-light);
    color: var(--text-muted);
}

/* Gana a .tacx__open (editor.panel.css) por especificidad, no por orden: ese
   fichero se enlaza dentro del body y por tanto va DESPUÉS de este. Solo se
   redefine el aspecto; .tacx__open--busy sigue poniendo su opacidad/cursor. */
.cpan__tac .cpan__tac-open {
    display: inline-flex;
    align-items: center;
    margin-top: .85rem;
    padding: .5rem 1.1rem;
    background: linear-gradient(180deg, var(--aq-gold), var(--aq-gold-mid));
    border: 1px solid var(--aq-gold-light);
    border-radius: 7px;
    color: var(--bg-content);
    font: inherit;
    font-weight: 600;
    font-size: .85rem;
    cursor: pointer;
    transition: filter .15s;
}
.cpan__tac .cpan__tac-open:hover { filter: brightness(1.1); }
.cpan__tac .cpan__tac-open:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--aq-gold-glow);
}

/* ── Interruptor de encendido del autoplay: el mismo patrón que los demás,
      pero grande y en oro, porque es la palanca principal de la pestaña. ── */
.cpan__power {
    margin: 0 0 1.2rem;
    padding: .85rem .95rem;
    background: radial-gradient(circle at 12% 30%, var(--aq-gold-soft), var(--bg-table-row) 70%);
    border: 1px solid var(--aq-gold-mid);
    border-radius: 9px;
}
.cpan__power-switch {
    display: flex;
    align-items: center;
    gap: .8rem;
    cursor: pointer;
}
.cpan__power-switch--off { cursor: default; opacity: .6; }

.cpan__power-track {
    position: relative;
    flex: 0 0 auto;
    width: 3.4rem;
    height: 1.75rem;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    transition: background .2s, border-color .2s, box-shadow .2s;
}
.cpan__power-knob {
    position: absolute;
    top: 50%;
    left: .2rem;
    width: 1.3rem;
    height: 1.3rem;
    margin-top: -.65rem;
    background: var(--text-muted);
    border-radius: 50%;
    transition: left .2s, background .2s, box-shadow .2s;
}
.cpan__switch-input:checked + .cpan__power-track {
    background: linear-gradient(180deg, var(--aq-gold-mid), var(--aq-gold-deep));
    border-color: var(--aq-gold-light);
    box-shadow: 0 0 16px var(--aq-gold-glow);
}
.cpan__switch-input:checked + .cpan__power-track .cpan__power-knob {
    left: calc(100% - 1.5rem);
    background: linear-gradient(180deg, #fff6e2, var(--aq-gold-light));
    box-shadow: 0 0 8px var(--aq-gold-glow);
}
.cpan__switch-input:focus-visible + .cpan__power-track {
    box-shadow: 0 0 0 3px var(--aq-gold-glow);
}
.cpan__switch-input:disabled + .cpan__power-track { cursor: default; }

.cpan__power-text { display: flex; flex-direction: column; gap: .15rem; }
.cpan__power-text b {
    font-size: .95rem;
    font-weight: 700;
    color: var(--text-heading2);
    letter-spacing: .01em;
}
.cpan__switch-input:checked ~ .cpan__power-text b { color: var(--aq-gold-light); }
.cpan__power-text span { font-size: .79rem; color: var(--text-muted); line-height: 1.45; }

.cpan__power .cpan__hint {
    display: block;
    margin: .65rem 0 0;
    padding-top: .55rem;
    border-top: 1px solid var(--border);
    font-size: .77rem;
    color: var(--text-muted);
    line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
    .cpan__power-track,
    .cpan__power-knob { transition: none; }
}

/* necROmantic 2026-08-01: boton "Configurar" en cada personaje de /account/view/,
   a la derecha del nombre y la clase. Lleva a la ficha del personaje, donde estan
   las pestanas de asistencia. .chc__id ya es un flex en fila, asi que basta con
   empujarlo al extremo con margin-left auto. */
.chc__config {
    flex: 0 0 auto;
    margin-left: auto;
    padding: .35rem .8rem;
    border: 1px solid var(--aq-gold-mid);
    border-radius: 999px;
    background: var(--aq-gold-soft);
    color: var(--aq-gold-light);
    font-size: .78rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: background .15s, color .15s, border-color .15s, box-shadow .15s;
}
.chc__config:hover,
.chc__config:focus-visible {
    background: linear-gradient(180deg, var(--aq-gold), var(--aq-gold-mid));
    border-color: var(--aq-gold-light);
    color: #2a1503;
    box-shadow: 0 0 12px var(--aq-gold-soft);
    text-decoration: none;
}

@media (max-width: 520px) {
    /* En movil el nombre ya ocupa el ancho; el boton baja a su propia linea. */
    .chc__id { flex-wrap: wrap; }
    .chc__config { margin-left: 0; width: 100%; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
    .chc__config { transition: none; }
}

/* necROmantic 2026-08-01 (v3): los resultados del buscador se agrupan por nombre
   exacto, así que una fila puede representar varios ids. Se listan debajo para
   que se vea qué se va a añadir. */
.cpan__hit-ids {
    font-size: .7rem;
    color: var(--text-muted);
    opacity: .8;
    font-variant-numeric: tabular-nums;
    word-break: break-word;
}
.cpan__hit b { line-height: 1.25; }

/* necROmantic 2026-08-01 (v4): huecos de companion en la pestaña Helpme, y la
   ficha agrupada (una por nombre, con "×N" cuando hay varias variantes). */
.cpan__power--slots { background: var(--bg-table-row); border-color: var(--border-light); }
.cpan__sub--tight { margin-top: 0; }
.cpan__hint--top { margin-top: 0; padding-top: 0; border-top: 0; }

.cpan__slots {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: .7rem;
    margin-top: .8rem;
}
.cpan__slots-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    margin-top: .9rem;
}

/* La ficha agrupada lleva "×6" en vez de un id; se marca para que no se lea como
   si fuera el número de identificación del monstruo. */
.cpan__chip[title] { cursor: help; }
.cpan__chip i {
    padding: .05rem .3rem;
    background: var(--bg-input);
    border-radius: 4px;
}

@media (max-width: 640px) {
    .cpan__slots { grid-template-columns: 1fr; }
}

/* necROmantic 2026-08-01 (v5): "Heredar de" — referencias virtuales entre las
   listas de los cuatro ayudantes. Píldoras marcables; la del propio sistema sale
   deshabilitada (heredarse a sí mismo no significa nada). */
.cpan__inherit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    margin-top: .7rem;
    padding-top: .6rem;
    border-top: 1px dashed var(--border);
}
.cpan__inherit-label {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--text-muted);
    margin-right: .2rem;
}
.cpan__pill { position: relative; display: inline-flex; cursor: pointer; }
.cpan__pill-input { position: absolute; opacity: 0; width: 0; height: 0; }
.cpan__pill span {
    display: inline-block;
    padding: .22rem .6rem;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-muted);
    font-size: .75rem;
    transition: background .15s, color .15s, border-color .15s;
}
.cpan__pill:hover span { color: var(--text-primary); border-color: var(--border-accent); }
.cpan__pill-input:checked + span {
    background: var(--aq-gold-soft);
    border-color: var(--aq-gold);
    color: var(--aq-gold-light);
    font-weight: 600;
}
.cpan__pill-input:focus-visible + span { box-shadow: 0 0 0 2px var(--aq-gold-glow); }
.cpan__pill--self { cursor: default; }
.cpan__pill--self span { opacity: .35; text-decoration: line-through; }
.cpan__pill--self:hover span { color: var(--text-muted); border-color: var(--border-light); }

.cpan__inherit-warn {
    flex: 1 1 100%;
    margin: .4rem 0 0;
    padding: .4rem .6rem;
    background: var(--aq-gold-soft);
    border-left: 2px solid var(--aq-gold);
    border-radius: 0 5px 5px 0;
    font-size: .75rem;
    line-height: 1.45;
    color: var(--text-muted);
}
.cpan__inherit-warn b { color: var(--aq-gold-light); }

@media (prefers-reduced-motion: reduce) { .cpan__pill span { transition: none; } }

/* necROmantic 2026-08-01 (v6): alimentación automática de mascota y homúnculo.
   Va fuera de las pestañas porque no es configuración de la IA sino del bicho. */
.cpan__feed {
    margin: 0 0 1.1rem;
    padding: .8rem .9rem;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 9px;
}
.cpan__feed-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: .55rem;
    margin-top: .6rem;
}
.cpan__feed-card { min-width: 0; }
/* Bloqueado por nivel: se ve, se entiende por qué, y no se puede pulsar. */
.cpan__switch--locked { cursor: default; opacity: .62; }
.cpan__switch--locked:hover { background: var(--bg-table-row); border-color: var(--border); }
.cpan__feed .cpan__msg { display: inline-block; margin-top: .5rem; }
@media (max-width: 640px) { .cpan__feed-row { grid-template-columns: 1fr; } }

/* ── Configuración por habilidad ─────────────────────────────────────
   necROmantic 2026-08-07 (etapa E4). Una tarjeta por habilidad que el personaje conoce.

   La rejilla es `auto-fill` y no `auto-fit` a propósito: con `auto-fit`, un personaje con una
   sola habilidad integrada se encontraría esa tarjeta estirada de lado a lado de la pantalla. */
/* LO OCULTO, OCULTO DE VERDAD.
   El atributo `hidden` del navegador vale `display: none`, y cualquier clase con `display` se lo
   come. Aquí mordió dos veces: `.cskl__find` es `display:flex`, así que los buscadores y el
   desplegable de objetivos se veían SIEMPRE, incluso recién cargada la página, con su `hidden`
   puesto y todo. Es la misma pareja que ya tenían `.cpan__field`, `.pnav__tile` y `.gacha`.
   Se pone una sola regla para toda la sección porque aquí hay veinte cosas que se ocultan y
   arreglarlas de una en una es esperar a que la próxima se olvide. `.cskl [hidden]` es más
   específico que cualquier clase suelta, así que gana sin necesidad de `!important`. */
.cskl [hidden] { display: none; }

/* MISMA ALTURA PARA TODO LO DE UNA FILA.
   Se mezclan `select`, `input` y `button`, y cada uno trae su altura de fábrica: la línea subía y
   bajaba según lo que tuviera puesto. Con una altura común y `box-sizing` los tres miden igual. */
.cskl__row select,
.cskl__row input[type="text"],
.cskl__row input[type="search"],
.cskl__row input[type="number"],
.cskl__row button {
    height: 1.95em;
    box-sizing: border-box;
    line-height: 1;
}
.cskl__row .cskl__c { min-height: 2.35em; box-sizing: border-box; }
/* Las de dentro de un buscador desplegado no: ahí no hay línea que cuadrar. */
.cskl__row .cskl__find input { height: auto; }

.cskl__tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    margin-bottom: .8rem;
}
.cskl__tools .cpan__input { flex: 1 1 14rem; }
.cskl__filter {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .82rem;
    color: var(--text-muted);
    cursor: pointer;
}
/* UNA TARJETA POR FILA, a lo ancho. Estuvo un rato en rejilla de tres columnas y era un error de
   bulto: un uso es una LÍNEA de controles, y en 19 rem se partía en cinco renglones -- exactamente
   lo contrario de lo que se buscaba. El ancho es el que hace que la línea sea una línea. */
.cskl__grid {
    display: flex;
    flex-direction: column;
    gap: .55rem;
}
.cskl__card {
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: .7rem .8rem;
}
/* El desplegable de "estos necesitan que les digas cuándo" (necROmantic 2026-08-10). Mismo
   lenguaje que el `.flt__more` del listado de objetos -- una pastilla con su flecha -- porque es
   la misma promesa: aquí abajo hay más, y sigue estando donde estaba. */
.cskl__fold { margin-top: .9rem; }
.cskl__fold > summary {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-black-22);
    color: var(--text-muted);
    font-size: .78rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.cskl__fold > summary::-webkit-details-marker { display: none; }
.cskl__fold > summary::before {
    content: "\25B8";
    display: inline-block;
    transition: transform .2s ease;
}
.cskl__fold[open] > summary::before { transform: rotate(90deg); }
.cskl__fold > summary:hover,
.cskl__fold[open] > summary { border-color: var(--border-accent); color: var(--text-label-hover); }
.cskl__fold .cpan__hint { margin: .7rem 0; }
.cskl__fold .cskl__grid { margin-top: .6rem; }
/* Las que la IA todavía no sabe usar: se ven, pero no prometen nada. */
.cskl__card--off { opacity: .55; }

/* Tocada y sin guardar. Se ve aunque esté plegada: si no, plegar una tarjeta con cambios los
   esconde y nadie sabe que siguen ahí sin guardar. */
/* "Se guarda solo": el pie ya no tiene botón. */
.cpan__auto { font-size: .8rem; color: var(--text-muted); font-style: italic; }

.cskl__card--sucia { border-color: var(--aq-gold, var(--border-accent)); }
.cskl__card--sucia .cskl__head::before {
    content: '●';
    color: var(--aq-gold, var(--text-muted));
    font-size: .7rem;
    margin-right: -.2rem;
}

/* Tarjeta plegable. Nace plegada: con doce abiertas la sección es ilegible, y el resumen de la
   cabecera dice desde fuera cuáles llevan algo dentro. */
.cskl__head--click { cursor: pointer; }
.cskl__head--click::after {
    content: '▾';
    color: var(--text-muted);
    font-size: .8rem;
    transition: transform .15s ease;
}
.cskl__card--fold .cskl__head--click::after { transform: rotate(-90deg); }
.cskl__card--fold .cskl__body { display: none; }
/* Cuántos usos y cuántas condiciones hay dentro. */
.cskl__sum {
    font-size: .74rem;
    color: var(--text-muted);
    white-space: nowrap;
    padding: .05rem .4rem;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.cskl__head {
    display: flex;
    align-items: center;
    gap: .55rem;
}
.cskl__icon { width: 24px; height: 24px; flex: 0 0 auto; image-rendering: pixelated; }
/* Sección configurable pero con su interruptor apagado (necROmantic 2026-08-10, petición del
   usuario). Los iconos a media tinta son el aviso: la lista se sigue pudiendo tocar entera --
   encender un objeto ahí es decidir cuáles valdrán cuando se encienda el consumo, no gastarlos
   ahora --, y esto es lo que dice que todavía no está gastando nada. Solo los iconos: atenuar
   además el texto la dejaría a un paso de parecer deshabilitada, que es justo lo contrario. */
.cskl--apagado .cskl__icon { opacity: .5; }
.cskl__title {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    min-width: 0;
    flex: 1 1 auto;
}
.cskl__title b { font-size: .9rem; overflow-wrap: anywhere; }
.cskl__lv { font-size: .76rem; color: var(--text-muted); }
.cskl__tag { font-size: .72rem; color: var(--text-muted); text-align: right; }
.cskl__body {
    display: flex;
    flex-direction: column;
    gap: .55rem;
    margin-top: .7rem;
    padding-top: .7rem;
    border-top: 1px solid var(--border);
}

/* UN USO = UNA FILA DE TABLA.
   La rejilla es la MISMA para la cabecera y para todas las filas, y ahí está todo el asunto: con
   la etiqueta encima de cada control, dos usos con distinto contenido las colocaban en sitios
   distintos y la tarjeta se leía como un amasijo. Ahora las columnas cuadran siempre.
   Si no cabe, la tabla scrollea a lo ancho DENTRO de la tarjeta -- que la fila siga siendo una
   fila importa más que verla entera sin mover nada. */
.cskl__rows { display: flex; flex-direction: column; gap: .3em; }

/* UN USO = UNA LÍNEA que empieza corta y crece con lo que añadas.
   necROmantic 2026-08-07 (idea del usuario). Antes fue una tabla con todas las columnas siempre
   visibles y no cabía: doce controles reales se salían del borde por más que se recortaran, y una
   columna fuera del borde es la peor forma de esconder algo -- quien no la ve no sabe que existe.
   Con las condiciones en línea y solo si se piden, un uso sencillo son dos controles. */
.cskl__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3em;
    font-size: .84rem;
    padding: .35em .5em;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.cskl__ord { font-style: normal; font-weight: 700; color: var(--text-muted); min-width: 1.1em; }
/* Cada condición puesta: su etiqueta, su control y la × de quitarla. */
.cskl__c {
    display: inline-flex;
    align-items: center;
    gap: .25em;
    padding: .12em .3em;
    background: var(--bg-table-row);
    border: 1px solid var(--border-light);
    border-radius: 5px;
    position: relative;
}
.cskl__c--fija { background: none; border-color: transparent; padding-left: 0; }
.cskl__c-l {
    font-style: normal;
    font-size: .85em;
    color: var(--text-muted);
    white-space: nowrap;
}
.cskl__c-x {
    background: none;
    border: 0;
    color: var(--text-muted);
    cursor: pointer;
    font-size: .95em;
    line-height: 1;
    padding: 0 .1em;
}
.cskl__c-x:hover { color: var(--aq-gold); }
.cskl__conds { display: contents; }

/* Objetivos: siempre en la fila, y se abre al pulsarlo. No es una condición -- toda habilidad se
   lanza sobre alguien -- así que no se añade ni se quita. */
.cskl__obj { position: relative; }
.cskl__obj-btn { padding: .15em .45em; font-size: .9em; max-width: 14em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* En gris mientras vale "los de siempre": así se distingue de un vistazo lo que está tocado. */
.cskl__obj-btn { color: var(--text-muted); }
.cskl__obj-btn--set { color: var(--aq-gold, var(--text-primary)); }
.cskl__find--obj { width: auto; min-width: 9em; }
.cskl__opt {
    display: flex;
    align-items: center;
    gap: .4em;
    padding: .15em .2em;
    font-size: .82em;
    white-space: nowrap;
    cursor: pointer;
    border-radius: 4px;
}
.cskl__opt:hover { background: var(--bg-table-row); }
.cskl__mas { width: auto; color: var(--text-muted); }
.cskl__del { margin-left: auto; padding: .1em .4em; line-height: 1; font-size: 1.1em; }
.cskl__ord { font-style: normal; font-weight: 700; color: var(--text-muted); font-size: .95em; }
/* Los controles NO crecen: dentro de una fila flexible, un `width: 100%` los estiraba a todo el
   ancho y la línea se partía en cuatro renglones. */
.cskl__sel { width: auto; padding: .22em .35em; font-size: .95em; flex: 0 0 auto; }
.cskl__row > * { flex: 0 0 auto; }
.cskl__sel--op { width: 5.1em; flex: 0 0 auto; }
.cskl__num { padding: .22em .35em; font-size: .95em; text-align: right; }
.cskl__num--s  { width: 4.8em; }
.cskl__num--xs { width: 3.5em; }
.cskl__num--m  { width: 6.2em; }
.cskl__cmp { display: flex; align-items: center; gap: .15rem; }
.cskl__y { font-style: normal; font-size: .7rem; color: var(--text-muted); }
.cskl__who { display: flex; flex-wrap: nowrap; gap: .15rem; }
.cskl__pill { padding: .1em .3em; font-size: .85em; white-space: nowrap; }
.cskl__del { padding: .1em .35em; line-height: 1; font-size: 1.1em; }

/* El buff elegido: icono + nombre, y una × para quitarlo. */
.cskl__buff { position: relative; display: flex; min-width: 0; }
.cskl__buff-btn {
    display: flex;
    align-items: center;
    gap: .2em;
    max-width: 100%;
    padding: .12em .3em;
    font-size: .88em;
    overflow: hidden;
}
.cskl__buff-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cskl__buff-ico { width: 16px; height: 16px; flex: 0 0 auto; image-rendering: pixelated; }

/* Listas de monstruos del uso: bloques con retrato y un buscador que sale al pulsar "+". */
.cskl__mobs { display: flex; align-items: center; flex-wrap: nowrap; gap: .15rem; position: relative; min-width: 0; }
.cskl__chips { display: flex; flex-wrap: wrap; gap: .15em; }
.cskl__chip {
    display: inline-flex;
    align-items: center;
    gap: .15em;
    padding: .05em .25em;
    background: var(--bg-table-row);
    border: 1px solid var(--border-light);
    border-radius: 4px;
    font-size: .85em;
}
.cskl__chip img { width: 16px; height: 16px; object-fit: contain; }
/* Cuántos monstruos hay dentro del bloque. Un nombre son varios ids en este juego -- "Poring" son
   el normal, el de evento, el de mazmorra -- y quien escribe el nombre los quiere todos. */
.cskl__chip-n {
    font-size: .64rem;
    font-weight: 700;
    color: var(--aq-gold, var(--text-muted));
    padding: 0 .05rem;
}
.cskl__chip-x {
    background: none;
    border: 0;
    color: var(--text-muted);
    cursor: pointer;
    font-size: .85rem;
    line-height: 1;
    padding: 0 .1rem;
}
.cskl__chip-x:hover { color: var(--aq-gold); }
.cskl__add { padding: .05em .35em; font-size: .95em; }

/* Los puntos suspensivos cuando hay más de un bloque, y su aviso al pasar por encima.
   necROmantic 2026-08-07 (idea del usuario): en la línea no caben cuatro bloques de monstruos, y
   las dos malas salidas eran recortar hasta que no se lea o esconder sin decirlo. Así se ve que
   hay más y se puede mirar sin abrir nada. */
.cskl__mas-n {
    position: relative;
    cursor: default;
    padding: 0 .25em;
    font-weight: 700;
    color: var(--aq-gold, var(--text-muted));
    border-radius: 4px;
}
.cskl__mas-n:hover, .cskl__mas-n:focus-visible { background: var(--bg-table-row); outline: none; }
.cskl__hint {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 8;
    min-width: 12em;
    max-width: 22em;
    max-height: 16em;
    overflow-y: auto;
    flex-direction: column;
    gap: .15em;
    padding: .4em;
    background: var(--bg-panel, var(--bg-table-row));
    border: 1px solid var(--border-light);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0,0,0,.5);
    font-weight: 400;
    color: var(--text-primary);
}
.cskl__mas-n:hover .cskl__hint, .cskl__mas-n:focus-visible .cskl__hint { display: flex; }
.cskl__hint-f { display: flex; align-items: center; gap: .3em; font-size: .9em; white-space: nowrap; }
.cskl__hint-f img { width: 18px; height: 18px; object-fit: contain; }
/* Los IDs, que es lo que hace falta para comprobar de verdad qué monstruos son. */
.cskl__hint-ids { font-style: normal; font-size: .8em; color: var(--text-muted); margin-left: auto; padding-left: .6em; }
.cskl__find {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 5;
    width: 15rem;
    display: flex;
    flex-direction: column;
    gap: .2rem;
    padding: .35rem;
    background: var(--bg-panel, var(--bg-table-row));
    border: 1px solid var(--border-light);
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0,0,0,.45);
}
.cskl__find-res { display: flex; flex-direction: column; gap: .1rem; max-height: 13rem; overflow-y: auto; }
.cskl__hit {
    display: flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .3rem;
    background: none;
    border: 0;
    border-radius: 4px;
    color: var(--text-primary);
    cursor: pointer;
    font-size: .76rem;
    text-align: left;
}
.cskl__hit:hover { background: var(--bg-table-row); }
.cskl__hit img { width: 18px; height: 18px; object-fit: contain; }

.cskl__foot { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: .2rem; }

/* necROmantic 2026-08-01: fichar desde la web, dentro de Participación. */
.part__buy {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1rem;
    padding: .9rem 1rem;
    background: radial-gradient(circle at 8% 30%, var(--aq-gold-soft), var(--bg-table-row) 72%);
    border: 1px solid var(--aq-gold-mid);
    border-radius: 9px;
}
.part__buy-text { flex: 1 1 22rem; min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.part__buy-text > b { font-size: .95rem; color: var(--aq-gold-light); }
.part__buy-text > span { font-size: .84rem; line-height: 1.55; color: var(--text-muted); }
.part__buy-text > span b { color: var(--text-primary); }
.part__buy-note {
    font-size: .76rem !important;
    padding-top: .35rem;
    border-top: 1px dashed var(--border);
    opacity: .85;
}
.part__buy-act { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: .35rem; }
.part__buy-why { margin: 0; font-size: .76rem; color: var(--accent-red); text-align: right; max-width: 16rem; }
@media (max-width: 640px) {
    .part__buy-act { align-items: stretch; width: 100%; }
    .part__buy-why { text-align: left; max-width: none; }
}

/* necROmantic 2026-08-01: aviso dentro de la guía de invitaciones (/account/view/). */
.invite-guide__warn {
    margin-top: .5rem;
    padding: .5rem .7rem;
    background: var(--aq-gold-soft);
    border-left: 2px solid var(--aq-gold);
    border-radius: 0 5px 5px 0;
    font-size: .82rem;
    line-height: 1.55;
}
.invite-guide__warn strong { color: var(--aq-gold-light); }
.invite-guide__warn em { font-style: italic; }

/* Nota bajo las capturas de SmartScreen en la página de descargas inglesa: las imágenes
   son de un Windows en español y conviene decirlo. necROmantic 2026-08-02. */
.dl-shots__note {
    margin: 10px 0 0;
    font-size: 0.85rem;
    opacity: 0.75;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BONUS ENTRE REFERIDOR Y REFERIDO                     necROmantic 2026-08-03

   Dos columnas enfrentadas en la ficha de cuenta: a la izquierda lo que el
   jugador REGALA a sus invitados directos (editable), a la derecha lo que le
   REGALA quien le invito (solo lectura, con el interruptor de renunciar).

   Los iconos son de Font Awesome, que el tema ya carga en su header. No se
   dibuja SVG en linea en esta pagina: la salida pasa por tidy con output-xhtml,
   que baja a minusculas el atributo viewBox y deja el dibujo sin escalar (la
   misma razon por la que los .emptystate usan mascara CSS). Los dos rotulos de
   cabecera si son mascara, para que tomen el color de un token.
   ═══════════════════════════════════════════════════════════════════════════ */

.rb {
    --rb-give:      var(--lvl-accent, #a97bf0);
    --rb-give-soft: rgba(169, 123, 240, 0.14);
    --rb-get:       var(--gold);
    --rb-get-soft:  rgba(223, 160, 198, 0.12);

    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    gap: 18px;
    margin: 0 0 26px;
}

@media (max-width: 900px) {
    .rb { grid-template-columns: 1fr; }
}

.rb__col {
    position: relative;
    padding: 22px 22px 20px;
    border: 1px solid var(--border);
    border-radius: 18px;
    background: var(--surface-card);
    box-shadow: var(--shadow-content);
    overflow: hidden;
}

/* Un filo de color arriba: identifica de un vistazo cual es cual sin leer. */
.rb__col::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
}

.rb__col--give::before { background: linear-gradient(90deg, var(--rb-give), transparent); }
.rb__col--get::before  { background: linear-gradient(90deg, var(--rb-get), transparent); }

/* La columna derecha va en un tono mas apagado a proposito: se tiene que leer
   como "esto no lo decides tu, te lo regalan". */
.rb__col--get { background: var(--surface-card-strong); }

.rb__head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 16px;
}

.rb__glyph {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    margin-top: 2px;
    -webkit-mask: var(--rb-glyph) center / contain no-repeat;
            mask: var(--rb-glyph) center / contain no-repeat;
}

.rb__glyph--give {
    background-color: var(--rb-give);
    --rb-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 12v9H4v-9'/%3E%3Cpath d='M2 7h20v5H2z'/%3E%3Cpath d='M12 21V7'/%3E%3Cpath d='M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z'/%3E%3Cpath d='M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z'/%3E%3C/svg%3E");
}

.rb__glyph--get {
    background-color: var(--rb-get);
    --rb-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='m7.5 10.5 4.5 4.5 4.5-4.5'/%3E%3Cpath d='M4 17v3h16v-3'/%3E%3C/svg%3E");
}

.rb__eyebrow {
    margin: 0 0 3px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.rb__col--give .rb__eyebrow { color: var(--rb-give); }
.rb__col--get  .rb__eyebrow { color: var(--rb-get); }

.rb__title {
    margin: 0 0 6px;
    font-family: var(--font-display, inherit);
    font-size: 1.18rem;
    line-height: 1.25;
    color: var(--text-heading2);
}

.rb__lead {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.rb__lead strong { color: var(--text-primary); }

/* Aviso de que todavia no ha elegido: es la unica llamada a la accion del panel. */
.rb__callout {
    margin: 0 0 14px;
    padding: 10px 13px;
    border: 1px solid var(--border-accent);
    border-left-width: 3px;
    border-radius: 10px;
    background: var(--rb-give-soft);
    font-size: 0.83rem;
    line-height: 1.5;
    color: var(--text-primary);
}

/* ── Rejilla de las diez opciones ────────────────────────────── */

.rb__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 9px;
}

.rb-opt {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 13px 8px 11px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: var(--alpha-black-22);
    cursor: pointer;
    text-align: center;
    transition: border-color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}

.rb-opt:hover {
    border-color: var(--border-accent);
    background: var(--surface-card-soft);
    transform: translateY(-2px);
}

/* El radio de verdad se esconde sin sacarlo del arbol de accesibilidad: sigue
   siendo enfocable con el teclado y el foco se dibuja sobre la tarjeta. */
.rb-opt__input {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
}

.rb-opt__input:focus-visible { outline: none; }
.rb-opt:has(.rb-opt__input:focus-visible) {
    border-color: var(--rb-give);
    box-shadow: 0 0 0 2px var(--rb-give-soft);
}

.rb-opt__icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--alpha-black-22);
    font-size: 0.95rem;
    color: var(--text-muted);
    transition: color 0.18s ease, background 0.18s ease;
}

.rb-opt__value {
    font-size: 1.02rem;
    font-weight: 800;
    color: var(--text-heading2);
    line-height: 1.1;
}

.rb-opt__name {
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--text-muted);
}

/* Marcada. Se pinta con :has() y ademas con la clase is-active que trae el
   servidor, para que el estado guardado se vea aunque :has() no exista. */
.rb-opt.is-active,
.rb-opt:has(.rb-opt__input:checked) {
    border-color: var(--rb-give);
    background: linear-gradient(180deg, var(--rb-give-soft), transparent);
    box-shadow: 0 0 22px var(--rb-give-soft);
}

.rb-opt.is-active .rb-opt__icon,
.rb-opt:has(.rb-opt__input:checked) .rb-opt__icon {
    background: var(--rb-give);
    color: var(--bg-content);
}

.rb-opt.is-active .rb-opt__name,
.rb-opt:has(.rb-opt__input:checked) .rb-opt__name { color: var(--text-primary); }

/* ── Que hace el bonus que se esta eligiendo ─────────────────── */

/* Vive DENTRO de la rejilla, justo detras de su opcion, y ocupa la fila entera:
   asi se abre donde esta la eleccion en vez de en un panel aparte al que hay que
   ir a mirar. */
.rb-what {
    display: none;
    grid-column: 1 / -1;
    margin: 0;
    padding: 11px 14px;
    border-radius: 12px;
    background: var(--rb-give-soft);
    font-size: 0.83rem;
    line-height: 1.55;
    color: var(--text-primary);
}

.rb-what strong { color: var(--text-heading2); }

/* Mientras no hay ninguno elegido no se pintan las dieciseis descripciones -serian
   dos pantallas de texto y ademas romperian la rejilla en una sola columna-: se
   dice donde mirar. Va la ultima de la rejilla y se apaga en cuanto hay eleccion. */
.rb-what--hint {
    display: block;
    border: 1px dashed var(--border-light);
    background: none;
    font-size: 0.78rem;
    color: var(--text-muted);
    text-align: center;
}

/* Lo que vale para las dieciseis, una sola vez y debajo de la rejilla. */
.rb__what-note {
    margin: 9px 0 0;
    font-size: 0.74rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* La regla del regalo unico va ENCIMA de la rejilla, asi que el margen se le da
   por abajo y no por arriba. No es una nota al pie: es la condicion de lo que se
   esta a punto de elegir, y por eso se pinta un punto mas viva que el resto de
   .rb__what-note. */
.rb__what-note--rule {
    margin: 0 0 11px;
    color: var(--text-footer);
}

/* Solo se ve la de la opcion marcada.
   Aqui la base va OCULTA, al reves que el sub-selector de hechizo, y a proposito:
   alli el exceso solo se ve en un navegador sin :has(), pero aqui "no hay ninguna
   marcada" es tambien el primer estado de todo el mundo, y ensenar las dieciseis
   descripciones de golpe es justo lo que no se quiere. La eleccion GUARDADA se
   pinta ademas con la clase is-active que trae el servidor, asi que sin :has()
   sigue viendose la que toca; lo unico que se pierde es el cambio en vivo.
   Las dos ultimas llevan delante el :has() del formulario para ganar en
   especificidad a la de encima; sin ese prefijo pesarian menos y no se veria
   ninguna. */
.rb-opt.is-active + .rb-what { display: block; }
.rb__form:has(input[name="rb_bonus"]:checked) .rb-what { display: none; }
.rb__form:has(input[name="rb_bonus"]:checked) .rb-opt:has(.rb-opt__input:checked) + .rb-what { display: block; }

/* ── Sub-selector de hechizo ─────────────────────────────────── */

.rb__spells {
    margin-top: 14px;
    padding: 13px 14px 12px;
    border: 1px dashed var(--border-light);
    border-radius: 13px;
    background: var(--alpha-black-22);
}

/* Solo tiene sentido cuando el bonus elegido es su autocast. Se colapsa con
   :has(); la regla base es VISIBLE a proposito, para que un navegador sin
   :has() falle por exceso (se ven los dos) y no por defecto (no se ve ninguno
   y no se puede elegir hechizo). */
.rb__form:has(input[name="rb_bonus"]:checked):not(:has(input[value="autocast"]:checked)) .rb__spells--attack,
.rb__form:has(input[name="rb_bonus"]:checked):not(:has(input[value="autocast_hit"]:checked)) .rb__spells--hit {
    display: none;
}

.rb__spells-title {
    margin: 0 0 9px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.rb__spells-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
}

.rb-spell {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px 7px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-input);
    font-size: 0.78rem;
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease, background 0.18s ease;
}

.rb-spell:hover { border-color: var(--border-accent); color: var(--text-primary); }

.rb-spell__input {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
}

.rb-spell i { font-size: 0.8rem; }

.rb-spell.is-active,
.rb-spell:has(.rb-spell__input:checked) {
    border-color: var(--rb-give);
    background: var(--rb-give-soft);
    color: var(--text-heading2);
}

/* ── Boton y letra pequeña ───────────────────────────────────── */

.rb__actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 16px;
    padding-top: 15px;
    border-top: 1px solid var(--border);
}

.rb__save {
    padding: 10px 22px;
    border: 0;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--rb-give), var(--accent-purple));
    color: var(--bg-content);
    font-size: 0.85rem;
    font-weight: 800;
    letter-spacing: 0.03em;
    cursor: pointer;
    transition: filter 0.18s ease, transform 0.18s ease;
}

.rb__save:hover { filter: brightness(1.12); transform: translateY(-1px); }

.rb__note {
    flex: 1 1 200px;
    margin: 0;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.rb__note strong { color: var(--text-primary); }

/* ── Tarjeta del regalo recibido ─────────────────────────────── */

.rb-gift {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas:
        "icon value"
        "icon name"
        "spell spell"
        "state state";
    align-items: center;
    gap: 2px 15px;
    padding: 20px 20px 17px;
    border: 1px solid var(--rb-get);
    border-radius: 15px;
    background: linear-gradient(150deg, var(--rb-get-soft), transparent 70%);
    box-shadow: 0 0 30px var(--rb-get-soft);
}

.rb-gift.is-off {
    border-color: var(--border);
    background: var(--alpha-black-22);
    box-shadow: none;
    opacity: 0.62;
}

.rb-gift__icon {
    grid-area: icon;
    display: grid;
    place-items: center;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    background: var(--rb-get);
    color: var(--bg-content);
    font-size: 1.35rem;
}

.rb-gift.is-off .rb-gift__icon { background: var(--bg-input); color: var(--text-muted); }

.rb-gift__value {
    grid-area: value;
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--text-heading2);
}

.rb-gift__name {
    grid-area: name;
    font-size: 0.85rem;
    color: var(--text-primary);
}

.rb-gift__spell {
    grid-area: spell;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    justify-self: start;
    margin-top: 12px;
    padding: 5px 12px 5px 10px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-input);
    font-size: 0.78rem;
    color: var(--text-primary);
}

.rb-gift__state {
    grid-area: state;
    margin-top: 12px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--rb-get);
}

.rb-gift.is-off .rb-gift__state { color: var(--text-muted); }

.rb-gift--empty {
    grid-template-columns: auto 1fr;
    grid-template-areas: "icon name";
    border-style: dashed;
    border-color: var(--border-light);
    background: var(--alpha-black-22);
    box-shadow: none;
}

.rb-gift--empty .rb-gift__icon {
    background: var(--bg-input);
    color: var(--text-muted);
}

.rb-gift--empty .rb-gift__name {
    align-self: center;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* ── Interruptor de aceptar o renunciar ──────────────────────── */

.rb__toggle { margin-top: 15px; }

.rb__toggle-btn {
    padding: 9px 20px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-size: 0.8rem;
    font-weight: 700;
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease;
}

.rb__toggle-btn:hover { border-color: var(--rb-get); color: var(--text-heading2); }

.rb__toggle-btn.is-on:hover { border-color: var(--text-status-error); color: var(--text-error); }

.rb__toggle .rb__note { margin-top: 9px; }

/* El nivel del hechizo, siempre "Lvl 1" y siempre en ingles: es el nombre tecnico de
   la habilidad del juego y no se traduce. necROmantic 2026-08-03. */
.rb-lvl {
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--alpha-black-22);
    font-style: normal;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.rb-spell.is-active .rb-lvl,
.rb-spell:has(.rb-spell__input:checked) .rb-lvl {
    background: var(--rb-give);
    color: var(--bg-content);
}

.rb-lvl--strong {
    background: var(--rb-get);
    color: var(--bg-content);
}

.rb-gift.is-off .rb-lvl--strong {
    background: var(--bg-input);
    color: var(--text-muted);
}

/* ── Segunda tanda de poderes: nivel del autocast y mejora por racha ──
   necROmantic 2026-08-03. */

.rb__spells-title--sub { margin-top: 14px; }

/* Los diez niveles con su probabilidad al lado. El intercambio -mas nivel, mucha
   menos probabilidad- tiene que verse sin tener que calcular nada. */
.rb__levels {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
    gap: 6px;
}

.rb-level {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    padding: 7px 4px 6px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-input);
    cursor: pointer;
    transition: border-color 0.18s ease, background 0.18s ease;
}

.rb-level:hover { border-color: var(--border-accent); }

.rb-level__input {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
}

.rb-level b {
    font-size: 0.74rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--text-primary);
}

.rb-level i {
    font-style: normal;
    font-size: 0.68rem;
    color: var(--text-muted);
}

.rb-level.is-active,
.rb-level:has(.rb-level__input:checked) {
    border-color: var(--rb-give);
    background: var(--rb-give-soft);
}

.rb-level.is-active b,
.rb-level:has(.rb-level__input:checked) b { color: var(--text-heading2); }

.rb-level.is-active i,
.rb-level:has(.rb-level__input:checked) i { color: var(--rb-give); }

/* La tarjeta del regalo gana dos lineas: que hace el bonus, con palabras, y si la
   racha de quien lo recibe lo mejora. necROmantic 2026-08-04 para la primera. */
.rb-gift {
    grid-template-areas:
        "icon value"
        "icon name"
        "tag tag"
        "spell spell"
        "detail detail"
        "streak streak"
        "state state";
}

/* La tarjeta vacia -sin referidor, o con uno que aun no ha elegido- solo tiene icono
   y frase, asi que se le repite aqui su plantilla: si no, hereda la de arriba (misma
   especificidad, y esta regla va despues) y se come las filas de sobra. */
.rb-gift--empty { grid-template-areas: "icon name"; }

/* La explicacion larga. La pastilla de arriba da la cifra y el nombre tecnico
   ("Skill Lvl1 on Attack"); esta linea dice cuando se dispara y sobre que, con los
   numeros que de verdad le tocan a quien la lee. necROmantic 2026-08-04. */
.rb-gift__detail {
    grid-area: detail;
    margin: 12px 0 0;
    max-width: 62ch;
    font-size: 0.8rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.rb-gift__detail strong { color: var(--text-primary); }

.rb-gift.is-gold .rb-gift__detail strong { color: var(--rb-gold); }

.rb-gift.is-off .rb-gift__detail strong { color: var(--text-muted); }

/* necROmantic 2026-08-04: display:block, NO flex, y va en serio.
   Dentro va una frase entera con <strong> y <b> incrustados (RbStreakBoostHtml). En un
   contenedor flex cada trozo de texto suelto se convierte en un item anonimo y cada
   etiqueta en otro, asi que la frase se partia en ocho cajas separadas por el gap de 7px
   y cada una rompia linea por su cuenta: "Tu racha de | 7 dias | mejora este regalo un |
   50% | : en vez de | ...". Como bloque vuelve a ser texto corrido y las negritas son lo
   que siempre fueron, palabras dentro de una frase.
   El mismo cuidado hace falta en cualquier otro hueco que reciba HTML traducido. */
.rb-gift__streak {
    grid-area: streak;
    display: block;
    margin-top: 12px;
    padding: 7px 12px;
    border: 1px solid var(--rb-gold-glow);
    border-radius: 10px;
    background: linear-gradient(135deg, var(--rb-gold-soft), transparent);
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-primary);
}

/* El icono ya no es un item flex: se separa el con su propio margen. */
.rb-gift__streak i { color: var(--rb-gold); margin-right: 7px; }
.rb-gift__streak strong { color: var(--rb-gold); }

/* La cifra de antes de la mejora, tachada al lado de la nueva: se ve de un vistazo
   en que consiste el 50%. Va en <b> y no en <strong> justamente para NO heredar el
   dorado de la regla de arriba. necROmantic 2026-08-04. */
.rb-was {
    font-weight: 700;
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    color: var(--text-muted);
}

/* Cuando todavia no hay racha, el mismo hueco explica como se consigue, en apagado:
   es un incentivo, no un premio. */
.rb-gift__streak--off {
    border-color: var(--border);
    border-style: dashed;
    background: none;
    color: var(--text-muted);
}

.rb-gift__streak--off i,
.rb-gift__streak--off strong { color: var(--text-muted); }

.rb-gift.is-gold { border-color: var(--rb-gold); box-shadow: 0 0 30px var(--rb-gold-soft); }
.rb-gift.is-gold .rb-gift__icon { background: var(--rb-gold); }
.rb-gift.is-off .rb-gift__streak { opacity: 0.7; }

/* ── Las DOS rachas que mejoran el regalo ────────────────────────
   necROmantic 2026-08-04. La de quien lo recibe y la de quien lo regala suman media
   mas cada una. Van en lineas separadas porque no dependen de la misma persona: una
   la controla quien lee, la otra no. Debajo, la suma en cifras.

   OJO: el contenedor si es flex, pero sus hijos son pastillas enteras, no texto
   suelto. Cada pastilla por dentro sigue siendo un bloque, por lo de arriba. */
.rb-gift__boosts {
    grid-area: streak;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 7px;
    margin-top: 12px;
}

.rb-gift__boosts .rb-gift__streak { margin-top: 0; }

/* El resumen: de cuanto a cuanto. Sin caja, que ya hay dos encima. */
.rb-gift__total {
    display: block;
    padding: 0 2px;
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.rb-gift__total strong { color: var(--text-heading2); }

/* El regalo fantastico: la racha la pone QUIEN INVITA, asi que se distingue del
   dorado de la racha propia. Violeta del tema, que ya es el acento de "esto no lo
   has hecho tu". */
.rb {
    --rb-fab:      var(--accent-purple);
    --rb-fab-soft: rgba(180, 140, 240, 0.16);
    --rb-fab-glow: rgba(180, 140, 240, 0.34);
}

.rb-gift__tag {
    grid-area: tag;
    justify-self: start;
    display: inline-block;
    margin-top: 10px;
    padding: 4px 12px;
    border: 1px solid var(--rb-fab-glow);
    border-radius: 999px;
    background: linear-gradient(135deg, var(--rb-fab-soft), transparent);
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--rb-fab);
}

.rb-gift__tag i { margin-right: 6px; }

.rb-gift__streak--fab {
    border-color: var(--rb-fab-glow);
    background: linear-gradient(135deg, var(--rb-fab-soft), transparent);
}

.rb-gift__streak--fab i,
.rb-gift__streak--fab strong { color: var(--rb-fab); }

/* Con la racha del referidor la tarjeta entera cambia de acento: es el estado bueno
   de verdad, y tiene que verse antes de leer nada. */
.rb-gift.is-fab {
    border-color: var(--rb-fab);
    box-shadow: 0 0 30px var(--rb-fab-glow);
}

.rb-gift.is-fab .rb-gift__icon { background: var(--rb-fab); }

.rb-gift.is-off .rb-gift__tag { opacity: 0.7; }

/* La misma idea en la columna de la izquierda: lo que TU racha le hace al regalo de
   tus invitados. Bloque, no flex: lleva una frase traducida con negritas dentro. */
.rb__streak {
    display: block;
    margin: 0 0 14px;
    padding: 8px 12px;
    border: 1px dashed var(--border);
    border-radius: 10px;
    font-size: 0.76rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.rb__streak i { margin-right: 7px; }

.rb__streak strong { color: var(--text-primary); }

.rb__streak--on {
    border-style: solid;
    border-color: var(--rb-fab-glow);
    background: linear-gradient(135deg, var(--rb-fab-soft), transparent);
    color: var(--text-primary);
}

.rb__streak--on i,
.rb__streak--on strong { color: var(--rb-fab); }

/* Tope real de la habilidad: Earth Spike llega a 5 y Holy Light solo a 1. Se avisa
   en la propia pastilla del hechizo. necROmantic 2026-08-03. */
.rb-lvl--cap {
    background: var(--bg-input);
    border: 1px solid var(--text-status-warning);
    color: var(--text-status-warning);
}

.rb__levels-note {
    margin: 9px 0 0;
    font-size: 0.72rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* ═══════════════════════════════════════════════════════════════════════════
   necROmantic 2026-08-03 · Tácticas avanzadas (/tactics/)
   Todo con los tokens de arriba y sin bordes duros, como el resto del sitio.
   ═══════════════════════════════════════════════════════════════════════════ */

.tac-hero { margin: 0 0 1.6rem; }
.tac-hero__kicker {
    display: inline-block; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
    color: var(--accent-purple); margin-bottom: .35rem;
}
.tac-hero__title { color: var(--text-heading2); margin: 0 0 .5rem; }
.tac-hero__intro { color: var(--text-muted); max-width: 62ch; line-height: 1.6; margin: 0; }

.tac-locked, .tac-guide, .tac-errors {
    background: var(--bg-surface-alt); border-radius: 14px; padding: 1.1rem 1.3rem;
    margin: 0 0 1.5rem;
}
.tac-locked__title, .tac-guide__title, .tac-errors__title {
    color: var(--text-heading); margin: 0 0 .45rem; font-size: 1.05rem;
}
.tac-locked__text, .tac-guide__text, .tac-errors__intro {
    color: var(--text-muted); margin: 0 0 .7rem; line-height: 1.6; max-width: 62ch;
}

.tac-guide__links { margin: 0; display: flex; gap: .6rem; flex-wrap: wrap; }
.tac-guide__link {
    display: inline-block; padding: .45rem .9rem; border-radius: 9px;
    background: var(--bg-surface); color: var(--text-link); text-decoration: none;
}
.tac-guide__link:hover { color: var(--text-link-hover); background: var(--bg-table-head); }

/* Los errores del validador: lo importante es la línea, que es donde el jugador tiene que ir. */
.tac-errors { background: #2a1526; }
.tac-errors__list { list-style: none; margin: 0; padding: 0; }
.tac-errors__item {
    display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline;
    padding: .4rem 0; color: var(--text-primary);
}
.tac-errors__where { color: var(--accent-red-h); font-weight: 600; min-width: 12rem; }
.tac-errors__what { flex: 1 1 18rem; }
.tac-errors__code { color: var(--text-muted); font-size: .8rem; opacity: .8; }

.tac-section { color: var(--text-heading); margin: 1.8rem 0 .7rem; }
.tac-empty { color: var(--text-muted); }
.tac-note { color: var(--text-muted); font-size: .9rem; margin: .6rem 0 0; max-width: 62ch; }

.tac-table { width: 100%; border-collapse: collapse; }
.tac-table th {
    text-align: left; background: var(--bg-table-head); color: var(--text-heading);
    padding: .55rem .8rem; font-weight: 600;
}
.tac-table td { padding: .55rem .8rem; background: var(--bg-table-row); color: var(--text-primary); }
.tac-row--active td { background: var(--bg-table-alt); }

.tac-badge {
    display: inline-block; padding: .15rem .55rem; border-radius: 999px;
    background: var(--bg-surface); color: var(--text-muted); font-size: .8rem;
}
.tac-badge--on { background: var(--accent-purple); color: var(--bg-body); font-weight: 600; }

.tac-actions { white-space: nowrap; }
.tac-inline-form { display: inline-flex; gap: .4rem; margin: 0; }

.tac-btn {
    padding: .4rem .85rem; border: 0; border-radius: 9px; cursor: pointer;
    background: var(--bg-surface); color: var(--text-link); font: inherit;
}
.tac-btn:hover { background: var(--bg-table-head); color: var(--text-link-hover); }
.tac-btn--primary { background: var(--accent-purple); color: var(--bg-body); font-weight: 600; }
.tac-btn--primary:hover { background: var(--accent-purple-h); color: var(--bg-body); }
.tac-btn--danger { color: var(--accent-red); }
.tac-btn--danger:hover { background: #3a1a2c; color: var(--accent-red-h); }

.tac-form { margin: 0 0 2rem; }
.tac-form__row { margin: 0 0 .9rem; }
.tac-form__label { display: block; color: var(--text-heading); margin-bottom: .3rem; }
.tac-form__input, .tac-form__select, .tac-form__area {
    background: var(--bg-input); color: var(--text-primary); border: 0; border-radius: 9px;
    padding: .55rem .75rem; font: inherit; width: 100%; max-width: 26rem;
}
.tac-form__area {
    max-width: none; width: 100%;
    /* Monoespaciada de verdad: en un script, que las columnas cuadren no es estético, es que
       el número de columna del error señale al sitio correcto. */
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: .9rem; line-height: 1.5; white-space: pre; overflow-wrap: normal; overflow-x: auto;
}
.tac-form__hint { color: var(--text-muted); font-size: .9rem; margin: .3rem 0 .9rem; max-width: 62ch; }

@media (max-width: 640px) {
    .tac-errors__where { min-width: 0; }
    .tac-table thead { display: none; }
    .tac-table td { display: block; }
}

/* necROmantic 2026-08-03: la llamada al editor visual desde la lista de tácticas.
   Tokens, nunca literales: si cambia el tema, esto cambia con él. */
.tac-cta {
    margin: 0 0 1.6rem; padding: 1rem 1.2rem; border-radius: 12px;
    background: var(--bg-surface); border-left: 3px solid var(--text-link);
}
.tac-cta__title { margin: 0 0 .4rem; font-size: 1.05rem; }
.tac-cta__text { margin: 0 0 .8rem; }
.tac-cta__link {
    display: inline-block; padding: .5rem 1rem; border-radius: 9px;
    background: var(--text-link); color: var(--bg-surface);
    text-decoration: none; font-weight: 600;
}
.tac-cta__link:hover { background: var(--text-link-hover); color: var(--bg-surface); }

/* ============================================================================
   .spx — Pagina de especificaciones (/especificaciones/)
   necROmantic 2026-08-04.

   Cada enunciado es un <details> nativo: se despliega sin JavaScript, se abre con
   teclado y /especificaciones/<id>/ llega con el suyo ya abierto desde el servidor.
   Lo que aporta el JavaScript (themes/necromantic-modern/js/modern.js, initSpecs) es
   el filtro en vivo, el desplazamiento y el destello; por eso el buscador y los dos
   botones de desplegar/plegar solo se pintan cuando la raiz lleva .spx--js.

   Nada de <dl> aqui: Tidy reescribe un <div> dentro de un <dl> y rompe la rejilla.
   ========================================================================== */

/* necROmantic 2026-08-30 (peticion del usuario): la barra de filtro YA NO SE PEGA arriba.
   Era `position: sticky` y, aun encogiendose al pegarse, seguia siendo demasiado alta: en
   una pagina de setenta enunciados se comia una franja de pantalla en todo el recorrido.
   Con esto se fueron tambien la variable --spx-stick, las cinco reglas .spx--stuck, el
   centinela .spx__sentinel y el IntersectionObserver que le ponia la clase (modern.js).
   El desplazamiento a un enunciado NO hubo que tocarlo: stickyOffset() lee la `position`
   calculada de cada barra, asi que al dejar de ser pegajosa deja sola de contar. */

/* --- Cabecera --- */

.spx__head {
    margin: 0 0 26px;
    padding: 26px 26px 24px;
    border: 1px solid var(--border);
    border-radius: 18px;
    background:
        radial-gradient(120% 180% at 0% 0%, var(--alpha-gold-08), transparent 62%),
        linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 28px var(--alpha-black-24);
}

.spx__eyebrow {
    margin: 0 0 10px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
}

.spx__title {
    margin: 0 0 12px;
    padding: 0;
    border: 0;
    font-size: 2rem;
    line-height: 1.15;
    color: var(--text-heading2);
}

.spx__lead {
    margin: 0 0 16px;
    max-width: 80ch;
    color: var(--text-panel-soft);
    line-height: 1.6;
}

.spx__meta {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.spx__meta-n {
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--alpha-silver-08);
    color: var(--text-primary);
    font-weight: 600;
}

.spx__meta-sep { color: var(--alpha-silver-42); }

/* Aviso de llegada desde una noticia */
.spx__fromnews {
    margin: 18px 0 0;
    padding: 12px 16px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    border-radius: 12px;
    background: var(--alpha-gold-12);
    color: var(--text-primary);
    font-size: 0.9rem;
}

.spx__fromnews i { color: var(--gold); }
.spx__fromnews-link { margin-left: auto; color: var(--gold); font-weight: 600; }
.spx__fromnews-link:hover { color: var(--text-link-hover); }

/* --- Barra de filtro --- */

.spx__filter {
    position: static;
    margin: 0 0 26px;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28);
}

/* El buscador y los dos botones no hacen nada sin JavaScript: no se pintan hasta que
   el script marca la raiz. Los apartados, en cambio, son anclas y funcionan siempre. */
.spx__search,
.spx__tools-btns { display: none; }
.spx--js .spx__search { display: block; }
.spx--js .spx__tools-btns { display: flex; gap: 8px; }

.spx__search { margin: 0 0 14px; }

.spx__search-label {
    display: block;
    margin: 0 0 6px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.spx__search-field { position: relative; display: block; }

.spx__search-icon {
    position: absolute;
    top: 50%;
    left: 14px;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}

.spx__search-input {
    width: 100%;
    padding: 12px 44px 12px 40px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.95rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.spx__search-input::placeholder { color: var(--text-muted); }
.spx__search-input::-webkit-search-cancel-button { display: none; }

.spx__search-input:focus {
    outline: none;
    border-color: var(--border-accent);
    box-shadow: 0 0 0 3px var(--alpha-bronze-20);
}

.spx__search-clear {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--alpha-silver-12);
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}

.spx__search-clear:hover { background: var(--alpha-gold-24); color: var(--text-label-hover); }

.spx__sr {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* Fichas de apartado */
.spx__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.spx__chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-silver-08);
    color: var(--text-panel-soft);
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.spx__chip i { font-size: 0.85em; color: var(--text-muted); transition: color 0.2s ease; }
.spx__chip:hover { background: var(--alpha-gold-16); color: var(--text-label-hover); border-color: var(--border-accent); }
.spx__chip:hover i { color: var(--gold); }

.spx__chip.is-on {
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    border-color: var(--border-accent);
    color: var(--bg-content);
}

.spx__chip.is-on i,
.spx__chip.is-on .spx__chip-n { color: var(--bg-content); }
.spx__chip.is-on .spx__chip-n { background: var(--alpha-black-22); }

.spx__chip-n {
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--alpha-black-18);
    color: var(--text-muted);
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
}

/* Ficha de apartado vacia tras filtrar por texto */
.spx__chip.is-empty { opacity: 0.38; }

.spx__tools {
    margin: 14px 0 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.spx__showing {
    margin: 0;
    font-size: 0.8rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.spx__tool {
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: transparent;
    color: var(--text-panel-soft);
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.spx__tool:hover { border-color: var(--border-accent); color: var(--text-label-hover); }
.spx__tool i { margin-right: 5px; color: var(--text-muted); }
.spx__tool:hover i { color: var(--gold); }

/* --- Nada coincide --- */

.spx__none {
    margin: 0 0 26px;
    padding: 42px 26px;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--alpha-silver-08);
    text-align: center;
}

.spx__none-glyph { font-size: 1.8rem; color: var(--alpha-silver-42); }
.spx__none-title { margin: 14px 0 6px; font-size: 1.15rem; font-weight: 700; color: var(--text-heading2); }
.spx__none-lead  { margin: 0 0 16px; color: var(--text-muted); }

.spx__none-act {
    padding: 9px 20px;
    border: 1px solid var(--border-accent);
    border-radius: 10px;
    background: transparent;
    color: var(--gold);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 700;
    cursor: pointer;
}

.spx__none-act:hover { background: var(--alpha-gold-16); color: var(--text-label-hover); }

/* --- Apartados --- */

.spx__group { margin: 0 0 34px; }
.spx__group.is-hidden { display: none; }

.spx__group-head {
    margin: 0 0 14px;
    padding: 0 0 12px 52px;
    position: relative;
    border-bottom: 1px solid var(--alpha-silver-12);
}

.spx__group-icon {
    position: absolute;
    top: 0;
    left: 0;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: 11px;
    background: var(--alpha-gold-16);
    color: var(--gold);
}

.spx__group-title {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 1.3rem;
    line-height: 1.25;
    color: var(--text-heading2);
}

.spx__group-lead {
    margin: 6px 0 0;
    max-width: 92ch;
    font-size: 0.9rem;
    color: var(--text-muted);
}

.spx__list { display: flex; flex-direction: column; gap: 10px; }

/* --- Enunciado desplegable --- */

.spx__item {
    position: relative;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    overflow: hidden;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    scroll-margin-top: calc(var(--nav-height, 84px) + 130px);
}

.spx__item.is-hidden { display: none; }
.spx__item:hover { border-color: var(--border-light); }

.spx__item[open] {
    border-color: var(--border-accent);
    box-shadow: 0 10px 26px var(--alpha-black-28);
}

/* Filo de color a la izquierda: apagado cerrado, encendido abierto. */
.spx__item::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 3px;
    background: var(--alpha-silver-16);
    transition: background 0.2s ease;
}

.spx__item:hover::before { background: var(--alpha-gold-42); }
.spx__item[open]::before { background: linear-gradient(180deg, var(--accent-purple), var(--gold)); }

.spx__sum {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 18px 16px 22px;
    cursor: pointer;
    list-style: none;
    transition: background 0.2s ease;
}

.spx__sum::-webkit-details-marker { display: none; }
.spx__sum:hover { background: var(--alpha-white-05); }
.spx__sum:focus-visible { outline: 2px solid var(--border-accent); outline-offset: -2px; }

.spx__sum-body { flex: 1 1 auto; min-width: 0; }

.spx__stmt {
    display: block;
    font-size: 1.02rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--text-heading2);
}

.spx__sub {
    display: block;
    margin-top: 4px;
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.spx__mark {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--alpha-silver-10);
    color: var(--text-muted);
    font-size: 0.75rem;
    transition: transform 0.25s ease, background 0.2s ease, color 0.2s ease;
}

.spx__sum:hover .spx__mark { background: var(--alpha-gold-24); color: var(--gold); }
.spx__item[open] .spx__mark { transform: rotate(180deg); background: var(--alpha-gold-28); color: var(--gold); }

/* --- Cuerpo desplegado --- */

.spx__panel {
    padding: 4px 22px 20px;
    border-top: 1px solid var(--alpha-silver-10);
    margin-top: -1px;
}

.spx__item[open] .spx__panel { animation: spxPanelIn 0.26s ease both; }

@keyframes spxPanelIn {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
}

.spx__body { padding-top: 16px; }

/* El cuerpo usa el componente .na de las noticias. Aqui dentro se acotan solo los
   margenes de los bloques anidados, para que una especificacion corta no ocupe lo
   mismo que una noticia entera. */
.spx__body .na-grid { gap: 12px; }
.spx__body .na-box,
.spx__body .na-col,
.spx__body .na-callout { padding: 14px 16px; }
/* necro (2026-08-09): el destacado en dorado estaba definido como `.na .na-accent`, o sea solo
   dentro del componente de las noticias. En las especificaciones el HTML vive en `.spx__body`, sin
   `.na` por encima, asi que los 29 enunciados que ya lo usaban lo tenian muerto: la marca estaba
   en el HTML y no pintaba nada. Misma regla y mismo token que en las noticias. */
.spx__body .na-accent { color: var(--gold); }

.spx__foot {
    margin: 16px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--alpha-silver-08);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.spx__tags { display: flex; flex-wrap: wrap; gap: 6px; }

.spx__tag {
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--alpha-bronze-16);
    color: var(--text-panel-soft);
    font-size: 0.72rem;
    letter-spacing: 0.02em;
}

.spx__perma {
    margin-left: auto;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    text-decoration: none;
    transition: color 0.2s ease;
}

.spx__perma:hover { color: var(--gold); }
.spx__perma i { margin-right: 4px; }
.spx__perma.is-copied { color: var(--text-status-success); }

.spx__rel {
    margin: 12px 0 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    font-size: 0.82rem;
}

.spx__rel-label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.spx__rel-link {
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--alpha-silver-08);
    color: var(--text-panel-soft);
    text-decoration: none;
    transition: background 0.2s ease, color 0.2s ease;
}

.spx__rel-link:hover { background: var(--alpha-gold-16); color: var(--text-label-hover); }

/* --- Destello al llegar desde una noticia --- */

.spx__item.is-target { animation: spxFlash 1.6s ease both; }

@keyframes spxFlash {
    0%   { box-shadow: 0 0 0 0 var(--alpha-gold-52); }
    25%  { box-shadow: 0 0 0 6px var(--alpha-gold-32); }
    100% { box-shadow: 0 10px 26px var(--alpha-black-28); }
}

@media (prefers-reduced-motion: reduce) {
    .spx__item[open] .spx__panel { animation: none; }
    .spx__item.is-target { animation: none; }
    .spx__mark { transition: none; }
}

/* --- Estrecho --- */

@media (max-width: 720px) {
    .spx__head { padding: 20px 18px; }
    .spx__title { font-size: 1.55rem; }

    .spx__filter { padding: 14px; }

    .spx__chips {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 6px;
        scrollbar-width: thin;
    }

    .spx__chip { flex: 0 0 auto; }

    .spx__group-head { padding-left: 46px; }
    .spx__group-icon { width: 34px; height: 34px; }
    .spx__group-title { font-size: 1.15rem; }

    .spx__sum { padding: 14px 14px 14px 18px; gap: 10px; }
    .spx__stmt { font-size: 0.96rem; }
    .spx__panel { padding: 4px 14px 16px; }
    .spx__perma { margin-left: 0; }
    .spx__item { scroll-margin-top: 90px; }
}

/* --- .na-specs: los enlaces de una noticia a sus especificaciones ---------------
   necROmantic 2026-08-04. Vive con el componente .na porque el HTML que lo usa esta
   en la base de datos (cp_cmsnews) y ahi no se pueden meter estilos en linea.

   La noticia cuenta que algo ha cambiado; el detalle esta en /especificaciones/<id>/,
   que llega con ese enunciado ya desplegado. */

.na-specs {
    margin: 20px 0 0;
    padding: 16px 18px;
    border-radius: 14px;
    background: var(--alpha-gold-08);
}

.na .na-specs__label {
    margin: 0 0 12px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--gold);
}

.na-specs__list { display: flex; flex-wrap: wrap; gap: 8px; }

.na .na-spec {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-radius: 999px;
    background: var(--alpha-silver-10);
    color: var(--text-panel-soft);
    font-size: 0.84rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.2s ease, color 0.2s ease;
}

.na .na-spec::after {
    content: "\2192";
    color: var(--gold);
    font-weight: 400;
}

.na .na-spec:hover { background: var(--alpha-gold-24); color: var(--text-label-hover); }
.na .na-spec:hover::after { color: var(--text-label-hover); }

/* ============================================================
   Acceso al panel (.lgn) — necROmantic 2026-08-05
   ------------------------------------------------------------
   La pagina de acceso era la tabla `generic-form-table` de serie:
   etiqueta en una caja oscura a la izquierda, campo a la derecha y
   el boton solo en una fila con una celda vacia. Ahora usa el mismo
   lenguaje que el alta (.register-*): franja de encabezado con
   sprite, tarjeta de formulario y columna de ayuda.
   Sin bordes, como el resto del sitio: la separacion la dan fondo,
   sombra y espaciado.
   ============================================================ */

/* Encabezado. El resto (fondo, radio, kicker, titulo, intro) lo
   comparte con .register-hero unas 11.000 lineas mas arriba. */
.lgn-hero {
    display: flex;
    align-items: center;
    gap: 24px;
}

.lgn-hero__text { min-width: 0; flex: 1 1 auto; }

.lgn-hero__sprite {
    display: block;
    flex: 0 0 auto;
    width: 166px;
    height: 208px;
}

/* Dos columnas: formulario y ayuda. Mas estrecha que la del alta
   porque aqui solo hay dos campos y una linea de medida comoda
   pesa mas que aprovechar el ancho. */
.lgn-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(260px, 0.85fr);
    gap: 18px;
    align-items: start;
}

.lgn-card,
.lgn-aside {
    padding: 22px 24px;
    border-radius: 22px;
    box-shadow: var(--shadow-pop);
}

/* Las dos columnas pesan lo mismo, como la pareja del alta: el fondo del panel y
   el de la tarjeta se distinguen poco, y dejar el formulario "al aire" al lado de
   una ayuda con fondo desequilibraba el conjunto. */
.lgn-card {
    background: var(--surface-silver-panel-soft);
}

.lgn-card__title,
.lgn-aside__title {
    margin: 0 0 16px;
    border: 0;
    padding: 0;
    font-size: 15px;
    letter-spacing: 0.4px;
    text-transform: none;
    color: var(--text-heading2);
}

/* ---- Aviso de error ---------------------------------------- */
.lgn-alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0 0 18px;
    padding: 12px 14px;
    border-radius: 16px;
    background: var(--alpha-gold-12);
    color: var(--text-error);
    box-shadow: inset 3px 0 0 var(--accent-red);
}

.lgn-alert__ico {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    background-color: var(--accent-red);
    -webkit-mask: var(--lgn-ico-alert) center / contain no-repeat;
            mask: var(--lgn-ico-alert) center / contain no-repeat;
    --lgn-ico-alert: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5.5'/%3E%3Cpath d='M12 16.4h.01'/%3E%3C/svg%3E");
}

.lgn-alert__text { min-width: 0; }

/* ---- Campos ------------------------------------------------ */
.lgn-field { margin-bottom: 16px; }

.lgn-label {
    display: block;
    margin-bottom: 7px;
    color: var(--text-label-strong);
    font-weight: bold;
}

/* La caja que lleva el icono; el input va dentro y transparente,
   para que el foco ilumine la caja entera y no solo el campo. */
.lgn-input {
    position: relative;
    display: flex;
    align-items: center;
    border-radius: 14px;
    background: var(--bg-input);
    box-shadow: inset 0 1px 0 var(--alpha-white-04);
    transition: background 0.2s ease, box-shadow 0.24s ease;
}

.lgn-input::before {
    content: "";
    position: absolute;
    left: 14px;
    width: 18px;
    height: 18px;
    background-color: var(--text-muted);
    pointer-events: none;
    transition: background-color 0.2s ease;
    -webkit-mask: var(--lgn-ico) center / contain no-repeat;
            mask: var(--lgn-ico) center / contain no-repeat;
}

.lgn-input--user { --lgn-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='3.6'/%3E%3Cpath d='M4.5 20a7.5 7.5 0 0 1 15 0'/%3E%3C/svg%3E"); }
.lgn-input--key  { --lgn-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4.5' y='10' width='15' height='10' rx='2.4'/%3E%3Cpath d='M8 10V7.5a4 4 0 0 1 8 0V10'/%3E%3Cpath d='M12 14v2.5'/%3E%3C/svg%3E"); }

/* `border: 0` no es decorativo: la regla global de inputs (arriba del todo de
   esta hoja) fija fondo, relleno y radio pero NO toca el borde, asi que cada
   campo se quedaba con el borde claro por omision del navegador. Aqui la caja
   es .lgn-input y el campo va transparente dentro de ella. */
.lgn-input input[type="text"],
.lgn-input input[type="password"] {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    padding: 13px 14px 13px 42px;
    border-radius: 14px;
    background: transparent;
    font-size: 10pt;
}

/* Sin icono (el codigo de seguridad) el texto no necesita el hueco. */
.lgn-input:not([class*="lgn-input--"]) input { padding-left: 14px; }
.lgn-input:not([class*="lgn-input--"])::before { content: none; }

.lgn-input:focus-within {
    background: var(--surface-input-focus);
    box-shadow: var(--shadow-focus);
}

.lgn-input:focus-within::before { background-color: var(--gold); }

.lgn-input input:focus { background: transparent; }

/* El relleno automatico de Chrome pinta el campo de azul claro y se
   come el fondo del componente; se le devuelve el color con la
   sombra interior, que es lo unico que respeta. */
.lgn-input input:-webkit-autofill,
.lgn-input input:-webkit-autofill:hover,
.lgn-input input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--text-primary);
    -webkit-box-shadow: 0 0 0 60px var(--bg-input) inset;
    caret-color: var(--text-primary);
}

.lgn-field select {
    width: 100%;
    padding: 13px 14px;
    font-size: 10pt;
}

.lgn-hint {
    margin: 7px 0 0;
    color: var(--text-muted);
    font-size: 9pt;
}

/* Boton de ver la contrasena. Nace con `hidden` y lo enciende el JS
   de la plantilla: sin JavaScript no aparece un boton que no hace
   nada. El ojo tachado es el estado "visible". */
.lgn-reveal {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    margin-right: 4px;
    border: 0;
    border-radius: 12px;
    background-color: transparent;
    background-image: none;
    color: transparent;
    cursor: pointer;
    position: relative;
}

.lgn-reveal[hidden] { display: none; }

/* TRAMPA: el selector lleva `.lgn-input` a proposito. modern.css (que carga
   DESPUES de esta hoja) trae `body.theme-modern button::before { content: none }`
   para que no se cuele el icono generico que el tema viejo pone en cada <button>.
   Con `.lgn-reveal::before` a secas esa regla gana por especificidad y el ojo no
   se pintaba: el boton salia, pero vacio. Con dos clases, esta manda. */
.lgn-input .lgn-reveal::before {
    content: "";
    position: absolute;
    inset: 11px;
    background-color: var(--text-muted);
    transition: background-color 0.2s ease;
    -webkit-mask: var(--lgn-eye) center / contain no-repeat;
            mask: var(--lgn-eye) center / contain no-repeat;
    --lgn-eye: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.6 12S6 5.8 12 5.8 21.4 12 21.4 12 18 18.2 12 18.2 2.6 12 2.6 12z'/%3E%3Ccircle cx='12' cy='12' r='2.9'/%3E%3C/svg%3E");
}

.lgn-input .lgn-reveal.is-on::before {
    --lgn-eye: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4.5l16 15'/%3E%3Cpath d='M9.6 6.2A9.6 9.6 0 0 1 12 5.8c6 0 9.4 6.2 9.4 6.2a17 17 0 0 1-3.3 3.9'/%3E%3Cpath d='M6.4 8.2A17 17 0 0 0 2.6 12S6 18.2 12 18.2c1 0 2-.2 2.8-.5'/%3E%3Cpath d='M10.2 10.4a2.9 2.9 0 0 0 3.9 4.1'/%3E%3C/svg%3E");
}

.lgn-input .lgn-reveal:hover::before,
.lgn-input .lgn-reveal.is-on::before { background-color: var(--gold); }

.lgn-reveal:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* Aviso de Bloq Mayus: tambien lo gobierna el JS. */
.lgn-caps {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 8px 0 0;
    padding: 8px 12px;
    border-radius: 12px;
    background: var(--alpha-gold-12);
    color: var(--text-status-warning);
    font-size: 9pt;
}

.lgn-caps[hidden] { display: none; }

.lgn-caps::before {
    content: "";
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    background-color: var(--text-status-warning);
    -webkit-mask: var(--lgn-caps-ico) center / contain no-repeat;
            mask: var(--lgn-caps-ico) center / contain no-repeat;
    --lgn-caps-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3.6 4.5 11h4v4h7v-4h4z'/%3E%3Crect x='8.5' y='17.6' width='7' height='2.8' rx='1'/%3E%3C/svg%3E");
}

/* ---- Boton de entrar --------------------------------------- */
.lgn-actions { margin-top: 20px; }

.lgn-submit {
    display: block;
    width: 100%;
    border: 0;
    padding: 13px 18px;
    border-radius: 16px;
    background: var(--grad-register-submit);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 11pt;
    font-weight: bold;
    letter-spacing: 0.4px;
    cursor: pointer;
    box-shadow: inset 0 1px 0 var(--alpha-white-06), 0 0 10px var(--alpha-bronze-16);
    transition: color 0.22s ease, background 0.22s ease, box-shadow 0.28s ease, transform 0.22s ease;
}

.lgn-submit:hover {
    color: var(--text-footer-link);
    background: var(--grad-register-submit-hover);
    box-shadow: var(--shadow-delete-hover), 0 0 28px var(--alpha-bronze-16), inset 0 0 12px var(--alpha-silver-18);
    transform: translateY(-1px);
}

.lgn-submit:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* ---- Pie de la tarjeta: crear cuenta ----------------------- */
.lgn-alt {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 20px;
    padding-top: 18px;
    box-shadow: inset 0 1px 0 var(--alpha-silver-10);
    color: var(--text-muted);
    font-size: 10pt;
}

.lgn-alt__link {
    padding: 7px 16px;
    border-radius: 999px;
    background: var(--surface-silver-panel-soft);
    color: var(--gold);
    font-weight: bold;
    transition: background 0.2s ease, color 0.2s ease;
}

.lgn-alt__link:hover {
    background: var(--alpha-gold-16);
    color: var(--text-label-hover);
}

/* ---- Columna de ayuda -------------------------------------- */
.lgn-aside {
    background: var(--surface-silver-panel-soft);
}

.lgn-notes {
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--text-hero-intro);
    font-size: 10pt;
}

.lgn-notes li {
    position: relative;
    margin-bottom: 12px;
    padding-left: 22px;
    line-height: 1.5;
}

.lgn-notes li:last-child { margin-bottom: 0; }

.lgn-notes li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5em;
    width: 10px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
}

/* ---- Estrecho ---------------------------------------------- */
@media (max-width: 980px) {
    .lgn-layout { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
    .lgn-hero { flex-direction: column; }
    .lgn-hero__sprite { margin: 0 auto; }
}

/* ══════════════════════════════════════════════════════════════════════════
   necROmantic 2026-08-06 — Huerfanos del arbol de referidos
   ══════════════════════════════════════════════════════════════════════════
   Tres sitios de la ficha de cuenta hablan de lo mismo desde angulos distintos:

     1. la tabla de invitaciones, donde el referidor SUELTA a quien no arranco;
     2. el panel de cupo, que explica los huecos recuperados y, si la cuenta esta
        fuera del arbol, sustituye el boton de generar por el porque;
     3. la columna derecha del panel de bonus, donde el huerfano vuelve a entrar
        escribiendo el codigo de otro jugador.

   Se apoyan todo lo posible en los componentes que ya existian (.invites-pill,
   .inv__note, .rb-gift--empty) y solo anaden lo que no habia. Nada de bordes
   nuevos donde el sitio no los lleva: la separacion la dan fondo y espaciado.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Tabla de invitaciones ───────────────────────────────────────────────── */

/* El nombre del PERSONAJE con el que se presenta un invitado que ha renacido o
   ha pasado del 99. Se distingue del userid censurado a proposito: no es el
   mismo tipo de dato, y quien mira la tabla tiene que notar la diferencia. */
.invites-char {
    color: var(--text-heading2);
    letter-spacing: 0.01em;
}

/* Un invitado ya soltado sigue apareciendo por historico, pero apagado. */
.invites-gone {
    color: var(--text-muted);
    font-weight: 600;
    text-decoration: line-through;
    text-decoration-color: var(--border-light);
}

/* "Soltada" comparte lenguaje con "Caducado": las dos devuelven el hueco. */
.invites-pill--released {
    background: var(--bg-input);
    color: var(--text-muted);
}

.invites-pill--orphan {
    background: var(--text-notice);
    color: var(--bg-content);
}

.invites-release {
    margin: 8px 0 0;
    padding: 0;
}

.invites-release__btn {
    margin-top: 6px;
    padding: 6px 13px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.74rem;
    font-weight: 700;
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease;
}

.invites-release__btn:hover {
    border-color: var(--text-status-error);
    color: var(--text-error);
}

/* ── Panel de cupo ───────────────────────────────────────────────────────── */

/* Aviso de que hay invitaciones sueltas esperando decision. No es un error, es
   dinero en la mesa: se destaca sin gritar. */
.inv__note--warn {
    color: var(--text-primary);
}

.inv__note--warn strong { color: var(--gold); }

/* Sustituye al boton de generar cuando la cuenta esta fuera del arbol. */
.inv__blocked {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0;
    padding: 14px 16px;
    border-radius: 10px;
    background: var(--alpha-black-22);
    font-size: 0.82rem;
    line-height: 1.55;
    text-align: left;
    color: var(--text-muted);
}

.inv__blocked i        { margin-top: 2px; color: var(--text-notice); }
.inv__blocked strong   { color: var(--text-primary); }

/* ── Panel de bonus: vuelta al arbol ─────────────────────────────────────── */

/* La tarjeta vacia de siempre, pero con la explicacion debajo del titulo: aqui
   hace falta contar que NO se ha perdido, que es lo que asusta al leerlo. */
.rb-gift--orphan {
    grid-template-columns: auto 1fr;
    grid-template-areas:
        "icon name"
        "detail detail";
}

.rb-gift--orphan .rb-gift__name { color: var(--text-primary); }

/* .rb-gift__detail ya trae su 'grid-area: detail'; aqui solo se aprieta el hueco,
   porque en esta tarjeta el parrafo va pegado al titulo y no debajo de una ficha. */
.rb-gift--orphan .rb-gift__detail { margin-top: 10px; }

.rb-adopt { margin-top: 15px; }

.rb-adopt__label {
    display: block;
    margin-bottom: 7px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.rb-adopt__row {
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
}

/* La regla global de input[type=text] fija fondo y radio pero NO declara borde,
   asi que sin este 'border' el campo se queda con el claro del navegador. */
.rb-adopt__input {
    flex: 1 1 9ch;
    min-width: 9ch;
    padding: 10px 13px;
    border: 1px solid var(--border-light);
    border-radius: 9px;
    background: var(--bg-input);
    color: var(--text-primary);
    font-family: monospace;
    font-size: 0.98rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.rb-adopt__input:focus {
    outline: none;
    border-color: var(--rb-get);
}

.rb-adopt__btn {
    flex: 0 0 auto;
    padding: 10px 20px;
    border: 1px solid var(--border-accent);
    border-radius: 9px;
    background: linear-gradient(150deg, var(--accent-purple), var(--gold));
    color: var(--bg-content);
    font-family: inherit;
    font-size: 0.84rem;
    font-weight: 700;
    cursor: pointer;
    transition: filter 0.2s ease;
}

.rb-adopt__btn:hover { filter: brightness(1.12); }

.rb-adopt .rb__note { margin-top: 9px; }

/* ═══════════════════════════════════════════════════════════════════════════
   necROmantic 2026-08-06 · Sistema de tiquets (/report/ y /sugerencias/)

   Reutiliza cuanto puede de .report-* y .rup: los campos, el botón de enviar,
   la barra de marcas y el subidor de capturas son EXACTAMENTE los mismos que
   ya tenía el formulario, y no había nada que arreglar ahí.

   Lo que se añade es lo que antes no existía porque no había conversación: la
   lista, las pastillas de estado y filtro, el hilo y la caja del equipo.

   Sin bordes, como el resto del sitio: la separación la hace el fondo. El
   color de cada estado sale de los tokens de la paleta, no de valores sueltos.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Cada estado tiene su color y su token, en un solo sitio. Añadir un estado a
   Necro\Tickets\Status es añadir dos líneas aquí y nada más: la clase la
   compone Status::modifier(). */
:root {
    --tk-new:            var(--accent-purple);
    /* "Encolado" (necROmantic 2026-08-30): visto y esperando turno. Va con --text-link, un
       lavanda claro, porque es el hueco que quedaba libre en una paleta ya muy cargada de
       rosas: --accent-purple es "sin tocar", --text-status-warning es "alguien esta en
       ello", --accent-red y --gold son "te toca a ti" y --text-muted es "archivada". Un
       color propio en hexadecimal habria roto la regla de esta hoja -- los estados salen de
       tokens de la paleta, no de valores sueltos. */
    --tk-queued:         var(--text-link);
    --tk-in-progress:    var(--text-status-warning);
    --tk-waiting-user:   var(--accent-red);
    --tk-awaiting-check: var(--gold);
    --tk-resolved:       var(--text-status-success);
    --tk-closed:         var(--text-muted);
}

/* ── Botones de cabecera ──────────────────────────────────────────────── */
.tk-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 20px;
    border-radius: 8px;
    background: var(--gold);
    color: var(--bg-content);
    font-weight: 600;
    text-decoration: none;
    transition: filter 0.18s ease, transform 0.18s ease;
}

.tk-cta:hover { filter: brightness(1.08); transform: translateY(-1px); }

.tk-back {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.88rem;
}

.tk-back:hover { color: var(--text-link-hover); }

/* ── Aviso del equipo dentro de la bandeja propia ─────────────────────── */
.tk-staffbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 18px;
    padding: 12px 16px;
    border-radius: 10px;
    background: var(--alpha-bronze-16);
    color: var(--text-primary);
    font-size: 0.92rem;
}

.tk-staffbar i { color: var(--accent-purple); }

.tk-staffbar__go {
    margin-left: auto;
    color: var(--text-link-hover);
    font-weight: 600;
    text-decoration: none;
}

/* ── Pastilla de estado ───────────────────────────────────────────────── */
.tk-badge {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 11px;
    border-radius: 999px;
    background: var(--alpha-silver-10);
    color: var(--text-primary);
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

.tk-badge__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

.tk-badge--new            { color: var(--tk-new); }
.tk-badge--queued         { color: var(--tk-queued); }
.tk-badge--in-progress    { color: var(--tk-in-progress); }
.tk-badge--waiting-user   { color: var(--tk-waiting-user); }
.tk-badge--awaiting-check { color: var(--tk-awaiting-check); }
.tk-badge--resolved       { color: var(--tk-resolved); }
.tk-badge--closed         { color: var(--tk-closed); }

.tk-badge__hint {
    margin-left: 10px;
    color: var(--text-muted);
    font-size: 0.88rem;
}

/* ── Filtros ──────────────────────────────────────────────────────────── */
.tk-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 18px;
}

.tk-filter {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border-radius: 999px;
    background: var(--alpha-silver-08);
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
    transition: background 0.16s ease, color 0.16s ease;
}

.tk-filter:hover { background: var(--alpha-silver-16); color: var(--text-primary); }

.tk-filter.is-on {
    background: var(--alpha-gold-24);
    color: var(--text-heading2);
    font-weight: 600;
}

/* Un estado sin ni un tiquet se queda, apagado y sin enlace: que la fila de
   filtros cambie de anchura cada vez que se resuelve algo desconcierta más de
   lo que ayuda. */
.tk-filter.is-empty { opacity: 0.4; cursor: default; }

.tk-filter__n {
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--alpha-black-24);
    font-size: 0.78rem;
    font-weight: 600;
}

/* ── Lista ────────────────────────────────────────────────────────────── */
.tk-list {
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.tk-row__link {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    border-radius: 10px;
    background: var(--surface-card-row);
    color: var(--text-primary);
    text-decoration: none;
    transition: background 0.16s ease, transform 0.16s ease;
}

.tk-row__link:hover { background: var(--bg-surface-alt); transform: translateX(2px); }

/* El marcador de no leído: una barra de color a la izquierda. Se ve de un
   vistazo bajando por la lista, que es como se lee una bandeja. */
.tk-row__mark {
    width: 4px;
    align-self: stretch;
    border-radius: 999px;
    background: transparent;
    flex: 0 0 auto;
}

.tk-row.is-unread .tk-row__mark { background: var(--gold); }
.tk-row.is-unread .tk-row__subject { color: var(--text-heading2); font-weight: 600; }
.tk-row.is-gone .tk-row__link { opacity: 0.55; }

.tk-row__main { flex: 1 1 auto; min-width: 0; }

.tk-row__top {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 6px;
}

.tk-row__ref {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    color: var(--text-muted);
    flex: 0 0 auto;
}

.tk-row__subject {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tk-row__subject--gone { font-style: italic; color: var(--text-muted); }

.tk-row__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.tk-row__cat,
.tk-row__who,
.tk-row__count {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.tk-row__side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 5px;
    flex: 0 0 auto;
    text-align: right;
}

.tk-row__new {
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--alpha-gold-24);
    color: var(--gold);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.tk-when { font-size: 0.8rem; color: var(--text-muted); white-space: nowrap; }

.tk-none {
    margin: 0 0 20px;
    padding: 22px;
    border-radius: 10px;
    background: var(--alpha-silver-08);
    color: var(--text-muted);
    text-align: center;
}

.tk-none a { color: var(--text-link-hover); margin-left: 6px; }

/* ── Paginación ───────────────────────────────────────────────────────── */
.tk-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin: 0 0 10px;
}

.tk-pager__step {
    padding: 8px 16px;
    border-radius: 8px;
    background: var(--alpha-silver-10);
    color: var(--text-primary);
    text-decoration: none;
    font-size: 0.86rem;
}

.tk-pager__step:hover { background: var(--alpha-silver-20); }
.tk-pager__at { color: var(--text-muted); font-size: 0.84rem; }

/* ── Buscador de la cola ──────────────────────────────────────────────── */
.tk-search {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 16px;
}

.tk-search__label {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.tk-search__input { flex: 1 1 240px; width: auto; }

.tk-search__go {
    padding: 10px 20px;
    border: 0;
    border-radius: 8px;
    background: var(--alpha-gold-24);
    color: var(--text-heading2);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.tk-search__go:hover { background: var(--alpha-gold-36); }
.tk-search__clear { color: var(--text-muted); font-size: 0.84rem; }

/* ── Hilo ─────────────────────────────────────────────────────────────── */
.tk-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 26px;
    align-items: start;
}

.tk-state { margin: 0 0 18px; }

.tk-thread {
    list-style: none;
    margin: 0 0 24px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.tk-entry {
    padding: 16px 20px;
    border-radius: 12px;
    background: var(--surface-card-row);
}

/* El mensaje propio y el del equipo se distinguen por el fondo y por una
   barra de color, no por alineación: una conversación de soporte se lee de
   arriba abajo, no como un chat. */
.tk-entry--user  { background: var(--bg-surface-alt); }
.tk-entry--staff { background: var(--alpha-bronze-16); }

.tk-entry--note {
    background: var(--alpha-gold-12);
    box-shadow: inset 3px 0 0 var(--gold-dim);
}

.tk-entry__head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 10px;
    font-size: 0.84rem;
    color: var(--text-muted);
}

.tk-entry__who {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--text-heading);
    font-weight: 600;
}

.tk-entry--staff .tk-entry__who { color: var(--accent-purple-h); }

.tk-entry__tag {
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--alpha-gold-24);
    color: var(--gold);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.tk-entry__edited { font-style: italic; }

.tk-entry__body { line-height: 1.7; }
.tk-entry__body p { margin: 0 0 10px; }
.tk-entry__body p:last-child { margin-bottom: 0; }
.tk-entry__body ul { margin: 0 0 10px; padding-left: 20px; }
.tk-entry__body code {
    padding: 1px 6px;
    border-radius: 5px;
    background: var(--alpha-black-24);
    color: var(--text-code-strong);
    font-size: 0.9em;
}
.tk-entry__body blockquote {
    margin: 0 0 10px;
    padding: 4px 0 4px 14px;
    box-shadow: inset 3px 0 0 var(--alpha-silver-24);
    color: var(--text-muted);
}

/* Cambio de estado: una línea discreta, no una tarjeta. Es contexto, no
   conversación. */
.tk-event {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 20px;
    font-size: 0.84rem;
    color: var(--text-muted);
}

.tk-event i { color: var(--accent-purple); font-size: 0.78rem; }
.tk-event__text { flex: 1 1 auto; }

/* Capturas de un mensaje */
.tk-shots {
    list-style: none;
    margin: 14px 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.tk-shots__link {
    display: block;
    width: 130px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--alpha-black-24);
    color: var(--text-muted);
    text-decoration: none;
}

.tk-shots__img {
    display: block;
    width: 100%;
    height: 86px;
    object-fit: cover;
}

.tk-shots__name {
    display: block;
    padding: 5px 8px;
    font-size: 0.72rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tk-shots__link:hover { color: var(--text-link-hover); }

/* Historial de ediciones, solo para el equipo */
.tk-revs {
    margin-top: 14px;
    padding: 10px 14px;
    border-radius: 8px;
    background: var(--alpha-black-18);
    font-size: 0.88rem;
}

.tk-revs summary { cursor: pointer; color: var(--text-muted); }
.tk-revs__one { margin-top: 12px; }
.tk-revs__when { margin: 0 0 4px; font-size: 0.76rem; color: var(--text-muted); }
.tk-revs__body { opacity: 0.8; }

/* ── Cajas de escritura ───────────────────────────────────────────────── */
.tk-compose {
    padding: 20px 22px;
    border-radius: 12px;
    background: var(--surface-card);
}

.tk-compose--edit  { background: var(--alpha-gold-08); }
.tk-compose--staff { background: var(--alpha-bronze-08); }

.tk-compose__title {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 6px;
    font-size: 1.02rem;
    color: var(--text-heading2);
}

.tk-compose__why {
    margin: 0 0 14px;
    font-size: 0.86rem;
    color: var(--text-muted);
    line-height: 1.55;
}

.tk-compose .report-textarea { min-height: 140px; }

.tk-staffbox {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    align-items: flex-start;
    margin: 16px 0;
}

.tk-staffbox__status { flex: 1 1 220px; }

.tk-staffbox__note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex: 1 1 260px;
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--alpha-gold-08);
    cursor: pointer;
}

.tk-staffbox__note b { display: block; color: var(--text-heading2); font-size: 0.9rem; }
.tk-staffbox__note i { display: block; margin-top: 3px; font-style: normal; font-size: 0.82rem; color: var(--text-muted); }

.tk-closed {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 18px 20px;
    border-radius: 10px;
    background: var(--alpha-silver-08);
    color: var(--text-muted);
}

.tk-closed a { color: var(--text-link-hover); margin-left: 6px; }

/* ── Barra lateral del hilo ───────────────────────────────────────────── */
.tk-side {
    padding: 18px 20px;
    border-radius: 12px;
    background: var(--surface-card-strong);
    position: sticky;
    top: 90px;
}

.tk-side__title {
    margin: 0 0 14px;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
}

.tk-facts { margin: 0 0 16px; }
.tk-facts dt {
    margin-top: 10px;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}
.tk-facts dt:first-child { margin-top: 0; }
.tk-facts dd { margin: 3px 0 0; color: var(--text-primary); font-size: 0.9rem; word-break: break-word; }
.tk-facts__dim { color: var(--text-muted); }

.tk-side__note {
    display: flex;
    gap: 10px;
    margin: 0 0 16px;
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--alpha-bronze-16);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--text-panel-soft);
}

.tk-side__note i { color: var(--accent-purple); flex: 0 0 auto; margin-top: 2px; }

.tk-ref { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ── Zona de eliminación ──────────────────────────────────────────────── */
/* Cerrada de partida y con su propio color. Es irreversible y vive en la
   barra lateral de una página que se abre para leer: no debe estar a un clic
   del ratón de nadie. */
.tk-danger {
    border-radius: 10px;
    background: var(--alpha-black-18);
    overflow: hidden;
}

.tk-danger__open {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 12px 14px;
    cursor: pointer;
    color: var(--text-status-error);
    font-size: 0.86rem;
}

.tk-danger__body { padding: 0 14px 16px; }

.tk-danger__lead { margin: 0 0 10px; font-size: 0.84rem; color: var(--text-muted); line-height: 1.55; }

.tk-danger__list {
    margin: 0 0 14px;
    padding-left: 18px;
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.5;
}

.tk-danger__list li { margin-bottom: 6px; }

.tk-danger__input { margin: 6px 0 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.tk-danger__go {
    width: 100%;
    padding: 11px;
    border: 0;
    border-radius: 8px;
    background: var(--text-status-error-strong);
    color: var(--text-white);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.tk-danger__go:hover { filter: brightness(1.1); }

/* ── Pasos de la ayuda del alta ───────────────────────────────────────── */
.tk-steps {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    counter-reset: tk;
}

.tk-steps li {
    display: flex;
    gap: 12px;
    margin-bottom: 12px;
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--text-panel-soft);
}

.tk-steps__n {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--alpha-gold-24);
    color: var(--gold);
    font-size: 0.76rem;
    font-weight: 700;
}

/* Marca de campo con error, para las clases is-wrong que pone la vista */
.report-field.is-wrong .report-input,
.report-field.is-wrong .report-textarea { box-shadow: inset 0 0 0 1px var(--text-status-error-strong); }

.report-field__err {
    margin: 6px 0 0;
    font-size: 0.82rem;
    color: var(--text-status-error);
}

.rep__choices.is-wrong .rep__grid { box-shadow: 0 0 0 1px var(--text-status-error-strong); border-radius: 10px; }

/* ── Estrecho ─────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
    .tk-shell { grid-template-columns: minmax(0, 1fr); }
    .tk-side { position: static; }
}

@media (max-width: 620px) {
    .tk-row__link { flex-wrap: wrap; }
    .tk-row__side { flex-direction: row; align-items: center; width: 100%; justify-content: flex-start; }
    .tk-row__top { flex-wrap: wrap; }
    .tk-row__subject { white-space: normal; }
    .tk-staffbar__go { margin-left: 0; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Mosaico de secciones de la ficha de cuenta (.pnav) y las secciones que
   gobierna (.pane).                                     necROmantic 2026-08-06

   /account/view/ tiene doce secciones y quien entra a mirar una sola tenia que
   barrer la pagina entera. Arriba va un mosaico con un mosaico por seccion -icono,
   nombre y el dato que importa de esa seccion- y al pulsarlo se queda solo esa.

   El comportamiento lo pone themes/default/js/unknown.accpanes.js; sin JavaScript
   los mosaicos son anclas normales y la pagina se queda como estaba.
   ══════════════════════════════════════════════════════════════════════════ */

.pnav {
    margin: 24px 0 4px;
    padding: 16px 16px 18px;
    border-radius: 20px;
    background: var(--grad-pnav);
    box-shadow: var(--shadow-soft);
}

.pnav__head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin: 0 4px 14px;
}

.pnav__eyebrow {
    margin: 0;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
}

.pnav__hint {
    margin: 0;
    flex: 1 1 auto;
    font-size: 0.82rem;
    color: var(--text-muted);
}

/* Nace con hidden en la plantilla: sin JavaScript no hay nada escondido que mostrar. */
/* "Mostrar todo" es una baldosa mas (usuario 2026-08-06): el aspecto entero se lo da
   .pnav__tile y aqui solo se le quita lo que el navegador le pone por ser un <button>,
   que si no rompe la cuadricula (los botones no ocupan el ancho de su celda y traen su
   propia tipografia). */
.pnav__all {
    width: 100%;
    border: 0;
    font: inherit;
    text-align: center;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

/* Cuadricula de verdad: todas las baldosas del mismo ancho y del mismo alto (usuario
   2026-08-06). El numero de columnas es fijo por tramo de ancho y no auto-fill, porque
   con 10 secciones cinco columnas dan dos filas exactas y ninguna queda coja. El alto lo
   igualan las filas del grid; el min-height solo pone el suelo. */
.pnav__grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 12px;
}

/* ── El mosaico ────────────────────────────────────────────────────────────
   Cristal oscuro; el color de la seccion vive en el filo de arriba, en el icono
   y en un resplandor de fondo, no en un relleno solido: doce baldosas de color a
   pantalla completa pelean con el resto del panel, que es morado y sobrio.
   Cada modificador de tono solo define las dos variables; las reglas son comunes. */
/* El atributo hidden lo pone la plantilla en la baldosa de "Mostrar todo" y lo quita el
   script. Hace falta decirlo aqui porque un display: flex de la hoja gana al del navegador
   para [hidden]: sin esta regla, quien navegue sin JavaScript veria un boton que no hace
   nada. */
.pnav__tile[hidden] { display: none; }

.pnav__tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 14px;
    min-height: 158px;
    padding: 18px 16px 16px;
    border-radius: 16px;
    overflow: hidden;
    background: var(--grad-tile);
    color: var(--text-primary);
    text-decoration: none;
    isolation: isolate;
    transition: transform 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}



/* Filo superior de color, que se apaga hacia la derecha. */
.pnav__tile::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--tile-tone), transparent 82%);
}

/* Resplandor de la esquina. z-index -1 para que no tape ni el icono ni el texto. */
.pnav__tile::after {
    content: "";
    position: absolute;
    top: -34px;
    left: 50%;
    width: 190px;
    height: 190px;
    margin-left: -95px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--tile-glow), transparent 68%);
    pointer-events: none;
    z-index: -1;
}

.pnav__tile:hover,
.pnav__tile:focus-visible {
    background: var(--grad-tile-hover);
    box-shadow: 0 16px 34px var(--alpha-black-28);
    transform: translateY(-3px);
}

.pnav__tile:focus-visible {
    outline: 2px solid var(--tile-tone);
    outline-offset: 2px;
}

.pnav__tile.is-active {
    background: var(--grad-tile-hover);
    box-shadow: inset 0 0 0 1px var(--tile-tone), 0 14px 32px var(--alpha-black-28);
}

.pnav__ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    border-radius: 18px;
    background: var(--tile-glow);
    color: var(--tile-tone);
    font-size: 1.72rem;
}

.pnav__text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    min-width: 0;
    max-width: 100%;
}

.pnav__label {
    font-size: 0.98rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--text-heading2);
}

/* Una linea y con puntos suspensivos: el dato en vivo nunca debe estirar la baldosa. */
.pnav__sub {
    max-width: 100%;
    font-size: 0.78rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pnav__tile--lilac   { --tile-tone: var(--tone-lilac);   --tile-glow: var(--tone-lilac-glow); }
.pnav__tile--azure   { --tile-tone: var(--tone-azure);   --tile-glow: var(--tone-azure-glow); }
.pnav__tile--teal    { --tile-tone: var(--tone-teal);    --tile-glow: var(--tone-teal-glow); }
.pnav__tile--amber   { --tile-tone: var(--tone-amber);   --tile-glow: var(--tone-amber-glow); }
.pnav__tile--gold    { --tile-tone: var(--tone-gold);    --tile-glow: var(--tone-gold-glow); }
.pnav__tile--rose    { --tile-tone: var(--tone-rose);    --tile-glow: var(--tone-rose-glow); }
.pnav__tile--mint    { --tile-tone: var(--tone-mint);    --tile-glow: var(--tone-mint-glow); }
.pnav__tile--indigo  { --tile-tone: var(--tone-indigo);  --tile-glow: var(--tone-indigo-glow); }
.pnav__tile--crimson { --tile-tone: var(--tone-crimson); --tile-glow: var(--tone-crimson-glow); }
.pnav__tile--violet  { --tile-tone: var(--tone-violet);  --tile-glow: var(--tone-violet-glow); }
.pnav__tile--copper  { --tile-tone: var(--tone-copper);  --tile-glow: var(--tone-copper-glow); }
.pnav__tile--silver  { --tile-tone: var(--tone-silver);  --tile-glow: var(--tone-silver-glow); }

/* ── Las secciones ───────────────────────────────────────────────────────── */

/* La cabecera del sitio es sticky: sin este margen de desplazamiento el titulo de
   la seccion queda por debajo de ella al bajar hasta ella. */
.pane { scroll-margin-top: calc(var(--nav-height, 84px) + 18px); }

.pane--off { display: none; }

/* Cada seccion ha pasado a vivir dentro de su propia caja, asi que TODOS los
   h3.sec-title se convirtieron en :first-of-type de su caja y cogieron la regla que
   quita la linea de separacion al primer titulo de la pagina. Aqui se les devuelve. */
.pane > .sec-title:first-of-type {
    margin-top: 46px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
}

.pane > .sec-title:first-of-type::before { display: block; }

/* Menos a dos: al primer titulo de la pagina (la seccion 1 es el resumen, que no
   lleva titulo, asi que el primero con titulo es la 2) y al de la seccion que se
   esta mirando sola. En los dos casos no hay nada encima de lo que separarse. */
.pane:nth-of-type(2) > .sec-title:first-of-type,
.pane--solo > .sec-title:first-of-type {
    margin-top: 26px;
    padding-top: 0;
    border-top: 0;
}

.pane:nth-of-type(2) > .sec-title:first-of-type::before,
.pane--solo > .sec-title:first-of-type::before { display: none; }

/* Vuelta al mosaico, debajo de la seccion que se mira sola. La pinta el JS. */
.pane-back {
    display: flex;
    justify-content: center;
    margin: 34px 0 10px;
}

.pane-back__btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 9px 20px;
    border: 0;
    border-radius: 999px;
    background: var(--surface-silver-panel-soft);
    color: var(--text-primary);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
}

.pane-back__btn::before {
    content: "\2191";
    font-size: 0.95rem;
    color: var(--gold);
}

.pane-back__btn:hover,
.pane-back__btn:focus-visible {
    background: var(--grad-secondary-button-hover);
    color: var(--text-on-accent);
    box-shadow: var(--shadow-secondary-hover);
}

.pane-back__btn:hover::before,
.pane-back__btn:focus-visible::before { color: var(--text-on-accent); }

/* ── Estrecho ─────────────────────────────────────────────────────────── */
/* Las cinco columnas se estiran hasta donde caben (a 1024 px de ventana salen a 166 px
   cada una): con diez secciones son dos filas exactas, y en cuanto se baja a cuatro
   quedan dos huecos al final. */
@media (max-width: 940px) {
    .pnav__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 820px) {
    .pnav__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
    .pnav { padding: 14px 12px 16px; border-radius: 16px; }
    .pnav__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .pnav__tile { min-height: 138px; padding: 15px 14px 14px; }
    .pnav__ico { width: 50px; height: 50px; border-radius: 15px; font-size: 1.45rem; }
}

/* Quien pide menos movimiento no tiene por que ver saltar las baldosas. */
@media (prefers-reduced-motion: reduce) {
    .pnav__tile { transition: none; }
    .pnav__tile:hover,
    .pnav__tile:focus-visible { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   "Mostrar todo" del mosaico, ancho entero        necROmantic 2026-08-06

   Era una pastilla pequena en la esquina de la cabecera del mosaico y se leia
   como un adorno. Ahora es el ULTIMO elemento de la cuadricula, ocupando la
   fila entera: se lee como lo que es, la salida del filtro.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════
   En que se ha ido el tiempo de automatizacion (.aqh)  necROmantic 2026-08-06

   Treinta renglones, uno por dia, con las tres cifras del mismo dia en la
   MISMA barra: consumido, ahorrado por Ciudad y ahorrado por Consumo
   Inteligente. Van juntas a proposito -- el ahorro solo significa algo al
   lado de lo que costo, que es justo lo que se pidio ensenar.

   Los dias sin jugar se pintan igual, apagados: son la otra mitad de la
   demostracion de que la cuota no baja sola.

   El ancho de cada tramo sale de .aqh__seg--pN (0..100, generadas al final de
   este bloque), nunca de un style="" en linea. La escala es comun a los 30
   dias: el 100% es el dia mas largo del tramo, asi que los renglones se
   pueden comparar entre si de un vistazo.
   ══════════════════════════════════════════════════════════════════════════ */

/* Los tonos de las graficas de la cuota. NO son los --tone-* del mosaico: aquellos son pasteles
   casi de la misma luminosidad y, puestos como lineas finas sobre el fondo, el azul y el verde no
   se distinguian ni con vision normal (medido: ΔE 12,9 sobre un minimo de 15, y 3,2 en
   tritanopia). Estos pasan las comprobaciones de una paleta categorica -- banda de luminosidad,
   croma minimo, separacion con daltonismo, separacion con vision normal y contraste contra el
   fondo -- medidas SIEMPRE con el validador y nunca a ojo. Si se cambia uno, hay que volver a
   medirlos.                                                    necROmantic 2026-08-06

   necROmantic 2026-08-12, tonos elegidos por el usuario: consumido ROJO, ahorrado AZUL, y el
   desglose del gasto en naranja / amarillo / rosa / purpura. Medida la separacion sobre el fondo
   de la tarjeta (#1b1230) y DENTRO DE CADA GRUPO DE TRAZO, que es como se lee la grafica:

     continuas    rojo #e4574a · azul #4a90e2                todo PASA · peor par ΔE 29,6 (22,5 CVD)
     discontinuas #c9741c #f5d76e #e05fa0 #8a52d6            todo PASA · peor par ΔE 18,1 (13,5 CVD)

   Dos desviaciones a proposito, y las dos cruzan la frontera continua/discontinua, que es
   justamente lo que la codificacion compuesta (tono + trazo) esta ahi para resolver:
     · rojo ↔ naranja ΔE 9,3. Se leen como FAMILIA porque lo son: el @autoplay es la mayor parte
       de lo consumido. La paleta vieja llegaba a usar el mismo tono para los dos.
     · rojo ↔ rosa ΔE 11,4.
   Y una tercera, esta de la banda de luminosidad: el amarillo sale a L 0,884, por encima del 0,67
   de la banda oscura. Es el precio de que exista un amarillo sobre fondo oscuro -- bajarlo a la
   banda lo vuelve oliva y entonces se cae contra el naranja (medido: ΔE 7,3 normal, 1,8 en
   protanopia) --, asi que se prefiere el amarillo brillante, que es ademas lo que se pidio. */
:root {
    --aqh-spent: #e4574a;   /* consumido */
    --aqh-saved: #4a90e2;   /* ahorrado = Ciudad + Consumo Inteligente, sumados */
    --aqh-auto:  #c9741c;   /* @autoplay */
    --aqh-h1:    #f5d76e;   /* @helpme 1 */
    --aqh-h2:    #e05fa0;   /* @helpme 2 */
    --aqh-h3:    #8a52d6;   /* @helpme 3 */
}

.aqh {
    margin: 0 0 22px;
    padding: 18px 20px 16px;
    border-radius: 14px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 10px 26px var(--alpha-black-28), inset 0 1px 0 var(--alpha-white-06);
}

.aqh-title {
    margin: 26px 0 10px;
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--text-primary);
}

.aqh__lead {
    margin: 0 0 14px;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.aqh__lead strong { color: var(--text-primary); }

/* ── Leyenda ─────────────────────────────────────────────────────────────── */
.aqh__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
}

.aqh__key {
    position: relative;
    padding-left: 18px;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
}

.aqh__key::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 11px;
    height: 11px;
    margin-top: -5px;
    border-radius: 3px;
    background: currentColor;
}

/* Grupo del desglose: la muestra es un TRAZO discontinuo, igual que su línea en la gráfica.
   Sin esto, ver el oro repetido en dos entradas de la leyenda no se entendería. */
.aqh__legend--dash { margin-top: -6px; }

.aqh__legend-title {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    opacity: 0.75;
}

.aqh__legend--dash .aqh__key::before {
    top: 50%;
    width: 16px;
    height: 0;
    margin-top: -1px;
    border-radius: 0;
    background: repeating-linear-gradient(90deg, currentColor 0 5px, transparent 5px 9px);
    height: 2px;
}

.aqh__legend--dash .aqh__key { padding-left: 22px; }

.aqh__key--spent { color: var(--aqh-spent); }
.aqh__key--saved { color: var(--aqh-saved); }

/* ── Los treinta renglones ───────────────────────────────────────────────── */
.aqh__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.aqh__day {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) 118px;
    align-items: center;
    gap: 12px;
    padding: 5px 8px;
    border-radius: 8px;
}

/* Cebra suave para no perder el renglon a mitad de la lista. Sin lineas: en esta
   web la separacion la dan fondo y espaciado, nunca un borde. */
.aqh__day:nth-child(odd) { background: var(--surface-card-soft); }

.aqh__date {
    display: flex;
    align-items: baseline;
    gap: 4px;
    font-size: 0.78rem;
    white-space: nowrap;
}

.aqh__date b { font-weight: 700; color: var(--text-primary); }
.aqh__date i { font-style: normal; color: var(--text-muted); }
.aqh__date em {
    margin-left: auto;
    font-style: normal;
    font-size: 0.7rem;
    opacity: 0.65;
    color: var(--text-muted);
}

/* La pista siempre esta, tenga datos o no: un dia sin jugar tiene que ocupar su
   sitio, o la lista dejaria de leerse como un calendario. */
.aqh__bar {
    display: flex;
    align-items: stretch;
    height: 14px;
    border-radius: 7px;
    overflow: hidden;
    background: var(--surface-card-soft);
}

.aqh__seg { height: 100%; }

.aqh__seg--spent { background: var(--aqh-spent); }
.aqh__seg--saved { background: var(--aqh-saved); }

.aqh__nums {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

.aqh__num { font-weight: 700; }
.aqh__num--spent { color: var(--aqh-spent); }
.aqh__num--saved { color: var(--aqh-saved); }

.aqh__num--off {
    font-weight: 500;
    font-size: 0.72rem;
    opacity: 0.55;
    color: var(--text-muted);
}

.aqh__day--empty .aqh__date b,
.aqh__day--empty .aqh__date i { opacity: 0.55; }

.aqh__foot {
    margin: 14px 0 0;
    font-size: 0.86rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.aqh__foot strong { color: var(--text-primary); }

.aqh__none {
    margin: 4px 0 0;
    font-size: 0.86rem;
    color: var(--text-muted);
}

.aqh__legendfoot {
    margin: 12px 0 0;
    font-size: 0.8rem;
    line-height: 1.6;
    color: var(--text-muted);
    opacity: 0.9;
}

.aqh__legendfoot b { color: var(--text-primary); }

@media (max-width: 560px) {
    .aqh { padding: 14px 14px 12px; }
    .aqh__day { grid-template-columns: 62px minmax(0, 1fr); grid-template-areas: "fecha barra" "fecha cifras"; row-gap: 4px; }
    .aqh__date { grid-area: fecha; }
    .aqh__bar  { grid-area: barra; }
    .aqh__nums { grid-area: cifras; justify-content: flex-start; }
}

/* Anchos de tramo, en pasos de 1%. Se escriben todos porque el ancho no puede ir
   en un style="" en linea (regla de esta web) y un dia con datos nunca debe
   quedarse sin pintar. */
.aqh__seg--p0 { width: 0%; }
.aqh__seg--p1 { width: 1%; }
.aqh__seg--p2 { width: 2%; }
.aqh__seg--p3 { width: 3%; }
.aqh__seg--p4 { width: 4%; }
.aqh__seg--p5 { width: 5%; }
.aqh__seg--p6 { width: 6%; }
.aqh__seg--p7 { width: 7%; }
.aqh__seg--p8 { width: 8%; }
.aqh__seg--p9 { width: 9%; }
.aqh__seg--p10 { width: 10%; }
.aqh__seg--p11 { width: 11%; }
.aqh__seg--p12 { width: 12%; }
.aqh__seg--p13 { width: 13%; }
.aqh__seg--p14 { width: 14%; }
.aqh__seg--p15 { width: 15%; }
.aqh__seg--p16 { width: 16%; }
.aqh__seg--p17 { width: 17%; }
.aqh__seg--p18 { width: 18%; }
.aqh__seg--p19 { width: 19%; }
.aqh__seg--p20 { width: 20%; }
.aqh__seg--p21 { width: 21%; }
.aqh__seg--p22 { width: 22%; }
.aqh__seg--p23 { width: 23%; }
.aqh__seg--p24 { width: 24%; }
.aqh__seg--p25 { width: 25%; }
.aqh__seg--p26 { width: 26%; }
.aqh__seg--p27 { width: 27%; }
.aqh__seg--p28 { width: 28%; }
.aqh__seg--p29 { width: 29%; }
.aqh__seg--p30 { width: 30%; }
.aqh__seg--p31 { width: 31%; }
.aqh__seg--p32 { width: 32%; }
.aqh__seg--p33 { width: 33%; }
.aqh__seg--p34 { width: 34%; }
.aqh__seg--p35 { width: 35%; }
.aqh__seg--p36 { width: 36%; }
.aqh__seg--p37 { width: 37%; }
.aqh__seg--p38 { width: 38%; }
.aqh__seg--p39 { width: 39%; }
.aqh__seg--p40 { width: 40%; }
.aqh__seg--p41 { width: 41%; }
.aqh__seg--p42 { width: 42%; }
.aqh__seg--p43 { width: 43%; }
.aqh__seg--p44 { width: 44%; }
.aqh__seg--p45 { width: 45%; }
.aqh__seg--p46 { width: 46%; }
.aqh__seg--p47 { width: 47%; }
.aqh__seg--p48 { width: 48%; }
.aqh__seg--p49 { width: 49%; }
.aqh__seg--p50 { width: 50%; }
.aqh__seg--p51 { width: 51%; }
.aqh__seg--p52 { width: 52%; }
.aqh__seg--p53 { width: 53%; }
.aqh__seg--p54 { width: 54%; }
.aqh__seg--p55 { width: 55%; }
.aqh__seg--p56 { width: 56%; }
.aqh__seg--p57 { width: 57%; }
.aqh__seg--p58 { width: 58%; }
.aqh__seg--p59 { width: 59%; }
.aqh__seg--p60 { width: 60%; }
.aqh__seg--p61 { width: 61%; }
.aqh__seg--p62 { width: 62%; }
.aqh__seg--p63 { width: 63%; }
.aqh__seg--p64 { width: 64%; }
.aqh__seg--p65 { width: 65%; }
.aqh__seg--p66 { width: 66%; }
.aqh__seg--p67 { width: 67%; }
.aqh__seg--p68 { width: 68%; }
.aqh__seg--p69 { width: 69%; }
.aqh__seg--p70 { width: 70%; }
.aqh__seg--p71 { width: 71%; }
.aqh__seg--p72 { width: 72%; }
.aqh__seg--p73 { width: 73%; }
.aqh__seg--p74 { width: 74%; }
.aqh__seg--p75 { width: 75%; }
.aqh__seg--p76 { width: 76%; }
.aqh__seg--p77 { width: 77%; }
.aqh__seg--p78 { width: 78%; }
.aqh__seg--p79 { width: 79%; }
.aqh__seg--p80 { width: 80%; }
.aqh__seg--p81 { width: 81%; }
.aqh__seg--p82 { width: 82%; }
.aqh__seg--p83 { width: 83%; }
.aqh__seg--p84 { width: 84%; }
.aqh__seg--p85 { width: 85%; }
.aqh__seg--p86 { width: 86%; }
.aqh__seg--p87 { width: 87%; }
.aqh__seg--p88 { width: 88%; }
.aqh__seg--p89 { width: 89%; }
.aqh__seg--p90 { width: 90%; }
.aqh__seg--p91 { width: 91%; }
.aqh__seg--p92 { width: 92%; }
.aqh__seg--p93 { width: 93%; }
.aqh__seg--p94 { width: 94%; }
.aqh__seg--p95 { width: 95%; }
.aqh__seg--p96 { width: 96%; }
.aqh__seg--p97 { width: 97%; }
.aqh__seg--p98 { width: 98%; }
.aqh__seg--p99 { width: 99%; }
.aqh__seg--p100 { width: 100%; }


/* La unidad del renglon (una sola vez por dia, detras de las tres cifras). */
.aqh__unit {
    font-style: normal;
    font-size: 0.7rem;
    opacity: 0.6;
    color: var(--text-muted);
}

/* ══════════════════════════════════════════════════════════════════════════
   Gráficas de la cuota (.aqg)                    necROmantic 2026-08-06

   Dos lienzos SVG con el mismo eje X: líneas para "consumido contra ahorrado"
   (tres recorridos que se comparan) y barras apiladas para "quién generó el
   gasto" (composición: las cuatro partes suman el total, y el total ES la
   altura de la barra).

   El color va SIEMPRE por clase, nunca por atributo de presentación ni por
   style="" — igual que el resto de esta web. Lo que sí son atributos son las
   coordenadas, que no son estilo.

   El lienzo tiene medidas fijas y escala por su viewBox; el contenedor lleva
   scroll horizontal para el caso en que no escalara.
   ══════════════════════════════════════════════════════════════════════════ */

.aqg {
    position: relative;
    margin: 4px 0 0;
}

.aqg__scroll {
    overflow-x: auto;
    overflow-y: hidden;
}

.aqg__svg {
    display: block;
    width: 100%;
    min-width: 620px;   /* por debajo de esto la gráfica deja de leerse y se desplaza */
    height: auto;
    overflow: visible;
}

/* Rejilla y ejes recesivos: son la referencia, no el dato. */
.aqg__grid {
    stroke: var(--alpha-white-06);
    stroke-width: 1;
}

.aqg__ylab,
.aqg__xlab {
    fill: var(--text-muted);
    font-size: 11px;
    opacity: 0.8;
}

.aqg__ylab { text-anchor: end; }
.aqg__xlab { text-anchor: middle; }

/* Marcas finas: 2 px, sin relleno y con las uniones redondeadas para que un pico
   de un solo día no salga en punta. */
.aqg__line {
    fill: none;
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.aqg__line--spent { stroke: var(--aqh-spent); }
.aqg__line--saved { stroke: var(--aqh-saved); }
.aqg__line--auto  { stroke: var(--aqh-auto); }
.aqg__line--h1    { stroke: var(--aqh-h1); }
.aqg__line--h2    { stroke: var(--aqh-h2); }
.aqg__line--h3    { stroke: var(--aqh-h3); }

/* Lo consumido manda sobre lo demás: es la línea que contesta la pregunta. */
.aqg__line--lead { stroke-width: 2.6; }

/* CODIFICACIÓN COMPUESTA (tono + trazo). Siete tonos que se distingan de verdad no existen en
   esta paleta — medidos, los pares se caen por debajo del mínimo —, así que el desglose de quién
   generó el gasto va DISCONTINUO y con un patrón propio por serie. El patrón es lo que separa a
   dos series que comparten tono, y funciona igual en blanco y negro y con cualquier daltonismo. */
.aqg__line--dash {
    stroke-width: 1.7;
    opacity: 0.92;
}

.aqg__line--dash.aqg__line--auto { stroke-dasharray: 8 5; }
.aqg__line--dash.aqg__line--h1   { stroke-dasharray: 5 4; }
.aqg__line--dash.aqg__line--h2   { stroke-dasharray: 2 4; }
.aqg__line--dash.aqg__line--h3   { stroke-dasharray: 10 4 2 4; }

.aqg__cap {
    margin: 6px 0 0;
    font-size: 0.76rem;
    color: var(--text-muted);
    opacity: 0.75;
}

/* ── Rastreador (lo enciende themes/default/js/unknown.aqchart.js) ───────── */
.aqg__cross {
    stroke: var(--alpha-white-06);
    stroke-width: 1;
}

.aqg__dot {
    stroke: var(--bg-surface);
    stroke-width: 2;   /* anillo del color del fondo: separa el punto de la línea */
}

.aqg__dot--spent { fill: var(--aqh-spent); }
.aqg__dot--saved { fill: var(--aqh-saved); }
.aqg__dot--auto  { fill: var(--aqh-auto); }
.aqg__dot--h1    { fill: var(--aqh-h1); }
.aqg__dot--h2    { fill: var(--aqh-h2); }
.aqg__dot--h3    { fill: var(--aqh-h3); }

.aqg__tip {
    position: absolute;
    z-index: 3;
    min-width: 150px;
    padding: 8px 10px;
    border-radius: 10px;
    background: var(--surface-card-strong);
    box-shadow: 0 10px 24px var(--alpha-black-28);
    font-size: 0.78rem;
    pointer-events: none;
    /* Anclado por su borde superior: el rotulo vive DENTRO del dibujo (ver el JS). */
    transform: translate(-50%, 0);
}

.aqg__tip[hidden] { display: none; }

.aqg__tip-day {
    display: block;
    margin-bottom: 4px;
    font-weight: 700;
    color: var(--text-primary);
}

.aqg__tip-row {
    display: flex;
    align-items: center;
    gap: 7px;
    color: var(--text-muted);
    white-space: nowrap;
}

.aqg__tip-chip {
    width: 9px;
    height: 9px;
    border-radius: 3px;
    flex: 0 0 auto;
}

.aqg__tip-chip--spent { background: var(--aqh-spent); }
.aqg__tip-chip--saved { background: var(--aqh-saved); }
.aqg__tip-chip--auto  { background: var(--aqh-auto); }
.aqg__tip-chip--h1    { background: var(--aqh-h1); }
.aqg__tip-chip--h2    { background: var(--aqh-h2); }
.aqg__tip-chip--h3    { background: var(--aqh-h3); }

.aqg__tip-val {
    margin-left: auto;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
}

/* ── Subtítulo y tabla plegable ──────────────────────────────────────────── */
.aqh-sub {
    margin: 26px 0 6px;
    font-size: 0.94rem;
    font-weight: 700;
    color: var(--text-primary);
}

.aqh__key--auto { color: var(--aqh-auto); }
.aqh__key--h1   { color: var(--aqh-h1); }
.aqh__key--h2   { color: var(--aqh-h2); }
.aqh__key--h3   { color: var(--aqh-h3); }

.aqh__table { margin: 16px 0 0; }

.aqh__summary {
    display: inline-block;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--surface-card-soft);
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    cursor: pointer;
}

.aqh__summary:hover,
.aqh__summary:focus-visible { color: var(--text-primary); }

.aqh__table[open] .aqh__summary { margin-bottom: 10px; }

/* La fila del total en el rótulo: no es una serie más, es la suma de las de arriba. */
.aqg__tip-row--sum {
    margin-top: 5px;
    padding-top: 5px;
    background: linear-gradient(var(--alpha-white-06), var(--alpha-white-06)) top left / 100% 1px no-repeat;
    color: var(--text-primary);
    font-weight: 600;
}

/* Las series del desglose dentro del rótulo: sangradas y algo más tenues, para que se lean como
   partes de lo consumido y no como cosas independientes. */
.aqg__tip-row--part {
    padding-left: 10px;
    opacity: 0.85;
}

/* necROmantic 2026-08-07 (usuario): condición que la habilidad trae DE FÁBRICA.
   Se distingue de las añadidas a mano porque no lleva × y porque el servidor la mira siempre:
   un borde tenue basta para decir "esto no es opcional" sin gritarlo. El padding derecho
   compensa el hueco que dejaba el botón que no está. */
.cskl__c--fija-skill {
    border-color: var(--alpha-gold-12, rgba(201,160,255,0.22));
    padding-right: 8px;
}

/* necROmantic 2026-08-08: aviso de "este objeto no tiene reglas propias". No es un error del
   jugador, es una explicación de por qué el interruptor está bloqueado, así que va en tono neutro
   y no en rojo. */
.cskl__nocore {
    margin: 0 0 8px;
    font-size: 0.78rem;
    opacity: 0.8;
}

/* necROmantic 2026-08-11: la NORMA BÁSICA que el servidor aplica a una tarjeta encendida y sin
   condiciones. Mismo tono neutro y mismo tamaño que .cskl__nocore porque son la misma clase de
   mensaje -- "esto no hace lo que parece que hace" --, y la diferencia entre las dos es de grado:
   aquélla explica un interruptor bloqueado y ésta, uno que sí funciona pero con una regla puesta
   por encima. El borde de la izquierda es lo único que la separa del texto de al lado; el medio
   tono se lo pone `cskl--apagado`, que ya lleva puesta desde el JS. */
.cskl__basica {
    margin: 0 0 8px;
    padding-left: 8px;
    font-size: 0.78rem;
    opacity: 0.8;
    border-left: 2px solid var(--alpha-gold-12, rgba(201,160,255,0.22));
}
.cskl__lv--none { opacity: 0.7; font-style: italic; }

/* ── Evoluciones de mascota (/especificaciones/, apartado "Evoluciones") ──────
   Una tarjeta por evolucion: el par "de que sale -> en que se convierte" arriba
   y los materiales debajo.

   Nada de <figure>/<figcaption> en el marcado, por lo mismo que .na-figure: la
   salida pasa por tidy (OutputCleanHTML) y no esta comprobado que los respete.

   Las imagenes llevan doble clase (`.na .evo__img`) por la misma razon que
   .na-mob: modern.css se carga DESPUES con `.news-slide__body img { height:auto }`
   y con la misma especificidad le ganaria a la altura de aqui. */
.evo {
    margin: 0 0 14px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-card-soft);
}

.evo__pair {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-bottom: 12px;
}

.evo__side {
    min-width: 0;
    text-align: center;
}

.na .evo__img {
    display: block;
    margin: 0 auto 6px;
    width: 64px;
    height: 64px;
    object-fit: contain;
    object-position: bottom center;
    /* Los gifs de monstruo son pixel art a tamano original: sin esto el navegador
       los interpola y quedan borrosos. */
    image-rendering: pixelated;
}

.evo__name {
    display: block;
    color: var(--text-heading2);
    font-weight: 700;
    font-size: 0.95em;
}

.evo__arrow {
    flex: 0 0 auto;
    color: var(--gold);
    font-size: 1.5em;
    line-height: 1;
}

/* Los materiales: lista sin vinetas que fluye en varias lineas. */
.evo__mats {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Mismo motivo que en .rcp__mats: sin esto, `.na li { margin-bottom: 10px }`
   deja la ultima pastilla de cada fila descuadrada. */
.evo__mats li { margin: 0; }

.evo__mat {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 6px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    font-size: 0.9em;
}

.na .evo__icon {
    display: block;
    width: 24px;
    height: 24px;
    image-rendering: pixelated;
}

.evo__matqty {
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* En movil el par no cabe en una linea con las dos criaturas y la flecha; antes
   de que las imagenes empiecen a encogerse, la flecha pasa a apuntar hacia abajo
   y el par se apila. */
@media (max-width: 460px) {
    .evo__pair {
        flex-direction: column;
        gap: 6px;
    }
    .evo__arrow {
        transform: rotate(90deg);
    }
}

/* ── Censo de mascotas (/especificaciones/, apartado "Mascotas") ──────────────
   Tabla de 127 filas con imagen. Es el primer <table> del catalogo: se compone
   con thead/tbody normales, que tidy respeta sin problema (lo que no esta
   comprobado son los elementos HTML5 tipo <figure>, ver .na-figure).

   El envoltorio con scroll propio es obligatorio: siete columnas no caben en un
   movil y sin el la pagina entera se desplazaria de lado. */
.petg__wrap {
    margin: 18px 0;
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: 12px;
}

.petg {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92em;
}

.petg th,
.petg td {
    padding: 7px 10px;
    text-align: left;
    border-bottom: 1px solid var(--border-light);
    white-space: nowrap;
}

.petg thead th {
    position: sticky;
    top: 0;
    background: var(--surface-card-strong);
    color: var(--gold);
    font-weight: 700;
}

.petg tbody tr:last-child td { border-bottom: 0; }

/* La columna de la imagen: estrecha y centrada, para que el nombre mande. */
.petg__c {
    width: 56px;
    text-align: center;
}

.na .petg__img {
    display: block;
    margin: 0 auto;
    width: 48px;
    height: 48px;
    object-fit: contain;
    image-rendering: pixelated;
}

/* Numeros alineados a la derecha y con cifras de ancho fijo: asi las columnas
   de vida y ataque se leen de un vistazo en vertical. */
.petg__n {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.petg__cd {
    color: var(--text-muted);
    font-size: 0.85em;
}

/* ── Tarjeta de receta (/especificaciones/: apartados "Alquimia" y "Herrería") ─
   necROmantic 2026-08-10.

   Se llamaba `.alq` cuando solo la usaba alquimia; al entrar las 59 recetas de
   herrería pasó a `.rcp`, que es lo que es: una receta, venga de un caldero o
   de un yunque.

   Tres usos con el mismo lenguaje visual: la tarjeta de receta (qué sale
   arriba, qué entra debajo), el listado del Alchemist Supplier —la misma
   pastilla de material con el precio en lugar de la cantidad— y las fichas de
   arma forjable, que añaden una línea de requisitos (`.rcp__req`).

   Se calca a propósito el tratamiento de .evo (las evoluciones de mascota):
   están en la misma página y separadas por dos apartados, así que si una
   llevara caja y la otra no, se leería como un fallo.

   Las imágenes llevan doble clase (`.na .rcp__icon`) por lo mismo que .evo__img
   y .na-mob: modern.css se carga DESPUÉS con `.news-slide__body img { height:
   auto }` y con la misma especificidad le ganaría a la altura de aquí.

   Nada de `title=` en los enlaces: el unitip del tema viejo se engancha a
   CUALQUIER elemento con ese atributo. Lo que importe va visible. */
.rcp {
    margin: 0 0 14px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-card-soft);
}

/* Encabezado de familia ("Pociones de vida", "Botellas de combate"...). Es un
   <p> y no un <h4> a propósito: el cuerpo de una especificación ya vive dentro
   de la jerarquía de encabezados de la página y colar otro nivel rompería el
   índice del lector de pantalla. */
.rcp__group {
    margin: 26px 0 10px;
    color: var(--gold);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.rcp__group:first-child { margin-top: 4px; }

.rcp__out { margin: 0 0 10px; }

/* El color y el subrayado los pone la regla global de <a>, así que el nombre
   solo cambia de peso y de tamaño: si le pusiera color propio, el hover del
   enlace dejaría de verse en el texto. */
.rcp__link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.na .rcp__icon {
    display: block;
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    image-rendering: pixelated;
}

/* Los iconos del cliente son de 24x24 clavados. El del producto se amplia al
   DOBLE exacto y no a 1,5x: a escala no entera el pixel art queda con los
   pixeles de tamano desigual (misma cuenta que .na-mobs). */
.na .rcp__icon--out {
    width: 48px;
    height: 48px;
}

.rcp__name {
    font-weight: 700;
    font-size: 1.05em;
}

/* Linea de requisitos de las armas forjables: nivel del arma y nivel de la
   habilidad. Va entre el producto y los materiales porque decide si la receta
   te aparece siquiera en la lista, o sea que pesa mas que los materiales. */
.rcp__req {
    margin: 0 0 10px;
    color: var(--text-muted);
    font-size: 0.88em;
}

.rcp__req-k { color: var(--text-heading2); font-weight: 600; }
.rcp__req-sep { margin: 0 4px; color: var(--alpha-silver-42); }

.rcp__mats {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Obligatorio, no cosmetico: `.na li` pone `margin-bottom: 10px` a todos los
   <li> del contenido editorial y `:last-child` se lo quita al ultimo. En una
   fila flexible con align-items: stretch eso deja la ultima pastilla mas alta
   que las demas y con el texto 5px mas abajo — se ve escalonado. */
.rcp__mats li { margin: 0; }

.rcp__mat {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 6px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    font-size: 0.9em;
}

.rcp__matname { min-width: 0; }

.rcp__qty {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* La guía no se consume: se lleva encima y ya. Lleva etiqueta en vez de
   cantidad y fondo propio para que no se lea como un material más. */
.rcp__mat--guide { background: var(--alpha-gold-08); }

.rcp__qty--carry {
    color: var(--gold);
    font-size: 0.92em;
}

.rcp__bonus {
    margin: 10px 0 0;
    color: var(--text-muted);
    font-size: 0.88em;
}

.rcp__bonus-key {
    margin-right: 6px;
    color: var(--gold);
    font-weight: 600;
}

/* El listado de la tienda son 56 pastillas de ancho muy desigual: en una fila
   flexible quedarían escalonadas y el precio de cada una caería en un sitio
   distinto. En rejilla las columnas se alinean y el precio queda clavado a la
   derecha de su pastilla. */
.rcp__mats--shop {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    margin-bottom: 6px;
}

.rcp__mats--shop .rcp__mat { justify-content: space-between; }
.rcp__mats--shop .rcp__link { flex: 1 1 auto; }

/* Por debajo de ~460px la pastilla de un material con nombre largo ya no cabe
   junto a su cantidad sin partir la palabra. Una por línea antes que eso. */
@media (max-width: 460px) {
    .rcp__mats--shop { grid-template-columns: 1fr; }
    .rcp { padding: 12px 12px; }
}

/* ── Mapa de fabricación (/especificaciones/, apartado "Fabricación") ─────────
   necROmantic 2026-08-10. Quién fabrica qué, en una tabla de cinco columnas.

   Se parece a `.petg` (el censo de mascotas) a propósito, pero con una
   diferencia importante: aquí el texto SÍ se parte. `.petg` usa `nowrap` porque
   sus celdas son nombres cortos y cifras; estas llevan frases, y con `nowrap`
   la tabla se iría a más del doble del ancho de la página y todo el mundo
   tendría que arrastrarla de lado para leer la columna de la derecha.

   El envoltorio con scroll propio se queda igualmente: en un móvil cinco
   columnas no caben ni partiendo, y sin él se desplazaría la página entera.

   necROmantic 2026-08-17: la tabla de los sets Ur y Peuz (apartado "Contenido")
   reutiliza este componente tal cual. Nació para "Fabricación", pero es la tabla
   de datos de /especificaciones/: si haces otra de cinco columnas con frases
   dentro, usa `.fab` en vez de duplicar estas reglas con otro nombre. */
.fab__wrap {
    margin: 18px 0;
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: 12px;
}

.fab {
    width: 100%;
    min-width: 640px;
    border-collapse: collapse;
    font-size: 0.92em;
}

.fab th,
.fab td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--border-light);
}

.fab thead th {
    background: var(--surface-card-strong);
    color: var(--gold);
    font-weight: 700;
    white-space: nowrap;
}

.fab tbody tr:last-child td { border-bottom: 0; }

/* El nombre de la habilidad y la forma de abrirla son datos de apoyo: se
   apagan un punto para que la vista caiga en el oficio y en qué fabrica. */
.fab__sk,
.fab__how { color: var(--text-muted); }

.fab__n {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* =================================================================================================
   SIMULADOR DE PERSONAJES  (/simulador/)
   necROmantic 2026-08-10. Ver PLAN_SIMULADOR_20260810.md.

   Sin bordes, como el resto del sitio: la separacion entre piezas la hace el fondo, no una linea.
   Todo el color sale de los tokens de arriba; aqui no hay ni un valor hexadecimal suelto.
   ================================================================================================= */

.sim { display: block; }

.sim--oculto { display: none !important; }

.sim__head { margin-bottom: 1.75rem; }
.sim__eyebrow {
    margin: 0 0 .35rem; font-size: .8125rem; letter-spacing: .08em;
    text-transform: uppercase; color: var(--gold-dim);
}
.sim__title { margin: 0 0 .5rem; color: var(--text-heading2); }
.sim__lead { margin: 0 0 .5rem; max-width: 62ch; color: var(--text-muted); }
.sim__sello-datos { margin: 0; font-size: .8125rem; color: var(--gold-dim); }

.sim__error {
    margin: 0 0 1rem; padding: .85rem 1rem; border-radius: .5rem;
    background: var(--crimson); color: var(--text-primary);
}
.sim__error-detalle { opacity: .75; font-size: .875rem; }

.sim__anuncio { margin: 0 0 1rem; color: var(--accent-purple); min-height: 1.25rem; }

/* --- rejilla principal -------------------------------------------------------------------- */
.sim__cuerpo {
    display: grid; gap: 1.25rem; align-items: start;
    grid-template-columns: minmax(15rem, 1fr) minmax(18rem, 1.35fr) minmax(15rem, 1fr);
}
@media (max-width: 60rem) { .sim__cuerpo { grid-template-columns: 1fr; } }

.sim__panel {
    background: var(--bg-surface); border-radius: .6rem; padding: 1.1rem 1.15rem;
}
.sim__panel--habilidades { margin-top: 1.25rem; }
.sim__panel-titulo {
    margin: 0 0 .9rem; font-size: 1rem; color: var(--text-heading);
    letter-spacing: .02em;
}

/* --- campos ------------------------------------------------------------------------------- */
.sim__campo { margin-bottom: .75rem; }
.sim__campo--doble { display: flex; gap: .75rem; }
.sim__campo-par { flex: 1 1 0; display: block; }
.sim__campo-nombre {
    display: block; margin-bottom: .25rem; font-size: .8125rem; color: var(--text-muted);
}
.sim__select, .sim__numero, .sim__buscar,
.sim__ranura-buscar, .sim__carta-buscar, .sim__stat-val, .sim__refino, .sim__nivel {
    background: var(--bg-input); color: var(--text-primary);
    border: 0; border-radius: .35rem; padding: .4rem .55rem; font: inherit; width: 100%;
}
.sim__numero, .sim__stat-val, .sim__refino, .sim__nivel { text-align: center; }
.sim__refino { width: 3.25rem; }
.sim__nivel { width: 3.5rem; }

/* necROmantic 2026-08-12 (pedido del usuario): el nivel de habilidad se sube y se baja con SUS
   botones, no con las flechitas del campo numerico. El navegador las pinta DENTRO de un campo de
   3,5rem, asi que quedaban pegadas a la cifra y a un dedo de los botones de verdad: dos controles
   para lo mismo, uno de ellos diminuto.
   El campo sigue siendo `type=number` -- teclado numerico en el movil y validacion de min/max --,
   solo pierde la ruedecita. Se sigue pudiendo teclear el numero, que es el tercer camino que ya
   contempla `ponerNivel()`. */
.sim__nivel::-webkit-outer-spin-button,
.sim__nivel::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.sim__nivel { -moz-appearance: textfield; appearance: textfield; }

.sim__boton {
    background: var(--bg-surface-alt); color: var(--text-primary);
    border: 0; border-radius: .35rem; padding: .45rem .9rem; font: inherit; cursor: pointer;
}
.sim__boton:hover { background: var(--bg-sidebar-head); color: var(--accent-purple-h); }

.sim__importar {
    margin-bottom: 1rem; padding-bottom: 1rem; background: var(--bg-surface-alt);
    border-radius: .45rem; padding: .75rem .8rem;
}
.sim__importar .sim__boton { margin-top: .5rem; }

/* --- stats -------------------------------------------------------------------------------- */
.sim__stats { margin-top: 1rem; }
.sim__stat {
    display: grid;
    /* nombre · − · valor · + · oficio · equipo · total · coste */
    grid-template-columns: 2.75rem 1.6rem minmax(2.75rem, 1fr) 1.6rem 1.9rem 1.9rem 2.4rem 2.2rem;
    gap: .3rem; align-items: center; margin-bottom: .4rem;
}
.sim__stat-job   { font-size: .75rem; color: var(--gold-dim);      text-align: right; }
.sim__stat-extra { font-size: .75rem; color: var(--accent-purple); text-align: right; }
.sim__stat-total { font-size: .9375rem; color: var(--text-primary); text-align: right; }
.sim__stat-total--sube { color: var(--gold); }
.sim__stat-nombre { font-size: .8125rem; color: var(--text-muted); }
.sim__stat-btn {
    background: var(--bg-surface-alt); color: var(--text-primary); border: 0;
    border-radius: .3rem; cursor: pointer; padding: .3rem 0; line-height: 1;
}
.sim__stat-btn:hover { background: var(--bg-sidebar-head); color: var(--accent-purple-h); }
.sim__stat-coste { font-size: .75rem; color: var(--gold-dim); text-align: right; }

.sim__puntos { margin: .75rem 0 0; font-size: .8125rem; color: var(--text-muted); }
.sim__puntos--pasado { color: var(--accent-red-h); background: var(--crimson);
    border-radius: .3rem; padding: .25rem .5rem; }

/* --- equipo ------------------------------------------------------------------------------- */
.sim__ranura { position: relative; margin-bottom: .7rem; }
.sim__ranura-nombre {
    display: block; font-size: .75rem; color: var(--text-muted); margin-bottom: .2rem;
}
.sim__puesto { margin-top: .35rem; }
.sim__puesto-linea { display: flex; align-items: center; gap: .35rem; }
.sim__puesto-nombre { color: var(--gold); font-size: .875rem; flex: 1 1 auto; }
.sim__refino-signo { color: var(--text-muted); }
.sim__quitar {
    background: none; border: 0; color: var(--text-muted); cursor: pointer;
    font-size: 1.1rem; line-height: 1; padding: 0 .25rem;
}
.sim__quitar:hover { color: var(--accent-red-h); }

.sim__carta {
    display: flex; align-items: center; gap: .35rem;
    margin: .25rem 0 0 1rem; position: relative;
}
.sim__carta-puesta { font-size: .8125rem; color: var(--accent-purple); flex: 1 1 auto; }

/* --- sugerencias -------------------------------------------------------------------------- */
.sim__sugerencias {
    position: absolute; z-index: 20; left: 0; right: 0; max-height: 17rem; overflow-y: auto;
    background: var(--bg-sidebar); border-radius: .35rem;
}
.sim__sugerencias:empty { display: none; }
.sim__sugerencia {
    display: block; width: 100%; text-align: left; background: none; border: 0;
    color: var(--text-primary); cursor: pointer; padding: .4rem .6rem; font: inherit;
}
.sim__sugerencia:hover { background: var(--bg-sidebar-head); }
.sim__sugerencia-nombre { display: block; font-size: .875rem; }
.sim__sugerencia-det { display: block; font-size: .75rem; color: var(--text-muted); }
.sim__sugerencia-vacia { margin: 0; padding: .5rem .6rem; font-size: .8125rem;
    color: var(--text-muted); }

/* --- avisos ------------------------------------------------------------------------------- */
.sim__avisos { margin-top: 1rem; }
.sim__aviso { background: var(--bg-surface-alt); border-radius: .4rem; padding: .5rem .65rem; }
.sim__aviso-titulo { cursor: pointer; font-size: .8125rem; color: var(--gold-dim); }
.sim__aviso-lista { margin: .5rem 0 0; padding-left: 1rem; }
.sim__aviso-item { margin-bottom: .45rem; font-size: .75rem; }
.sim__aviso-objeto { display: block; color: var(--gold); }
.sim__aviso-trozo {
    display: block; color: var(--text-primary); background: var(--bg-sidebar);
    border-radius: .25rem; padding: .15rem .35rem; margin: .15rem 0; word-break: break-word;
}
.sim__aviso-motivo { color: var(--text-muted); }

/* --- ficha -------------------------------------------------------------------------------- */
.sim__grupo { margin-bottom: 1rem; }
.sim__grupo-titulo {
    margin: 0 0 .4rem; font-size: .75rem; text-transform: uppercase; letter-spacing: .07em;
    color: var(--gold-dim);
}
.sim__valores { display: grid; grid-template-columns: auto 1fr; gap: .15rem .75rem; margin: 0; }
.sim__valor-nombre { font-size: .8125rem; color: var(--text-muted); margin: 0; }
.sim__valor-dato { font-size: .8125rem; color: var(--text-primary); margin: 0; text-align: right; }

/* --- objetivo y tabla --------------------------------------------------------------------- */
.sim__objetivo { position: relative; max-width: 30rem; margin-bottom: 1.1rem; }
.sim__nota { margin: .4rem 0 0; font-size: .75rem; color: var(--text-muted); }

.sim__habilidades { overflow-x: auto; }
.sim__tabla { width: 100%; border-collapse: collapse; font-size: .8125rem; }
.sim__tabla th {
    background: var(--bg-table-head); color: var(--text-heading); text-align: left;
    padding: .45rem .6rem; font-weight: 600; white-space: nowrap;
}
.sim__tabla td { padding: .4rem .6rem; background: var(--bg-table-row); vertical-align: top; }
.sim__tabla tr:nth-child(even) td { background: var(--bg-table-alt); }
/* Los estados de fila van con el selector completo (`.sim__tabla tr.estado td`) porque el rayado
   de las filas pares -- `.sim__tabla tr:nth-child(even) td` -- tiene mas especificidad que un
   `.estado td` a secas y se los comia. El fondo rojo de las ilegales no se veia en la mitad de
   las filas, y el resaltado de las letales tampoco. */
.sim__tabla tr.sim__fila--letal td { background: var(--bg-sidebar-head); }

.sim__hab-nombre { display: block; color: var(--text-primary); }
.sim__hab-const { display: block; font-size: .6875rem; color: var(--text-muted); }
.sim__cel-num { text-align: right; white-space: nowrap; }
.sim__cel-dano { white-space: nowrap; }
.sim__dano { color: var(--gold); font-size: .9375rem; }
.sim__dano-rango { display: block; font-size: .6875rem; color: var(--text-muted); }
.sim__ele { display: block; font-size: .6875rem; color: var(--accent-purple); }
.sim__matar { display: block; font-size: .6875rem; color: var(--text-muted); }
.sim__sin-dato { color: var(--text-muted); }

.sim__sello {
    display: inline-block; padding: .1rem .4rem; border-radius: .25rem;
    font-size: .6875rem; white-space: nowrap;
}
.sim__sello--exacta  { background: var(--bg-sidebar-head); color: var(--accent-purple-h); }
.sim__sello--parcial { background: var(--bg-surface-alt);  color: var(--gold); }
.sim__sello--ninguna { background: var(--crimson);         color: var(--accent-red-h); }

.sim__vacio { color: var(--text-muted); }
.sim__limites {
    margin: 1.25rem 0 0; font-size: .75rem; color: var(--text-muted); max-width: 80ch;
}

/* --- simulador: arbol de habilidades por clase (necROmantic 2026-08-10) ------------------------
   La franja separa las habilidades por la clase de la que vienen, y lleva el nivel de oficio de
   ESA clase. El icono no es decoracion: es el boton de subir nivel, asi que se comporta como tal
   (foco visible, cursor, estado desactivado al llegar al maximo).                              */

.sim__franja {
    display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
    margin: 1.25rem 0 .35rem; padding: .5rem .7rem;
    background: var(--bg-sidebar-head); border-radius: .4rem;
}
.sim__franja:first-child { margin-top: 0; }
.sim__franja-clase {
    margin: 0; font-size: .875rem; color: var(--text-heading2);
    letter-spacing: .04em; text-transform: uppercase; flex: 1 1 auto;
}
.sim__franja-job { display: flex; align-items: center; gap: .4rem; }
.sim__franja-job-nombre { font-size: .75rem; color: var(--text-muted); }
.sim__franja-job-val {
    width: 3.5rem; text-align: center; background: var(--bg-input); color: var(--text-primary);
    border: 0; border-radius: .3rem; padding: .25rem .35rem; font: inherit;
}
.sim__franja-puntos { font-size: .75rem; color: var(--gold-dim); }
.sim__franja-puntos--pasado { color: var(--accent-red-h); }

.sim__puntos-skill { margin: .9rem 0 0; font-size: .8125rem; color: var(--text-muted); }

/* El icono como boton */
.sim__icono-btn {
    background: none; border: 0; padding: 0; cursor: pointer; line-height: 0;
    border-radius: .25rem; flex: 0 0 auto;
}
.sim__icono-btn:disabled { cursor: default; opacity: .45; }
.sim__icono-btn:not(:disabled):hover { background: var(--bg-surface-alt); }
.sim__icono-btn:focus-visible { outline: 2px solid var(--accent-purple); outline-offset: 1px; }
.sim__icono { width: 24px; height: 24px; display: block; image-rendering: pixelated; }
.sim__icono--falta { visibility: hidden; }

.sim__hab-linea { display: flex; align-items: center; gap: .5rem; }
.sim__hab-texto { min-width: 0; }

.sim__cel-nivel { white-space: nowrap; }
.sim__bajar {
    background: var(--bg-surface-alt); color: var(--text-primary); border: 0;
    border-radius: .25rem; cursor: pointer; padding: .1rem .35rem; line-height: 1;
    font: inherit; vertical-align: middle;
}
.sim__bajar:disabled { opacity: .35; cursor: default; }
.sim__bajar:not(:disabled):hover { background: var(--bg-sidebar-head); color: var(--accent-purple-h); }
.sim__cel-nivel .sim__nivel { width: 3rem; display: inline-block; vertical-align: middle; }
.sim__nivel-max { font-size: .6875rem; color: var(--text-muted); }

.sim__fila--sin-aprender .sim__hab-nombre { color: var(--text-muted); }
.sim__cel-sin-aprender { color: var(--text-muted); font-size: .75rem; }

/* Las tres tablas del arbol (una por clase) son tablas SEPARADAS, asi que cada una se dimensiona
   por su cuenta y las columnas bailan de una franja a otra. Con el ancho fijado se leen como una
   sola tabla partida, que es lo que son. */
.sim__tabla { table-layout: fixed; }
.sim__tabla th:nth-child(1), .sim__tabla td:nth-child(1) { width: 26%; }
.sim__tabla th:nth-child(2), .sim__tabla td:nth-child(2) { width: 11%; }
.sim__tabla th:nth-child(3), .sim__tabla td:nth-child(3) { width: 15%; }
.sim__tabla th:nth-child(4), .sim__tabla td:nth-child(4) { width: 7%; }
.sim__tabla th:nth-child(5), .sim__tabla td:nth-child(5) { width: 7%; }
.sim__tabla th:nth-child(6), .sim__tabla td:nth-child(6) { width: 9%; }
.sim__tabla th:nth-child(7), .sim__tabla td:nth-child(7) { width: 9%; }
.sim__tabla th:nth-child(8), .sim__tabla td:nth-child(8) { width: 8%; }
.sim__tabla th:nth-child(9), .sim__tabla td:nth-child(9) { width: 8%; }
.sim__hab-const { overflow-wrap: anywhere; }

/* --- simulador: puntos restantes, guia de colocacion e iconos de objeto (2026-08-10) ---------- */

.sim__puntos-n { font-size: 1.5rem; color: var(--gold); line-height: 1; }
.sim__puntos-txt { color: var(--text-muted); }
.sim__puntos--pasado .sim__puntos-n { color: var(--accent-red-h); }
/* De donde salen unos puntos que no cuadran con la tabla por nivel (2026-08-12). Un punto por
   debajo del texto que acompana: es una nota al pie, no parte de la cifra. */
.sim__puntos-nota { color: var(--text-code); font-size: .9375em; }

.sim__stat-coste--nollega { color: var(--accent-red); }
.sim__stat-coste--tope { color: var(--accent-purple); }
.sim__stat-btn:disabled { opacity: .35; cursor: default; }

.sim__franja-libres {
    background: var(--gold-dim); color: var(--bg-body);
    border-radius: .25rem; padding: .1rem .45rem; font-size: .75rem;
}

/* La fila donde cabe un punto. El borde-izquierdo es la unica "linea" de todo el simulador, y va
   aqui a proposito: es una senal que hay que poder seguir con el ojo bajando por la tabla. */
.sim__tabla tr.sim__fila--cabe td:first-child { box-shadow: inset 3px 0 0 var(--accent-purple); }
.sim__cabe { color: var(--accent-purple); }
.sim__no-cabe { color: var(--gold-dim); }
.sim__no-cabe-suave { color: var(--text-muted); }

/* Iconos de objeto */
.sim__item-icono {
    width: 24px; height: 24px; flex: 0 0 auto; object-fit: contain;
    image-rendering: pixelated; vertical-align: middle;
}
.sim__item-icono--falta { visibility: hidden; }
.sim__sugerencia--item { display: flex; align-items: center; gap: .5rem; }
.sim__sugerencia-texto { min-width: 0; flex: 1 1 auto; }
.sim__del-equipo { display: block; font-size: .6875rem; color: var(--gold-dim); }
.sim__franja--actual { background: var(--bg-sidebar-head); box-shadow: inset 3px 0 0 var(--gold); }
.sim__franja-actual { font-size: .6875rem; color: var(--gold); }
/* --- habilidades ILEGALES ---------------------------------------------------------------------
   Una habilidad puesta que ha dejado de cumplir sus requisitos: al bajar la que le servia de base,
   o al bajar el nivel de oficio despues de repartir.

   Tiene estilo PROPIO, y a proposito no es el `--crimson` que ya usa el resto del panel para los
   errores: eso es un rojo vinoso que aqui se confundiria con el subrayado de una fila normal. Es
   un rojo muy oscuro, casi negro, para que una build rota se vea de un vistazo al pasar la vista
   por la tabla sin tener que leer nada. */
.sim {
    --sim-ilegal-bg:    #2e0a10;
    --sim-ilegal-borde: #7a1524;
    --sim-ilegal-txt:   #e88b98;
}

.sim__tabla tr.sim__fila--rota td { background: var(--sim-ilegal-bg); }
.sim__tabla tr.sim__fila--rota td:first-child { box-shadow: inset 3px 0 0 var(--sim-ilegal-borde); }
.sim__fila--rota .sim__hab-nombre { color: var(--sim-ilegal-txt); text-decoration: line-through; }
.sim__fila--rota .sim__icono { filter: grayscale(1) brightness(.6); }
.sim__hab-rota { display: block; font-size: .6875rem; color: var(--sim-ilegal-txt); }
.sim__rotas {
    margin: .5rem 0 0; padding: .35rem .6rem; border-radius: .3rem;
    background: var(--sim-ilegal-bg); color: var(--sim-ilegal-txt); font-size: .8125rem;
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-25 — /woe/: la zona horaria del servidor y la tabla de husos
   ══════════════════════════════════════════════════════════════
   La pagina daba la hora del servidor sin decir de que zona era. Ahora la cabecera lleva la
   abreviatura (CEST) y el desfase (UTC+02:00), y debajo del horario va la tabla con la hora
   que es en cada pais de America Latina.
   La tabla se pinta con la parrilla de la propia celda y no con anchos fijos: los nombres de
   los paises cambian de largo entre castellano e ingles ("Republica Dominicana" / "Dominican
   Republic") y un ancho en px descuadraria una de las dos versiones.
   ══════════════════════════════════════════════════════════════ */

.acchead__tz {
    margin-left: 4px;
    font-style: normal;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--accent-purple);
}

/* El identificador completo de la zona (Europe/Madrid) va en monoespaciada: es un dato para
   copiar tal cual en un conversor, no una frase que se lea. */
.woe__tzid {
    display: inline-block;
    padding: 1px 7px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.woetz { margin: 26px 0 0; }

.woetz__title {
    margin: 0 0 4px;
    font-size: 1.05rem;
    color: var(--text-heading2);
}

.woetz__lead,
.woetz__foot {
    margin: 0 0 14px;
    font-size: 0.9rem;
    line-height: 1.65;
    color: var(--text-muted);
}

.woetz__foot { margin: 12px 0 0; }

/* La tabla se desplaza dentro de su caja: en un movil el ancho de tres columnas con varios
   paises en la primera no cabe, y sin esto la pagina entera se iria de lado. */
.woetz__wrap {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    box-shadow: 0 8px 20px var(--alpha-black-24);
}

.woetz__table {
    width: 100%;
    border-collapse: collapse;
}

.woetz__th {
    padding: 11px 16px;
    border-bottom: 1px solid var(--border);
    text-align: left;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
}

.woetz__th--time,
.woetz__th--diff { text-align: right; }

.woetz__row td {
    padding: 11px 16px;
    border-top: 1px solid var(--border);
    vertical-align: top;
}

.woetz__table tbody tr:first-child td { border-top: 0; }

/* La fila del servidor no se enseña "distinta por bonita": es la referencia de todas las
   demas, y se marca con la misma barra lateral que el resto del panel usa para "aqui estas". */
.woetz__row--server td { background: var(--bg-sidebar-head); }
.woetz__row--server td:first-child { box-shadow: inset 3px 0 0 var(--accent-purple); }

.woetz__countries {
    display: table-cell;
    font-size: 0.88rem;
    line-height: 1.7;
    color: var(--text-primary);
}

/* Los paises de un mismo huso van seguidos y separados por un punto medio puesto por CSS: en
   el HTML son elementos sueltos, asi que el separador no se cuela al copiar la fila. */
.woetz__country + .woetz__country::before {
    content: "·";
    margin: 0 6px;
    color: var(--text-muted);
}

.woetz__time,
.woetz__diff {
    text-align: right;
    white-space: nowrap;
}

.woetz__time b {
    display: block;
    font-size: 1.12rem;
    font-weight: 700;
    color: var(--text-heading2);
}

.woetz__shift,
.woetz__utc {
    display: block;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.woetz__shift { color: var(--gold-dim); }

.woetz__diff b {
    font-size: 1rem;
    font-weight: 700;
    color: var(--accent-purple);
}

.woetz__mark,
.woetz__same {
    display: inline-block;
    padding: 2px 9px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.woetz__mark { color: var(--accent-purple); }

/* Un pais no se parte nunca: sin esto "El Salvador" y "Republica Dominicana" se rompen por
   el espacio y la lista se lee como si hubiera paises de mas. El punto separador va DENTRO
   del span, asi que viaja pegado al nombre que precede. */
.woetz__country { display: inline-block; white-space: nowrap; }

/* En movil la tabla deja de ser tabla: tres columnas con seis paises en la primera no caben
   en 390 px, y dejarla con desplazamiento lateral escondia justo la columna que se viene a
   mirar -- la diferencia horaria. Cada fila pasa a ser una ficha: paises arriba, y debajo la
   hora y la diferencia en la misma linea. */
@media (max-width: 620px) {
    .woetz__wrap { overflow-x: visible; }

    .woetz__table,
    .woetz__table tbody,
    .woetz__row,
    .woetz__row td { display: block; width: auto; }

    .woetz__table thead { display: none; }

    .woetz__row {
        padding: 12px 14px;
        border-top: 1px solid var(--border);
    }

    .woetz__table tbody tr:first-child { border-top: 0; }

    .woetz__row td {
        padding: 0;
        border-top: 0;
        background: none;
    }

    /* La marca de la fila del servidor pasa de la celda a la ficha entera: con las celdas
       en bloque, el fondo de la primera solo pintaba su propio alto. */
    .woetz__row--server { background: var(--bg-sidebar-head); box-shadow: inset 3px 0 0 var(--accent-purple); }
    .woetz__row--server td:first-child { box-shadow: none; }

    .woetz__countries { font-size: 0.86rem; }

    .woetz__time,
    .woetz__diff {
        text-align: left;
        white-space: normal;
    }

    .woetz__time {
        display: flex;
        align-items: baseline;
        flex-wrap: wrap;
        gap: 4px 10px;
        margin-top: 6px;
    }

    .woetz__time b { display: inline; font-size: 1.05rem; }
    .woetz__shift,
    .woetz__utc { display: inline; }

    .woetz__diff { margin-top: 6px; }
}

/* --- /woe/: elegir pais y ver la hora de cada asedio en la hora de alli --------------------
   Las cinco variantes de cada franja se pintan siempre y se esconden con `hidden`; el script
   solo destapa la que toca. Por eso las reglas que las tapan van DESPUES de las que les dan
   `display`: un elemento con `display` puesto ignora el atributo `hidden`, y eso ya mordio dos
   veces el mismo dia en este panel. */

.woepick {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
    margin: 0 0 16px;
    padding: 12px 16px;
    border: 1px solid var(--border);
    border-radius: 13px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
}

.woepick__label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.woepick__select {
    padding: 7px 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-body);
    font: inherit;
    font-size: 0.92rem;
    color: var(--text-primary);
    cursor: pointer;
}

.woepick__select:focus-visible {
    outline: 2px solid var(--accent-purple);
    outline-offset: 2px;
}

.woepick__hint {
    flex: 1 1 auto;
    font-size: 0.74rem;
    color: var(--text-muted);
}

.woe__mine {
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px dashed var(--border);
}

.woe__mine-label {
    display: block;
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.woe__mine-line {
    display: block;
    margin-top: 4px;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.woe__mine-line b { color: var(--accent-purple); }
.woe__mine-line i { font-style: normal; font-size: 0.74rem; color: var(--text-muted); }

/* El asedio que cae en otro dia de la semana en tu pais: es el dato por el que existe todo
   esto, asi que se ve, no se susurra. */
.woe__mine-shift {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--alpha-silver-08);
    font-style: normal;
    font-size: 0.7rem;
    color: var(--gold-dim);
}

/* Estas dos reglas van las ultimas a proposito: son las que hacen que `hidden` mande. */
.woe__mine[hidden],
.woe__mine-line[hidden] { display: none; }

@media (max-width: 620px) {
    .woepick { gap: 6px 10px; padding: 11px 13px; }
    .woepick__select { flex: 1 1 100%; }
    /* En movil la pista se va debajo del todo: al lado del desplegable no cabe sin partirse
       en tres lineas. */
    .woepick__hint { flex: 1 1 100%; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-25 — Cuota de automatizacion en "quien esta conectado" (.onl__aq)
   ══════════════════════════════════════════════════════════════
   Marcado en themes/necromantic/character/online.php, datos en
   modules/character/online.php (Necro\AutoQuota).

   Version compacta del medidor .aq de la ficha de cuenta: misma rampa dorada, mismos
   cortes de estado y el mismo criterio de que el relleno es lo que QUEDA, no lo gastado.
   Lo unico que se pierde por el camino es el detalle, que ahi no cabe: aqui van el
   porcentaje, lo que le queda y si tiene el autoplay encendido ahora mismo.

   El ancho del relleno viene de una clase .onl__aq-fill--pN en pasos de 5, no de un
   estilo en linea: en esta web no se usan ni para un ancho calculado.

   Solo la ve el staff (capacidad 'ViewOnlineAutoQuota'), asi que se permite ser densa:
   quien la mira sabe lo que esta mirando.
   ══════════════════════════════════════════════════════════════ */

:root {
    /* Verde de "esto esta pasando ahora mismo". No sale de la rampa dorada a proposito:
       el oro mide CUANTO queda y el verde dice SI esta corriendo, que son dos preguntas
       distintas y se leen mal si comparten color. */
    --onl-live:      #3fbf83;
    --onl-live-soft: rgba(63, 191, 131, 0.16);
    --onl-live-glow: rgba(63, 191, 131, 0.45);
}

.onl__aq {
    position: relative;
    padding: 8px 10px 7px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: linear-gradient(180deg, var(--alpha-black-22), var(--alpha-black-28));
}

/* Filo de color a la izquierda: es lo que da el golpe de vista al recorrer la lista, sin
   tener que leer ni un numero. */
.onl__aq::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    bottom: 8px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--aq-gold);
}

.onl__aq--warn::before  { background: var(--aq-amber); }
.onl__aq--low::before,
.onl__aq--empty::before { background: var(--aq-ember); }

/* --- Cabecera: etiqueta a la izquierda, interruptor a la derecha --- */

.onl__aq-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 4px 8px;
    margin: 0 0 6px;
}

.onl__aq-label {
    font-size: 0.64rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.onl__aq-flag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-white-03);
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;   /* partido en dos lineas ("Autoplay / activo") queda ridiculo */
    color: var(--text-muted);
    cursor: help;
}

.onl__aq-flag-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    opacity: 0.5;
}

/* Encendido: el unico elemento vivo de la ficha. El latido es lo que distingue "tiene el
   autoplay puesto" de "lo tuvo hace un rato", que es justo la pregunta que se hace quien
   abre esta pagina. */
.onl__aq--busy .onl__aq-flag {
    border-color: var(--onl-live);
    background: var(--onl-live-soft);
    color: var(--onl-live);
}

.onl__aq--busy .onl__aq-flag-dot {
    background: var(--onl-live);
    opacity: 1;
    box-shadow: 0 0 6px var(--onl-live-glow);
    animation: onl-aq-pulse 1.8s ease-in-out infinite;
}

@keyframes onl-aq-pulse {
    0%, 100% { transform: scale(1);    box-shadow: 0 0 6px var(--onl-live-glow); }
    50%      { transform: scale(1.35); box-shadow: 0 0 12px var(--onl-live-glow); }
}

/* --- El medidor --- */

.onl__aq-track {
    position: relative;
    height: 9px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: linear-gradient(180deg, var(--bg-body), var(--bg-input));
    box-shadow: inset 0 1px 4px var(--alpha-black-34);
    overflow: hidden;
}

/* Marcas cada cuarto. En la barra grande van cada 10%, pero con 9 px de alto y media
   ficha de ancho eso es una trama, no una escala. */
.onl__aq-ticks {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(
        90deg,
        transparent 0,
        transparent calc(25% - 1px),
        var(--alpha-white-07) calc(25% - 1px),
        var(--alpha-white-07) 25%
    );
}

.onl__aq-fill {
    position: relative;
    z-index: 1;
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(
        180deg,
        var(--aq-gold-light) 0%,
        var(--aq-gold) 45%,
        var(--aq-gold-mid) 70%,
        var(--aq-gold-deep) 100%
    );
    box-shadow: 0 0 10px var(--aq-gold-glow), inset 0 1px 0 rgba(255, 255, 255, 0.4);
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.onl__aq--warn .onl__aq-fill {
    background: linear-gradient(180deg, var(--aq-gold) 0%, var(--aq-amber) 60%, var(--aq-amber-deep) 100%);
}
.onl__aq--low .onl__aq-fill {
    background: linear-gradient(180deg, var(--aq-ember-light) 0%, var(--aq-ember) 55%, var(--aq-ember-deep) 100%);
    box-shadow: 0 0 10px rgba(184, 73, 42, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.onl__aq--empty .onl__aq-fill { background: none; box-shadow: none; }

/* El barrido de brillo SOLO corre con el autoplay encendido, y esa es la parte que
   significa algo: una barra que reluce es una barra que se esta vaciando en este momento.
   Quieta = el jugador esta ahi, pero no gasta. */
.onl__aq-fill::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    /* 'background-repeat: no-repeat' es obligatorio: el atajo 'background:' lo reinicia a
       'repeat' y con un tamano mayor que el elemento el degradado se TESELA, asi que
       entraria un segundo destello por detras del primero. Misma trampa que en .aq__fill. */
    background-image: linear-gradient(
        105deg,
        transparent 34%,
        rgba(255, 231, 199, 0.45) 50%,
        transparent 66%
    );
    background-repeat: no-repeat;
    background-size: 300% 100%;
    background-position: 100% 0;
    pointer-events: none;
}

.onl__aq--busy .onl__aq-fill::before { animation: aq-sweep 3.6s ease-in-out infinite; }
.onl__aq--empty .onl__aq-fill::before { background-image: none; animation: none; }

/* --- Pie: porcentaje, lo que queda y la concesion del dia --- */

.onl__aq-legend {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 7px;
    margin: 6px 0 0;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.onl__aq-pct {
    font-size: 0.86rem;
    font-weight: 700;
    line-height: 1;
    color: var(--aq-gold-light);
}

.onl__aq--warn .onl__aq-pct  { color: var(--aq-amber); }
.onl__aq--low .onl__aq-pct,
.onl__aq--empty .onl__aq-pct { color: var(--aq-ember-light); }

.onl__aq-time { color: var(--text-primary); }

/* La concesion diaria se va al final y en pequeno: es el contexto del porcentaje, no el
   dato que se viene a buscar. */
.onl__aq-total {
    margin-left: auto;
    font-size: 0.68rem;
    opacity: 0.75;
}

/* Anchos del relleno, en pasos de 5. Ver la nota de arriba sobre estilos en linea. */
.onl__aq-fill--p0   { width: 0;    box-shadow: none; }
.onl__aq-fill--p5   { width: 5%;   }
.onl__aq-fill--p10  { width: 10%;  }
.onl__aq-fill--p15  { width: 15%;  }
.onl__aq-fill--p20  { width: 20%;  }
.onl__aq-fill--p25  { width: 25%;  }
.onl__aq-fill--p30  { width: 30%;  }
.onl__aq-fill--p35  { width: 35%;  }
.onl__aq-fill--p40  { width: 40%;  }
.onl__aq-fill--p45  { width: 45%;  }
.onl__aq-fill--p50  { width: 50%;  }
.onl__aq-fill--p55  { width: 55%;  }
.onl__aq-fill--p60  { width: 60%;  }
.onl__aq-fill--p65  { width: 65%;  }
.onl__aq-fill--p70  { width: 70%;  }
.onl__aq-fill--p75  { width: 75%;  }
.onl__aq-fill--p80  { width: 80%;  }
.onl__aq-fill--p85  { width: 85%;  }
.onl__aq-fill--p90  { width: 90%;  }
.onl__aq-fill--p95  { width: 95%;  }
.onl__aq-fill--p100 { width: 100%; }

/* Quien pida menos animacion no ve ni el latido ni el barrido; el color y el ancho dicen
   lo mismo sin moverse. */
@media (prefers-reduced-motion: reduce) {
    .onl__aq--busy .onl__aq-flag-dot,
    .onl__aq--busy .onl__aq-fill::before { animation: none; }
    .onl__aq-fill { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   necROmantic 2026-08-25 — "quien esta conectado": barra apagada y ¿hay alguien al teclado?
   ══════════════════════════════════════════════════════════════
   Dos peticiones del usuario sobre el medidor de cuota (.onl__aq, de esta misma manana):

   1. Con el autoplay PARADO la barra sale en GRIS. El oro dice "esto se esta gastando ahora
      mismo"; parado no se gasta nada, y una barra dorada quieta invita a leer un consumo que
      no existe.

      Se griseа SOLO el relleno. El filo de color de la izquierda y el porcentaje se quedan con
      el color de su estado a proposito: son la otra pregunta -- a quien se le esta acabando la
      cuota --, y esa sigue valiendo con el autoplay parado. Si se griseara todo, "sin cuota" y
      "cuota llena" solo se distinguirian por el ancho del relleno.

   2. Si el jugador esta JUGANDO o AFK, en una pastilla al lado de la del autoplay. El dato
      viene de `#IDLE_AT` (Necro\Presence), y el veredicto lo da el motor: aqui no hay ningun
      umbral copiado.

   Las dos preguntas se leen a la vez y no comparten color: verde = automatizando, ambar =
   ausente, gris = ni una cosa ni la otra.
   ══════════════════════════════════════════════════════════════ */

:root {
    --onl-idle:       #767b87;
    --onl-idle-light: #9298a5;
    --onl-idle-deep:  #4d525c;
    --onl-away:       #d8a24a;
    --onl-away-soft:  rgba(216, 162, 74, 0.14);
}

/* La regla va DESPUES de las de estado y gana por especificidad (0,3,0 contra 0,2,0), asi que
   sirve para los cuatro estados sin repetir ninguno. El barrido de brillo ya estaba condicionado
   a --busy por su lado y no se toca. */
.onl__aq:not(.onl__aq--busy) .onl__aq-fill {
    background: linear-gradient(
        180deg,
        var(--onl-idle-light) 0%,
        var(--onl-idle) 55%,
        var(--onl-idle-deep) 100%
    );
    /* Sin resplandor: el halo es parte de lo que hace que el oro parezca encendido. */
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* Vacia y parada no pinta nada, igual que vacia y en marcha: --p0 lleva `box-shadow: none` a
   proposito y esta regla no debe devolverselo. */
.onl__aq:not(.onl__aq--busy) .onl__aq-fill--p0 { background: none; box-shadow: none; }
.onl__aq--empty:not(.onl__aq--busy) .onl__aq-fill { background: none; box-shadow: none; }

/* --- ¿Hay alguien al teclado? --- */

/* Las dos pastillas van juntas en un hueco propio: la cabecera reparte con space-between y
   sueltas se habrian separado a lo ancho, con la etiqueta en medio. */
.onl__aq-flags {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 6px;
}

.onl__aq-who {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 8px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--alpha-white-03);
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
    color: var(--text-muted);
    cursor: help;
}

.onl__aq-who-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    opacity: 0.5;
}

/* Jugando: punto lleno y texto claro, sin latido. El latido es del autoplay -- si latieran las
   dos pastillas, la ficha diria dos veces "esto esta vivo" sin decir cual de las dos cosas. */
.onl__aq-who--active {
    border-color: var(--alpha-white-08);
    color: var(--text-primary);
}

.onl__aq-who--active .onl__aq-who-dot {
    background: var(--text-primary);
    opacity: 1;
}

/* Ausente: ambar, que es el color de "atencion" del panel y no compite con el verde de
   "automatizando" -- las dos pastillas pueden estar encendidas a la vez, y de hecho el caso
   interesante es justo ese: la IA jugando sola con nadie delante. */
.onl__aq-who--afk {
    border-color: var(--onl-away);
    background: var(--onl-away-soft);
    color: var(--onl-away);
}

.onl__aq-who--afk .onl__aq-who-dot {
    background: none;
    border: 1px solid var(--onl-away);
    opacity: 1;
}

/* Sin señal: se ve que es un hueco, no un estado. El punto va vacio y la pastilla, apagada. */
.onl__aq-who--unknown {
    border-style: dashed;
    opacity: 0.7;
}

.onl__aq-who--unknown .onl__aq-who-dot {
    background: none;
    border: 1px dashed var(--text-muted);
}

.onl__aq-who-ago {
    font-style: normal;
    font-weight: 400;
    opacity: 0.85;
}

/* A 340 px las pastillas ya bajan a su propia linea; ahi el rato sobra antes que la palabra. */
@media (max-width: 360px) {
    .onl__aq-who-ago { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   PLEGABLES DE LA FICHA DE PERSONAJE  (.fold)     necROmantic 2026-08-26
   ──────────────────────────────────────────────────────────────────────────
   Peticion del usuario: "Asistencia automatica", "Acompanantes", "Inventario"
   y "Carro" nacen plegados y se abren al pulsar. El marcado es un <details>
   nativo (ver el porque en el comentario de la plantilla), asi que aqui NO hay
   ningun estado que simular: manda el atributo [open] del navegador.

   La cabecera hereda a proposito la marca de color de .sec-title -- la barrita
   morado->oro sobre la linea --, que es lo que separaba una seccion de otra
   antes de que fueran plegables. Al abrir, la barrita recorre la cabecera
   entera: es la unica pieza que dice "esto esta abierto" sin leer nada.

   NADA DE overflow:hidden en .fold. Dentro viven los menus de objeto
   (.ipol__pop), que son absolutos y se salen de su tarjeta; recortarlos habria
   dejado la mitad de los menus del inventario cortados por abajo.
   ══════════════════════════════════════════════════════════════════════════ */

.fold {
    margin: 34px 0 0;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-surface));
    transition: border-color .18s, box-shadow .18s;
}
.fold + .fold { margin-top: 18px; }
.fold[open] {
    border-color: var(--border-light);
    box-shadow: 0 12px 34px rgba(0, 0, 0, .34);
}

/* La seccion de Acompanantes ya trae su propio margen; el del plegado sobra. */
.elecare > .fold { margin: 0; }

/* ── Cabecera ─────────────────────────────────────────────────────────── */

.fold__head {
    position: relative;
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: .95rem 1.15rem;
    border-radius: 11px;
    cursor: pointer;
    list-style: none;
    -webkit-user-select: none;
    user-select: none;
    transition: background .18s;
}
/* El triangulito de serie sobra: ya hay un galon a la derecha. Hacen falta las
   dos reglas -- ::marker es lo estandar y ::-webkit-details-marker lo que
   entienden los Safari y los Chrome viejos. */
.fold__head::-webkit-details-marker { display: none; }
.fold__head::marker { content: ""; }
.fold__head:hover { background: var(--bg-table-alt); }
.fold__head:focus-visible { outline: 2px solid var(--accent-purple); outline-offset: -3px; }
.fold[open] .fold__head { border-radius: 11px 11px 0 0; }

/* La marca de .sec-title, que al abrir se estira de lado a lado. */
.fold__head::before {
    content: "";
    position: absolute;
    top: -1px;
    left: -1px;
    width: 56px;
    height: 3px;
    border-radius: 11px 0 2px 0;
    background: linear-gradient(90deg, var(--accent-purple), var(--gold));
    transition: width .32s cubic-bezier(.4, 0, .2, 1);
}
.fold[open] .fold__head::before {
    width: calc(100% + 2px);
    border-radius: 11px 11px 0 0;
}

.fold__mark {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 10px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    color: var(--accent-purple);
    font-size: 1.02rem;
    transition: color .18s, border-color .18s, background .18s;
}
.fold[open] .fold__mark {
    color: var(--gold);
    border-color: var(--border-accent);
    background: var(--bg-table-alt);
}

.fold__title {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 1.08rem;
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--text-heading2);
}
/* Una linea y con puntos suspensivos, como los subtextos del mosaico de la
   ficha de cuenta: si hace falta mas, va en el titulo, no aqui. */
.fold__sub {
    display: block;
    margin-top: .16rem;
    font-size: .82rem;
    font-weight: 400;
    line-height: 1.35;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* El dato en vivo (cuantos objetos, cuantos acompanantes, cuantos sistemas).
   Con la seccion cerrada es lo unico que dice si dentro hay algo. */
.fold__tag {
    flex: 0 0 auto;
    min-width: 2rem;
    padding: .2rem .55rem;
    border-radius: 999px;
    background: var(--aq-gold-soft);
    border: 1px solid var(--aq-gold-mid);
    color: var(--aq-gold-light);
    font-size: .78rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}
/* Explicito a proposito: en cuanto una regla le da `display`, el atributo
   `hidden` del navegador deja de esconderlo y sale una pastilla vacia. */
.fold__tag[hidden] { display: none; }

.fold__chev {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 8px;
    color: var(--text-muted);
    font-size: .8rem;
    transition: transform .3s cubic-bezier(.4, 0, .2, 1), color .18s, background .18s;
}
.fold__head:hover .fold__chev { color: var(--text-primary); background: var(--bg-input); }
.fold[open] .fold__chev { transform: rotate(180deg); color: var(--gold); }

/* ── Cuerpo ───────────────────────────────────────────────────────────── */

/* <details> no sabe animar el cierre (el navegador quita el contenido de
   golpe), asi que se anima solo la apertura. Un alto animado exigiria dejarlo
   en el DOM a mano, y eso es justo lo que se gana usando <details> nativo. */
.fold__body {
    padding: 1rem 1.15rem 1.25rem;
    border-top: 1px solid var(--border);
    animation: foldIn .3s cubic-bezier(.16, 1, .3, 1);
}
@keyframes foldIn {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: none; }
}

/* Lo de dentro ya venia siendo una tarjeta con su marco. Dentro del plegado
   seria una tarjeta dentro de otra, asi que se le quita el marco y se queda
   el del plegado. */
.fold__body > .cpan,
.fold__body > .stg {
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}
.fold__body > .ipol { margin-top: 0; }

@media (max-width: 620px) {
    .fold__head { gap: .7rem; padding: .8rem .85rem; }
    .fold__body { padding: .85rem .85rem 1rem; }
    .fold__mark { width: 2.2rem; height: 2.2rem; font-size: .92rem; }
    .fold__title { font-size: 1rem; }
    /* A este ancho el subtexto se come el sitio del titulo y del dato. */
    .fold__sub { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   SUB-PESTANAS DE UN SISTEMA DE ASISTENCIA        necROmantic 2026-08-26
   ──────────────────────────────────────────────────────────────────────────
   Comportamiento / Listas de monstruos / Uso de habilidades / Uso de objetos.
   Son un control segmentado a proposito, y no otra fila de pestanas como las
   de arriba: si las dos se pintaran igual no se sabria cual manda sobre cual.

   LA MARCA DESLIZANTE NO SE MIDE CON JAVASCRIPT. Las columnas son de ancho
   identico (grid-auto-columns: 1fr), asi que su sitio sale de dos custom
   properties: --n, cuantas hay, que la pone PHP con la clase --nN; y --i, cual
   esta puesta, que la pone el JS con la clase is-iN. Medirla con offsetLeft
   habria dado 0: este marcado nace dentro de un <details> cerrado, que no
   tiene caja hasta que alguien lo abre.
   ══════════════════════════════════════════════════════════════════════════ */

.cpan__subwrap { margin: 0 0 1.15rem; }

.cpan__subtabs {
    position: relative;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    padding: .28rem;
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--bg-body);
}
.cpan__subtabs--n2 { --n: 2; }
.cpan__subtabs--n3 { --n: 3; }
.cpan__subtabs--n4 { --n: 4; }
.cpan__subtabs.is-i0 { --i: 0; }
.cpan__subtabs.is-i1 { --i: 1; }
.cpan__subtabs.is-i2 { --i: 2; }
.cpan__subtabs.is-i3 { --i: 3; }

.cpan__subtabs-ink {
    position: absolute;
    top: .28rem;
    bottom: .28rem;
    left: .28rem;
    width: calc((100% - .56rem) / var(--n, 1));
    transform: translateX(calc(var(--i, 0) * 100%));
    border-radius: 8px;
    background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-table-alt));
    border: 1px solid var(--aq-gold-mid);
    box-shadow: 0 0 14px var(--aq-gold-soft);
    transition: transform .3s cubic-bezier(.4, 0, .2, 1);
    pointer-events: none;
    z-index: 0;
}

.cpan__subtab {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-width: 0;
    padding: .58rem .7rem;
    background: none;
    border: 0;
    border-radius: 8px;
    color: var(--text-muted);
    font-size: .87rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: color .18s;
}
.cpan__subtab:hover { color: var(--text-primary); }
.cpan__subtab--on { color: var(--text-heading2); }
.cpan__subtab:focus-visible { outline: 2px solid var(--accent-purple); outline-offset: -2px; }

.cpan__subtab-ico { font-size: .95rem; opacity: .72; transition: opacity .18s, color .18s; }
.cpan__subtab--on .cpan__subtab-ico { opacity: 1; color: var(--aq-gold-light); }
.cpan__subtab-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cpan__subtab-n {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 .32rem;
    border-radius: 999px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    color: var(--text-muted);
    font-size: .68rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition: color .18s, border-color .18s, background .18s;
}
.cpan__subtab-n[hidden] { display: none; }
.cpan__subtab--on .cpan__subtab-n {
    background: var(--aq-gold-soft);
    border-color: var(--aq-gold-mid);
    color: var(--aq-gold-light);
}

.cpan__sub-panel { animation: cpanSubIn .26s cubic-bezier(.16, 1, .3, 1); }
.cpan__sub-panel--off { display: none; }
@keyframes cpanSubIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

/* Cuatro columnas con texto no caben en un movil: se apilan y la marca
   deslizante se retira -- ya no habria por donde deslizarse --, asi que la
   puesta se pinta ella misma. El resalte va por box-shadow y no por `border`
   para que ponerlo y quitarlo no mueva nada de sitio. */
@media (max-width: 720px) {
    .cpan__subtabs { grid-auto-flow: row; grid-auto-columns: auto; gap: .25rem; }
    .cpan__subtabs-ink { display: none; }
    .cpan__subtab { justify-content: flex-start; }
    .cpan__subtab--on {
        background: linear-gradient(180deg, var(--bg-surface-alt), var(--bg-table-alt));
        box-shadow: inset 0 0 0 1px var(--aq-gold-mid);
    }
    .cpan__subtab-n { margin-left: auto; }
}

@media (prefers-reduced-motion: reduce) {
    .fold__body,
    .cpan__sub-panel { animation: none; }
    .fold__chev,
    .fold__head::before,
    .cpan__subtabs-ink { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ESTADO EN DOS COLUMNAS + ESTRELLA DE CARACTERISTICAS
                                                   necROmantic 2026-08-26
   ──────────────────────────────────────────────────────────────────────────
   Peticion del usuario: las seis caracteristicas dejan de ser seis cajas con
   un numero y pasan a ser una grafica radial en un tercio del ancho; los dos
   tercios restantes se quedan con las barras de vida y las cuatro baldosas.

   Las baldosas se mudan a esa columna y no se quedan a lo ancho a proposito:
   la estrella es cuadrada, asi que con solo dos barras al lado quedaria un
   tercio con contenido y dos tercios de aire.
   ══════════════════════════════════════════════════════════════════════════ */

.chv__top {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 22px;
}
.chv__top-main { min-width: 0; }

/* La linea de debajo de las baldosas separaba las cifras de las caracteristicas.
   Ahora las caracteristicas estan al lado, asi que la linea no separa nada.

   Y pasan a 2x2: en una sola fila la columna izquierda medía la mitad que la
   estrella y quedaba un hueco enorme debajo. Repartidas en dos filas las dos
   columnas terminan casi a la vez, que es lo que hace que se lean como una. */
.chv__top-main .chv__tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding-bottom: 0;
    margin-bottom: 0;
    border-bottom: 0;
}

/* Se estira a lo alto de la fila y centra el dibujo dentro. Sin esto la caja
   termina donde termina la estrella y deja un hueco debajo, que es el hueco de
   la columna izquierda cambiado de lado. */
.chv__radar {
    min-width: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 12px 8px 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: linear-gradient(180deg, var(--alpha-silver-08), transparent 70%);
}

.chv__rad {
    display: block;
    width: 100%;
    height: auto;
}

/* ── Rejilla: hairlines solidas, un tono por encima de la superficie. Ni
      punteadas (leen como "umbral") ni gruesas (compiten con el dato). ── */
.chv__rad-ring {
    fill: none;
    stroke: var(--border);
    stroke-width: 1;
}
.chv__rad-ring--out { stroke: var(--border-light); }

.chv__rad-spoke {
    stroke: var(--border);
    stroke-width: 1;
}

/* ── La serie. UNA sola, asi que un solo color y ninguna leyenda: el titulo
      de la seccion ya dice de quien son estas caracteristicas. ── */
.chv__rad-area {
    fill: var(--rad-series);
    fill-opacity: 0.22;
    stroke: none;
}
.chv__rad-line {
    fill: none;
    stroke: var(--rad-series);
    stroke-width: 2;
    stroke-linejoin: round;
}
.chv__rad-dot {
    fill: var(--rad-series);
    stroke: var(--bg-surface);      /* el anillo de 2 px que despega el punto del relleno */
    stroke-width: 2;
    transition: r 0.15s ease;
}
/* La zona sensible es MAS GRANDE que el punto: 8 px de marca no se apuntan con
   el raton. Transparente y no `fill:none`, que no recibe el puntero. */
.chv__rad-hit {
    fill: transparent;
    pointer-events: all;
}

/* ── Textos: SIEMPRE con tonos de texto, nunca con el color de la serie. ── */
.chv__rad-abbr {
    fill: var(--text-muted);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.12em;
}
.chv__rad-val {
    fill: var(--text-primary);
    font-size: 14px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* La escala. Va por encima del poligono, asi que lleva halo del color de la
   superficie: `paint-order` pinta primero el trazo y despues el relleno, que es
   la unica forma de recortar un texto contra lo que tenga debajo sin una caja. */
.chv__rad-scale {
    fill: var(--text-muted);
    font-size: 9px;
    font-weight: 600;
    opacity: 0.75;
    paint-order: stroke fill;
    stroke: var(--bg-surface);
    stroke-width: 3;
    stroke-linejoin: round;
}

.chv__rad-ax:hover .chv__rad-dot  { r: 6; }
.chv__rad-ax:hover .chv__rad-val  { fill: var(--text-heading2); }
.chv__rad-ax:hover .chv__rad-abbr { fill: var(--text-primary); }

.chv__radar-cap {
    margin: 4px 0 0;
    text-align: center;
    font-size: 0.78rem;
    color: var(--text-muted);
}
.chv__radar-cap b {
    color: var(--text-primary);
    font-weight: 700;
    letter-spacing: 0.06em;
}
.chv__radar-cap span {
    display: block;
    margin-top: 2px;
    font-size: 0.68rem;
    opacity: 0.8;
}

/* Apiladas, la estrella no crece hasta ocupar la pantalla: pasado cierto tamano
   deja de decir mas y solo aleja el resto de la ficha. */
@media (max-width: 900px) {
    .chv__top { grid-template-columns: 1fr; }
    .chv__radar { max-width: 380px; margin: 0 auto; }
    .chv__top-main .chv__tiles {
        padding-bottom: 18px;
        margin-bottom: 0;
        border-bottom: 1px solid var(--border);
    }
}

@media (prefers-reduced-motion: reduce) {
    .chv__rad-dot { transition: none; }
}

/* ══ VINCULOS Y COMPAÑEROS, DENTRO DE LA TARJETA DE ESTADO ═════════════════
   necROmantic 2026-08-26, peticion del usuario. La estrella ocupa su tercio
   entero y de arriba abajo; con solo las barras, las baldosas y los puntos al
   lado, la columna izquierda terminaba a media altura. Los vinculos llenan ese
   hueco, y los compañeros de grupo van PLEGADOS porque una party son hasta doce
   personas y la tarjeta no puede crecer sin freno.

   Encabezados de SEGUNDO nivel (.chv__sub): esto es una parte de la tarjeta, no
   una seccion hermana de "Estado", y con un .sec-title lo pareceria. */

.chv__extra {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

.chv__sub {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 11px;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.chv__sub-ico {
    flex: 0 0 auto;
    color: var(--accent-purple);
    font-size: 0.8rem;
}

/* Dentro de la tarjeta las pastillas ya no cierran una seccion: lo que va debajo
   es el desplegable de los compañeros, a un palmo y no a un renglon en blanco. */
.chv__extra .chv__bonds { margin-bottom: 12px; }

/* ── El desplegable de los compañeros de grupo ── */

.chv__crew {
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--bg-surface);
}

.chv__crew-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 10px 13px;
    border-radius: 10px;
    cursor: pointer;
    list-style: none;
    -webkit-user-select: none;
    user-select: none;
    transition: background 0.18s;
}
/* El triangulito de serie sobra: a la derecha hay un galon. Hacen falta las dos
   reglas -- ::marker es lo estandar y ::-webkit-details-marker lo que entienden
   los Safari y los Chrome viejos. */
.chv__crew-head::-webkit-details-marker { display: none; }
.chv__crew-head::marker { content: ""; }
.chv__crew-head:hover { background: var(--bg-table-alt); }
.chv__crew-head:focus-visible {
    outline: 2px solid var(--accent-purple);
    outline-offset: -3px;
}

.chv__crew-lbl {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* El NOMBRE del grupo se queda como lo escribio quien lo creo: "myParty" no es
   "MYPARTY", y pasarlo por uppercase es inventarse el nombre de otro. */
.chv__crew-lbl b {
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-primary);
}
.chv__crew[open] .chv__crew-lbl { color: var(--text-primary); }

.chv__crew-n {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.32rem;
    border-radius: 999px;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    color: var(--text-primary);
    font-size: 0.68rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
}

.chv__crew-chev {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    color: var(--text-muted);
    font-size: 0.72rem;
    transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1), color 0.18s;
}
.chv__crew[open] .chv__crew-chev {
    transform: rotate(180deg);
    color: var(--gold);
}

/* <details> no sabe animar el cierre, asi que se anima solo la apertura -- misma
   decision y mismo fotograma que los plegables grandes de la ficha. */
.chv__crew-body {
    padding: 0 13px 12px;
    animation: foldIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.chv__crew .chv__people {
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    margin-bottom: 0;
}

@media (prefers-reduced-motion: reduce) {
    .chv__crew-body { animation: none; }
    .chv__crew-chev { transition: none; }
}

/* ── "Compañeros" dentro de "Acompañantes" (necROmantic 2026-08-26) ──────────
   Peticion del usuario: la foto de la fila de `char` (nombre, nivel, vida, las
   seis caracteristicas del homunculo, cariño y hambre) va arriba del todo del
   plegable, por delante de las tarjetas vivas que llegan por AJAX. */

.elecare-mates {
    margin: 0 0 20px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--border);
}

/* El margen de separacion lo pone el bloque; la rejilla ya no cierra nada. */
.elecare-mates .chv__mates { margin-bottom: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   MERCADO DE LA INCINERADORA  (/mercado/)   necROmantic 2026-08-26
   Peticion del usuario. Marcado en themes/necromantic/mercado/index.php, todo
   lo de dentro lo pinta themes/necromantic/js/mercado.js.
   ══════════════════════════════════════════════════════════════════════════ */

/* OJO CON [hidden]: aqui el atributo esconde el selector de personaje, la tienda entera y el
   paginador, y varios de esos elementos declaran `display` en su clase. El `display: none` del
   agente de usuario es la declaracion mas debil que existe y CUALQUIER clase con display se lo
   come -- ya mordio dos veces en este panel el mismo dia. Una sola regla scoped, que con (0,2,0)
   gana a cualquier clase suelta sin necesidad de !important, en vez de una por elemento: arreglarlas
   de una en una es esperar a que la proxima se olvide. */
.mk [hidden] { display: none; }

.mk { max-width: 1180px; margin: 0 auto; }

.mk__head { margin-bottom: 18px; }

.mk__title {
    margin: 0 0 6px;
    font-size: 1.35rem;
    color: var(--text-heading2);
}

.mk__lead {
    margin: 0;
    max-width: 70ch;
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-muted);
}

.mk__h2 {
    margin: 0 0 6px;
    font-size: 1rem;
    color: var(--text-primary);
}

.mk__help {
    margin: 0 0 14px;
    max-width: 70ch;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.mk__vacio {
    margin: 0;
    padding: 22px 16px;
    border: 1px dashed var(--border);
    border-radius: 12px;
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--text-muted);
    text-align: center;
}

/* --- El aviso de la ultima accion --- */

.mk__flash {
    margin: 0 0 14px;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--alpha-black-22);
    font-size: 0.86rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.mk__flash--bien { border-color: var(--border-accent); color: var(--text-success); }
.mk__flash--ojo  { border-color: var(--gold-dim);      color: var(--gold); }
.mk__flash--mal  { border-color: var(--crimson);       color: var(--accent-red); }

/* --- Paso 1: elegir con quien se compra --- */

.mk__chars {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 12px;
}

.mk__char {
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

/* El personaje que esta dentro del juego se ensena APAGADO y con el motivo escrito, no escondido:
   esconderlo dejaria al jugador buscando un personaje que el sabe que tiene. */
.mk__char--busy { opacity: 0.55; }

.mk__char-name {
    margin: 0 0 2px;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.mk__char-lv {
    margin: 0 0 8px;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.mk__char-zeny {
    margin: 0 0 12px;
    font-size: 0.9rem;
    color: var(--gold);
}

.mk__char-busy {
    margin: 0;
    font-size: 0.78rem;
    color: var(--accent-red);
}

.mk__char-pick,
.mk__change,
.mk__item-add,
.mk__buy,
.mk__clear,
.mk__page-btn,
.mk__line-del {
    font: inherit;
    cursor: pointer;
    border: 1px solid var(--border-light);
    border-radius: 9px;
    background: var(--bg-surface);
    color: var(--text-link);
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.mk__char-pick:hover,
.mk__change:hover,
.mk__item-add:hover:not(:disabled),
.mk__page-btn:hover:not(:disabled),
.mk__line-del:hover {
    border-color: var(--border-accent);
    color: var(--text-link-hover);
}

.mk__char-pick:disabled,
.mk__item-add:disabled,
.mk__page-btn:disabled,
.mk__buy:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.mk__char-pick { width: 100%; padding: 8px 10px; font-size: 0.84rem; }

/* --- La barra de quien compra --- */

.mk__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
    padding: 12px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

.mk__who {
    flex: 1 1 200px;
    margin: 0;
    font-size: 0.92rem;
    color: var(--text-primary);
}

.mk__wallet { margin: 0; font-size: 0.92rem; color: var(--text-muted); }
.mk__wallet-label { margin-right: 6px; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; }
.mk__wallet-n { color: var(--gold); }
.mk__z { color: var(--gold-dim); }

.mk__change { padding: 7px 12px; font-size: 0.8rem; }

/* --- El reparto: escaparate y lista --- */

.mk__layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 18px;
    align-items: start;
}

@media (max-width: 900px) {
    .mk__layout { grid-template-columns: minmax(0, 1fr); }
}

/* --- Herramientas del escaparate --- */

.mk__tools {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin-bottom: 14px;
}

.mk__field { flex: 1 1 220px; display: block; }
.mk__field--sort { flex: 0 1 220px; }

.mk__label {
    display: block;
    margin-bottom: 4px;
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.mk__search,
.mk__sort,
.mk__item-qty,
.mk__line-n {
    font: inherit;
    width: 100%;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-input);
    color: var(--text-primary);
}

.mk__search:focus,
.mk__sort:focus,
.mk__item-qty:focus,
.mk__line-n:focus { outline: none; border-color: var(--border-accent); }

.mk__count {
    flex: 0 0 auto;
    margin: 0 0 8px;
    font-size: 0.78rem;
    color: var(--text-muted);
}

/* --- Las tarjetas del escaparate --- */

.mk__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 12px;
}

.mk__item {
    display: flex;
    gap: 10px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

.mk__item-icon {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    object-fit: contain;
    image-rendering: pixelated;
}

/* El hueco del icono se reserva aunque el fichero no exista: sin el, las tarjetas sin icono
   descuadran la rejilla entera. */
.mk__item-icon--none {
    display: block;
    border: 1px dashed var(--border);
    border-radius: 6px;
}

.mk__item-body { flex: 1 1 auto; min-width: 0; }

.mk__item-name {
    margin: 0 0 4px;
    font-size: 0.88rem;
    line-height: 1.3;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.mk__item-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0 0 6px;
}

.mk__tag {
    padding: 1px 7px;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    font-size: 0.7rem;
    color: var(--text-muted);
}

.mk__tag--ref   { border-color: var(--border-accent); color: var(--accent-purple); }
.mk__tag--bound { border-color: var(--crimson);       color: var(--accent-red); }

.mk__item-price { margin: 0 0 2px; font-size: 0.95rem; color: var(--gold); }
.mk__item-each  { font-size: 0.72rem; color: var(--text-muted); }

.mk__item-cap {
    margin: 0 0 2px;
    font-size: 0.7rem;
    line-height: 1.3;
    color: var(--accent-purple);
    cursor: help;
}

.mk__item-stock { margin: 0 0 8px; font-size: 0.76rem; color: var(--text-muted); }

.mk__item-buy { display: flex; gap: 6px; }
.mk__item-qty { width: 74px; padding: 5px 7px; font-size: 0.82rem; }
.mk__item-add { padding: 5px 12px; font-size: 0.8rem; white-space: nowrap; }

/* --- El paginador --- */

.mk__pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: 16px;
}

.mk__page-btn { padding: 6px 14px; font-size: 0.8rem; }
.mk__page-n   { font-size: 0.8rem; color: var(--text-muted); }

/* --- La lista de la compra --- */

.mk__cart {
    position: sticky;
    top: 84px;
    padding: 14px;
    border: 1px solid var(--border-light);
    border-radius: 12px;
    background: var(--bg-surface);
}

@media (max-width: 900px) {
    .mk__cart { position: static; }
}

.mk__lines {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    max-height: 420px;
    overflow-y: auto;
}

.mk__line {
    display: flex;
    gap: 8px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
}

.mk__line:last-child { border-bottom: 0; }

/* Una linea muerta se queda A LA VISTA y tachada, no se borra sola: el jugador tiene que
   enterarse de que ya no lo tiene, no encontrarse una lista mas corta sin explicacion. */
.mk__line--gone { opacity: 0.6; text-decoration: line-through; }
.mk__line--gone .mk__line-warn { text-decoration: none; }

.mk__line-icon {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    object-fit: contain;
    image-rendering: pixelated;
}

.mk__line-body { flex: 1 1 auto; min-width: 0; }

.mk__line-name {
    margin: 0 0 4px;
    font-size: 0.82rem;
    line-height: 1.3;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.mk__line-warn {
    margin: 0 0 4px;
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--accent-red);
}

.mk__line-qty { display: flex; align-items: center; gap: 8px; }
.mk__line-n   { width: 70px; padding: 4px 6px; font-size: 0.8rem; }
.mk__line-sub { font-size: 0.82rem; color: var(--gold); }

.mk__line-del {
    align-self: flex-start;
    margin-top: 4px;
    padding: 3px 9px;
    border-color: transparent;
    background: none;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.mk__cartnote { margin: 0 0 10px; font-size: 0.72rem; color: var(--text-muted); }

.mk__totals {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 4px 10px;
    margin: 0 0 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    font-size: 0.86rem;
}

.mk__totals-k { margin: 0; color: var(--text-muted); }
.mk__totals-v { margin: 0; text-align: right; color: var(--gold); }

/* Cuando la lista pasa de la cartera se marca en rojo, pero NO se recorta sola: decidir que linea
   sobra es del jugador. El boton de aceptar ya viene apagado del servidor. */
.mk__cart--over .mk__totals-v { color: var(--accent-red); }

.mk__actions { display: flex; flex-direction: column; gap: 8px; }

.mk__buy {
    padding: 10px;
    border-color: var(--border-accent);
    background: var(--crimson);
    font-size: 0.88rem;
    color: var(--accent-red-h);
}

.mk__buy:hover:not(:disabled) { background: var(--bg-sidebar-head); color: var(--text-panel-bright); }

.mk__clear {
    padding: 7px;
    border-color: transparent;
    background: none;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.mk__clear:hover { color: var(--accent-red); }

/* --- Las reglas de la casa --- */

.mk__rules {
    margin-top: 22px;
    padding: 14px 18px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

.mk__rulelist { margin: 0; padding-left: 20px; }

.mk__rule {
    margin-bottom: 6px;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.mk__rule:last-child { margin-bottom: 0; }
.mk__rule strong { color: var(--text-primary); }

/* --- Aviso: un jugador lo tiene a la venta dentro del juego (2026-08-26) ---------------------
   Peticion del usuario, corrigiendo la primera version: estos articulos NO se esconden del
   escaparate. Se quedan, con este aviso y con lo que pide el puesto, y decide el comprador. */

/* Marca lateral y NO pastilla: el texto lleva dentro un precio con separadores de millares y en
   una tarjeta estrecha se parte en dos lineas. Una pastilla partida en dos deja el borde redondeado
   envolviendo un bloque, que se lee como un error de maquetacion. */
.mk__vend {
    margin: 0 0 4px;
    padding: 1px 0 1px 8px;
    border-left: 2px solid var(--gold-dim);
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--gold);
    cursor: help;
}

/* --- Mis compras: deshacer una compra dentro de la semana ------------------------------------ */

.mk__sales {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}

.mk__saleslist {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 12px;
}

.mk__sale {
    display: flex;
    gap: 10px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface-alt);
}

/* Lo que ya no se puede devolver se queda A LA VISTA y apagado, con el motivo escrito debajo:
   una compra que desaparece de la lista parece un error del panel. */
.mk__sale--no { opacity: 0.6; }

.mk__sale-icon {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    object-fit: contain;
    image-rendering: pixelated;
}

.mk__sale-body { flex: 1 1 auto; min-width: 0; }

.mk__sale-name {
    margin: 0 0 4px;
    font-size: 0.88rem;
    line-height: 1.3;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

.mk__sale-n { color: var(--text-muted); }

.mk__sale-when {
    margin: 0 0 2px;
    font-size: 0.72rem;
    color: var(--text-muted);
}

.mk__sale-paid { margin: 6px 0 2px; font-size: 0.9rem; color: var(--gold); }
.mk__sale-paid-k { font-size: 0.72rem; color: var(--text-muted); }

.mk__sale-where {
    margin: 0 0 8px;
    font-size: 0.74rem;
    line-height: 1.35;
    color: var(--text-muted);
}

.mk__sale--no .mk__sale-where { color: var(--accent-red); }

.mk__sale-undo {
    font: inherit;
    cursor: pointer;
    padding: 6px 12px;
    border: 1px solid var(--border-light);
    border-radius: 9px;
    background: var(--bg-surface);
    font-size: 0.78rem;
    color: var(--text-link);
    transition: border-color 0.15s ease, color 0.15s ease;
}

.mk__sale-undo:hover:not(:disabled) { border-color: var(--border-accent); color: var(--text-link-hover); }
.mk__sale-undo:disabled { opacity: 0.45; cursor: not-allowed; }

/* Dentro de la ficha de cuenta la tienda vive en un panel que ya trae su propio marco, asi que
   la cabecera de /mercado/ sobra y el ancho lo manda el panel. */
.pane .mk { max-width: none; }

/* --- Pestanas por categoria del escaparate (2026-08-26) -------------------------------------- */

.mk__cats {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 14px;
}

.mk__cat {
    font: inherit;
    cursor: pointer;
    padding: 5px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-surface);
    font-size: 0.78rem;
    color: var(--text-muted);
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.mk__cat:hover { border-color: var(--border-light); color: var(--text-primary); }

.mk__cat.is-on {
    border-color: var(--border-accent);
    background: var(--alpha-black-22);
    color: var(--text-primary);
}

/* La pestana sin nada dentro se queda en su sitio, apagada. Sigue siendo pulsable a proposito:
   quien la pulsa lee "nada coincide con esa busqueda", que es una respuesta; una pestana que no
   responde al clic parece rota. Mismo criterio que .ipol__cat--empty. */
.mk__cat--empty { opacity: 0.45; }

.mk__cat-n { color: var(--gold-dim); font-variant-numeric: tabular-nums; }
.mk__cat.is-on .mk__cat-n { color: var(--gold); }

/* ==========================================================================
   PREFERENCIAS DEL PERSONAJE — celdas, plegables y frases a mano
   necROmantic 2026-08-26 (peticion del usuario).

   Los interruptores de esta pagina pasan al MISMO marcado que los de «Funciones» del panel
   de acompañantes (.cpan__fn / .cpan__switch / .cpan__more): icono sobre el interruptor,
   titulo y resumen al lado, y la explicacion larga plegada debajo. Se reutilizan aquellas
   clases tal cual en vez de copiarlas -- una segunda copia acabaria pareciendose cada vez
   menos a la primera -- y aqui solo va lo que esta pagina necesita de mas.
   ========================================================================== */

/* Las celdas de preferencias son mas anchas que las del panel de acompañantes: aqui los
   textos son de aviso legal y de consecuencias, no etiquetas de tres palabras, y en 17rem
   salian a cinco palabras por linea. `min()` para que en el movil no desborde. */
.prefs-fns {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
    margin-bottom: 26px;
}

/* Fila entera para las dos que llevan medidores o el visor de la memoria dentro. */
.cpan__fn--wide { grid-column: 1 / -1; }

/* El encabezado de grupo iba pegado a .prefs-list; ahora lo que le sigue es la rejilla. */
.prefs-group + .cpan__switches { margin-bottom: 26px; }

/* Puentes con lo que ya habia dentro de las tarjetas: notas, medidores y el visor de la
   memoria siguen usando sus clases .prefs-*, y solo hay que darles el aire que antes les
   daba el relleno de .prefs-card. */
/* El sangrado los alinea con el TEXTO de la celda y no con el icono: son continuacion de lo
   que dice el titulo, no otra seccion. La medida es el ancho de la columna del interruptor
   (2.3rem de pastilla) mas su separacion (0.65rem). El «Saber más…» se queda sin sangrar a
   proposito, igual que en el panel de acompañantes. */
.prefs-fns .cpan__fn > .prefs-card__note,
.prefs-fns .cpan__fn > .prefs-meter,
.prefs-fns .cpan__fn > .prefs-memo {
    margin-top: 0.7rem;
    margin-left: 2.95rem;
}

/* Dentro del «Saber más…» manda el tamaño del desplegable, no el de la tarjeta de antes. */
.cpan__more-body .prefs-card__desc,
.cpan__more-body .prefs-card__note,
.cpan__more-body .prefs-comp__desc {
    font-size: inherit;
    line-height: inherit;
    color: inherit;
    max-width: none;
}
.cpan__more-body .prefs-card__desc + .prefs-card__desc { margin-top: 0.6rem; }

/* EL BOTON POR DEFECTO DEL FORMULARIO. No se puede usar `hidden` ni `display:none`: un submit
   asi no cuenta como boton por defecto en todos los navegadores, y entonces Intro vuelve a
   disparar el primer boton de verdad -- que era «Borrar la memoria». Se saca de la vista sin
   quitarlo del flujo de envio. */
.prefs-noop {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --- Secciones plegables ------------------------------------------------- */

/* «Quiénes te acompañan». Nace plegada: son tres fichas largas y a la vista empujaban el
   resto de la pagina fuera de la pantalla. */
.prefs-fold {
    margin-bottom: 26px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-surface);
}

.prefs-fold__summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    padding: 14px 18px;
    cursor: pointer;
    list-style: none;
    border-radius: 12px;
}

.prefs-fold__summary::marker,
.prefs-fold__summary::-webkit-details-marker { display: none; content: ""; }

.prefs-fold__summary::before {
    content: "\25B8";
    color: var(--gold);
    transition: transform 0.2s ease;
}

.prefs-fold[open] > .prefs-fold__summary::before { transform: rotate(90deg); }
.prefs-fold__summary:hover { background: var(--bg-surface-alt); }

.prefs-fold__title {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--gold);
}

.prefs-fold__hint {
    flex: 1 1 18rem;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.prefs-fold__lead { padding: 0 18px 12px; }
/* necROmantic 2026-08-29: era `.prefs-fold > .prefs-companions`. Ese contenedor ya no
   existe -- lo sustituyo la tira de pestañas `.cmt` --, asi que la regla se repunta en vez
   de dejarla apuntando a una clase que no pinta nadie. */
.prefs-fold > .cmt { padding: 0 18px 18px; margin-bottom: 0; }

/* --- Un bloque por unidad ------------------------------------------------ */

/* Una ficha por mercenario, homunculo o mascota. Hacen falta separadas porque el limite de
   frases es POR UNIDAD: juntas, el mercenario de quien habia contratado nueve decia «90 de
   10» -- ver Flux_Athena::getAiChatLineUnits(). */
.prefs-unit {
    margin-top: 0.5rem;
    border: 1px solid var(--border-light);
    border-radius: 8px;
    background: var(--bg-table-row);
}

.prefs-unit__summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.6rem;
    cursor: pointer;
    list-style: none;
    border-radius: 8px;
}

.prefs-unit__summary::marker,
.prefs-unit__summary::-webkit-details-marker { display: none; content: ""; }

.prefs-unit__summary::before {
    content: "\25B8";
    font-size: 0.8rem;
    color: var(--gold);
    transition: transform 0.2s ease;
}

.prefs-unit[open] > .prefs-unit__summary::before { transform: rotate(90deg); }
.prefs-unit__summary:hover { background: var(--bg-table-alt); }

.prefs-unit__name {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

/* La unidad que ya no se tiene: sus frases se ven y se borran, pero no admite mas. */
.prefs-unit__gone {
    padding: 0.05rem 0.4rem;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.prefs-unit__count {
    margin-left: auto;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.prefs-unit__body { padding: 0 0.6rem 0.6rem; }

/* --- Los momentos, tambien plegados -------------------------------------- */

/* .prefs-lines paso de <div> a <details>: la cabecera de antes es ahora el <summary>. */
.prefs-lines > summary.prefs-lines__head {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    cursor: pointer;
    list-style: none;
    padding: 0.3rem 0.2rem;
    border-radius: 5px;
}

.prefs-lines__head::marker,
.prefs-lines__head::-webkit-details-marker { display: none; content: ""; }

.prefs-lines > summary.prefs-lines__head::before {
    content: "\25B8";
    font-size: 0.72rem;
    color: var(--text-muted);
    transition: transform 0.2s ease;
}

.prefs-lines[open] > summary.prefs-lines__head::before { transform: rotate(90deg); }
.prefs-lines > summary.prefs-lines__head:hover { background: var(--bg-table-alt); }

.prefs-lines__title { flex: 1 1 auto; }

/* Lleno no es un problema: significa que ya no va a gastar unidades en este momento. */
.prefs-lines__count--lleno { color: var(--gold); }

.prefs-lines__full {
    margin: 0.3rem 0 0;
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* --- Escribirle una frase a mano ----------------------------------------- */

.prefs-lines__add {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.4rem;
}

.prefs-lines__new {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.3rem 0.45rem;
    border: 1px dashed var(--border-light);
    border-radius: 5px;
    background: transparent;
    color: var(--text-primary);
    font: inherit;
    font-size: 0.85rem;
}

.prefs-lines__new:focus {
    outline: none;
    border-style: solid;
    border-color: var(--gold);
    background: var(--bg-input);
}

.prefs-lines__addbtn {
    flex: 0 0 auto;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--border-light);
    border-radius: 5px;
    background: var(--bg-table-alt);
    color: var(--text-muted);
    font: inherit;
    font-size: 0.8rem;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease;
}

.prefs-lines__addbtn:hover,
.prefs-lines__addbtn:focus-visible {
    border-color: var(--gold);
    color: var(--gold);
}

/* ══════════════════════════════════════════════════════════════════════════
   MENÚ DE SECCIONES DE LA FICHA DE PERSONAJE (.chnav)
                                                   necROmantic 2026-08-26
   ──────────────────────────────────────────────────────────────────────────
   Petición del usuario: "un menú similar al de 'Secciones de tu cuenta' pero
   que lo que haga sea ... contraer y expandir cosas, además de scroll
   automático".

   Habla el MISMO idioma que el mosaico de /account/view/ (.pnav) -- cristal
   oscuro, filo de color arriba, resplandor detrás del icono y los mismos
   --tone-* -- pero NO reutiliza sus clases a propósito: son dos páginas
   distintas y el día que una cambie de tamaño o de columnas no debe arrastrar
   a la otra. Aquí las baldosas son más bajas porque son nueve como mucho, y no
   doce, y porque debajo empieza enseguida "Estado".

   LO QUE ESTA HOJA NO HACE: nada de abrir ni cerrar. El estado de cada sección
   es el atributo [open] del <details>, que pone el navegador; aquí solo se
   marca cuál está abierta (.is-active). Sin JavaScript las baldosas son
   anclas normales y todo esto se ve igual.
   ══════════════════════════════════════════════════════════════════════════ */

.chnav {
    margin: 22px 0 6px;
    padding: 16px 16px 18px;
    border-radius: 20px;
    background: var(--grad-pnav);
    box-shadow: var(--shadow-soft);
    /* "Contraer todo" vuelve aqui, y la cabecera del sitio flota por encima: sin
       este margen de desplazamiento el menu volvia con su titulo y la primera
       fila de baldosas medio tapados. Mismo valor que el de los plegables. */
    scroll-margin-top: calc(var(--nav-height, 84px) + 18px);
}

.chnav__head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin: 0 4px 14px;
}

.chnav__eyebrow {
    margin: 0;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
}

.chnav__hint {
    margin: 0;
    flex: 1 1 auto;
    font-size: 0.82rem;
    color: var(--text-muted);
}

/* Columnas fijas por tramo de ancho y no auto-fit: el número de secciones
   depende de los permisos de quien mira (van de cuatro a nueve), y con auto-fit
   la última fila quedaba coja de una forma distinta en cada ficha. */
.chnav__grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 12px;
}

/* El atributo `hidden` lo pone la plantilla en "Contraer todo" y lo quita el
   guión. Hace falta decirlo porque el display de la regla de abajo le gana al
   del navegador: sin esto, quien navegue sin JavaScript vería un botón que no
   hace nada. */
.chnav__tile[hidden] { display: none; }

.chnav__tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 132px;
    padding: 16px 12px 14px;
    border-radius: 16px;
    overflow: hidden;
    background: var(--grad-tile);
    color: var(--text-primary);
    text-align: center;
    text-decoration: none;
    isolation: isolate;
    transition: transform 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}

/* "Contraer todo" es un <button>: solo hay que quitarle lo que el navegador le
   pone de serie, que si no rompe la cuadrícula (los botones no ocupan el ancho
   de su celda y traen su propia tipografía). */
.chnav__all {
    width: 100%;
    border: 0;
    font: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

/* Apagado mientras no hay ninguna sección abierta: no se esconde porque
   desaparecer haría saltar la cuadrícula entera cada vez que se abre o se
   cierra algo. */
.chnav__all:disabled {
    opacity: 0.42;
    cursor: default;
}
.chnav__all:disabled:hover { transform: none; background: var(--grad-tile); box-shadow: none; }

/* Filo superior de color, que se apaga hacia la derecha. Es la misma marca que
   llevan la cabecera de cada plegable (.fold__head::before) y las baldosas de
   la ficha de cuenta. */
.chnav__tile::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--tile-tone), transparent 82%);
}

/* Resplandor detrás del icono. z-index -1 para que no tape ni el icono ni el
   texto. */
.chnav__tile::after {
    content: "";
    position: absolute;
    top: -46px;
    left: 50%;
    width: 170px;
    height: 170px;
    margin-left: -85px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--tile-glow), transparent 68%);
    pointer-events: none;
    z-index: -1;
}

.chnav__tile:hover,
.chnav__tile:focus-visible {
    background: var(--grad-tile-hover);
    box-shadow: 0 16px 34px var(--alpha-black-28);
    transform: translateY(-3px);
    text-decoration: none;
}

.chnav__tile:focus-visible {
    outline: 2px solid var(--tile-tone);
    outline-offset: 2px;
}

/* La sección que está abierta ahora mismo. Lo marca el guión al abrir y al
   cerrar, también cuando se abre a mano desde la cabecera del plegable. */
.chnav__tile.is-active {
    background: var(--grad-tile-hover);
    box-shadow: inset 0 0 0 1px var(--tile-tone), 0 14px 32px var(--alpha-black-28);
}
.chnav__tile.is-active .chnav__ico {
    border-color: var(--tile-tone);
}

.chnav__ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 15px;
    border: 1px solid transparent;
    background: var(--tile-glow);
    color: var(--tile-tone);
    font-size: 1.35rem;
    transition: border-color 0.18s ease;
}

.chnav__text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 0;
    max-width: 100%;
}

.chnav__label {
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--text-heading2);
}

/* Una línea y con puntos suspensivos, igual que el subtítulo de la cabecera del
   plegable del que sale: si hace falta más, va en el título, no aquí. */
.chnav__sub {
    max-width: 100%;
    font-size: 0.75rem;
    line-height: 1.3;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* El dato en vivo copiado del plegable (cuántos objetos, cuántos sistemas). Va
   en la esquina y no en el texto para que no le robe el sitio al título. */
.chnav__tag {
    position: absolute;
    top: 8px;
    right: 8px;
    min-width: 1.8rem;
    padding: 0.12rem 0.42rem;
    border-radius: 999px;
    background: var(--aq-gold-soft);
    border: 1px solid var(--aq-gold-mid);
    color: var(--aq-gold-light);
    font-size: 0.7rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.chnav__tile--lilac   { --tile-tone: var(--tone-lilac);   --tile-glow: var(--tone-lilac-glow); }
.chnav__tile--azure   { --tile-tone: var(--tone-azure);   --tile-glow: var(--tone-azure-glow); }
.chnav__tile--teal    { --tile-tone: var(--tone-teal);    --tile-glow: var(--tone-teal-glow); }
.chnav__tile--amber   { --tile-tone: var(--tone-amber);   --tile-glow: var(--tone-amber-glow); }
.chnav__tile--gold    { --tile-tone: var(--tone-gold);    --tile-glow: var(--tone-gold-glow); }
.chnav__tile--rose    { --tile-tone: var(--tone-rose);    --tile-glow: var(--tone-rose-glow); }
.chnav__tile--mint    { --tile-tone: var(--tone-mint);    --tile-glow: var(--tone-mint-glow); }
.chnav__tile--indigo  { --tile-tone: var(--tone-indigo);  --tile-glow: var(--tone-indigo-glow); }
.chnav__tile--violet  { --tile-tone: var(--tone-violet);  --tile-glow: var(--tone-violet-glow); }
.chnav__tile--copper  { --tile-tone: var(--tone-copper);  --tile-glow: var(--tone-copper-glow); }
.chnav__tile--silver  { --tile-tone: var(--tone-silver);  --tile-glow: var(--tone-silver-glow); }

/* La cabecera del sitio flota por encima: sin este margen de desplazamiento, la
   sección a la que se baja queda por debajo de ella y no se ve su título. Es el
   mismo valor que usa .pane en la ficha de cuenta. */
.fold { scroll-margin-top: calc(var(--nav-height, 84px) + 18px); }

@media (max-width: 1100px) {
    .chnav__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
    .chnav__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
    .chnav { padding: 14px 12px 16px; border-radius: 16px; }
    .chnav__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .chnav__tile { min-height: 116px; padding: 14px 10px 12px; }
    .chnav__ico { width: 42px; height: 42px; border-radius: 13px; font-size: 1.2rem; }
    /* A este ancho el subtítulo se come el sitio del nombre de la sección. */
    .chnav__sub { display: none; }
}

/* Quien pide menos animación no quiere que las baldosas salten al pasar por
   encima; el desplazamiento ya lo decide el guión con la misma consulta. */
@media (prefers-reduced-motion: reduce) {
    .chnav__tile { transition: none; }
    .chnav__tile:hover,
    .chnav__tile:focus-visible { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   SUBMENÚ "IR A UNA SECCIÓN" DE CADA PERSONAJE (.chc__menu-sub)
                                                   necROmantic 2026-08-26
   ──────────────────────────────────────────────────────────────────────────
   Petición del usuario: "en el menú deseo que de cada personaje también
   aparezcan como submenús accesos directos a cada sección de /character/N/".

   Vive dentro del menú de tres puntos que ya tiene cada tarjeta de personaje en
   /account/view/ (.chc__menu-panel). Es un <details> ANIDADO y no una lista
   suelta porque son nueve enlaces: desplegados de partida convertirían un menú
   de cinco acciones en uno de catorce, y lo que casi siempre se busca ahí son
   las acciones.

   Nativo otra vez: funciona sin JavaScript, con ratón y con teclado, igual que
   el propio menú que lo contiene.
   ══════════════════════════════════════════════════════════════════════════ */

.chc__menu-sub {
    margin: 0 0 2px;
    border-bottom: 1px solid var(--border);
    padding-bottom: 4px;
}

/* La cabecera es un .chc__menu-item más: mismo alto, mismo texto y mismo
   subrayado al apuntarlo, para que no se lea como algo de otra clase. */
.chc__menu-sub__head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 11px;
    border-radius: 8px;
    color: var(--text-primary);
    font-size: 0.87rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.chc__menu-sub__head::-webkit-details-marker { display: none; }
.chc__menu-sub__head::marker { content: ""; }
.chc__menu-sub__head:hover { background: var(--bg-input); color: var(--text-label-hover); }
.chc__menu-sub__head:focus-visible { outline: 2px solid var(--accent-purple); outline-offset: -2px; }

/* El galón, que gira al abrir. Mismo gesto que el de los plegables de la ficha. */
.chc__menu-sub__chev {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 0.72rem;
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), color 0.18s;
}
.chc__menu-sub[open] .chc__menu-sub__chev { transform: rotate(180deg); color: var(--gold); }

/* Nueve entradas: se les pone techo y barra propia para que el menú no se salga
   de la pantalla en una tarjeta que ya esté abajo del todo. */
.chc__menu-sub__list {
    display: flex;
    flex-direction: column;
    max-height: 15rem;
    overflow-y: auto;
    padding: 2px 0 0;
}

/* Más compactas que las acciones y con el icono delante: son destinos, no
   cosas que le pasen al personaje. */
.chc__menu-sub__item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 11px;
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-weight: 500;
    text-decoration: none;
}
.chc__menu-sub__item:hover {
    background: var(--bg-input);
    color: var(--text-label-hover);
    text-decoration: none;
}
.chc__menu-sub__item i {
    width: 1.05rem;
    text-align: center;
    color: var(--accent-purple);
    font-size: 0.82rem;
}
.chc__menu-sub__item:hover i { color: var(--gold); }

@media (prefers-reduced-motion: reduce) {
    .chc__menu-sub__chev { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA FICHA DE CUENTA SE PLIEGA (necROmantic 2026-08-26, peticion del usuario)

   "Quiero que en /account/view/ se muestren los paneles como colapsables y
   expandibles como en /character/N/ ... y que el menu estilo windows 8 tambien
   ayude".

   Cada seccion de /account/view/ ha pasado de <section class="pane"> a
   <details class="fold pane">. El aspecto entero se lo da el bloque .fold de
   mas arriba, que ya existia para la ficha de personaje y no se toca: aqui solo
   esta lo que necesita ADEMAS por vivir en la ficha de cuenta.

   LO QUE ESTA HOJA NO HACE: nada de abrir ni cerrar. El estado de cada seccion
   es el atributo [open] del <details>, que pone el navegador.

   QUEDAN SIN USAR, a proposito y sin borrarlas: .pane--off, .pane--solo y
   .pane-back. Eran del mosaico viejo, el que escondia con `display`. Se dejan
   por si algun tema de terceros o alguna pagina vieja todavia las nombra;
   ninguna plantilla del panel las escribe ya.
   ══════════════════════════════════════════════════════════════════════════ */

/* La cabecera del sitio flota por encima. `.pane` ya traia su margen de
   desplazamiento, pero tres anclas apuntan a la CABECERA del plegable y no al
   plegable entero -- #almacen (el que escribe el paginador del almacen), #bonus
   (al que devuelve modules/account/referralbonus.php) y #mercado --, y sin esto
   el titulo de la seccion aterrizaba justo debajo de la barra. */
.pane > .fold__head { scroll-margin-top: calc(var(--nav-height, 84px) + 18px); }

/* Entre plegables de la ficha de cuenta hay mas aire que en la de personaje: aqui
   son diez seguidos y casi siempre estan todos cerrados, asi que la pagina es una
   lista de cabeceras y necesita respirar mas que una ficha con dos abiertas. */
.pane + .pane { margin-top: 14px; }

/* ── El color de la baldosa, en la seccion ────────────────────────────────
   Cada seccion lleva el tono de su baldosa del mosaico en el icono de la
   cabecera, para que el menu y la seccion se reconozcan como la misma cosa. Es
   el unico sitio donde se tine: la barrita de color de .fold__head::before se
   queda morado->oro en las dos fichas, que es lo que las hermana.

   El tono se hereda del propio plegable (--tile-tone, la misma variable que usan
   las baldosas), asi que anadir una seccion nueva no pide ni una regla mas. */
.pane[open] > .fold__head > .fold__mark {
    color: var(--tile-tone, var(--gold));
    border-color: var(--tile-tone, var(--border-accent));
    background: var(--tile-glow, var(--bg-table-alt));
}
.pane > .fold__head:hover > .fold__mark { color: var(--tile-tone, var(--accent-purple)); }

.pane--lilac   { --tile-tone: var(--tone-lilac);   --tile-glow: var(--tone-lilac-glow); }
.pane--azure   { --tile-tone: var(--tone-azure);   --tile-glow: var(--tone-azure-glow); }
.pane--teal    { --tile-tone: var(--tone-teal);    --tile-glow: var(--tone-teal-glow); }
.pane--amber   { --tile-tone: var(--tone-amber);   --tile-glow: var(--tone-amber-glow); }
.pane--gold    { --tile-tone: var(--tone-gold);    --tile-glow: var(--tone-gold-glow); }
.pane--rose    { --tile-tone: var(--tone-rose);    --tile-glow: var(--tone-rose-glow); }
.pane--mint    { --tile-tone: var(--tone-mint);    --tile-glow: var(--tone-mint-glow); }
.pane--indigo  { --tile-tone: var(--tone-indigo);  --tile-glow: var(--tone-indigo-glow); }
.pane--crimson { --tile-tone: var(--tone-crimson); --tile-glow: var(--tone-crimson-glow); }
.pane--violet  { --tile-tone: var(--tone-violet);  --tile-glow: var(--tone-violet-glow); }
.pane--copper  { --tile-tone: var(--tone-copper);  --tile-glow: var(--tone-copper-glow); }
.pane--silver  { --tile-tone: var(--tone-silver);  --tile-glow: var(--tone-silver-glow); }

/* ── "Mostrar todo" y "Contraer todo" ─────────────────────────────────────
   Las dos se APAGAN en vez de esconderse -- la primera con todo abierto, la
   segunda con todo cerrado --: si desaparecieran, la cuadricula del mosaico
   daria un salto cada vez que se abre o se cierra una seccion. Es la misma
   regla que ya tiene .chnav__all en la ficha de personaje. */
.pnav__all:disabled {
    opacity: 0.42;
    cursor: default;
}
.pnav__all:disabled:hover {
    transform: none;
    background: var(--grad-tile);
    box-shadow: none;
}

/* El primer titulo de dentro de una seccion no se separa de la cabecera del
   plegable: ya hay una raya y un cambio de fondo entre los dos. Solo lo lleva
   "Personajes", que pinta un <h3> por servidor dentro del cuerpo. */
.pane > .fold__body > .sec-title:first-child {
    margin-top: 4px;
    padding-top: 0;
    border-top: 0;
}
.pane > .fold__body > .sec-title:first-child::before { display: none; }

/* "Contraer todo" y el boton de vuelta devuelven al mosaico, y la cabecera del sitio
   flota por encima: sin este margen de desplazamiento el mosaico volvia con su titulo
   y media primera fila de baldosas tapados por la barra. Medido: la barra llega a los
   66 px y el mosaico aterrizaba en 0. Es el mismo valor que ya tienen `.pane` y `.chnav`. */
.pnav { scroll-margin-top: calc(var(--nav-height, 84px) + 18px); }

/* ══════════════════════════════════════════════════════════════════════════════
   LA PESTAÑA DE IA DEL COMPAÑERO (necROmantic 2026-08-27, encargo del usuario)
   Marcado en themes/default/character/_companero_body.php, datos en
   Flux_Companero::aiPanel() y ordenes en modules/character/companero.php.

   HABLA EL MISMO IDIOMA VISUAL QUE .cpan (el panel de asistencia automática), que es
   lo que se pidió: mismas tarjetas de interruptor, mismas fichas de monstruo, mismo
   buscador. Pero NO reutiliza sus clases, y no es por gusto: allí el interruptor es un
   <input type="checkbox"> y aquí es un <button> que manda un formulario (este panel
   funciona sin JavaScript), así que el estado no se pinta con `:checked + …` sino con
   `[aria-checked]`. Colgar dos mecánicas distintas del mismo nombre de clase es como se
   consigue que arreglar una rompa la otra.

   El acento es --gold, el del bloque .compa, y no la rampa --aq-gold-* de .cpan: esto
   es una pestaña más de la ficha del Compañero y tiene que leerse como sus hermanas.
   Ni un color escrito a mano.
   ══════════════════════════════════════════════════════════════════════════════ */

/* --- Ayudas y avisos ------------------------------------------------------------ */

.compa__iahelp {
    margin: .25rem 0 0;
    font-size: .77rem;
    line-height: 1.5;
    color: var(--text-muted);
}
.compa__iahelp b { color: var(--text-primary); font-weight: 600; }

/* "Esta lista está apagada". No es un error, así que no va en rojo: es un estado, y lo
   que tiene que hacer es explicar por qué una lista llena no está haciendo nada.
   La marca lateral va en --aq-gold-mid y no en --gold-dim (rosa): en esta pestaña el oro
   es el color de "estado", y era la última pieza que se había quedado en la otra rampa. */
.compa__ianote {
    margin: .5rem 0 0;
    padding: .4rem .55rem;
    border-left: 2px solid var(--aq-gold-mid);
    background: var(--bg-table-alt);
    border-radius: 0 6px 6px 0;
    font-size: .76rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.compa__iaempty {
    margin: .5rem 0 0;
    font-size: .78rem;
    font-style: italic;
    color: var(--text-muted);
}

/* --- Los tres desplegables ------------------------------------------------------ */

.compa__iamodes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: .6rem;
    margin-bottom: 4px;
}

/* Cada desplegable es su propio <form> porque cada uno manda su propia orden. La rejilla
   de dos columnas deja el botón de confirmar pegado al selector y la ayuda debajo,
   cruzando las dos: sin el `grid-column`, la ayuda se metía en la columna del botón y
   salía en tres palabras por línea. */
.compa__iamode {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: end;
    gap: .4rem;
    margin: 0;
    padding: .6rem .7rem;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 7px;
}
.compa__iamode > .compa__iahelp { grid-column: 1 / -1; }

/* La ayuda LARGA, plegada (necROmantic 2026-09-03, con los dos ajustes de kiteo). Los dos
   traen el texto entero del @autoplay -- cinco parrafos el de la prioridad --, y suelto bajo
   el desplegable hacia que su tarjeta midiese diez veces mas que las otras de la rejilla.
   Mismo planteamiento que `.prefs-more`: <details> nativo, sin JS, con teclado de serie.
   Cruza las dos columnas igual que la ayuda corta, o el <details> se metia en la columna del
   boton de confirmar. */
.compa__iamore {
    grid-column: 1 / -1;
    margin-top: .25rem;
}

.compa__iamore-sum {
    display: inline-block;
    cursor: pointer;
    padding: .1rem 0;
    font-size: .77rem;
    color: var(--aq-gold);
}

.compa__iamore-sum::marker,
.compa__iamore-sum::-webkit-details-marker { color: var(--aq-gold); }

.compa__iamore-sum:hover { text-decoration: underline; }

/* Dentro del plegado la ayuda ya no es hija directa de la tarjeta, asi que la sangria de la
   izquierda es lo que la ata visualmente al rotulo que la abre. */
.compa__iamore > .compa__iahelp {
    margin-top: .35rem;
    padding-left: .6rem;
    border-left: 2px solid var(--border);
}

.compa__iamode-lab {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    min-width: 0;
}

.compa__iamode-name {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .85rem;
    font-weight: 600;
    color: var(--text-primary);
}
.compa__iamode-ico { color: var(--aq-gold); font-size: .95rem; }

/* El selector ocupa el ancho de su celda: los rótulos son frases enteras ("Buscar y
   destruir — sin límite de distancia") y con el `flex: 0 1 240px` de .compa__select se
   quedaban cortados. */
.compa__iasel { flex: 1 1 auto; width: 100%; }

/* El botón de confirmar sólo hace falta SIN JavaScript: con él, el selector se manda
   solo al soltarlo. La marca la pone el propio guion en la raíz del documento, que es lo
   único que sobrevive a los repintados del panel. */
.compa-ia-js .compa__iago { display: none; }

/* --- Los interruptores ---------------------------------------------------------- */

.compa__iafns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: .55rem;
    margin-bottom: 4px;
}

/* La TARJETA. El <form> es la tarjeta entera y dentro van el botón-interruptor y la
   ayuda: la ayuda tiene que quedar DENTRO de la tarjeta pero FUERA del botón, o leerla
   sería parte del nombre del control y tocarla lo cambiaría. */
.compa__iafn {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: .6rem .7rem;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 7px;
    transition: border-color .15s, background .15s;
}
.compa__iafn:hover { background: var(--bg-table-alt); border-color: var(--border-light); }

/* Dentro de una lista de monstruos la tarjeta va a una sola columna y sin fondo propio:
   la tarjeta de la lista ya es la caja, y una caja dentro de otra caja se lee como dos
   cosas distintas. */
.compa__iafns--inlist { grid-template-columns: 1fr; gap: .4rem; margin: .6rem 0 0; }
.compa__iafn--inlist { background: var(--bg-table-alt); }
.compa__iafn--inlist:hover { background: var(--bg-input); }

/* EL INTERRUPTOR ES UN BOTÓN: manda un formulario y por eso hay que quitarle el aspecto
   de botón entero. Lo que se ve es la pastilla, el icono y el nombre. */
.compa__iasw {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    width: 100%;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    color: inherit;
    font-family: inherit;
    letter-spacing: normal;
    text-align: left;
    cursor: pointer;
    transition: none;
}

/* necROmantic 2026-08-27 (aviso del usuario: «los switches se resaltan cosas que no se
   deberían resaltar al señalarse»).

   LA TRAMPA, QUE YA HA MORDIDO TRES VECES EN ESTA HOJA. flux.css trae, para TODO <button>:

       button:hover { transform: translateY(-1px);
                      box-shadow: var(--shadow-secondary-hover);
                      background: var(--grad-secondary-button-hover); }

   `button:hover` vale 0-1-1 y `.compa__iasw` vale 0-1-0, así que el fondo de la regla
   global GANA por especificidad aunque aquí se pida `background: none` -- y `transform`
   y `box-shadow` ni siquiera se disputan, porque arriba no se declaran. Resultado: al
   pasar el ratón el interruptor entero se convertía en una pastilla degradada morada con
   resplandor, que se comía el nombre, y saltaba un píxel hacia arriba.

   El reset va con :hover, :focus Y :active porque el degradado vuelve en cada uno de los
   tres. Se declara con la misma forma que ya usan .hero-nav y .news-nav para el mismo
   problema; la diferencia es que aquí no hay transform propio que conservar.

   En la pantalla de asistencia esto no pasa porque allí el interruptor es un <label> con
   un <input> dentro: nunca fue un <button> y la regla global nunca lo tocó. */
.compa__iasw:hover,
.compa__iasw:focus,
.compa__iasw:active {
    transform: none;
    box-shadow: none;
    background: none;
}

/* El icono y la pastilla, en UNA sola columna y el icono encima: es el mismo reparto
   que en el panel de asistencia, donde en columna aparte el icono empujaba el texto y
   las tres piezas competían por la vista. */
.compa__iasw-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 0 0 auto;
}
.compa__iasw-ico {
    font-size: 31px;
    margin-bottom: 7px;
    line-height: 1;
    color: var(--text-muted);
    transition: color .18s;
}

.compa__iasw-track {
    position: relative;
    flex: 0 0 auto;
    width: 2.3rem;
    height: 1.25rem;
    margin-top: .1rem;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    transition: background .18s, border-color .18s;
}
.compa__iasw-knob {
    position: absolute;
    top: 50%;
    left: .15rem;
    width: .9rem;
    height: .9rem;
    margin-top: -.45rem;
    background: var(--text-muted);
    border-radius: 50%;
    transition: left .18s, background .18s;
}

/* EL ESTADO SALE DE `aria-checked` Y DE NINGÚN OTRO SITIO. Una clase paralela sería una
   segunda verdad que un día dice lo contrario que el atributo, y el atributo es el que
   lee quien no ve la pantalla. */
/* necROmantic 2026-08-27: la rampa es --aq-gold-*, NO --gold. En esta piel `--gold` es
   ROSA-MAGENTA (#dfa0c6) y conserva ese nombre solo por compatibilidad -- la misma nota
   está escrita en .gift-btn, donde ya costó un hover rosa. El interruptor encendido tiene
   que ser exactamente el mismo oro que en Asistencia automática, porque son el mismo
   control diciendo lo mismo: si uno es rosa y el otro naranja, el color deja de
   significar «encendido» y pasa a significar «otra pantalla».

   Los tres valores son los de .cpan__switch-input:checked, copiados uno a uno:
   soft en el carril, --aq-gold en el filo, light en la bola y en el icono. */
.compa__iasw[aria-checked="true"] .compa__iasw-track {
    background: var(--aq-gold-soft);
    border-color: var(--aq-gold);
}
.compa__iasw[aria-checked="true"] .compa__iasw-knob {
    left: calc(100% - 1.05rem);
    background: var(--aq-gold-light);
}
.compa__iasw[aria-checked="true"] .compa__iasw-ico { color: var(--aq-gold-light); }

.compa__iasw:focus-visible { outline: none; }
.compa__iasw:focus-visible .compa__iasw-track { box-shadow: 0 0 0 2px var(--aq-gold-glow); }

.compa__iasw-name {
    padding-top: .1rem;
    font-size: .87rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--text-primary);
}
/* necROmantic 2026-08-27: AQUÍ NO SE TIÑE EL NOMBRE al pasar el ratón. Lo hacía, y era
   parte de lo mismo que se veía raro: en Asistencia automática el texto no cambia nunca
   de color -- lo que responde al ratón es la tarjeta (.compa__iafn:hover), y lo que
   responde al estado es la pastilla. Tres cosas reaccionando a la vez se leen como un
   fallo, no como una respuesta. */

/* --- Las tres listas de monstruos ------------------------------------------------ */

.compa__ialists {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: .9rem;
}

.compa__ialist {
    display: flex;
    flex-direction: column;
    padding: .8rem .85rem;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 8px;
}

/* Apagada se atenúa, pero NO se esconde ni se bloquea nada: se sigue pudiendo añadir y
   quitar monstruos con la lista apagada, que es justo lo que se hace antes de volver a
   encenderla. El aviso de dentro dice lo que la opacidad sólo insinúa. */
.compa__ialist--off { border-style: dashed; }
.compa__ialist--off .compa__ialist-head b { color: var(--text-muted); }

.compa__ialist-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .5rem;
}
.compa__ialist-head b { font-size: .88rem; color: var(--text-primary); }
.compa__ialist-ico { color: var(--aq-gold); }

/* --- Buscador y resultados ------------------------------------------------------- */

.compa__iaadd {
    display: flex;
    gap: .4rem;
    margin: .6rem 0 0;
}
.compa__iaq { flex: 1 1 auto; min-width: 0; }

.compa__iares {
    margin-top: .4rem;
    max-height: 15rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    border: 1px solid var(--border-light);
    border-radius: 6px;
    background: var(--bg-surface-alt);
}
/* El atributo `hidden` deja de esconder en cuanto una clase le pone `display`, y esta
   caja tiene reglas propias: hay que devolvérselo a mano. Es la trampa que ya ha mordido
   dos veces en esta ficha. */
.compa__iares[hidden] { display: none; }

/* LA FILA ENTERA ES UN BOTON desde el 2026-08-29 (antes era un <div> con un boton por id). Al
   pasar a <button> hay que devolverle a mano lo que el navegador le quita: el fondo, el borde, la
   alineacion del texto y el ancho completo. Sin `width: 100%` una fila corta dejaria media lista
   sin zona pulsable, que es peor que el problema que esto viene a resolver. */
.compa__iahit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    width: 100%;
    padding: .45rem .6rem;
    border: 0;
    border-bottom: 1px solid var(--border);
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.compa__iahit:last-child { border-bottom: 0; }

.compa__iahit:hover,
.compa__iahit:focus-visible { background: var(--bg-input); }

.compa__iahit-txt {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    flex: 1 1 8rem;
    min-width: 0;
}
.compa__iahit-txt b { font-size: .84rem; color: var(--text-primary); }
.compa__iahit-txt span {
    font-size: .74rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* UN BOTÓN POR CADA ID, y no uno por nombre. En Ragnarok hay seis "Poring" con ids
   distintos e indistinguibles desde el juego: la orden del servidor mete UNO, así que se
   enseñan todos y se ve exactamente cuál entra. */
.compa__iahit-ids {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
}
.compa__iaid {
    padding: .15rem .45rem;
    background: var(--bg-input);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    color: var(--text-muted);
    font-family: inherit;
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: color .15s, border-color .15s, background .15s;
}
/* Misma historia que el interruptor: son <button>, así que hay que anular a mano el
   degradado, el salto y la sombra que flux.css le pone a todo botón al señalarlo. */
.compa__iaid:hover {
    transform: none;
    box-shadow: none;
    background: var(--bg-table-alt);
    border-color: var(--aq-gold);
    color: var(--aq-gold);
}
.compa__iaid:focus-visible { outline: 1px solid var(--aq-gold); }

/* --- Las fichas de lo que hay dentro --------------------------------------------- */

.compa__iachips {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    gap: .35rem;
    margin: .6rem 0 0;
    padding: 0;
    list-style: none;
    max-height: 15rem;
    overflow-y: auto;
    /* Al llegar al final, la rueda no sigue arrastrando la página de debajo. */
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--border-light) transparent;
}
.compa__iachips::-webkit-scrollbar-thumb { background: var(--border-light); }
.compa__iachips::-webkit-scrollbar-track { background: transparent; }

.compa__iachip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .25rem .2rem .45rem;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border-light);
    border-radius: 999px;
    font-size: .78rem;
}
/* UN ID SIN NOMBRE SE PINTA IGUAL: un monstruo retirado de la base deja su número
   escrito y sigue ocupando uno de los 256 huecos. Se marca con el borde de trazos para
   que se distinga de un vistazo, pero NUNCA se esconde -- una lista que no enseña todo
   lo que contiene deja al jugador contando doce donde el contador dice trece. */
.compa__iachip--raw { border-style: dashed; }

.compa__iachip-txt { display: inline-flex; align-items: baseline; gap: .3rem; }
.compa__iachip-txt b { color: var(--text-primary); font-weight: 600; }
.compa__iachip-id,
.compa__iachip-lv {
    font-style: normal;
    font-size: .71rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* El retrato del monstruo. Puede no haberlo (el servidor manda img=null cuando no está
   cacheado en data/monsters/) y entonces la ficha va sin él, no con un icono roto. */
.compa__iamob {
    width: 22px;
    height: 22px;
    object-fit: contain;
    image-rendering: pixelated;
    flex: none;
}
.compa__iahit .compa__iamob { width: 30px; height: 30px; }

/* La × de quitar. Cada ficha lleva su propio <form>, así que el formulario no puede
   aportar caja ni hueco: la ficha es la caja. */
.compa__iachip form { display: inline-flex; margin: 0; }
.compa__iax {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 50%;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
/* `#fff` y no --text-primary: es el mismo valor que usa .cpan__chip-x, y sobre el rojo
   de aviso hace falta el blanco puro para que el aspa siga leyéndose. */
.compa__iax:hover {
    transform: none;
    box-shadow: none;
    background: var(--accent-red);
    color: #fff;
}
.compa__iax:focus-visible { outline: 1px solid var(--aq-gold); }

/* "Vaciar la lista" se queda abajo del todo y separado: es la única acción de esta
   tarjeta que no tiene vuelta atrás. `margin-top: auto` la empuja al fondo para que las
   tres tarjetas de la fila la tengan a la misma altura por larga que sea cada lista. */
.compa__iaclear { margin: .7rem 0 0; padding-top: .6rem; border-top: 1px solid var(--border); }

/* --- Los controles COMPARTIDOS, solo dentro de esta pestana ---------------------------

   `.compa__btn`, `.compa__input` y `.compa__select` son de TODO el panel de Companero, no
   de esta pestana: el resto de las pestanas (Basico, Equipamiento, Habilidades...) llevan
   la rampa rosa desde el primer dia y ahi se queda. Aqui se reescriben acotadas al panel
   de la IA, que es el que tiene que ser indistinguible de Asistencia automatica.

   El acotador es el propio `data-compa-panel="ia"` del contenedor -- el atributo que ya
   existe para que el guion sepa que panel ensenar --, asi que no hay una clase nueva que
   alguien pueda olvidarse de poner: si el panel esta, el color esta.

   El `:hover` del boton repite `background` y anade `transform: none` por lo mismo que el
   interruptor: sin eso, `button:hover` de flux.css gana y el boton se convierte en una
   pastilla degradada que salta. */
[data-compa-panel="ia"] .compa__input:focus,
[data-compa-panel="ia"] .compa__select:focus { outline: none; border-color: var(--aq-gold); }

/* El hover se copia LITERAL de .cpan__btn--mini, que es el boton equivalente en
   Asistencia automatica: fondo un punto mas claro y el texto en primario. NO se pone oro
   -- lo comprobe pintando los dos lados y alli el boton no se tine, solo se aclara; el
   oro es el idioma del INTERRUPTOR encendido, y gastarlo tambien en los botones le quita
   el significado.

   Aqui NO se anula el `transform`/`box-shadow` de la regla global, al reves que en el
   interruptor: en un boton pequeno ese salto de un pixel se lee como un boton normal
   respondiendo, y es exactamente lo que hace el boton de Asistencia. Lo que estorbaba era
   en el interruptor, que no es un boton aunque este hecho con uno. Lo que si hace falta es
   repetir `background`, porque si no gana el degradado de flux.css. */
[data-compa-panel="ia"] .compa__btn:hover {
    background: var(--bg-table-alt);
    border-color: var(--border-light);
    color: var(--text-primary);
}
[data-compa-panel="ia"] .compa__btn:focus-visible { outline: 1px solid var(--aq-gold); }
[data-compa-panel="ia"] .compa__btn:disabled:hover {
    border-color: var(--border-light);
    color: var(--text-primary);
}

/* Quien haya pedido menos animación no la tiene. Los estados siguen viéndose: lo que se
   quita es el viaje, no el cambio. */
@media (prefers-reduced-motion: reduce) {
    .compa__iafn,
    .compa__iasw-ico,
    .compa__iasw-track,
    .compa__iasw-knob,
    .compa__iaid { transition: none; }
}

/* ==========================================================================
   necROmantic 2026-08-26: LA MATRIZ DE ZONAS (3 zonas x 6 ayudantes).
   Vive en el plegable "Quienes te acompanan" de la ficha.

   Es una tabla conceptual pero NO un <table>: en movil una tabla de tres columnas obliga a
   scroll horizontal o a letra ilegible, y aqui lo que se necesita es que cada fila se pueda
   apilar. Con grid, el ancho de columna se declara una vez y el movil solo tiene que cambiar
   esa declaracion.
   ========================================================================== */

.aizone {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 14px 0 22px;
}

.aizone__head,
.aizone__row {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
    gap: 8px;
    align-items: center;
}

.aizone__head { padding: 0 10px 4px; }

.aizone__col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-align: center;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.aizone__col b { color: var(--gold); font-size: 0.84rem; }
.aizone__col em { font-style: normal; font-size: 0.72rem; line-height: 1.3; }
.aizone__col i { color: var(--gold-dim, var(--gold)); }

.aizone__row {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
}

.aizone__who {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-size: 0.86rem;
    color: var(--text-primary);
}

.aizone__who i { flex: none; color: var(--gold-dim, var(--gold)); }

/* La casilla entera es pulsable, no solo el cuadrito: en movil un objetivo de 14px es una
   invitacion a fallar el toque. */
.aizone__cell {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 34px;
    padding: 2px 4px;
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.15s;
}

.aizone__cell:hover { background: var(--bg-surface-alt); }

/* El <input> real se queda: es quien lleva el estado, el foco y el teclado. Solo se saca de la
   vista, NUNCA con display:none -- eso lo sacaria tambien del orden de tabulacion. */
.aizone__box {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.aizone__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 22px;
    height: 22px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-surface-alt);
    color: transparent;
    font-size: 0.7rem;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.aizone__box:checked + .aizone__mark {
    border-color: var(--gold);
    background: var(--gold);
    color: var(--bg-surface);
}

/* Pista de foco por teclado: sin esto, tabular por dieciocho casillas es ir a ciegas. */
.aizone__box:focus-visible + .aizone__mark {
    outline: 2px solid var(--border-accent, var(--gold));
    outline-offset: 2px;
}

/* necROmantic 2026-08-27: LA MATRIZ YA NO SE TOCA, la decide el servidor
   (conf/battle/necro_zonas_ia.conf). La celda pasa de <label> con casilla a <span> con una
   marca, y hay que deshacer lo que la version editable daba por hecho: ni cursor de mano ni
   resaltado al pasar por encima, porque los dos prometen que ahi se puede pulsar.

   Un si/no y no una casilla desactivada: una casilla gris se lee como "esto deberia poder
   tocarse y algo va mal", y esto no esta roto -- es que no es tuyo. */
.aizone__cell--ro { cursor: default; }
.aizone__cell--ro:hover { background: none; }

.aizone__cell--ro.is-on .aizone__mark {
    border-color: var(--aq-gold, var(--gold));
    background: var(--aq-gold, var(--gold));
    color: var(--bg-surface);
}

/* El "no" se dibuja, no se deja en blanco. Una celda vacia y una celda que no ha cargado se
   parecen demasiado; el guion dice "he mirado y es que no". */
.aizone__cell--ro.is-off .aizone__mark {
    border-color: var(--border);
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    opacity: 0.75;
}

/* El nombre de la zona dentro de la casilla solo hace falta cuando la cabecera desaparece,
   o sea en movil. En escritorio seria repetir tres veces lo que ya dice la columna. */
.aizone__cellname { display: none; font-size: 0.76rem; color: var(--text-muted); }

@media (max-width: 640px) {
    /* La cabecera de columnas no cabe: se retira y cada casilla pasa a decir su propia zona. */
    .aizone__head { display: none; }

    .aizone__row {
        grid-template-columns: 1fr;
        gap: 4px;
    }

    .aizone__who {
        padding-bottom: 4px;
        border-bottom: 1px solid var(--border);
        font-weight: 600;
    }

    .aizone__cell { justify-content: flex-start; }
    .aizone__cellname { display: inline; }
}

@media (prefers-reduced-motion: reduce) {
    .aizone__cell,
    .aizone__mark { transition: none; }
}

/* ==========================================================================
   EL PLANIFICADOR DEL COMPANERO (necROmantic 2026-08-27)

   Peticion del usuario: Caracteristicas y Habilidades como el simulador -- repartir libre, sin
   ida y vuelta por click, y un solo boton de Aceptar. Sin campos de numero: solo + y -.

   LAS DOS CARAS. La pantalla trae DOS paneles: el nuevo (`.compa__plan`, que pinta el guion) y el
   de formularios de siempre (`.compa__legado`). Mientras el guion no arranca se ve el viejo, que
   es el que funciona sin JavaScript; en cuanto arranca se marca `.compa-plan-vivo` en la raiz y
   se cambian las tornas. Asi una pagina sin JS -- o con un fallo al traer el arbol -- no se queda
   en blanco: se queda como estaba ayer.
   ========================================================================== */

.compa__plan,
.compa [data-compa-plan-solo] { display: none; }

.compa-plan-vivo .compa__legado { display: none; }
.compa-plan-vivo .compa__plan,
.compa-plan-vivo [data-compa-plan-solo] { display: block; }

.compa__planbarra {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
}

/* --- Las clases del linaje, una caja cada una --------------------------------------------- */

.compa__plclase {
    margin: 0 0 14px;
    padding: 10px 12px;
    background: var(--bg-table-row);
    border: 1px solid var(--border);
    border-radius: 8px;
}

.compa__plclase-cab {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem;
    margin-bottom: .6rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--border);
}

.compa__plclase-nombre { font-size: .95rem; color: var(--text-primary); }

/* La cobertura. En oro cuando esta cubierta, apagada cuando no: es un estado, no un aviso, asi
   que NO va en rojo -- el rojo aqui diria "has hecho algo mal" y no ha pasado nada malo. */
.compa__plclase-cob {
    font-size: .78rem;
    color: var(--text-muted);
    margin-right: auto;
}
.compa__plclase-cob.es-ok { color: var(--aq-gold-light); }

/* --- La rejilla de habilidades ------------------------------------------------------------ */

.compa__planskills { margin-top: .4rem; }

.compa__plskills {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: .5rem;
}

.compa__plskill {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    padding: .5rem .6rem;
    background: var(--bg-table-alt);
    border: 1px solid var(--border);
    border-radius: 7px;
}
/* LA QUE YA SABE (necROmantic 2026-08-27, peticion del usuario: "#9d7ad1 y con un relleno que
   haga efecto de relieve suave y redondeado").

   El color va como variable local y no suelto: las cuatro capas de abajo son el MISMO morado a
   distintas opacidades, y tenerlo escrito cuatro veces significa que el dia que se retoque
   quedaran tres iguales y una distinta. `--sab-rgb` guarda los componentes para poder montar los
   rgba(); el hex se deja al lado para que se pueda buscar por el.

   EL RELIEVE SON DOS LINEAS DE UN PIXEL, no una sombra grande: un `inset` claro arriba y otro
   oscuro abajo es como se finge que la luz viene de arriba. Con la sombra exterior floja despega
   la tarjeta del fondo lo justo; mas de eso, en una rejilla de cuarenta tarjetas, se convierte en
   ruido. El degradado del relleno va de arriba a abajo por el mismo motivo: es la cara iluminada
   apagandose, no un adorno.

   `background` lleva DOS capas y el color plano va el ULTIMO: en CSS la primera capa es la de
   arriba, asi que el degradado tiene que ir antes que `--bg-table-alt` o lo taparia entero. */
.compa__plskill.es-sabida {
    --sab-rgb: 157, 122, 209;   /* #9d7ad1 */

    border-color: rgb(var(--sab-rgb));
    border-radius: 9px;
    background:
        linear-gradient(180deg,
            rgba(var(--sab-rgb), 0.17) 0%,
            rgba(var(--sab-rgb), 0.08) 48%,
            rgba(var(--sab-rgb), 0.02) 100%),
        var(--bg-table-alt);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.11),
        inset 0 -1px 0 rgba(0, 0, 0, 0.26),
        0 1px 2px rgba(0, 0, 0, 0.22);
}

/* LOS OTROS TRES ESTADOS (necROmantic 2026-08-28, petición del usuario: "que los skills
   aprendibles se muestren resaltados un poco, que no se vean apagados y los aprendidos se muestren
   con un relieve un poco más fuerte que hasta ahora, y que las skills maximizadas se muestren más
   fuerte todavía").

   La escalera completa, y las reglas van EN ESE ORDEN para que gane siempre la de más abajo:

     (base)      bloqueada    le faltan requisitos -> apagada, y es la única que debe verse así
     .es-abierta aprendible   la puede subir YA    -> a plena luz, con filo
     .es-sabida  a medias     el relieve morado de arriba (2026-08-27), ahora un punto más marcado
     .es-max     al máximo    el más fuerte: borde de 2px y halo

   Se reutiliza `--sab-rgb` en las tres para que el día que se retoque el morado se muevan juntas.
   Ese color se declara dentro de `.es-sabida`, así que las otras dos lo repiten: una variable en
   una regla hermana no se hereda. */
.compa__plskill {
    opacity: 0.6;                      /* bloqueada: apagada a propósito */
    transition: opacity .15s ease, box-shadow .15s ease, border-color .15s ease;
}

.compa__plskill.es-abierta {
    --sab-rgb: 157, 122, 209;
    opacity: 1;
    border-color: rgba(var(--sab-rgb), 0.55);
    box-shadow: inset 0 0 0 1px rgba(var(--sab-rgb), 0.10);
}

/* Un punto más de relieve que hasta hoy: la sombra exterior pasa de 1px a 2 y el filo superior
   sube un poco. Sigue siendo discreto -- son cuarenta tarjetas en una rejilla --, pero ya no se
   confunde con la de al lado que solo está abierta. */
.compa__plskill.es-sabida {
    opacity: 1;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.14),
        inset 0 -1px 0 rgba(0, 0, 0, 0.28),
        0 2px 5px rgba(0, 0, 0, 0.30);
}

/* AL MÁXIMO. El `padding` se compensa por el borde de 2px: sin esa resta, subir la última
   habilidad al tope daría un salto de un píxel en toda la fila de la rejilla. */
.compa__plskill.es-max {
    --sab-rgb: 157, 122, 209;
    opacity: 1;
    border: 2px solid rgb(var(--sab-rgb));
    padding: calc(.5rem - 1px) calc(.6rem - 1px);
    border-radius: 9px;
    background:
        linear-gradient(180deg,
            rgba(var(--sab-rgb), 0.26) 0%,
            rgba(var(--sab-rgb), 0.13) 48%,
            rgba(var(--sab-rgb), 0.04) 100%),
        var(--bg-table-alt);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.16),
        inset 0 -1px 0 rgba(0, 0, 0, 0.30),
        0 3px 9px rgba(0, 0, 0, 0.34),
        0 0 0 1px rgba(var(--sab-rgb), 0.28);
}

/* LA CADENA DE REQUISITOS al señalar una habilidad (necROmantic 2026-08-28).

   Se usa el DORADO y no el morado a propósito: el morado ya significa "cuánto tengo de esto", y
   pintar el resaltado del mismo color obligaría a distinguir dos cosas distintas por el tono. El
   dorado no significa nada más en esta pantalla, así que puede significar esto.

   `outline` y no `border`: el borde ya está ocupado por el estado, y un outline no ocupa sitio ni
   mueve la rejilla -- resaltar seis tarjetas no puede reorganizar la página debajo del cursor. */
.compa__plskill.es-requisito {
    opacity: 1;
    outline: 2px solid var(--gold);
    outline-offset: 1px;
}

/* ⚠️ LA ETIQUETA "necesita nivel N" SALE DEL FLUJO (necROmantic 2026-08-29).
 *
 * Aparece y desaparece al señalar, así que no puede mover NADA. El primer intento la dejó dentro
 * de la cabecera con `flex-wrap: nowrap`, y no bastó: medido, las cuatro tarjetas resaltadas
 * crecían 9,6 px -- la etiqueta es más alta que el texto que la rodea y estiraba la fila, aunque
 * no llegara a partirse en dos líneas.
 *
 * Con `position: absolute` no participa en el cálculo de altura y el temblor es imposible por
 * construcción. Se ancla ABAJO a la derecha, sobre el hueco que ya está reservado para el aviso:
 * ahí no se choca con el `9/9` de la cabecera, y en una habilidad que es requisito de otra ese
 * hueco está vacío casi siempre. */
.compa__plskill { position: relative; }

.compa__plskill-req {
    position: absolute;
    right: .6rem;
    bottom: .5rem;
    max-width: 60%;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--gold);
    color: var(--bg-content);
    font-size: .68rem;
    font-weight: 700;
    white-space: nowrap;
}

/* El aviso de "al pulsar subirá antes lo que falta". No es un error, así que no va en rojo como
   `.compa__plskill-no`: es lo que va a pasar. */
.compa__plskill-cad {
    font-size: .72rem;
    font-style: normal;
    color: var(--gold);
}

/* El `+` que resuelve la cadena entera se marca, para que se vea que hace algo más que sumar uno. */
.compa__step.es-cadena {
    border-color: var(--gold);
    color: var(--gold);
}

/* LA ESTRELLA DE DOS ANILLOS DEL COMPAÑERO (necROmantic 2026-08-28).

   Se calca la de la ficha (`.chv__rad*`) en rejilla, radios y rótulos -- misma figura, misma
   lectura -- y lo único propio son las DOS capas de datos: lo de ahora y lo proyectado.

   El relleno proyectado va MUY translúcido y con el borde discontinuo: tiene que leerse como "esto
   todavía no ha pasado". El de ahora va sólido encima. Y el orden en el marcado los pinta en ese
   orden, así que al subir puntos la proyección asoma como un halo alrededor de lo actual. */
/* ═══ EQUIPAMIENTO REORDENADO (necROmantic 2026-08-29, petición del usuario) ═══════════════════
 *
 * Dos columnas: lo PUESTO a la izquierda y el almacén a la derecha ("esta de inventario debe estar
 * a la derecha del Equipado"). El almacén se lleva la parte ancha porque es donde se lee y se
 * busca; lo puesto son diez casillas de tamaño fijo.
 */
.compa__eqwrap {
    display: grid;
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

@media (max-width: 900px) {
    .compa__eqwrap { grid-template-columns: 1fr; }
}

/* LA ZONA DE LO PUESTO SE MARCA, PERO NO SE ROTULA.
 *
 * Petición literal: «no quiero que en equipamiento ni en disfraces se muestre la etiqueta de
 * "Equipado" pero quiero que se vea resaltado que esa es la zona de Equipado». Así que nada de
 * título: un marco tenue, un fondo propio y un filo dorado a la izquierda. Se lee como "esto es
 * otra cosa que la lista de al lado" sin gastar una línea en decirlo. */
.compa__gear--zona {
    padding: 12px;
    border: 1px solid var(--gold-dim);
    border-left: 3px solid var(--gold);
    border-radius: 10px;
    background: var(--bg-surface-alt);
}

/* LA PASTILLA "equipado" NO SE PINTA EN ESTAS DOS ZONAS (necROmantic 2026-08-29).
 *
 * Petición literal: «no quiero que en equipamiento ni en disfraces se muestre la etiqueta de
 * "Equipado" pero quiero que se vea resaltado que esa es la zona de Equipado».
 *
 * Y tiene razón: dentro del marco de lo puesto, decir "equipado" en cada una de las diez piezas es
 * repetir diez veces lo que el marco ya dice una. Se esconde con CSS y no se quita del ayudante
 * `$cvItemTags`, que es COMPARTIDO: en el almacén de la cuenta, en la mochila o en la ficha del
 * personaje esa misma pastilla sí informa de algo, porque allí conviven piezas puestas y sueltas.
 *
 * Se esconden sólo la de "equipado"; las de "sin identificar", "roto" y "vinculado" se quedan,
 * porque ésas siguen diciendo algo que el marco no dice. */
.compa__gear--zona .stg__tag--on,
[data-compa-subpanel="eq-disfraces"] .stg__tag--on {
    display: none;
}

/* ═══ EL ALMACÉN, UNA FILA POR OBJETO ═════════════════════════════════════════════════════════
 *
 * «1 objeto por línea cuya altura sea el alto del icono». El icono de Ragnarok mide 24 px, así que
 * la fila mide eso más el aire mínimo para que no se toquen. Con 152 piezas, cada línea que se
 * ahorra son 152.
 */
.compa__stlist {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 520px;
    overflow-y: auto;
}

.compa__strow {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 6px;
    border-radius: 6px;
    min-height: 28px;
}

.compa__strow:nth-child(odd)  { background: var(--alpha-black-34); }
.compa__strow:hover           { background: var(--bg-input); }
.compa__strow--no             { opacity: 0.55; }

.compa__strow-ico {
    flex: none;
    width: 24px;
    height: 24px;
    image-rendering: pixelated;
}
.compa__strow-ico--none { opacity: .25; }

/* ⚠️ `min-width: 0` ES LO QUE HACE QUE EL ELLIPSIS FUNCIONE. Un hijo de flex no se encoge por
   debajo de su contenido salvo que se le diga, así que sin esta línea el nombre empuja la fila y
   desborda en vez de recortarse. Es la trampa clásica de `text-overflow` dentro de flex. */
.compa__strow-nom {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: .82rem;
}

/* ⚠️ Y EL RECORTE HAY QUE REPETIRLO EN EL HIJO. `$cvItemName()` devuelve un `.stg__name`, que es un
   bloque: `text-overflow` recorta la caja que lo declara, no un bloque hijo que la desborde, así
   que el nombre largo se cortaba a hachazo y sin puntos suspensivos. Se veía poco porque hasta hoy
   nada más competía por el ancho de la fila; con las pastillas de cartas al lado, se ve siempre.
   (necROmantic 2026-08-30) */
.compa__strow-nom .stg__name {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* LAS CARTAS DE LA FILA (necROmantic 2026-08-30). Van en la MISMA línea que el nombre para que la
   lista siga midiendo un icono de alto. `flex: 0 1 auto` con `min-width: 0` es lo que hace que sean
   ellas -- y no el nombre -- las primeras en encogerse cuando la columna se estrecha: el nombre ya
   tiene su propio ellipsis y perderlo sería peor que perder una pastilla, porque el nombre completo
   está en el `title` de la fila junto con las cartas. */
.compa__strow-cards {
    /* Se encoge ANTES que el nombre (factor 20 contra 1) pero nunca por debajo de 5em: una
       pastilla reducida a una letra no dice nada y ensucia la fila más que faltar. Pasado ese
       suelo, el que cede es el nombre, que sí tiene puntos suspensivos y `title`. */
    flex: 0 20 auto;
    min-width: 5em;
    max-width: 45%;
    display: flex;
    gap: 4px;
    overflow: hidden;
}

/* Pastilla comprimida: la de `.stg__card` mide para una ficha de tres renglones y aquí haría crecer
   la fila. Sólo cambian el relleno y el cuerpo; el color, el borde y el enlace siguen siendo los
   mismos de la celda de cartas del inventario. */
.compa__strow-cards .stg__card {
    padding: 0 7px;
    font-size: .7rem;
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    display: inline-block;
    line-height: 20px;
}

.compa__strow-id {
    flex: none;
    font-size: .7rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.compa__strow-no {
    flex: none;
    max-width: 40%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: .7rem;
    color: var(--text-muted);
}

/* El botón: sólo el icono. Cuadrado y del alto de la fila, para que la lista no crezca por él. */
.compa__stbtn {
    flex: none;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-surface);
    color: var(--text-primary);
    cursor: pointer;
    font-size: .72rem;
}
.compa__stbtn:hover      { border-color: var(--gold); color: var(--gold); }
.compa__stbtn--swap      { border-color: var(--gold-dim); color: var(--gold); }
.compa__stbtn--swap:hover{ border-color: var(--gold); }

/* La fila oculta por el filtro de categorías. Clase y no `hidden`: la regla de esta casa -- con un
   `display` puesto por otra regla, el atributo `hidden` deja de ocultar nada. */
/* La de ocultar vive con la de `.compa__card`, mas abajo: una sola regla para las dos formas
   de lista, que es lo que hace el filtro comun. */

/* DOS COLUMNAS: los controles a la izquierda, la estrella a la derecha (necROmantic 2026-08-29,
   petición del usuario). `align-items: start` para que la figura no se estire a la altura de la
   columna de controles, y `min-width: 0` en las dos porque un hijo de grid no se encoge por debajo
   de su contenido y la estrella acabaría desbordando la caja.

   Por debajo de 820px se apilan: a media pantalla, dos columnas dejan la figura del tamaño de un
   sello y los seis controles en una tira ilegible. */
/* ============================================================================
 * CARACTERISTICAS DENTRO DE BASICO (necROmantic 2026-08-29)
 * ============================================================================
 * Peticion del usuario: "que quede algo parecido a Estado del PNJ, la grafica alineada a la
 * derecha, los stats debajo de las barras de HP, SP, Exp base y exp job".
 *
 * La seccion se separa de las barras con una linea y aire, no con una caja: es la MISMA lectura
 * -- como esta y en que se convierte -- y encerrarla en un recuadro la volveria a separar
 * visualmente justo despues de haberla juntado.
 */
.compa__caract {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

.compa__caract-h {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.compa__caract-h i { opacity: 0.75; }

.compa__statwrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
    gap: 18px;
    align-items: start;
    margin-bottom: 10px;
}

/* La grafica, PEGADA A LA DERECHA de su columna. Sin esto queda centrada en una columna de 320 px
   y a un ancho de pantalla grande se ve flotando en medio del hueco, que es justo lo que el
   usuario describio como "alineada a la derecha" al pedirla. */
.compa__statcol--rad { display: flex; justify-content: flex-end; }
.compa__statcol--rad .compa__radar { width: 100%; max-width: 320px; }

/* EL NUMERO QUE IMPORTA. Los puntos sin repartir son el dato accionable de toda la seccion -- es lo
   que decide si hay algo que hacer aqui -- y como parrafo suelto se leia igual que una nota al pie.
   Se le da peso y color propio, sin caja: es una frase, no una etiqueta. */
.compa__caract .compa__count {
    margin-bottom: 14px;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--aq-gold, var(--gold));
}

/* Las seis fichas de caracteristica se estrechan un poco dentro de Basico: con la estrella al lado
   la columna izquierda es mas corta, y a 230 px de minimo solo entraban dos por fila en pantallas
   medianas, que dejaba la mitad del hueco vacio debajo. */
.compa__caract .compa__stats { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

@media (max-width: 820px) {
    .compa__statwrap { grid-template-columns: 1fr; }
}

/* LA ESTRELLA, EN TARJETA (necROmantic 2026-08-29, peticion del usuario: "que quede algo parecido a
   Estado del PNJ ... haz que quede bonito").
   Mismo tratamiento que `.chv__radar` de la ficha del jugador -- borde fino, esquina redonda y
   aire -- porque es la MISMA figura leyendo lo mismo. Sin la tarjeta, el hexagono flotaba suelto en
   el hueco de la derecha y no se leia como una pieza, sino como un dibujo perdido. */
.compa__radar {
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin: 0;
    padding: 12px 8px 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--alpha-black-20);
    text-align: center;
}

.compa__rad   { display: block; width: 100%; height: auto; }

.compa__rad-ring      { fill: none; stroke: var(--border); stroke-width: 1; }
.compa__rad-ring--out { stroke: var(--gold-dim); }
.compa__rad-spoke     { stroke: var(--border); stroke-width: 1; }

.compa__rad-area--proy { fill: rgba(223, 160, 198, 0.16); }
.compa__rad-area--hoy  { fill: rgba(157, 122, 209, 0.34); }
.compa__rad-line       { fill: none; stroke-width: 2; }
.compa__rad-line--proy { stroke: var(--gold); stroke-dasharray: 4 3; }
.compa__rad-line--hoy  { stroke: #9d7ad1; }

.compa__rad-abbr { fill: var(--text-muted);   font-size: 11px; font-weight: 700; }
.compa__rad-val  { fill: var(--text-primary); font-size: 11px; }
.compa__rad-val.es-cambia { fill: var(--gold); font-weight: 700; }

.compa__radar-cap {
    display: flex;
    justify-content: center;
    gap: 12px;
    flex-wrap: wrap;
    font-size: 0.72rem;
    color: var(--text-muted);
}

/* La leyenda lleva su propia muestra de color delante: sin ella hay que adivinar cuál de las dos
   líneas es cuál, y con dos morados parecidos eso es adivinar de verdad. */
.compa__radar-key::before {
    content: '';
    display: inline-block;
    width: 10px;
    height: 10px;
    margin-right: 5px;
    border-radius: 2px;
    vertical-align: -1px;
}
.compa__radar-key--hoy::before  { background: #9d7ad1; }
.compa__radar-key--proy::before { background: var(--gold); }

/* El botón que REEMPLAZA en vez de meter en un hueco libre (necROmantic 2026-08-28). Se marca
   porque no hace lo mismo: al pulsarlo se cae una pieza que el jugador lleva puesta, y eso tiene
   que verse ANTES de pulsar, no descubrirse después en el aviso. */
.compa__btn--swap {
    border-color: var(--gold);
    color: var(--gold);
}

.compa__plskill-cab {
    display: flex;
    align-items: center;
    gap: .45rem;
}
.compa__plskill-nombre {
    font-size: .84rem;
    color: var(--text-primary);
    line-height: 1.25;
}
/* El nivel se va al final de la fila y con cifras de ancho fijo, para que la columna de numeros
   no baile entre tarjeta y tarjeta. */
.compa__plskill-lv {
    margin-left: auto;
    font-size: .78rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.compa__plskill-ctl { display: inline-flex; gap: 5px; }

/* El MOTIVO por el que un boton esta apagado, escrito. Un boton gris sin explicacion es lo que
   hace creer que la pagina esta rota. */
.compa__plskill-no,
.compa__plskill-mal {
    font-size: .73rem;
    font-style: normal;
    line-height: 1.4;
    color: var(--text-muted);
}
.compa__plskill-mal { color: var(--accent-red); }

/* EL HUECO DEL AVISO, RESERVADO (necROmantic 2026-08-29, petición del usuario: "no debe temblar la
   pantalla por ese motivo").

   Dos líneas de alto y siempre presente, tenga texto o no. Dos y no una porque los avisos largos
   -- "Al pulsar subirá antes lo que falta (Roundhouse Kick)." -- parten en dos en una tarjeta de
   rejilla, y reservar una sola dejaría el temblor igual de vivo para la mitad de los casos.

   `min-height` en `em` y no en píxeles: si algún día cambia el tamaño de letra del aviso, el hueco
   lo sigue solo. Y `overflow: hidden` como red: un aviso de tres líneas empujaría igual, y es
   preferible recortarlo -- el texto completo sigue en el `title` del botón -- a que la rejilla
   baile. */
.compa__plskill-hueco {
    display: block;
    min-height: 2.8em;      /* 2 líneas a line-height 1.4 */
    overflow: hidden;
}

/* --- El pie: lo que falta por enviar ------------------------------------------------------ */

.compa__planpie {
    margin-top: 1rem;
    padding-top: .7rem;
    border-top: 1px solid var(--border);
}

.compa__plancambios {
    margin: 0 0 .5rem;
    font-size: .82rem;
    color: var(--text-primary);
}

.compa__planaviso {
    margin: 0 0 .4rem;
    font-size: .8rem;
    color: var(--aq-gold-light);
}
.compa__planaviso:empty { display: none; }

.compa__planbtns { display: flex; flex-wrap: wrap; gap: .5rem; }

/* El formulario no tiene nada dentro hasta que se pulsa Aceptar: lo llena el guion. Sin esto
   deja un hueco de margen entre los botones y el texto. */
.compa__planform { margin: 0; }

@media (max-width: 640px) {
    .compa__plskills { grid-template-columns: 1fr; }
    .compa__planbtns .compa__btn { flex: 1 1 auto; }
}

/* ==========================================================================
   EL EQUIPO QUE SALE DEL ALMACEN (necROmantic 2026-08-27)
   ========================================================================== */

.compa__store {
    margin-top: 0.9rem;
}

.compa__h5 {
    margin: 0 0 0.4rem;
    font-size: 0.9rem;
    color: var(--aq-gold, var(--gold));
}

/* EL FILTRO Y EL BUSCADOR (necROmantic 2026-08-29). Sustituye a `.compa__stcats`/`.compa__stcat`,
   que solo sabian de las categorias de equipo; ahora lo usan las cuatro listas -- los dos almacenes
   de Equipamiento y los dos de Inventario -- con el mismo guion y el mismo aspecto. */
.compa__filtro {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 12px;
    margin-bottom: 0.6rem;
}

.compa__filcats {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* El buscador se lleva el hueco que sobre, y nunca baja de 10em: por debajo de eso no cabe una
   palabra y el campo deja de servir para lo que esta. */
.compa__busca {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 10em;
    min-width: 10em;
    padding: 2px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
}

.compa__busca i {
    font-size: 0.76rem;
    opacity: 0.7;
}

/* `min-width: 0` es lo que deja que el campo se encoja dentro del flex en vez de desbordar. */
.compa__busca input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: none;
    color: var(--text);
    font-size: 0.8rem;
    line-height: 1.6;
    outline: none;
}

.compa__busca:focus-within {
    border-color: var(--aq-gold, var(--gold));
}

.compa__filcat {
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    font-size: 0.76rem;
    line-height: 1.5;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.compa__filcat:hover {
    border-color: var(--aq-gold, var(--gold));
    color: var(--text);
}

.compa__filcat.is-on {
    border-color: var(--aq-gold, var(--gold));
    background: var(--aq-gold, var(--gold));
    color: var(--bg-surface);
}

/* El aviso de "no hay nada" ocupa la fila entera dentro de la rejilla de fichas; sin esto se
   colocaria como una ficha mas y quedaria en una columna suelta. */
.compa__filnada {
    grid-column: 1 / -1;
    width: 100%;
    margin: 0.4rem 0 0;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-style: italic;
}

/* Cada almacen del Inventario, con su filtro y su lista, en su propia caja: el guion busca la
   lista entre los hermanos del widget y sin esto los dos almacenes se robarian la lista. */
.compa__filzona {
    margin-bottom: 1rem;
}

/* La tarjeta de "no lleva nada equipado" (necROmantic 2026-08-29). Es UNA para todo el Companero,
   no una por ranura, asi que ocupa el ancho entero y se centra en vez de fingir ser una casilla. */
.compa__slot--nada {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 1.2rem;
    text-align: center;
}

.compa__slot-ico {
    font-size: 1.6rem;
    color: var(--text-muted);
    opacity: 0.6;
}

.compa__stcats {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 0.6rem;
}

.compa__stcat {
    padding: 3px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    font-size: 0.76rem;
    line-height: 1.5;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.compa__stcat:hover {
    border-color: var(--aq-gold, var(--gold));
    color: var(--text);
}

.compa__stcat.is-on {
    border-color: var(--aq-gold, var(--gold));
    background: var(--aq-gold, var(--gold));
    color: var(--bg-surface);
}

/* ⚠️ Una CLASE y no `hidden`: el atributo pierde contra cualquier `display` que traiga la
   tarjeta, y esa trampa ya mordio dos veces el mismo dia en este panel. Con `!important` porque
   `.compa__card` es un flex declarado despues. */
.compa__strow.es-oculta,
.compa__card.es-oculta {
    display: none !important;
}

/* ============================================================================
 * BOTON DE REFRESCAR POR SECCION (necROmantic 2026-08-29)
 * ============================================================================
 * El titulillo y su boton comparten fila: el boton se pega a la derecha con `margin-left:auto`,
 * sin tocar el ancho del titulo. Los margenes de los encabezados se anulan aqui porque quien manda
 * en la separacion ahora es la fila, no cada uno por su cuenta.
 */
.compa__subhead {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 0.5rem;
}

.compa__subhead > h4,
.compa__subhead > h5 { margin: 0; }

.compa__refrescar { margin-left: auto; }

/* Boton de solo icono: cuadrado, para que no se lea como un boton de texto vacio. */
.compa__btn--icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    line-height: 1;
}

.compa__btn--icon i { font-size: 0.82rem; }

/* ============================================================================
 * PLEGABLE ANIDADO (necROmantic 2026-08-29)
 * ============================================================================
 * "Unidades de charla" pasa a vivir DENTRO de "Quienes te acompañan". Un <details class="fold">
 * dentro de otro se pinta igual que el de fuera, y dos cajas identicas anidadas se leen como dos
 * secciones hermanas mal alineadas. Esto lo baja de rango: mismo componente, menos peso.
 */
.fold--sub {
    margin: 14px 0 4px;
    border-radius: 12px;
    background: var(--alpha-black-20);
}

.fold--sub > .fold__head { padding: 10px 12px; }
.fold--sub > .fold__head .fold__title { font-size: 0.95rem; }
.fold--sub > .fold__body { padding: 0 12px 12px; }

/* ============================================================================
 * EDITAR LA MEMORIA DE CHARLA (necROmantic 2026-08-29)
 * ============================================================================ */
.prefs-memo__turn {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}

.prefs-memo__turn .prefs-memo__text { flex: 1 1 auto; min-width: 0; }

/* El boton de olvidar un turno: discreto en reposo y rojo al acercarse. Borrar un recuerdo no es
   una accion que haya que invitar a hacer, pero tiene que estar donde se mira. */
.prefs-memo__del {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: none;
    color: var(--text-muted);
    font-size: 0.72rem;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}

.prefs-memo__del:hover,
.prefs-memo__del:focus-visible {
    border-color: var(--danger, #c0392b);
    color: var(--danger, #c0392b);
}

.prefs-memo__lbl {
    display: block;
    margin: 8px 0 6px;
    color: var(--text-muted);
    font-size: 0.82rem;
}

.prefs-memo__edit {
    width: 100%;
    min-height: 9em;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
    color: var(--text);
    font-family: inherit;
    font-size: 0.86rem;
    line-height: 1.5;
    resize: vertical;
}

.prefs-memo__edit:focus { border-color: var(--aq-gold, var(--gold)); outline: none; }

/* ---------------------------------------------------------------------------
   EL DADO DEL PASADO (necROmantic 2026-08-29)
   ---------------------------------------------------------------------------
   Encargo del usuario: "que exista un boton dentro de cada para generar un pasado aleatorio".

   Va DENTRO del pie del contador, en la misma linea que "x de 1.024 caracteres", y por eso es
   pequeño y de contorno en vez de macizo: no compite con el recuadro de escribir, que es donde
   el jugador tiene que mirar. El de verdad es escribirlo; esto es la ayuda para el que se queda
   en blanco.

   Los colores salen de los tokens de siempre (var(--gold), var(--border)) y no de un valor
   escrito aqui: el panel encadena temas y un color suelto se queda igual cuando el tema cambia. */
.prefs-comp__dice {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: none;
    color: var(--gold);
    font-family: inherit;
    font-size: 0.8rem;
    line-height: 1.4;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, opacity 0.15s;
}

.prefs-comp__dice:hover,
.prefs-comp__dice:focus-visible {
    border-color: var(--gold);
    color: var(--text-primary);
}

/* Mientras la peticion esta en vuelo. `disabled` ya impide el segundo clic; esto es solo para
   que se VEA que esta ocupado, que es lo que evita el tercero. */
.prefs-comp__dice[disabled] {
    opacity: 0.55;
    cursor: progress;
}

.prefs-comp__dicehint {
    margin-left: 0.5rem;
}

/* El contador que repinta el dado. Cifras de ancho fijo para que el numero no baile al cambiar
   de 998 a 1.024 -- lo hereda del pie, pero se deja dicho aqui porque este si cambia en vivo. */
.prefs-comp__count {
    font-variant-numeric: tabular-nums;
}

/* En pantalla estrecha la pista se va debajo del boton: en una linea de movil "Sustituye lo que
   haya en el recuadro" no cabe al lado de nada. */
@media (max-width: 600px) {
    .prefs-comp__dicehint {
        display: block;
        margin-left: 0;
        margin-top: 0.35rem;
    }
}

/* ==========================================================================================
   EL GLOBO DE INFORMACION (necROmantic 2026-08-31, peticion del usuario)
   ==========================================================================================

   Un pseudoboton `ⓘ` al lado de cada habilidad y de cada objeto del panel del Compañero: al
   señalarlo sale la descripcion que el jugador lee dentro del juego. El texto lo trae
   themes/necromantic/js/hint.js pidiendolo a character/desc.

   HAY UN SOLO GLOBO EN TODA LA PAGINA, colgado del <body>. No es una elección de estilo: las
   fichas viven dentro de pestañas y rejillas con `overflow` propio, asi que un globo pintado
   dentro de la ficha se cortaria por su borde -- justo en las de abajo, que son las que mas se
   miran. Fijo a la ventana y fuera de todo eso, no lo corta nada.

   Por eso aqui no hay ni un `:hover` que enseñe nada: quien abre y cierra es el JavaScript, que
   es tambien quien puede voltear el globo hacia arriba cuando no cabe debajo. */

.nhint__btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    padding: 0;
    border: 1px solid var(--border-light);
    border-radius: 50%;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.62rem;
    line-height: 1;
    /* Junto al nombre de un objeto el boton va en linea, dentro del <b>; en la cabecera de una
       habilidad va dentro de un flex, donde esto se ignora. Poner los dos casos en la misma regla
       es lo que permite que sea UN componente y no dos. */
    vertical-align: middle;
    cursor: help;
    transition: color 0.12s ease, border-color 0.12s ease, background-color 0.12s ease;
}

.nhint__btn:hover,
.nhint__btn:focus-visible {
    color: var(--gold);
    border-color: var(--gold-dim);
    background: var(--bg-table-alt);
    outline: none;
}

.nhint {
    position: fixed;
    /* Las dos unicas cosas que pone el JavaScript, y como DATO: donde esta el boton al que
       apunta. Todo lo demas es de aqui. */
    left: var(--nhint-x, 0);
    top: var(--nhint-y, 0);
    z-index: 2000;
    max-width: min(30rem, calc(100vw - 16px));
    max-height: 60vh;
    overflow-y: auto;
    padding: 0.55rem 0.7rem;
    background: var(--bg-loginbox);
    border: 1px solid var(--border-light);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
    color: var(--text-primary);
    font-size: 0.78rem;
    font-weight: 400;
    font-style: normal;
    line-height: 1.45;
    text-transform: none;
    letter-spacing: normal;
    /* LO QUE HACE QUE ESTO SIRVA DE ALGO: `pre-line` respeta los saltos de linea del cliente y
       sigue ajustando los parrafos al ancho del globo. Las descripciones de Ragnarok son una
       linea por rasgo, con rayas entre bloques; aplastadas en un parrafo no se pueden leer.
       `anywhere` es para los nombres de objeto larguisimos sin espacios. */
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* EL NOMBRE DEL OBJETO, EN LINEA, para que el boton no se caiga solo a la linea de abajo.
   `.stg__name` es `display: block` porque en las TABLAS de objetos tiene que ocupar su propia
   linea. En la casilla del Compañero no hace falta: el nombre y las etiquetas ya son dos hijos
   distintos de una columna flex, asi que el salto lo da el contenedor y no el nombre. Dejandolo
   en linea, el `ⓘ` va detras del nombre como una palabra mas y se ajusta con el. */
.compa__slot-text .stg__name { display: inline; }

/* Al pasar de un boton a otro el globo salta, y una transicion de posicion lo dejaria volando por
   la pantalla detras del raton. */
@media (prefers-reduced-motion: reduce) {
    .nhint__btn { transition: none; }
}

/* Los DISPARADORES QUE NO SON EL `ⓘ` (necROmantic 2026-08-31, informe del usuario: señalaba el
   icono de la habilidad y no salia nada).

   El `ⓘ` sigue siendo el boton que se ve y el que se puede pulsar con el dedo, pero lo que la
   gente señala es el DIBUJO -- es lo que identifica a la habilidad de un vistazo --, asi que el
   icono abre el mismo globo. Lo unico que hace falta es que el cursor lo diga: sin esto no habia
   forma de saber que ahi encima habia algo.

   `[data-desc]:not(.nhint__btn)` y no una clase nueva: el disparador lo pone cada pantalla en el
   elemento que le viene bien -- la ficha en el <img>, el simulador en la linea entera porque su
   icono es un boton que se deshabilita --, y una clase obligaria a acordarse de ponerla en los
   tres sitios. */
[data-desc]:not(.nhint__btn) {
    cursor: help;
}


/* =========================================================================================
   DONAR MINUTOS AL GREMIO  (necROmantic 2026-08-31, petición del usuario)
   =========================================================================================
   Vive dentro de la sección "Automatización" de /account/view/, justo debajo de la barra de
   la cuota: la pregunta «¿y si le doy parte a mi gremio?» solo tiene sentido después de ver
   cuánto tienes.

   La ventana de confirmación NO tiene armazón propio: reutiliza `.nmodal*`, que son las
   mismas reglas del gacha agrupadas más arriba en este mismo fichero. Aquí abajo solo está
   lo que es de esta ventana y no de cualquier otra. */

.gtd {
    margin-top: 1.1rem;
    padding: 1.1rem 1.2rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface-alt);
}

.gtd__head { display: flex; gap: .8rem; align-items: flex-start; margin-bottom: .9rem; }
.gtd__icon { font-size: 1.5rem; line-height: 1; flex: none; }
.gtd__titles { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.gtd__title { color: var(--gold); font-size: 1rem; letter-spacing: .02em; }
.gtd__sub { color: var(--text-muted); font-size: .86rem; line-height: 1.45; }

.gtd__pick { margin: 0 0 .7rem; color: var(--text-panel-soft); font-size: .88rem; }

.gtd__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .6rem; }
/* `.gtd__item` no lleva margen propio: el hueco lo pone el `gap` del flex. Es la lección de
   `.na li`, que descuadraba las pastillas por traer margen heredado. */
.gtd__item { margin: 0; padding: 0; }

.gtd__guild {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    min-width: 11rem;
    padding: .7rem .9rem;
    border: 1px solid var(--border-accent);
    border-radius: 9px;
    background: var(--bg-surface);
    color: var(--text-primary);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.gtd__guild:hover:not(:disabled) {
    border-color: var(--gold);
    transform: translateY(-2px);
    box-shadow: 0 8px 22px rgba(0, 0, 0, .45);
}
.gtd__guild:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.gtd__guild--off, .gtd__guild:disabled { opacity: .45; cursor: default; transform: none; box-shadow: none; }

.gtd__guild-name { color: var(--gold); font-weight: 600; letter-spacing: .02em; }
.gtd__guild-facts { display: flex; flex-wrap: wrap; gap: .1rem .8rem; }
.gtd__fact { display: flex; gap: .3rem; align-items: baseline; font-size: .8rem; }
.gtd__fact i { color: var(--text-muted); font-style: normal; }
.gtd__fact b { color: var(--text-panel-soft); font-variant-numeric: tabular-nums; }

.gtd__empty { margin: 0; color: var(--text-muted); font-size: .88rem; }
.gtd__empty--soft { margin-top: .7rem; }

.gtd__done {
    margin: .9rem 0 0;
    padding: .6rem .8rem;
    border-left: 3px solid var(--accent-purple);
    border-radius: 4px;
    background: var(--bg-surface);
    color: var(--text-panel-soft);
    font-size: .88rem;
}

/* --- La ventana ------------------------------------------------------------------------- */

.gtd-dlg .nmodal__panel { text-align: left; }

.gtd-dlg__q { margin: 0 0 .2rem; color: var(--text-panel-soft); font-size: .9rem; }

.gtd-dlg__amount { margin: 0 0 .2rem; display: flex; align-items: baseline; gap: .35rem; }
.gtd-dlg__amount b {
    color: var(--gold);
    font-size: 2.6rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.gtd-dlg__amount span { color: var(--text-muted); font-size: .95rem; }

.gtd-dlg__slider { margin: .5rem 0 .9rem; }

/* EL DESLIZADOR.
   El relleno de lo ya recorrido se pinta con `--gtd-pct`, que el JS actualiza al mover. Es un
   valor dinámico de verdad -- el caso que la regla de «nada de estilos inline» deja pasar por
   custom property --, y trae fallback para que sin JS la barra siga siendo legible.

   Hay que peinar los dos motores por separado: `::-webkit-slider-*` y `::-moz-range-*` NO se
   pueden agrupar en un mismo selector (un selector con una pseudo-clase desconocida invalida
   la regla ENTERA para el otro navegador, así que agruparlos deja el deslizador sin estilo en
   los dos). Por eso los bloques están duplicados a propósito. */
.gtd-dlg__range {
    --gtd-pct: 0%;
    width: 100%;
    height: 26px;
    margin: 0;
    padding: 0;
    background: transparent;
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
}
.gtd-dlg__range:focus { outline: none; }
.gtd-dlg__range:focus-visible { outline: 2px solid var(--gold); outline-offset: 4px; border-radius: 6px; }

.gtd-dlg__range::-webkit-slider-runnable-track {
    height: 10px;
    border-radius: 999px;
    border: 1px solid var(--border-accent);
    background:
        linear-gradient(90deg, var(--gold) 0%, var(--gold) var(--gtd-pct), transparent var(--gtd-pct), transparent 100%),
        var(--bg-surface);
}
.gtd-dlg__range::-moz-range-track {
    height: 10px;
    border-radius: 999px;
    border: 1px solid var(--border-accent);
    background: var(--bg-surface);
}
.gtd-dlg__range::-moz-range-progress {
    height: 10px;
    border-radius: 999px 0 0 999px;
    background: var(--gold);
}

.gtd-dlg__range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 24px;
    height: 24px;
    margin-top: -8px;   /* (24 - 10) / 2 + 1 del borde: centra el pulgar en la pista */
    border: 2px solid var(--bg-surface);
    border-radius: 50%;
    background: var(--gold);
    box-shadow: 0 0 0 1px var(--border-accent), 0 4px 12px rgba(0, 0, 0, .55);
    transition: transform .12s ease;
}
.gtd-dlg__range::-moz-range-thumb {
    width: 24px;
    height: 24px;
    border: 2px solid var(--bg-surface);
    border-radius: 50%;
    background: var(--gold);
    box-shadow: 0 0 0 1px var(--border-accent), 0 4px 12px rgba(0, 0, 0, .55);
    transition: transform .12s ease;
}
.gtd-dlg__range:active::-webkit-slider-thumb { transform: scale(1.15); }
.gtd-dlg__range:active::-moz-range-thumb { transform: scale(1.15); }

.gtd-dlg__scale {
    display: flex;
    justify-content: space-between;
    margin-top: .25rem;
    color: var(--text-muted);
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
}

.gtd-dlg__keep { margin: 0 0 .15rem; color: var(--text-panel-soft); font-size: .9rem; }
.gtd-dlg__cap  { margin: 0 0 .15rem; color: var(--text-muted); font-size: .82rem; }
.gtd-dlg__as   { margin: 0 0 .8rem; color: var(--text-muted); font-size: .82rem; }

.gtd-dlg__warn {
    margin: 0 0 1rem;
    padding: .55rem .75rem;
    border-left: 3px solid var(--gold);
    border-radius: 4px;
    background: var(--bg-surface);
    color: var(--text-panel-soft);
    font-size: .84rem;
}

.gtd-dlg__error {
    margin: 0 0 .8rem;
    padding: .55rem .75rem;
    border-left: 3px solid var(--accent-red);
    border-radius: 4px;
    background: var(--bg-surface);
    color: var(--text-panel-soft);
    font-size: .86rem;
}
/* Sin esto, el `display` de arriba le ganaría a lo que el navegador le pone por `[hidden]` y el
   aviso de error se quedaría siempre visible. Mordió dos veces el mismo día en este panel. */
.gtd-dlg__error[hidden] { display: none; }

.gtd-dlg__actions { display: flex; gap: .6rem; justify-content: flex-end; flex-wrap: wrap; }

.gtd-dlg__cancel, .gtd-dlg__ok {
    padding: .55rem 1.1rem;
    border-radius: 8px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, opacity .15s ease;
}
.gtd-dlg__cancel {
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
}
.gtd-dlg__cancel:hover { border-color: var(--border-accent); color: var(--text-primary); }
.gtd-dlg__ok {
    border: 1px solid var(--gold);
    background: var(--gold);
    color: var(--bg-body);
}
.gtd-dlg__ok:hover:not(:disabled) { filter: brightness(1.1); }
.gtd-dlg__ok:disabled { opacity: .45; cursor: default; }
.gtd-dlg__cancel:focus-visible, .gtd-dlg__ok:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .gtd__guild, .gtd-dlg__range::-webkit-slider-thumb, .gtd-dlg__range::-moz-range-thumb { transition: none; }
    .gtd__guild:hover:not(:disabled) { transform: none; }
}

@media (max-width: 480px) {
    .gtd__guild { min-width: 100%; }
    .gtd-dlg__actions { justify-content: stretch; }
    .gtd-dlg__cancel, .gtd-dlg__ok { flex: 1 1 auto; }
}

/* --- Autodonar excedentes (necROmantic 2026-08-31) ---------------------------------------- */

/* La insignia del botón: dice de un vistazo a qué gremio le va el excedente, sin abrir nada. */
.gtd__auto-badge {
    margin-left: .45rem;
    padding: .05rem .4rem;
    border: 1px solid var(--accent-purple);
    border-radius: 999px;
    color: var(--accent-purple);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    vertical-align: middle;
}

.gtd-dlg__auto {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    margin: 0 0 .9rem;
    padding: .65rem .8rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-surface);
    cursor: pointer;
    transition: border-color .15s ease;
}
.gtd-dlg__auto:hover { border-color: var(--border-accent); }
/* `:focus-within` y no `:focus`: quien recibe el foco es la casilla de dentro, no la etiqueta. */
.gtd-dlg__auto:focus-within { outline: 2px solid var(--gold); outline-offset: 2px; }

.gtd-dlg__auto-box { flex: none; width: 18px; height: 18px; margin: .1rem 0 0; accent-color: var(--accent-purple); cursor: pointer; }
.gtd-dlg__auto-text { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.gtd-dlg__auto-text strong { color: var(--text-primary); font-size: .88rem; }
.gtd-dlg__auto-text i { color: var(--text-muted); font-style: normal; font-size: .78rem; line-height: 1.45; }

@media (prefers-reduced-motion: reduce) { .gtd-dlg__auto { transition: none; } }

/* =========================================================================================
   QUESTS DE LA CUENTA  (necROmantic 2026-09-01, petición del usuario)
   =========================================================================================
   Sección `#pane-quests` de /account/view/ y su ventana de copiar.

   La ventana NO tiene armazón propio: reutiliza `.nmodal*`, las mismas reglas del gacha
   agrupadas más arriba en este mismo fichero. Aquí abajo sólo está lo que es de esta
   pantalla y no de cualquier otra. */

.qst__intro { margin: 0 0 1rem; color: var(--text-muted); }

/* El aviso de "falta el catálogo". Es informativo, no un error del jugador: tono ámbar y
   no rojo, que aquí no ha hecho nada mal. */
.qst__alert {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    margin: 0 0 1rem;
    padding: .7rem .9rem;
    border: 1px solid var(--tone-amber);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-notice);
    font-size: .9rem;
}

/* ── Barra de herramientas: buscador + filtros ────────────────────────────────────────── */
.qst__tools {
    display: flex;
    flex-wrap: wrap;
    gap: .7rem;
    align-items: center;
    margin: 0 0 .9rem;
}

.qst__search {
    display: flex;
    flex: 1 1 16rem;
    gap: .55rem;
    align-items: center;
    min-width: 0;
    padding: .5rem .8rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-input);
}

/* La etiqueta existe para los lectores de pantalla; a la vista está el marcador de dentro
   del campo. `clip-path` y no `display:none`, que a un lector le quita también el texto. */
.qst__search-label {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.qst__search-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--text-primary);
    font: inherit;
}
.qst__search-input:focus { outline: none; }

.qst__filters { display: flex; flex-wrap: wrap; gap: .35rem; }

.qst__filter {
    padding: .4rem .8rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
    white-space: nowrap;
}
.qst__filter:hover { color: var(--text-primary); }

.qst__filter.is-on {
    border-color: var(--border-accent);
    background: var(--bg-surface);
    color: var(--gold);
}

/* El de "cronometradas" es un interruptor y no una opción más de la tira: se cruza con
   cualquiera de las otras tres, así que se distingue con su propio tono encendido. */
.qst__filter--timed.is-on {
    border-color: var(--tone-amber);
    color: var(--tone-amber);
}

.qst__count { margin: 0 0 .8rem; color: var(--text-muted); font-size: .82rem; }

/* ── La rejilla de fichas ─────────────────────────────────────────────────────────────── */
/* Tres columnas en pantalla grande, dos en tableta y una en móvil, como se pidió. Se hace
   con tramos explícitos y no con `auto-fill`: así el número de columnas es el que es y no
   depende de lo largo que sea el nombre de una quest. */
.qst__grid {
    display: grid;
    gap: .8rem;
    margin: 0;
    padding: 0;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    list-style: none;
}

@media (max-width: 1100px) { .qst__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px)  { .qst__grid { grid-template-columns: minmax(0, 1fr); } }

.qst__card {
    display: flex;
    flex-direction: column;
    gap: .55rem;
    min-width: 0;
    padding: .85rem 1rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface-alt);
}

/* ⚠️ `hidden` NO esconde nada si la regla de arriba fija `display`. El paginador esconde las
   fichas con `el.hidden = true`, así que sin esto la paginación no pinta nada y el filtro
   tampoco. Ya mordió dos veces en este mismo panel el mismo día. */
.qst__card[hidden] { display: none; }

.qst__card--locked { border-style: dashed; opacity: .82; }

/* La ficha a la que se vuelve después de aplicar un cambio. Se marca un par de segundos y
   se apaga sola: es "era ésta", no un estado. Sin esto, la recarga te dejaba mirando una
   lista igual a la de antes sin saber cuál acababas de tocar. */
.qst__card--foco {
    border-color: var(--tone-gold);
    box-shadow: 0 0 0 2px var(--tone-gold-glow);
    animation: qst-foco 2.6s ease-out;
}

@keyframes qst-foco {
    0%   { box-shadow: 0 0 0 7px var(--tone-gold-glow); }
    100% { box-shadow: 0 0 0 2px var(--tone-gold-glow); }
}

/* Quien haya pedido menos movimiento no ve el latido; el borde dorado se queda, que es lo
   que de verdad señala la ficha. */
@media (prefers-reduced-motion: reduce) {
    .qst__card--foco { animation: none; }
}

.qst__card-head { min-width: 0; }

.qst__name {
    margin: 0;
    color: var(--text-heading);
    font-size: .95rem;
    line-height: 1.3;
}

.qst__id {
    margin-left: .35rem;
    color: var(--text-muted);
    font-size: .75rem;
    font-weight: normal;
}

.qst__obj,
.qst__note {
    margin: .25rem 0 0;
    color: var(--text-muted);
    font-size: .82rem;
    line-height: 1.4;
}
.qst__note { font-style: italic; }

/* ── Quién la tiene ───────────────────────────────────────────────────────────────────── */
/* BALDOSAS, NO PASTILLAS (2026-09-02, pedido del usuario): al copiar una quest a toda la
   cuenta la lista pasaba de una pastilla a ocho, cada una con nombre, nivel y estado
   escritos, y la ficha crecía más por quién la tiene que por la quest. Ahora cada personaje
   es un cuadradito con el icono de su clase y el nivel debajo; el nombre y el estado los
   dice el globo (y el texto de lectores de pantalla que va dentro). */
.qst__who {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* OJO: `.qst__who li` lleva margen 0 explícito. La regla `.na li` de más arriba le mete un
   margen inferior a cualquier `<li>`, y en una fila flex eso descuadra la última pastilla
   dejándola más alta que las demás. Ya mordió en otra pantalla. */
.qst__who > li { margin: 0; }

.qst__chip {
    position: relative;          /* ancla del globo y de la varita */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: .12rem;
    width: 3.15rem;
    padding: .3rem .15rem .28rem;
    border: 1px solid var(--border-light);
    border-radius: .5rem;
    background: var(--bg-surface);
    line-height: 1.15;
    cursor: help;
}

.qst__chip-icon {
    width: 28px;
    height: 28px;
    flex: 0 0 auto;
}

.qst__chip-icon--none {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    font-size: .82rem;
    font-weight: 700;
}

.qst__chip-lv {
    color: var(--text-muted);
    font-size: .66rem;
    font-weight: 600;
    white-space: nowrap;
}

/* El estado ya no se escribe en la baldosa: lo llevan el borde y el color del nivel, y las
   palabras están en el globo. */
.qst__chip--complete { border-color: var(--tone-mint); }
.qst__chip--complete .qst__chip-lv { color: var(--tone-mint); }
.qst__chip--active   { border-color: var(--tone-amber); }
.qst__chip--active   .qst__chip-lv { color: var(--tone-amber); }

/* La varita marca lo que puso el panel: es lo único que se puede desmarcar, así que tiene
   que verse de un vistazo sin abrir la ventana. Va en la esquina y se sale un par de
   píxeles de la baldosa, que es menos que el hueco entre baldosas: no pisa a la vecina. */
.qst__chip--panel { border-style: dashed; }

.qst__chip-tag {
    position: absolute;
    top: -5px;
    right: -4px;
    padding: 1px 2px;
    border-radius: 999px;
    background: var(--bg-surface-alt);
    color: var(--tone-lilac);
    font-size: .58rem;
    line-height: 1;
}

/* El texto que el globo pinta con `content` no existe para un lector de pantalla, así que
   viaja también como texto de verdad, escondido a la vista. */
.qst__chip-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* EL GLOBO. Mismo mecanismo que los sellos de la cartilla (`.stamp[data-tip]`): `data-tip` y
   no `title`, porque unitip engancha los `title` y los repinta con su caja rota.
   `max-width` en vez de `nowrap`: un nombre largo parte en dos renglones en lugar de estirar
   el globo hasta salirse de la ficha y empujar la página a lo ancho. */
.qst__chip[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 20;
    width: max-content;
    max-width: 12rem;
    padding: 6px 9px;
    border: 1px solid var(--border-light);
    border-radius: 7px;
    background: var(--bg-content);
    color: var(--text-primary);
    font-size: .72rem;
    font-weight: 500;
    line-height: 1.35;
    text-align: center;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .5);
    opacity: 0;
    visibility: hidden;
    transition: opacity .12s ease;
    pointer-events: none;
}

.qst__chip[data-tip]:hover::after,
.qst__chip[data-tip]:focus-within::after { opacity: 1; visibility: visible; }

/* ── Acción ───────────────────────────────────────────────────────────────────────────── */
/* `margin-top:auto` pega el botón al fondo de la ficha: sin él, en una rejilla las fichas
   son igual de altas pero sus botones quedan a alturas distintas según lo largo que sea el
   objetivo, y la fila entera parece descuadrada. */
.qst__act { margin-top: auto; }

.qst__copy {
    display: inline-flex;
    width: 100%;
    gap: .45rem;
    align-items: center;
    justify-content: center;
    padding: .45rem .9rem;
    border: 1px solid var(--border-accent);
    border-radius: 8px;
    background: var(--bg-surface);
    color: var(--gold);
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
}
.qst__copy:hover:not(:disabled) { background: var(--bg-surface-alt); color: var(--text-link-hover); }
.qst__copy:disabled { opacity: .45; cursor: not-allowed; }

.qst__hunt,
.qst__lock {
    display: flex;
    gap: .45rem;
    align-items: flex-start;
    margin: 0 0 .5rem;
    color: var(--text-muted);
    font-size: .76rem;
    line-height: 1.4;
}
.qst__hunt .fa-crosshairs { margin-top: .15rem; color: var(--tone-teal); }
.qst__lock { margin-bottom: 0; }
.qst__lock .fa-lock { margin-top: .15rem; color: var(--tone-crimson); }
.qst__lock strong { color: var(--text-primary); }

.qst__none { margin: 1rem 0 0; color: var(--text-muted); text-align: center; }

/* ── Paginador ────────────────────────────────────────────────────────────────────────── */
.qst__pager {
    display: flex;
    gap: .8rem;
    align-items: center;
    justify-content: center;
    margin-top: 1rem;
}
.qst__pager[hidden] { display: none; }

.qst__page-btn {
    padding: .4rem .9rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-primary);
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
}
.qst__page-btn:hover:not(:disabled) { border-color: var(--border-accent); color: var(--gold); }
.qst__page-btn:disabled { opacity: .4; cursor: not-allowed; }

.qst__page-n { color: var(--text-muted); font-size: .82rem; }

/* ═════════════════════════════════════════════════════════════════════════════════════════
   LA VENTANA DE COPIAR
   ═════════════════════════════════════════════════════════════════════════════════════════ */

/* Más ancha que la de serie: dentro van hasta nueve botones de personaje con icono, nombre,
   nivel y a veces un motivo, y a 30rem salían a uno por línea. */
.qst-dlg .nmodal__panel { width: min(38rem, calc(100vw - 2rem)); text-align: left; }

.qst-dlg__intro { margin: 0 0 .9rem; color: var(--text-muted); font-size: .88rem; }

.qst-dlg__chars {
    display: grid;
    gap: .5rem;
    margin: 0 0 1rem;
    padding: 0;
    grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
    list-style: none;
}
.qst-dlg__chars > li { margin: 0; }

.qst-dlg__btn {
    display: grid;
    width: 100%;
    gap: 0 .55rem;
    padding: .5rem .7rem;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-surface-alt);
    color: var(--text-primary);
    font: inherit;
    text-align: left;
    cursor: pointer;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        "icon name lv"
        "why  why  why";
    align-items: center;
}

.qst-dlg__icon { width: 26px; height: 26px; grid-area: icon; }
.qst-dlg__name { grid-area: name; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qst-dlg__lv   { grid-area: lv; color: var(--text-muted); font-size: .78rem; }

.qst-dlg__why {
    margin-top: .2rem;
    grid-area: why;
    color: var(--text-muted);
    font-size: .74rem;
    line-height: 1.3;
}

.qst-dlg__btn:hover:not([disabled]) { border-color: var(--border-accent); }

/* Marcado. Se hace con una clase y no con :checked porque son <button>, no casillas: hacía
   falta poder desactivarlos con `disabled` y darles un motivo dentro. */
.qst-dlg__btn.is-on {
    border-color: var(--tone-mint);
    background: var(--bg-surface);
    box-shadow: inset 0 0 0 1px var(--tone-mint);
}

.qst-dlg__btn[disabled] { opacity: .5; cursor: not-allowed; }

.qst-dlg__warn {
    margin: 0 0 .9rem;
    padding: .7rem .9rem;
    border: 1px solid var(--tone-amber);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-notice);
    font-size: .82rem;
    line-height: 1.5;
}
.qst-dlg__warn .fa-triangle-exclamation { margin-right: .35rem; color: var(--tone-amber); }

.qst-dlg__error {
    margin: 0 0 .9rem;
    padding: .6rem .8rem;
    border: 1px solid var(--accent-red);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-error);
    font-size: .84rem;
}

.qst-dlg__actions { display: flex; gap: .6rem; justify-content: flex-end; }

.qst-dlg__cancel,
.qst-dlg__ok {
    padding: .5rem 1.1rem;
    border-radius: 8px;
    font: inherit;
    font-size: .88rem;
    cursor: pointer;
}

.qst-dlg__cancel {
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
}
.qst-dlg__cancel:hover { color: var(--text-primary); }

.qst-dlg__ok {
    border: 1px solid var(--border-accent);
    background: var(--bg-surface-alt);
    color: var(--gold);
}
.qst-dlg__ok:hover:not(:disabled) { color: var(--text-link-hover); }
.qst-dlg__ok:disabled { opacity: .5; cursor: not-allowed; }

.qst-dlg__hunt {
    display: flex;
    gap: .45rem;
    align-items: flex-start;
    margin: 0 0 .9rem;
    padding: .6rem .8rem;
    border: 1px solid var(--tone-teal);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    color: var(--text-muted);
    font-size: .8rem;
    line-height: 1.45;
}
.qst-dlg__hunt[hidden] { display: none; }
.qst-dlg__hunt .fa-crosshairs { margin-top: .15rem; color: var(--tone-teal); }

/* ══════════════════════════════════════════════════════════════
   BADGE DE QUIEN PUSO EL PRECIO  (necROmantic 2026-09-02, peticion del usuario)
   ──────────────────────────────────────────────────────────────
   "Cuando un precio haya sido definido por smazork que tenga un badge Sm en rojo, y cuando lo
   edite Scripttab un badge azul con Sc; cuando uno de los dos edite el que tenia el precio fijado
   por el otro y lo guarde con el mismo, badge dorado Verificado como un icono de medalla".

   Sale al lado del precio en las seis listas de /character/<id>/#inventario y en el escaparate del
   mercado (/mercado/ y /account/view/#pane-mercado). Lo pintan tres sitios -- la rejilla del
   inventario en PHP, el resto de la ficha en su JS y el mercado en el suyo -- pero el marcado es
   el mismo y por eso el CSS es uno solo.

   NO se esconde con CSS para quien no puede tocar precios: el campo ni siquiera viaja en su JSON.
   Esconder con una regla lo que ya esta en el HTML es enseñarlo a quien mire el codigo.

   Colores prestados de la cartilla de sellos y del oro del panel: el rojo y el azul saturados ya
   existen (--stamp-red / --stamp-blue) y el dorado es --tone-gold, que en esta piel es el color
   del dinero (el token --gold es rosa-magenta, heredado de la paleta anterior).
   ══════════════════════════════════════════════════════════════ */
:root {
    --pxb-sm-bg: var(--stamp-red);      /* Smazork   */
    --pxb-sc-bg: var(--stamp-blue);     /* Scripttab */
    --pxb-ink:   #ffffff;               /* texto sobre los dos anteriores */
    --pxb-ok-fg: var(--tone-gold);      /* verificado por los dos */
    --pxb-ok-bg: var(--tone-gold-glow);
}

.pxb {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.45em;
    padding: 0.12em 0.42em;
    border-radius: 0.5em;
    /* El pie de una tarjeta va en cursiva y en pequeno: sin esto el badge la hereda y las dos
       letras salen inclinadas. */
    font-style: normal;
    font-weight: 700;
    font-size: 0.78em;
    line-height: 1.25;
    letter-spacing: 0.02em;
    vertical-align: baseline;
    white-space: nowrap;
    /* Un badge no se parte de linea ni arrastra el precio a la siguiente. */
    flex: 0 0 auto;
}

.pxb--sm { background: var(--pxb-sm-bg); color: var(--pxb-ink); }
.pxb--sc { background: var(--pxb-sc-bg); color: var(--pxb-ink); }

/* La medalla no lleva sigla: el icono ES el badge, asi que ni min-width de dos letras ni el
   fondo saturado de los otros dos -- el dorado sobre fondo oscuro se lee solo, y un relleno
   macizo al lado de una cifra dorada seria dos oros peleando. */
.pxb--ok {
    min-width: 0;
    padding: 0.12em 0.34em;
    background: var(--pxb-ok-bg);
    color: var(--pxb-ok-fg);
    font-size: 0.86em;
}

/* El texto de la medalla, para quien no ve el icono. Misma tecnica que .ipol__sr: fuera de la
   vista pero dentro del arbol, que es lo unico que un lector de pantalla lee. */
.pxb__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* En el escaparate el precio es una linea grande con la cifra en <strong>: el badge se separa un
   poco mas para no pegarse al "cada uno". */
.mk__item-price .pxb { margin-left: 0.35em; }

/*  ============================================================
    LA TIENDA DEL COMPAÑERO  (necROmantic 2026-09-03)
    Encargo del usuario: un panel "tienda" dentro de la pestaña
    Inventario, con buscador, precio y cantidad objetivo, y el
    ticket de las últimas compras.
    Reutiliza .compa__strow / -ico / -nom / -id de la lista de
    almacén: es la misma forma de fila -- un icono de alto -- y
    tener dos era garantizar que se separaran.
    ============================================================ */

/* Una nota que AVISA. Misma familia que .compa__note (no repite su caja) y sólo cambia el color,
   que es lo que la distingue de una nota informativa. */
.compa__note--warn { color: var(--gold); }

/* EL RESUMEN: las dos bolsas, lo que falta y el descuento. Rejilla que se pliega sola en móvil en
   vez de una fila que desborda. */
.compa__shopsum {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 8px;
    margin: 0 0 12px;
    padding: 0;
    list-style: none;
}

.compa__shopsum-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-surface-alt);
}

.compa__shopsum-k { font-size: .72rem; color: var(--text-muted); }
.compa__shopsum-v { font-size: .95rem; color: var(--gold); font-variant-numeric: tabular-nums; }
.compa__shopsum-x { font-size: .7rem; color: var(--text-muted); }

.compa__shopacts {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* La lista de la tienda es más alta que la del almacén a propósito: son 171 filas y aquí se viene a
   comparar precios, no a mover un objeto concreto. */
.compa__shoplist { max-height: 560px; }

/* LO PEDIDO, MARCADO. Va con un borde a la izquierda y no con un fondo: el fondo ya lo usa el
   rayado de filas pares e impares, y pisarlo dejaba la lista sin ese rayado justo en la parte de
   arriba, que es la que más se lee. */
.compa__shoprow--want {
    border-left: 3px solid var(--gold);
    padding-left: 4px;
}

.compa__shopprice {
    flex: none;
    min-width: 5.5em;
    text-align: right;
    font-size: .78rem;
    color: var(--gold);
    font-variant-numeric: tabular-nums;
}

.compa__shophave {
    flex: none;
    min-width: 5em;
    font-size: .72rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.compa__shopwarn {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: .7rem;
    color: var(--accent-red);
}

/* LAS DOS FLECHAS, UNA AL LADO DE OTRA. Cada una es su propio <form> -- así tienen que ser: cada
   botón manda una petición distinta -- y un <form> es un bloque, así que sin esto se apilaban en
   vertical y la fila crecía al doble. Se ve en cuanto hay algo en la lista, no antes. */
.compa__shopmove {
    flex: none;
    display: inline-flex;
    gap: 2px;
}
.compa__shopmove form,
.compa__shopset  form { display: inline-flex; }

/* Texto que solo leen los lectores de pantalla. `clip-path` además de la receta clásica: la etiqueta
   del campo de cantidad se repite una vez por fila del catálogo y con texto normal ocupaba más que
   el propio campo. */
.compa__solotexto {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.compa__shopset {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* El campo de cantidad, estrecho: son cuatro cifras como mucho y con el ancho por defecto del
   navegador se comía la mitad de la fila. */
.compa__shopset .compa__num { width: 5.5em; }

.compa__shopth { margin-top: 18px; }

/* ── EL TICKET ─────────────────────────────────────────────── */

.compa__tickets {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 420px;
    overflow-y: auto;
}

.compa__ticket {
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-surface-alt);
    padding: 8px 10px;
}

.compa__ticket-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 6px;
    padding-bottom: 5px;
    border-bottom: 1px dashed var(--border);
}

.compa__ticket-map  { color: var(--text-heading); font-size: .85rem; }
.compa__ticket-when { color: var(--text-muted); font-size: .72rem; }

.compa__ticket-lines {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Cuatro columnas fijas -- cantidad, objeto, precio unitario y total -- para que los importes
   queden alineados en vertical: un ticket con las cifras bailando no se lee, se descifra. */
.compa__ticket-line {
    display: grid;
    grid-template-columns: 3.5em 1fr 6em 7em;
    gap: 6px;
    font-size: .76rem;
    padding: 1px 0;
}

.compa__ticket-n  { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.compa__ticket-it { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.compa__ticket-u,
.compa__ticket-t  { text-align: right; font-variant-numeric: tabular-nums; }
.compa__ticket-u  { color: var(--text-muted); }
.compa__ticket-t  { color: var(--gold); }

.compa__ticket-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin-top: 6px;
    padding-top: 5px;
    border-top: 1px dashed var(--border);
    font-size: .74rem;
}

.compa__ticket-tot { color: var(--gold); font-variant-numeric: tabular-nums; }
.compa__ticket-pay { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.compa__ticket-cut { color: var(--accent-red); flex-basis: 100%; }

/* El filtro esconde filas con `.es-oculta`, y la regla que ya existe nombra a `.compa__strow` y a
   las fichas: la fila de la tienda es un `.compa__strow`, así que hereda ese ocultado. Esta línea
   está aquí sólo para que quede escrito y nadie la "arregle" añadiendo un selector nuevo. */
