/* Fuentes servidas desde el panel (OFL, ver static/fonts/OFL-*.txt): sin servicios externos en runtime.
   Inter es una fuente variable: un solo archivo cubre 400-700. Subconjunto latin. */
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400 700; font-display: swap;
    src: url("/static/fonts/inter-latin-400-700.woff2") format("woff2"); }
@font-face { font-family: "Rajdhani"; font-style: normal; font-weight: 400; font-display: swap;
    src: url("/static/fonts/rajdhani-latin-400.woff2") format("woff2"); }
@font-face { font-family: "Rajdhani"; font-style: normal; font-weight: 600; font-display: swap;
    src: url("/static/fonts/rajdhani-latin-600.woff2") format("woff2"); }
@font-face { font-family: "Rajdhani"; font-style: normal; font-weight: 700; font-display: swap;
    src: url("/static/fonts/rajdhani-latin-700.woff2") format("woff2"); }

/* Mundo «Papel de seguridad» (.impeccable/surfaces/panel-src-templates.md):
   papel frío con underprint de roseta, riel en tinta calcográfica, tarjetas
   blancas con filete, tinta de texto y tintas de línea. Cian solo en el riel. */
:root {
    color-scheme: light;

    /* Superficies */
    --paper: #eef3f5;
    --card: #ffffff;
    --rule: #cfdde3;
    --rule-soft: #e3ecf0;      /* filete entre filas, pista de barras */
    --rule-strong: #6b8693;    /* borde de controles de formulario (≥3:1 sobre blanco) */
    --rail: #0c2a3a;
    --rail-ink: #dbe7ee;
    --rail-muted: #8fb0c2;     /* 6.5:1 sobre el riel */
    --rail-hover: #14384b;
    --rail-rule: #1d4256;
    --rail-accent: #00d4ff;

    /* Tinta */
    --ink: #0b1f2a;
    --ink-muted: #4a6270;

    /* Tintas de línea: --line-2 para texto y enlaces; --line-1 (4.1:1) para gráficos y foco */
    --line-1: #0089a8;
    --line-2: #1d5f73;
    --line-2-strong: #154a5a;  /* hover de botón */
    --line-fill: #edf7f9;      /* --line-1 al 7 % sobre blanco: casilla activa de la banda */
    --on-ink: #ffffff;         /* texto sobre botón de tinta */

    /* Estados con relleno pálido */
    --critical: #b42318;
    --critical-fill: #fdecea;
    --critical-rule: #f1c4bf;
    --critical-strong: #8f1c13; /* hover del botón de peligro */
    --critical-deep: #761710;
    --degraded: #a15c00;
    --degraded-fill: #fff4e0;
    --degraded-rule: #ecd3a6;
    --ok: #1e6b45;
    --ok-fill: #e6f4ec;
    --ok-rule: #b9dcc7;
    --focus: #0089a8;
    --selection: #b9e4ee;
    --row-hover: #f6f9fa;
    --scroll-thumb: #9fb5bf;

    /* Underprint: roseta de guilloche casi invisible (el único "degradado" del mundo) */
    --underprint: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220' viewBox='-110 -110 220 220' fill='none' stroke='%230089a8' stroke-opacity='.03' stroke-width='.7'%3E%3Cellipse rx='100' ry='38'/%3E%3Cellipse rx='100' ry='38' transform='rotate(15)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(30)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(45)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(60)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(75)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(90)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(105)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(120)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(135)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(150)'/%3E%3Cellipse rx='100' ry='38' transform='rotate(165)'/%3E%3Ccircle r='104'/%3E%3Ccircle r='60'/%3E%3C/svg%3E");

    --font-ui: "Inter", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
    --font-display: "Rajdhani", "Arial Narrow", sans-serif;
    --font-code: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

    /* Filete de guilloche bajo los títulos de sección del dashboard */
    --rule-guilloche: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='6' viewBox='0 0 24 6' fill='none' stroke-width='.6'%3E%3Cpath d='M0 3q3 -3 6 0t6 0t6 0t6 0' stroke='%230089a8' stroke-opacity='.6'/%3E%3Cpath d='M0 3q3 3 6 0t6 0t6 0t6 0' stroke='%231d5f73' stroke-opacity='.45'/%3E%3C/svg%3E");

    --shadow-menu: 0 12px 24px -12px rgba(11, 31, 42, 0.5); /* menú desplegado en el celular */

    --radius: 6px;
    --radius-sm: 4px;
    --transition: 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

* { box-sizing: border-box; }

html { scrollbar-color: var(--scroll-thumb) var(--paper); }

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    line-height: 1.5;
    background-color: var(--paper);
    background-image: var(--underprint);
    background-size: 220px 220px;
    color: var(--ink);
    caret-color: var(--line-2);
}

::selection { background: var(--selection); color: var(--ink); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

a { color: var(--line-2); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--ink); }

/* Barra de estado — arriba de todo, en las páginas con sesión (todas menos
   login): tira blanca con filete inferior. body es flex-column para que esto
   quede como una fila de altura fija y .app-shell se reparta el resto. */
.metrics-banner {
    flex-shrink: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1.25rem;
    min-height: 48px;
    padding: 0.5rem 1.5rem;
    background: var(--card);
    border-bottom: 1px solid var(--rule);
    font-size: 0.8rem;
}
.metric { color: var(--ink-muted); }
.metric strong { color: var(--ink); font-weight: 600; margin-right: 0.3rem; }
.metric-ok strong { color: var(--ok); }
.metric-warning strong { color: var(--degraded); }
.metric-critical strong { color: var(--critical); }

/* Layout: riel fijo a la izquierda, contenido de trabajo a la derecha —
   más cómodo que un top-bar una vez que el panel tiene 5+ secciones
   (pedido explícito del usuario, doc "Mejoras", 2026-09-24). */
.app-shell { display: flex; flex: 1; min-height: 0; }

.sidebar {
    width: 220px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1rem 0.5rem;
    background: var(--rail);
    color: var(--rail-ink);
    overflow-y: auto;
    scrollbar-color: var(--rail-rule) var(--rail);
}

.brand { display: flex; align-items: center; padding: 0.25rem 0.75rem 1rem; border-bottom: 1px solid var(--rail-rule); }
.brand img { display: block; }

.sidebar nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }

/* Navegación: una sola lista de enlaces dentro de un <details> nativo (sin
   JavaScript). En escritorio se muestra siempre abierta y sin su «Menú»
   (::details-content); en el celular es el menú plegable de la barra
   superior. Si el navegador no soporta ::details-content, el riel muestra
   «Menú» y se despliega igual: nunca queda sin navegación. */
.nav-menu { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.nav-menu > summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0 0.85rem;
    color: var(--rail-ink);
    font-weight: 600;
    font-size: 0.9rem;
    border: 1px solid var(--rail-rule);
    border-radius: var(--radius-sm);
    list-style: none;
    cursor: pointer;
    user-select: none;
    transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.nav-menu > summary::-webkit-details-marker { display: none; }
.nav-menu > summary:hover { color: var(--on-ink); background: var(--rail-hover); }
.nav-menu[open] > summary { color: var(--rail-accent); background: var(--rail-hover); border-color: var(--rail-accent); }
.nav-menu-icon { display: block; flex-shrink: 0; }
.nav-body { flex: 1; display: flex; flex-direction: column; gap: 1.25rem; }
@media (width > 760px) {
    .nav-menu::details-content { flex: 1; display: flex; flex-direction: column; content-visibility: visible; }
    @supports selector(::details-content) {
        .nav-menu > summary { display: none; }
    }
}
.sidebar nav a {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--rail-ink);
    text-decoration: none;
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-sm);
    border-left: 3px solid transparent;
    transition: background var(--transition), color var(--transition);
}
.sidebar nav a:hover { color: var(--on-ink); background: var(--rail-hover); }
.sidebar nav a.active {
    color: var(--rail-accent);
    background: var(--rail-hover);
    border-left-color: var(--rail-accent);
}
.sidebar :focus-visible { outline-color: var(--rail-accent); }

.sidebar-footer {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.75rem;
    border-top: 1px solid var(--rail-rule);
}
.sidebar-footer .whoami { color: var(--rail-muted); font-size: 0.85rem; }
.sidebar-footer .whoami em { color: var(--rail-ink); font-style: normal; font-weight: 600; }
.sidebar .link-button { color: var(--rail-ink); }
.sidebar .link-button:hover { color: var(--on-ink); }

main { flex: 1; min-width: 0; padding: 1.75rem 2.25rem; }
main.no-sidebar { max-width: 1080px; margin: 0 auto; width: 100%; }

/* Celular: el riel pasa a una barra de una línea (logo + «Menú») debajo de
   la barra de estado, en el mismo orden que el documento (el orden del
   teclado coincide con el visual); el menú se despliega sobre la página.
   Objetivos táctiles de 44 px. La página nunca supera el ancho de la ventana:
   las tablas se desplazan dentro de .table-scroll. */
@media (max-width: 760px) {
    .app-shell { flex-direction: column; }
    .sidebar {
        position: relative;
        z-index: 10;
        width: 100%;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        padding: 0.375rem 0.5rem 0.375rem 1rem;
        overflow: visible;
    }
    .brand { min-height: 44px; padding: 0; border-bottom: none; }
    .nav-menu { flex: none; }
    .nav-body {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        max-height: calc(100dvh - 56px);
        overflow-y: auto;
        overscroll-behavior: contain;
        gap: 0.75rem;
        padding: 0.5rem 0.5rem 0.75rem;
        background: var(--rail);
        border-top: 1px solid var(--rail-rule);
        box-shadow: var(--shadow-menu);
        scrollbar-color: var(--rail-rule) var(--rail);
    }
    .sidebar nav a { display: flex; align-items: center; min-height: 44px; }
    .nav-section { margin: 0.75rem 0 0.25rem; }
    .sidebar-footer { flex-direction: row; align-items: center; justify-content: space-between; padding: 0.5rem 0 0 0.75rem; }
    .sidebar .link-button { min-height: 44px; padding: 0 0.75rem; }

    .metrics-banner { gap: 0.35rem 0.9rem; padding: 0.5rem 1rem; }
    main { padding: 1.25rem 1rem; }

    /* Lo que antes empujaba el ancho de la página */
    .filter-range, .report-head { flex-wrap: wrap; }
}

h1, h2, h3 { text-wrap: balance; }
h1 {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.75rem;
    line-height: 1.15;
    letter-spacing: 0.03em;
    overflow-wrap: anywhere;
    color: var(--ink);
    margin: 0.25rem 0 1rem;
}
h2 {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.25rem;
    letter-spacing: 0.04em;
    color: var(--ink);
    margin: 1.75rem 0 0.6rem;
}

/* Tablas: filetes finos. Las que van sueltas en la página llevan papel blanco. */
table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 1rem; }
th, td { text-align: left; padding: 0.55rem 0.75rem; border-bottom: 1px solid var(--rule-soft); }
th {
    color: var(--ink-muted);
    font-weight: 500;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-bottom-color: var(--rule);
}
tbody tr:hover td { background: var(--row-hover); }

/* Formularios */
form { display: flex; flex-direction: column; gap: 0.9rem; max-width: 480px; }
form.inline { display: inline; }

/* La etiqueta es un bloque (no flex) para que el <code> dentro del texto
   quede en línea; el control va debajo a todo el ancho. */
label { display: block; font-size: 0.9rem; font-weight: 500; color: var(--ink); }
label > input:not([type="checkbox"]):not([type="radio"]),
label > select,
label > textarea { display: block; width: 100%; margin-top: 0.35rem; font-weight: 400; }
label.checkbox, label.radio { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; font-weight: 400; }
label.radio { align-items: flex-start; }
label.radio input { margin-top: 0.3rem; }
label:has(> input:disabled) { color: var(--ink-muted); }

fieldset {
    border: 1px solid var(--rule); border-radius: var(--radius); background: var(--card);
    padding: 0.75rem 1rem 1rem; display: flex; flex-direction: column; gap: 0.6rem;
}
/* Hasta 1100 px el fieldset no se estira al ancho de la tabla de destinos
   (que se desplaza en su caja): sin esto, el formulario de vhost ensancha la
   página en tablet y celular. En pantallas anchas queda como estaba. */
@media (max-width: 1100px) { fieldset { min-width: 0; } }
fieldset legend {
    padding: 0 0.4rem; font-size: 0.75rem; font-weight: 600; color: var(--ink-muted);
    text-transform: uppercase; letter-spacing: 0.06em;
}

input, select, textarea {
    background-color: var(--card);
    border: 1px solid var(--rule-strong);
    color: var(--ink);
    padding: 0.5rem 0.7rem;
    border-radius: var(--radius-sm);
    font-size: 0.95rem;
    font-family: inherit;
}
input::placeholder, textarea::placeholder { color: var(--ink-muted); opacity: 1; }
input:hover, select:hover, textarea:hover { border-color: var(--line-2); }
input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--focus);
    outline-offset: 1px;
    border-color: var(--focus);
}
input[readonly] { background-color: var(--paper); color: var(--ink-muted); }
input:disabled, select:disabled, textarea:disabled { background-color: var(--paper); color: var(--ink-muted); cursor: not-allowed; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--line-2); width: 1rem; height: 1rem; margin: 0; padding: 0; flex-shrink: 0; }
textarea { resize: vertical; }

/* Botones: tinta sólida, sin degradado ni brillo */
button, .button {
    display: inline-block;
    background: var(--line-2);
    color: var(--on-ink);
    font-family: inherit;
    font-weight: 600;
    border: 1px solid var(--line-2);
    padding: 0.5rem 1.1rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    text-decoration: none;
    font-size: 0.9rem;
    line-height: 1.4;
    margin-top: 0.5rem;
    transition: background var(--transition), border-color var(--transition);
}
button:hover, .button:hover { background: var(--line-2-strong); border-color: var(--line-2-strong); color: var(--on-ink); }
button:active, .button:active { background: var(--ink); border-color: var(--ink); }
button:disabled { opacity: 0.5; cursor: not-allowed; }
form > button[type="submit"]:not(.filter-pill):not(.link-button) { align-self: flex-start; min-width: 8rem; }

.link-button {
    background: none;
    border: none;
    color: var(--line-2);
    font-weight: 500;
    cursor: pointer;
    padding: 0;
    margin: 0;
    font-size: 0.9rem;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.link-button:hover, .link-button:active { background: none; border: none; color: var(--ink); }
.link-button.danger { color: var(--critical); }
.link-button.danger:hover { color: var(--critical-strong); }

/* Mensajes */
.error { color: var(--critical); }
p.error {
    background: var(--critical-fill); border: 1px solid var(--critical-rule); border-radius: var(--radius);
    padding: 0.6rem 0.9rem; font-weight: 500; max-width: 75ch;
}
.notice {
    background: var(--line-fill); border: 1px solid var(--line-1); border-radius: var(--radius);
    padding: 0.6rem 0.9rem; color: var(--ink); max-width: 75ch;
}
.hint { color: var(--ink-muted); font-size: 0.875rem; font-weight: 400; }
p.hint { max-width: 75ch; }
.flash {
    background: var(--ok-fill); border: 1px solid var(--ok-rule); border-radius: var(--radius);
    padding: 0.6rem 0.9rem; color: var(--ink); max-width: 75ch;
}
code {
    font-family: var(--font-code);
    color: var(--ink);
    background: var(--rule-soft);
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    font-size: max(0.85em, 0.75rem);
}

td.ok { color: var(--ok); }
td.fail, .fail { color: var(--critical); }
.level-standby { color: var(--ink-muted); }

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 1rem 0 0.5rem;
}
.filter-pill {
    display: inline-block;
    padding: 0.35rem 0.85rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--rule);
    background: var(--card);
    color: var(--ink-muted);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 500;
    margin: 0;
    cursor: pointer;
}
.filter-pill:hover { color: var(--ink); background: var(--card); border-color: var(--line-2); }
.filter-pill:active { color: var(--ink); background: var(--card); border-color: var(--ink); }
.filter-pill.active {
    color: var(--ink);
    background: var(--card);
    border-color: var(--line-2);
    font-weight: 600;
}
.filter-range {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    max-width: none;
    margin: 0;
}
.filter-range input[type="date"] { padding: 0.35rem 0.6rem; font-size: 0.85rem; }
.filter-range span { color: var(--ink-muted); font-size: 0.85rem; }

/* Auditoría: filtros de accesos y cambios de vhost plegados. */
form.audit-filters { display: flex; flex-direction: row; flex-wrap: wrap; max-width: none; align-items: flex-end; gap: 0.6rem 1rem; margin: 0.5rem 0; }
.audit-filters label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.875rem; color: var(--ink-muted); }
.audit-filters label > input { margin-top: 0; width: 12rem; max-width: 100%; }
.audit-filters input[type="text"] { width: 12rem; max-width: 100%; padding: 0.4rem 0.7rem; font-size: 0.875rem; }
details.cambios summary { cursor: pointer; font-size: 0.875rem; }
details.cambios ul { margin: 0.35rem 0 0; padding-left: 1.1rem; font-size: 0.875rem; }
details.cambios li { overflow-wrap: anywhere; }

/* min-width: dentro de una tabla con scroll propio, el JSON no se aplasta a una letra por línea. */
pre.detail {
    margin: 0;
    min-width: 18rem;
    max-width: 480px;
    white-space: pre-wrap;
    word-break: break-word;
    font-family: var(--font-code);
    font-size: 0.8rem;
    color: var(--ink-muted);
}

.login-box {
    max-width: 360px;
    margin: 4rem auto;
    padding: 2rem;
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
}
/* El logo está dibujado para el riel: se le da su campo de tinta. */
.login-logo {
    display: block; margin: 0 auto 0.75rem; height: 40px; box-sizing: content-box;
    padding: 10px 14px; background: var(--rail); border-radius: var(--radius-sm);
}
.login-subtitle {
    text-align: center;
    color: var(--ink-muted);
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.06em;
    margin-top: 0;
    margin-bottom: 1.25rem;
}

/* --- Tarjetas de cifras (dashboard, reportes) --- */

.kpi-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
    margin-bottom: 1.75rem;
}

.kpi-tile {
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 0.9rem 1.1rem;
}
.kpi-tile .kpi-label {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--ink-muted);
}
.kpi-tile .kpi-value {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 2rem;
    letter-spacing: 0.04em;
    line-height: 1.1;
    margin-top: 0.15rem;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

.gauge {
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 1.1rem 1.25rem;
}
.gauge-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-family: var(--font-display);
}
.gauge-head .gauge-label { font-weight: 600; letter-spacing: 0.04em; color: var(--ink); }
.gauge-head .gauge-percent { font-weight: 600; font-size: 1.4rem; }

.gauge-track {
    margin-top: 0.6rem;
    height: 8px;
    border-radius: 999px;
    background: var(--rule-soft);
    overflow: hidden;
}
.gauge-fill {
    height: 100%;
    border-radius: 999px;
    transition: width var(--transition);
}
.gauge.ok .gauge-percent { color: var(--ok); }
.gauge.ok .gauge-fill { background: var(--line-1); }
.gauge.warning .gauge-percent { color: var(--degraded); }
.gauge.warning .gauge-fill { background: var(--degraded); }
.gauge.critical .gauge-percent { color: var(--critical); }
.gauge.critical .gauge-fill { background: var(--critical); }

.gauge-detail { margin-top: 0.4rem; font-size: 0.82rem; color: var(--ink-muted); }

/* --- Usuarios de ARX Guard --- */

.status-ok { color: var(--ok); font-weight: 600; }
.status-warning { color: var(--degraded); font-weight: 600; }
.status-critical { color: var(--critical); font-weight: 600; }
.status-pending { color: var(--ink-muted); }

.badge-emergency {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--degraded);
    background: var(--degraded-fill);
    border: 1px solid var(--degraded-rule);
    border-radius: var(--radius-sm);
    padding: 0.05rem 0.45rem;
    margin-left: 0.3rem;
}

td.actions { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center; }

.temp-password {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--ink);
    background: var(--card);
    border: 1px solid var(--line-2);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
    margin: 1rem 0;
    user-select: all;
    word-break: break-all;
}

/* --- Seguridad: paneles WAF / Fail2Ban / Buscar IP (2026-10-08) --- */

a.metric { text-decoration: none; }
a.metric:hover strong { text-decoration: underline; }

.nav-section {
    margin: 1rem 0 0.25rem;
    padding: 0 0.75rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--rail-muted);
}

.card {
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
    min-width: 0;
}
.card h2 { margin-top: 0; font-size: 1.1rem; }
.card h3 { font-family: var(--font-display); font-weight: 600; letter-spacing: 0.04em; font-size: 0.95rem; color: var(--ink-muted); margin: 0.9rem 0 0.4rem; }

.sec-grid { display: grid; grid-template-columns: 260px 1fr; gap: 1rem; }
.sec-grid.two { grid-template-columns: 1fr 1fr; }
.sec-grid > .card { margin-bottom: 0; }
.sec-grid > * { min-width: 0; }
.sec-grid { margin-bottom: 1rem; }
@media (max-width: 1100px) { .sec-grid, .sec-grid.two { grid-template-columns: 1fr; } }

.gauge-card { display: flex; flex-direction: column; align-items: center; }
/* Anillo: pista fina de filete y arco en tinta de línea (el color lo pasa la plantilla). */
.ring { width: 200px; height: 200px; }
.ring-track { fill: none; stroke: var(--rule-soft); stroke-width: 6; }
.ring-arc { fill: none; stroke-width: 6; stroke-linecap: butt; transition: stroke-dasharray 0.6s cubic-bezier(0.16, 1, 0.3, 1); }
.ring-value { fill: var(--ink); font-family: var(--font-display); font-weight: 600; font-size: 44px; letter-spacing: 0.02em; text-anchor: middle; font-variant-numeric: tabular-nums; }
.ring-caption { fill: var(--ink-muted); font-family: var(--font-ui); font-weight: 500; font-size: 13px; text-anchor: middle; text-transform: uppercase; letter-spacing: 0.08em; }
.ring-sub { fill: var(--ink-muted); font-family: var(--font-ui); font-size: 12px; text-anchor: middle; }

.bars { display: flex; align-items: flex-end; gap: 3px; height: 140px; padding-bottom: 1.2rem; position: relative; border-bottom: 1px solid var(--rule); }
.bar-col { flex: 1; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; position: relative; }
.bar { width: 100%; background: var(--bar-color); border-radius: 1px 1px 0 0; opacity: 0.85; min-height: 0; }
.bar-col:hover .bar { opacity: 1; }
.bar-label { position: absolute; bottom: -1.25rem; font-size: 0.75rem; color: var(--ink-muted); font-family: var(--font-display); font-weight: 600; font-variant-numeric: tabular-nums; }

.kpi-inline { display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem; margin-top: 0.75rem; align-items: baseline; color: var(--ink-muted); }
.kpi-inline strong { font-family: var(--font-display); font-weight: 600; font-size: 1.3rem; color: var(--ink); }

.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.75rem; }
.chip { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: 0.1rem 0.55rem; font-size: 0.82rem; }

table.compact { margin-top: 0.5rem; }
table.compact th, table.compact td { padding: 0.4rem 0.5rem; font-size: 0.875rem; vertical-align: top; }
table.compact th { font-size: 0.75rem; }

/* Tablas anchas: se desplazan dentro de su propia caja y la página no se
   ensancha. El margen superior pasa de la tabla a la caja (mismo espaciado
   que antes); las que van sueltas en la página llevan papel blanco y filete. */
.table-scroll { position: relative; overflow-x: auto; max-width: 100%; margin-top: 1rem; }
.table-scroll:has(> table.compact) { margin-top: 0.5rem; }
fieldset .table-scroll { margin-top: 0.25rem; }
.table-scroll > table { margin-top: 0; }
main > .table-scroll {
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
}
main > .table-scroll tbody tr:last-child td { border-bottom: none; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.num { font-family: var(--font-display); font-weight: 600; font-size: 0.95rem; letter-spacing: 0.02em; }
.small, td.small { font-size: 0.8rem; }
.hint.small { font-size: 0.8rem; }
td .hint { font-size: 0.78rem; }

/* País: código ISO en texto (sin emoji de bandera). */
.country { white-space: nowrap; font-family: var(--font-display); font-weight: 600; font-size: 0.9rem; letter-spacing: 0.06em; }
.country.lan { color: var(--line-2); font-size: 0.85rem; }
.country.unknown { color: var(--ink-muted); }

.ip-link { text-decoration: none; }
.ip-link code { cursor: pointer; color: var(--line-2); }
.ip-link:hover code { text-decoration: underline; text-underline-offset: 3px; }

.badge-banned {
    display: inline-block; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
    color: var(--critical); background: var(--critical-fill); border: 1px solid var(--critical-rule);
    border-radius: var(--radius-sm); padding: 0.02rem 0.45rem; margin-left: 0.25rem;
}

.filter-pill.toggle { margin-left: auto; }

.search-form { flex-direction: row; align-items: center; gap: 0.6rem; max-width: 520px; }
.search-form input { flex: 1; min-width: 0; }
.search-form button { margin-top: 0; }

.banned-list { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; }
.banned-item { display: flex; align-items: center; gap: 0.4rem; background: var(--paper); border: 1px solid var(--rule-soft); border-radius: var(--radius-sm); padding: 0.25rem 0.6rem; }

.ip-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.ip-big code { font-size: 1.5rem; }
.ip-status { display: flex; flex-direction: column; gap: 0.4rem; align-items: flex-end; }
.ip-status form { display: inline; }
.ip-status button { margin: 0 0 0 0.5rem; padding: 0.3rem 0.8rem; font-size: 0.85rem; }

/* --- Reportes --- */

.report-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.report-head h1 { margin-bottom: 0.5rem; }
button.secondary { background: var(--card); color: var(--line-2); border: 1px solid var(--line-2); margin: 0; }
button.secondary:hover { background: var(--paper); color: var(--ink); border-color: var(--ink); }

.tabs { display: flex; flex-wrap: wrap; gap: 0.25rem; border-bottom: 1px solid var(--rule); margin: 0.5rem 0 0.75rem; }
.tab {
    font-weight: 500; font-size: 0.9rem;
    color: var(--ink-muted); text-decoration: none; padding: 0.55rem 1rem;
    border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--ink); font-weight: 600; border-bottom-color: var(--line-2); }

.vhost-filter { flex-direction: row; max-width: 360px; margin: 0.25rem 0 0.75rem; }
.vhost-filter select { width: 100%; }

.report-meta { color: var(--ink-muted); font-size: 0.9rem; margin: 0.25rem 0 1rem; }
.report-meta strong { color: var(--ink); }

.csv-link {
    float: right; font-size: 0.75rem; font-weight: 600;
    color: var(--line-2); text-decoration: none; border: 1px solid var(--rule);
    border-radius: var(--radius-sm); padding: 0.1rem 0.5rem; letter-spacing: 0.04em;
}
.csv-link:hover { border-color: var(--line-2); color: var(--ink); }

.status-4xx { color: var(--degraded); }
.status-5xx { color: var(--critical); }

/* Impresión: tinta sobre papel blanco, sin riel ni barra de estado. */
@media print {
    .no-print, .csv-link, .sidebar, .metrics-banner { display: none !important; }
    body { background: #fff; color: #000; display: block; }
    main { padding: 0; }
    a { color: #000; }
    .card, .kpi-tile, main > .table-scroll, fieldset { background: #fff; border-color: var(--rule-strong); break-inside: avoid; }
    .table-scroll { overflow: visible; }
    th, .hint, .report-meta, .kpi-label, .bar-label { color: #000 !important; }
    td, .kpi-value, h1, h2 { color: #000 !important; }
    tbody tr:hover td { background: none; }
    code { background: none; color: #000; }
    .bar { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
    .sec-grid, .sec-grid.two { grid-template-columns: 1fr 1fr; }
}

/* --- Dashboard: triage (templates/_triage.html, dashboard.html) ---
   Primer pantallazo del contrato: RESUMEN en cifras grandes, tarjetas de
   problema con relleno pálido de su gravedad, y la tabla única de vhosts con
   la banda reducida. Columna derecha de eventos; debajo a menos de 1100 px. */
.visually-hidden {
    position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.dash { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 1.75rem; align-items: start; }
.dash-main, .dash-side { min-width: 0; }
.dash-side { padding-left: 1.75rem; border-left: 1px solid var(--rule); align-self: stretch; }
@media (max-width: 1100px) {
    .dash { grid-template-columns: minmax(0, 1fr); gap: 0; }
    .dash-side { padding-left: 0; border-left: none; margin-top: 2rem; }
}

/* Título de sección con filete de guilloche (eco de la banda), sin microtexto. */
.dash-h {
    font-family: var(--font-display); font-weight: 600; font-size: 1.05rem;
    letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink); margin: 0 0 0.75rem;
}
.dash-h::after {
    content: ""; display: block; height: 6px; margin-top: 0.3rem;
    background: var(--rule-guilloche) repeat-x left center / 24px 6px;
}
.triage > .dash-h + .table-tools, .triage > .dash-h + .table-scroll { margin-top: 0; }
.triage > .dash-h:not(:first-child) { margin-top: 2rem; }

.summary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; }
.summary-fig {
    margin: 0; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.6rem;
    padding: 0.75rem 1rem; background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
    color: var(--ink-muted);
}
.summary-num {
    font-family: var(--font-display); font-weight: 600; font-size: 2.5rem; line-height: 1;
    letter-spacing: 0.02em; color: var(--ink); font-variant-numeric: tabular-nums;
}
.summary-bad { border-color: var(--critical-rule); color: var(--critical); }
.summary-bad .summary-num { color: var(--critical); }
.summary-names { margin: 0.6rem 0 0; font-size: 0.875rem; color: var(--ink-muted); overflow-wrap: anywhere; }
.triage-stamp { margin: 0.4rem 0 0; }
.triage-stamp.is-stale { color: var(--degraded); font-weight: 600; }

.problem-cards {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
    gap: 0.75rem; margin-top: 1rem;
}
.problem-card {
    min-width: 0; display: flex; flex-direction: column; gap: 0.45rem;
    padding: 0.85rem 1rem 1rem; border: 1px solid var(--rule); border-top-width: 3px; border-radius: var(--radius);
}
.problem-critical { background: var(--critical-fill); border-color: var(--critical-rule); border-top-color: var(--critical); }
.problem-degraded { background: var(--degraded-fill); border-color: var(--degraded-rule); border-top-color: var(--degraded); }
.problem-meta { margin: 0; font-size: 0.8rem; font-weight: 600; }
.problem-critical .problem-meta { color: var(--critical); }
.problem-degraded .problem-meta { color: var(--degraded); }
.problem-name {
    margin: 0; font-family: var(--font-ui); font-weight: 600; font-size: 1.05rem; line-height: 1.3;
    letter-spacing: 0; color: var(--ink); overflow-wrap: anywhere;
}
.problem-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.2rem; font-size: 0.875rem; color: var(--ink); }
.problem-card .band-svg { max-width: 240px; }
.problem-card .band-labels { font-size: 0.75rem; gap: 0 10px; }
.problem-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: auto; padding-top: 0.35rem; }
.action-link {
    display: inline-flex; align-items: center; min-height: 36px; padding: 0.3rem 0.8rem;
    background: var(--card); color: var(--line-2); border: 1px solid var(--line-2); border-radius: var(--radius-sm);
    font-size: 0.875rem; font-weight: 600; text-decoration: none;
}
.action-link:hover { color: var(--ink); border-color: var(--ink); }

.serial { font-family: var(--font-display); font-weight: 600; letter-spacing: 0.12em; font-variant-numeric: tabular-nums; }

.table-tools { display: flex; justify-content: flex-end; margin: 0 0 0.6rem; }
.table-tools input[type="search"] { width: min(100%, 280px); padding: 0.4rem 0.7rem; font-size: 0.875rem; }
.triage .table-scroll { margin-top: 0; background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius); }
/* Aviso «Sin resultados» del buscador (static/tables.js): vacío no ocupa espacio,
   pero sigue en el árbol de accesibilidad para que role="status" lo anuncie. */
.table-empty { margin: 0.6rem 0 0; }
.table-empty:empty { margin: 0; }
.triage tbody tr:last-child td { border-bottom: none; }
table.vhosts-tabla td { vertical-align: middle; }
table.vhosts-tabla th { white-space: nowrap; vertical-align: bottom; letter-spacing: 0.04em; }
table.vhosts-tabla th, table.vhosts-tabla td { padding-left: 0.45rem; padding-right: 0.45rem; }
.vhosts-tabla td.serial { color: var(--line-2); letter-spacing: 0.06em; white-space: nowrap; }
.vhost-name { font-weight: 500; }
.vhost-label { white-space: nowrap; }
.dest { white-space: nowrap; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.state { min-width: 7rem; max-width: 15rem; }
/* El detalle completo está en la tarjeta del problema (y en el title): en la tabla, dos líneas. */
.state-text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.state-critical { color: var(--critical); font-weight: 600; }
.state-degraded { color: var(--degraded); font-weight: 600; }
.tag {
    display: inline-block; margin-left: 0.35rem; padding: 0 0.4rem; font-size: 0.75rem; font-weight: 500;
    color: var(--ink-muted); border: 1px solid var(--rule); border-radius: var(--radius-sm);
}
.empty-state {
    margin: 0; padding: 1rem 1.25rem; background: var(--card);
    border: 1px dashed var(--rule-strong); border-radius: var(--radius);
}

/* Banda reducida (fila de tabla): sin etiquetas; los trazos no se adelgazan al escalar. */
.band-reducida .band-svg { width: 96px; max-width: none; }
.band-reducida .band-box, .band-reducida .band-line { vector-effect: non-scaling-stroke; }

.dash-host { margin-top: 2rem; }
.host-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 1rem; margin: 0; font-size: 0.875rem; color: var(--ink-muted); }
.host-line strong { color: var(--ink); }
.chip-ok { color: var(--ok); background: var(--ok-fill); border-color: var(--ok-rule); }
.chip-critical { color: var(--critical); background: var(--critical-fill); border-color: var(--critical-rule); font-weight: 600; }

@media (max-width: 760px) {
    .summary { gap: 0.5rem; }
    .summary-fig { flex-direction: column; gap: 0.15rem; padding: 0.6rem 0.75rem; }
    .summary-num { font-size: 2rem; }
    .action-link { min-height: 44px; }
    .table-tools input[type="search"] { width: 100%; min-height: 44px; }
}

/* --- Límites anti-DDoS: insignia de modo con relleno pálido de estado --- */
.mode-badge {
    font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em;
    text-transform: uppercase; border-radius: var(--radius-sm); padding: 0.1rem 0.5rem; margin-left: 0.5rem;
    vertical-align: middle; border: 1px solid var(--rule); color: var(--ink-muted); background: var(--card);
}
.mode-registro { color: var(--degraded); border-color: var(--degraded-rule); background: var(--degraded-fill); }
.mode-bloqueo { color: var(--ok); border-color: var(--ok-rule); background: var(--ok-fill); }
.mode-apagado { color: var(--critical); border-color: var(--critical-rule); background: var(--critical-fill); }

/* --- Indicadores de estado del banner (WAF, Fail2Ban, Anti-DDoS):
   texto en tinta con punto de estado; la palabra de estado (Activo,
   Detección/Parcial, Apagado) lleva el color. Solo lo que no está activo
   toma relleno pálido, para que el problema salte en la tira blanca. --- */
.metric.pill {
    --pill: var(--ink-muted);
    display: inline-flex; align-items: center; gap: 0.45rem;
    padding: 0.2rem 0.65rem 0.2rem 0.55rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    background: var(--card);
    transition: border-color var(--transition);
}
.metric.pill:hover { border-color: var(--line-2); }
.metric.pill strong { color: var(--ink); margin-right: 0; }
.pill-state { color: var(--pill); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; font-size: 0.75rem; }
.pill-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--pill); }
.metric.pill-activo { --pill: var(--ok); }
.metric.pill-registro { --pill: var(--degraded); background: var(--degraded-fill); border-color: var(--degraded-rule); }
.metric.pill-apagado { --pill: var(--critical); background: var(--critical-fill); border-color: var(--critical-rule); }
.metric.pill-registro:hover { border-color: var(--degraded); }
.metric.pill-apagado:hover { border-color: var(--critical); }
.pill-apagado .pill-dot { animation: dot-pulse 1s ease-in-out 3; }
/* Pulsa 3 veces al entrar en problema y queda fijo. */
@keyframes dot-pulse { 50% { opacity: 0.3; } }
.pill-count { color: var(--ink-muted); font-size: 0.78rem; padding-left: 0.45rem; border-left: 1px solid var(--rule); }

@media (prefers-reduced-motion: reduce) {
    .pill-dot { animation: none; }
    .ring-arc { transition: none; }
}


/* --- Zona de peligro: mundo «Papel de seguridad» (usa los tokens de :root) --- */
.paper {
    color: var(--ink);
    font-family: var(--font-ui);
}
body.paper-body { display: block; padding: 0; }

.danger-sheet {
    box-sizing: border-box; width: min(100% - 32px, 640px); margin: 0 auto; padding: 40px 0 56px;
}
.danger-logo {
    font-family: var(--font-display); font-weight: 600; letter-spacing: 0.3em;
    font-size: 0.95rem; color: var(--rail);
}
.danger-head { padding-bottom: 20px; border-bottom: 1px solid var(--rule); margin-bottom: 28px; }
.paper h1.danger-title {
    font-family: var(--font-display); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    font-size: 1.1rem; color: var(--critical); margin: 0 0 4px;
}
.danger-subject {
    font-family: var(--font-display); font-weight: 600; letter-spacing: 0.03em; font-size: clamp(1.8rem, 6vw, 2.75rem);
    line-height: 1.1; margin: 0 0 24px; overflow-wrap: anywhere; color: var(--ink);
}
.danger-bands, .danger-effects, .danger-form {
    background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius); padding: 20px;
    margin: 0 0 16px;
}
.danger-bands { display: grid; gap: 20px; }
.danger-band-block h2 {
    font-family: var(--font-display); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
    font-size: 0.95rem; color: var(--ink-muted); margin: 0 0 8px;
}
.danger-effects { list-style: none; display: grid; gap: 10px; background: var(--critical-fill); border-color: var(--critical-rule); }
.danger-effects li { font-size: 1rem; line-height: 1.5; max-width: 65ch; color: var(--ink); }

.band-svg { display: block; width: 100%; max-width: 372px; height: auto; }
.band-box { fill: none; stroke: none; }
.band-line { fill: none; stroke-width: 0.8; stroke-linecap: round; }
.band-line-a { stroke: var(--line-1); }
.band-line-b { stroke: var(--line-2); }
.band-line-c { stroke: var(--line-2); stroke-width: 0.5; }
.band-on .band-box { fill: var(--line-fill); stroke: var(--line-2); stroke-width: 1.2; }
.band-off .band-box { fill: none; stroke: var(--critical); stroke-width: 1.4; stroke-dasharray: 4 3; }
.band-na { opacity: 0.25; }
.band-na .band-box { stroke: var(--line-2); stroke-width: 1; }
.band-labels {
    list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 2px 14px;
    font-size: 0.82rem; color: var(--ink);
}
.paper .band-label { font-weight: 600; }
.band-label span { font-weight: 400; color: var(--ink-muted); }
.band-label-off, .band-label-off span { color: var(--critical); font-weight: 600; }

.paper form.danger-form { display: grid; gap: 10px; max-width: none; }
.paper label.danger-label { display: block; font-weight: 600; font-size: 0.95rem; color: var(--ink); }
.paper .danger-input {
    box-sizing: border-box; width: 100%; padding: 10px 12px; font: inherit; color: var(--ink);
    background: var(--card); border: 1px solid var(--rule-strong); border-radius: var(--radius-sm); caret-color: var(--line-2);
}
.danger-input.has-error { border-color: var(--critical); border-width: 2px; }
.danger-error { margin: 0; color: var(--critical); font-weight: 600; font-size: 0.95rem; }
.danger-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 20px; margin-top: 8px; }
.paper .btn-danger {
    margin: 0; background-image: none; font: inherit; font-weight: 600; background: var(--critical); color: var(--on-ink); border: 1px solid var(--critical);
    border-radius: var(--radius-sm); padding: 11px 18px; cursor: pointer; min-height: 44px;
}
.paper .btn-danger:hover { background: var(--critical-strong); border-color: var(--critical-strong); }
.paper .btn-danger:active { background: var(--critical-deep); border-color: var(--critical-deep); }
.paper .btn-danger:focus-visible { outline-color: var(--ink); }
.danger-cancel { color: var(--line-2); font-weight: 600; text-underline-offset: 3px; padding: 10px 4px; }
.danger-cancel:hover { color: var(--ink); }

/* Últimos eventos: lista en la columna derecha, tarjetas blancas con filete. */
.events { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.event {
    display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.1rem 0.6rem; align-items: baseline;
    padding: 0.55rem 0.75rem; background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
}
.event-time {
    font-family: var(--font-display); font-weight: 600; font-size: 1rem; letter-spacing: 0.04em;
    color: var(--ink-muted); font-variant-numeric: tabular-nums;
}
.event-title {
    font-family: var(--font-display); font-weight: 600; font-size: 0.95rem; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--ink);
}
.event-detail { grid-column: 2; font-size: 0.8125rem; color: var(--ink-muted); overflow-wrap: anywhere; }

/* Tablas con orden y búsqueda (static/tables.js) y menú de fila */
th .sort-btn {
    all: unset;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    cursor: pointer;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
}
th .sort-btn::after { content: "\2195"; color: var(--rule); font-size: 0.75rem; }
th[aria-sort="ascending"] .sort-btn::after { content: "\2191"; color: var(--ink); }
th[aria-sort="descending"] .sort-btn::after { content: "\2193"; color: var(--ink); }
th[aria-sort] { color: var(--ink); }
.sort-btn:hover { color: var(--ink); }
.sort-btn:focus-visible, details.row-menu > summary:focus-visible { outline: 2px solid var(--line-2); outline-offset: 2px; }
/* Un elemento con `hidden` nunca se muestra, aunque otra regla le fije display. */
[hidden] { display: none !important; }
.dest-state { font-size: 0.8125rem; font-weight: 600; }
.dest-up { color: var(--ok); }
.dest-down { color: var(--critical); }
details.row-menu { display: inline-block; }
details.row-menu > summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 0.2rem 0.7rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
    background: var(--card);
    color: var(--ink);
    font-size: 0.875rem;
    font-weight: 500;
}
details.row-menu > summary::-webkit-details-marker { display: none; }
details.row-menu > summary::after { content: "\25BE"; margin-left: 0.35rem; }
details.row-menu[open] > summary { border-color: var(--line-2); }
.row-menu-panel {
    /* En el flujo (no flotante): .table-scroll recorta lo que sobresale. */
    margin-top: 0.4rem;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    min-width: 12rem;
    padding: 0.7rem 0.8rem;
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius-sm);
}
@media (max-width: 760px) {
    details.row-menu > summary { min-height: 44px; }
    .row-menu-panel .link-button, .row-menu-panel a { min-height: 44px; display: inline-flex; align-items: center; }
}

/* --- Formulario de vhost por secciones (Destinos, Protección, Certificado, Avanzado) --- */
form.vhost-form { max-width: 760px; }
.vhost-form fieldset legend,
.vhost-form details.avanzado > summary {
    font-family: var(--font-display); font-weight: 600; font-size: 1.1rem; letter-spacing: 0.04em;
    text-transform: none; color: var(--ink);
}
/* La explicación va bajo la etiqueta, en una línea de ayuda; la de checkbox y radio se alinea con el texto. */
.vhost-form .hint { display: block; margin-top: -0.35rem; }
.vhost-form .hint-indent { padding-left: 1.5rem; }
.vhost-form fieldset > .hint:first-of-type { margin-top: 0; }
.vhost-form .form-actions { display: flex; align-items: center; gap: 1.25rem; }
.vhost-form .form-actions button[type="submit"] { min-width: 8rem; }
.vhost-form #device-type-field { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 0.4rem; }

details.avanzado {
    border: 1px solid var(--rule); border-radius: var(--radius); background: var(--card); padding: 0.75rem 1rem;
}
details.avanzado > summary { cursor: pointer; }
details.avanzado > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
details.avanzado[open] > summary { margin-bottom: 0.75rem; }
.avanzado-cuerpo { display: flex; flex-direction: column; gap: 0.6rem; }

.vhost-form table.destinations td.dest-actions { white-space: nowrap; }

/* Celular: cada destino se apila (dirección, nivel y etiqueta en bloque, con su
   etiqueta visible por fila) y la tabla ya no se desplaza de lado. */
@media (max-width: 760px) {
    .vhost-form .table-scroll { overflow-x: visible; }
    .vhost-form table.destinations,
    .vhost-form table.destinations tbody,
    .vhost-form table.destinations tr,
    .vhost-form table.destinations td { display: block; width: 100%; }
    .vhost-form table.destinations thead {
        position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
    }
    .vhost-form table.destinations tr.dest-row {
        padding: 0.6rem 0; border-bottom: 1px solid var(--rule);
    }
    .vhost-form table.destinations td { padding: 0.25rem 0; border-bottom: none; }
    .vhost-form table.destinations td[data-label]::before {
        content: attr(data-label); display: block; font-size: 0.9rem; font-weight: 500; color: var(--ink);
        margin-bottom: 0.25rem;
    }
    .vhost-form table.destinations td input,
    .vhost-form table.destinations td select { width: 100%; }
    .vhost-form table.destinations td.dest-actions { text-align: right; }
    .vhost-form .dest-remove, .vhost-form #dest-add { min-height: 44px; }
}
