/* Capatest / Moviltest — sistema de diseño "instrumento de calibración".
   Tokens y componentes derivados de docs/diseno-dashboard.md (§2 color, §4 layout, §5 componentes). */

:root {
    --paper: #E7EAE4;
    --card: #F8F9F5;
    --card-2: #FFFFFF;
    --ink: #181B18;
    --ink-2: #565C55;
    --ink-3: #888E86;
    --line: #CFD4CA;
    --line-2: #E1E5DC;
    --brand: #205FED;
    --brand-ink: #11337E;
    --verify: #227A4B;
    --verify-bg: #DDEBE0;
    --warn: #B9741A;
    --warn-bg: #F1E6D2;
    --alert: #AE3A2C;
    --alert-bg: #F0DAD3;
    --neutral: #9AA096;

    --r: 14px;
    --shadow: 0 1px 0 rgba(24,27,24,.04), 0 12px 28px -18px rgba(24,27,24,.30);

    --sans: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, "SF Mono", Menlo, monospace;
}

:root[data-theme="dark"] {
    --paper: #15171A;
    --card: #1D2023;
    --card-2: #23272A;
    --ink: #E9ECE5;
    --ink-2: #A6ADA2;
    --ink-3: #767D72;
    --line: #2C3230;
    --line-2: #262B29;
    --brand: #4F86FF;
    --brand-ink: #8FB2FF;
    --verify: #38B36E;
    --verify-bg: #16281F;
    --warn: #E0982E;
    --warn-bg: #2B2318;
    --alert: #E05745;
    --alert-bg: #2C1B18;
    --neutral: #6C7269;
    --shadow: 0 1px 0 rgba(0,0,0,.3), 0 18px 34px -20px rgba(0,0,0,.7);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --paper: #15171A;
        --card: #1D2023;
        --card-2: #23272A;
        --ink: #E9ECE5;
        --ink-2: #A6ADA2;
        --ink-3: #767D72;
        --line: #2C3230;
        --line-2: #262B29;
        --brand: #4F86FF;
        --brand-ink: #8FB2FF;
        --verify: #38B36E;
        --verify-bg: #16281F;
        --warn: #E0982E;
        --warn-bg: #2B2318;
        --alert: #E05745;
        --alert-bg: #2C1B18;
        --neutral: #6C7269;
        --shadow: 0 1px 0 rgba(0,0,0,.3), 0 18px 34px -20px rgba(0,0,0,.7);
    }
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
    font-family: var(--sans);
    font-size: 14px;
    line-height: 1.45;
    color: var(--ink);
    background-color: var(--paper);
    /* Retícula de papel milimetrado (spec §2.2): celda 52×52, offset -1px. */
    background-image:
        linear-gradient(to right, var(--line-2) 1px, transparent 1px),
        linear-gradient(to bottom, var(--line-2) 1px, transparent 1px);
    background-size: 52px 52px;
    background-position: -1px -1px;
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

.num { font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }

.ey {
    font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase;
    font-weight: 600; color: var(--ink-3);
}

/* ---------- Layout global (spec §4) ---------- */

.app { display: grid; grid-template-columns: 74px 1fr; min-height: 100vh; }

.rail {
    position: sticky; top: 0; height: 100vh;
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 16px 0; background: var(--card); border-right: 1px solid var(--line);
}

.brand {
    width: 40px; height: 40px; border-radius: 11px; background: var(--ink);
    box-shadow: inset 0 0 0 2px var(--brand);
    display: grid; place-items: center; color: var(--card); font-weight: 800;
    margin-bottom: 8px;
}

.nav { display: flex; flex-direction: column; gap: 4px; width: 100%; align-items: center; }

.nav a {
    position: relative; width: 46px; height: 44px; border-radius: 10px;
    display: grid; place-items: center; color: var(--ink-3);
    transition: color .15s, background .15s;
}

.nav a:hover { color: var(--ink); background: var(--line-2); }

.nav a.on {
    color: var(--brand-ink);
    background: color-mix(in srgb, var(--brand) 15%, transparent);
}

.nav a.on::before {
    content: ""; position: absolute; left: -0; top: 9px; bottom: 9px; left: 0;
    width: 3px; border-radius: 0 3px 3px 0; background: var(--brand);
}

.nav a svg { width: 21px; height: 21px; }

.nav .tip {
    position: absolute; left: 54px; white-space: nowrap;
    background: var(--ink); color: var(--card); font-size: 12px;
    padding: 5px 9px; border-radius: 7px; opacity: 0; pointer-events: none;
    transform: translateX(-4px); transition: opacity .14s, transform .14s; z-index: 20;
}

.nav a:hover .tip { opacity: 1; transform: translateX(0); }

.rail .spacer { flex: 1; }

.iconbtn {
    width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--line);
    background: var(--card-2); color: var(--ink-2); cursor: pointer;
    display: grid; place-items: center;
}

.iconbtn:hover { color: var(--ink); }

/* Iconos utilitarios (campana · tema · logout) más contenidos que la navegación (21px): jerarquía. */
.iconbtn svg { width: 20px; height: 20px; }

/* Selector de idioma (topbar · login). Alineado con .iconbtn en alto y borde para que la fila de
   controles de usuario lea como una sola pieza, pero con texto en vez de icono: no hay glifo que
   diga "idioma" sin ambigüedad — la bandera es el error clásico, porque un idioma no es un país. */
.langpick select {
    height: 40px; border-radius: 10px; border: 1px solid var(--line);
    background: var(--card-2); color: var(--ink-2); cursor: pointer;
    font-family: var(--sans); font-size: 13px; padding: 0 8px;
}

.langpick select:hover { color: var(--ink); }

/* ---------- Topbar (spec §5.2) ---------- */

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

.topbar {
    position: sticky; top: 0; z-index: 10;
    display: flex; align-items: center; gap: 16px;
    padding: 9px 26px; border-bottom: 1px solid var(--line);
    background: color-mix(in srgb, var(--paper) 82%, transparent);
    backdrop-filter: blur(8px);
}

.brandline { display: flex; flex-direction: row; align-items: center; gap: 12px; }
.brandline b { font-size: 14px; }

/* Logo de marca en la barra. Alto fijo; el ancho se deriva del viewBox. */
.brandlogo { display: inline-flex; align-items: center; }
.brandlogo svg { height: 38px; width: auto; display: block; }
.brandsep { width: 1px; height: 20px; background: var(--line); }
.brandtag { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; font-weight: 600; color: var(--ink-3); }

/* El gris del isotipo/tagline (.cls-1) se pierde sobre fondo oscuro: aclararlo. El azul de marca se mantiene. */
:root[data-theme="dark"] .brandlogo .cls-1 { fill: #C7CBD1; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .brandlogo .cls-1 { fill: #C7CBD1; }
}

/* En pantallas estrechas, el logo basta; oculta el descriptor. */
@media (max-width: 560px) {
    .brandsep, .brandtag { display: none; }
}

.search {
    flex: 1; max-width: 460px; display: flex; align-items: center; gap: 8px;
    padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px;
    background: var(--card-2); color: var(--ink-3);
}
.search input { border: 0; outline: 0; background: transparent; color: var(--ink); width: 100%; font-size: 13px; }

.spacer { flex: 1; }

.user { display: flex; align-items: center; gap: 10px; }
.user .who { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.15; }
.user .who b { font-size: 13px; }
.user .who span { font-size: 11px; color: var(--ink-3); }
.av {
    width: 34px; height: 34px; border-radius: 999px; background: var(--brand);
    color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 13px;
}

/* ---------- Contenedor de contenido ---------- */

.wrap { width: 100%; max-width: 1360px; margin: 0 auto; padding: 26px;
    display: flex; flex-direction: column; gap: 22px; }

.head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.head h1 { margin: 0; font-size: 24px; font-weight: 700; }
.head .sub { color: var(--ink-2); font-size: 13px; }

.card {
    background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
    box-shadow: var(--shadow);
}
.card .panel-h {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 20px; border-bottom: 1px solid var(--line-2);
}
.card .panel-h h2 { margin: 0; font-size: 14px; }

/* ---------- Botones ---------- */

.btn {
    display: inline-flex; align-items: center; gap: 8px; justify-content: center;
    padding: 9px 14px; border-radius: 10px; border: 1px solid var(--line);
    background: var(--card-2); color: var(--ink); font-size: 13px; font-weight: 600;
    cursor: pointer; transition: background .14s, border-color .14s;
}
.btn:hover { background: var(--line-2); }
.btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn.primary:hover { background: color-mix(in srgb, var(--brand) 88%, #000); }
.btn.ghost { background: transparent; }
.btn.danger { background: var(--alert); border-color: var(--alert); color: #fff; }
.btn.danger:hover { background: color-mix(in srgb, var(--alert) 88%, #000); border-color: color-mix(in srgb, var(--alert) 88%, #000); }

/* ---------- Barra de filtros (P2) ---------- */

.filters {
    display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
    padding: 16px 20px;
}
.field { display: flex; flex-direction: column; gap: 5px; }
.field > label { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; }
.field select, .field input {
    padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px;
    background: var(--card-2); color: var(--ink); font-size: 13px; min-width: 150px;
    font-family: var(--sans);
}
.field.grow { flex: 1; min-width: 200px; }
.field.grow input { width: 100%; }
.filters .actions { display: flex; gap: 8px; margin-left: auto; }

/* ---------- Tabla (spec §5.8) ---------- */

.tablewrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl thead th {
    text-align: left; padding: 11px 20px; font-size: 10.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-3); font-weight: 600;
    border-bottom: 1px solid var(--line); white-space: nowrap;
}
.tbl tbody td { padding: 12px 20px; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
.tbl tbody tr { transition: background .14s; }
.tbl tbody tr:hover { background: var(--card-2); }
.tbl .name { font-weight: 600; }
.tbl .name a:hover { color: var(--brand-ink); text-decoration: underline; }
.tbl .em { color: var(--ink-3); font-size: 12px; }
.tbl .path { font-family: var(--mono); font-size: 12px; color: var(--ink-2); }

/* ---------- Chips / pills / estados (spec §5.9, §7) ---------- */

.pill {
    display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px;
    border-radius: 999px; font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.pill .dot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; }
.pill.ok { background: var(--verify-bg); color: var(--verify); }
.pill.warn { background: var(--warn-bg); color: var(--warn); }
.pill.bad { background: var(--alert-bg); color: var(--alert); }
.pill.neutral { background: color-mix(in srgb, var(--neutral) 20%, transparent); color: var(--ink-2); }

.badge {
    display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
    font-family: var(--mono); font-size: 11.5px; font-weight: 600;
}
.badge.ok { background: var(--verify-bg); color: var(--verify); }
.badge.warn { background: var(--warn-bg); color: var(--warn); }
.badge.bad { background: var(--alert-bg); color: var(--alert); }
.badge.neutral { background: color-mix(in srgb, var(--neutral) 20%, transparent); color: var(--ink-2); }

.muted { color: var(--ink-3); }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ---------- Paginación ---------- */

.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 20px; border-top: 1px solid var(--line-2); }
.pager .info { color: var(--ink-3); font-size: 12.5px; }
.pager .nav-btns { display: flex; gap: 8px; }

/* ---------- Empty state ---------- */

.empty { padding: 48px 20px; text-align: center; color: var(--ink-3); }

/* ---------- Home P1: hero instrumento (spec §5.3) ---------- */

.hero { display: grid; grid-template-columns: 1.05fr 1fr 1.15fr; }
.hero > div { padding: 20px 24px; }
.hero > div + div { border-left: 1px solid var(--line); }

.readout .big { font-size: 66px; line-height: 1; font-weight: 700; margin: 6px 0 10px; }
.readout .big small { color: var(--ink-3); font-weight: 600; }
.state { display: inline-flex; align-items: center; gap: 7px; padding: 4px 11px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.readout .note { margin-top: 10px; color: var(--ink-2); font-size: 12.5px; }
/* Disponibilidad del mes: dato de retrovisor, con el peso que le toca. Ocupaba un gauge en el hero
   y casi nunca se mueve (una flota sana vive en el 97-99%), así que no accionaba nada. */
.readout .subnote {
    margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-2);
    color: var(--ink-3); font-size: 12px;
}
.readout .subnote b { color: var(--ink-2); font-weight: 600; }

/* ---------- Ritmo de ensayos (hero, celda 2) ----------
   Sustituye al gauge de disponibilidad del mes: el hero no tenía ninguna lectura de volumen de
   trabajo, y un recuento de hoy sin su histórico no dice si 1.847 es mucho o poco. */
.rate { display: flex; flex-direction: column; }
.rate .big { font-size: 46px; line-height: 1; font-weight: 700; margin: 6px 0 2px; }
.rate .brk { color: var(--ink-2); font-size: 12.5px; }
.rate .brk i {
    display: inline-block; width: 7px; height: 7px; border-radius: 2px;
    vertical-align: middle; margin-right: 5px; background: var(--brand);
}
.rate .brk i.s { background: color-mix(in srgb, var(--brand) 45%, var(--card)); }
/* Tercer término (deslizamiento): sigue bajando la rampa de tinte, pero con un aro tenue porque a
   7px un relleno al 20% se pierde contra la tarjeta clara. */
.rate .brk i.t {
    background: color-mix(in srgb, var(--brand) 20%, var(--card));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand) 45%, var(--card));
}
/* Cuarto término (placas): la rampa de tinte se acabó —por debajo del 20% no queda contraste
   utilizable a 7px, y comprimir los tres pasos anteriores para hacer sitio acercaría el primero al
   segundo, que es justo lo que hay que distinguir. Cambia de recurso: sin relleno y con el aro a
   plena tinta. Es el final natural de una rampa y se lee por forma, no por claridad. */
.rate .brk i.p {
    background: var(--card);
    box-shadow: inset 0 0 0 1.5px var(--brand);
}
.rate .sparkwrap { margin-top: auto; padding-top: 14px; }
.rate .spark { width: 100%; height: 62px; display: block; overflow: visible; }
.rate .spark g:hover rect { opacity: .65; }
.rate .base { display: flex; justify-content: space-between; align-items: baseline; margin-top: 7px; font-size: 11.5px; color: var(--ink-3); }
.rate .base b { font-family: var(--mono); color: var(--ink-2); font-weight: 600; }
.rate .sparkempty { color: var(--ink-3); font-size: 12.5px; padding: 18px 0; }

/* Donut de calibración en regla: anillo segmentado (al día / por vencer / vencidas) + % central. */
.donut { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.donutwrap { position: relative; width: 150px; height: 150px; margin: 6px 0 2px; }
.donutwrap svg { width: 150px; height: 150px; display: block; }
.donutc { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.donutval { font-size: 36px; font-weight: 700; line-height: 1; }
.donutval small { font-size: 17px; font-weight: 600; margin-left: 1px; }
.donutlab { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin-top: 5px; }
.dlgnd { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; margin-top: 14px; font-size: 12px; color: var(--ink-2); }
.dlgnd i.d-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.dlgnd b { font-family: var(--mono); color: var(--ink); margin-left: 5px; }
.dnote { margin-top: 7px; font-size: 11.5px; color: var(--ink-3); }

/* ---------- Ruler (spec §5.4) ---------- */
.ruler { height: 16px; position: relative; }
.ruler::before { content: ""; position: absolute; top: 8px; left: 0; right: 0; height: 1px; background: var(--line); }
.ruler::after { content: ""; position: absolute; top: 5px; left: 0; right: 0; height: 7px;
    background: repeating-linear-gradient(90deg, var(--line) 0 1px, transparent 1px 26px); }

/* ---------- Hero fila 2: escalón secundario ----------
   Mismo lenguaje de tarjeta que la fila 1, menos peso. Sustituye a la antigua tira de 6 KPIs: los
   datos siguen todos ahí (máquinas -> /total del readout, en servicio -> celda 1, ensayos -> celda 2,
   calibradas -> celda 3, mantenimiento -> celda 4, sin dato -> celda 6), pero repartidos en lecturas
   con contexto en vez de seis cifras sueltas sin línea base. */
.hero.tier2 { grid-template-columns: repeat(3, 1fr); margin-top: 14px; }
.hero.tier2 > div { padding: 16px 20px; }

/* Barra segmentada (mantenimiento). Deliberadamente NO es un donut: con dos donuts iguales, uno
   sobre otro, la fila 2 dejaría de ser un escalón y competiría con la 1.
   El gap de 2px es codificación secundaria obligatoria, no estética: los tokens de estado están a
   ΔE 6,9 (verde/ámbar, protanopia) y 14,0 (rojo/ámbar, visión normal), por debajo del suelo de 15;
   sin separación y sin la cifra en la leyenda, el reparto no se lee. */
.segbar { display: flex; gap: 2px; height: 13px; margin: 12px 0 0; }
.segbar span { border-radius: 3px; min-width: 3px; }
.segbar .s-ok { background: var(--verify); }
.segbar .s-warn { background: var(--warn); }
.segbar .s-bad { background: var(--alert); }
.seglgnd { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 11px; font-size: 12px; color: var(--ink-2); }
.seglgnd i.d-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.seglgnd b { font-family: var(--mono); color: var(--ink); margin-left: 5px; }
.segpct { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; }
.segpct .v { font-size: 30px; font-weight: 700; line-height: 1; }
.segpct .v small { font-size: 15px; font-weight: 600; color: var(--ink-3); }
.segpct .of { font-size: 11.5px; color: var(--ink-3); }

/* Celdas contables (licencias/garantía · fechas sin configurar). Sin gráfico a propósito: son
   cifras que se leen una a una, no magnitudes que se comparen entre sí. */
.facts { display: flex; flex-direction: column; }
.factrow { display: flex; align-items: baseline; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line-2); }
.factrow:last-of-type { border-bottom: 0; }
.factrow .fv { font-family: var(--mono); font-size: 26px; font-weight: 700; line-height: 1; min-width: 34px; }
.factrow .fl { font-size: 12.5px; color: var(--ink-2); line-height: 1.35; }
.factrow .fl em { display: block; font-style: normal; color: var(--ink-3); font-size: 11.5px; }
.fv.bad { color: var(--alert); }
.fv.warn { color: var(--warn); }
.facts .factsempty { color: var(--ink-3); font-size: 12.5px; padding: 14px 0; }
.golink { margin-top: auto; padding-top: 12px; font-size: 12px; font-weight: 600; color: var(--brand); }
.golink:hover { text-decoration: underline; }

.blank { display: flex; flex-direction: column; }
.blank .big { font-size: 46px; line-height: 1; font-weight: 700; margin: 8px 0 2px; }
.blank .big small { font-size: 17px; color: var(--ink-3); font-weight: 600; }
.blank .d { font-size: 12.5px; color: var(--ink-2); }

/* ---------- Paneles: atención + ranking (spec §5.6/5.7) ---------- */
.cols { display: grid; grid-template-columns: 1.25fr 1fr; gap: 22px; }
.alist { display: flex; flex-direction: column; }
.arow { display: grid; grid-template-columns: 4px 1fr auto; gap: 12px; align-items: center; padding: 12px 20px; border-bottom: 1px solid var(--line-2); transition: background .14s; }
.arow:hover { background: var(--card-2); }
.arow .flag { width: 4px; height: 34px; border-radius: 3px; background: var(--neutral); }
.arow .flag.warn { background: var(--warn); }
.arow .flag.bad { background: var(--alert); }
.arow .t { font-weight: 600; font-size: 13px; }
.arow .m { color: var(--ink-3); font-size: 12px; }
.arow .m .path { font-family: var(--mono); }

.rank { padding: 8px 20px 16px; }
.rrow { display: grid; grid-template-columns: 130px 1fr auto; gap: 12px; align-items: center; padding: 9px 0; }
.rrow .rn { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rrow .rn em { display: block; font-style: normal; color: var(--ink-3); font-size: 11px; }
.track { height: 8px; background: var(--line-2); border-radius: 999px; overflow: hidden; }
.fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, color-mix(in srgb, var(--brand) 55%, var(--ink)), var(--brand)); }
.rrow .rv { font-family: var(--mono); font-size: 13px; }

/* Selectores del ranking en la cabecera del panel: métrica (relés/tests) + periodo (día…año).
   Van agrupados y separados por una regla fina para que se lean como DOS controles y no como una
   tira de seis chips donde "Tests" y "Día" parecerían la misma clase de opción. */
.rankfilters { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rankfiltersep { width: 1px; height: 16px; background: var(--line); }

/* Qué mide la métrica elegida. Relés y tests no son dos escalas del mismo dato (desgaste frente a
   trabajo), así que el panel dice cuál está mirando en vez de dejar el número desnudo. */
.ranksub { padding: 10px 20px 0; font-size: 11.5px; color: var(--ink-3); }

.rankfilter { display: inline-flex; gap: 2px; }
.rankfilter a { font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); padding: 3px 8px; border-radius: 7px; }
.rankfilter a:hover { color: var(--ink); background: var(--line-2); }
.rankfilter a.on { color: var(--brand-ink); background: color-mix(in srgb, var(--brand) 15%, transparent); font-weight: 600; }

/* ---------- Ficha de máquina (P3) ---------- */

.back { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-3); font-size: 12.5px; margin-bottom: 6px; }
.back:hover { color: var(--ink); }

.dhead { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.dhead .dtitle h1 { margin: 0; font-size: 24px; }
.dhead .dtitle .path { font-family: var(--mono); color: var(--ink-2); font-size: 13px; margin-top: 3px; }
.dhead .dbadges { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-left: auto; }

.sections { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
.section.wide { grid-column: 1 / -1; }

.dl { display: grid; grid-template-columns: max-content 1fr; gap: 8px 18px; padding: 16px 20px; }
.dl dt { color: var(--ink-3); font-size: 14px; }
.dl dd { margin: 0; font-size: 13px; }
.dl dd.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

.relays { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; padding: 16px 20px; }
.relay { border: 1px solid var(--line-2); border-radius: 10px; padding: 8px 10px; text-align: center; }
.relay .ri { font-size: 10.5px; color: var(--ink-3); letter-spacing: .08em; text-transform: uppercase; }
.relay .rv { font-family: var(--mono); font-size: 17px; font-weight: 600; margin-top: 2px; }
.relay.zero { opacity: .5; }

/* Desgaste de motores. Las columnas numéricas se alinean a la derecha —el resto de tablas del
   panel no lo hace— porque aquí la lectura es comparar cuatro filas entre sí: con las unidades
   alineadas la diferencia entre dos motores se ve sin leer los números. */
.motors td.v, .motors th.v { text-align: right; white-space: nowrap; }
.motors tbody td.v { font-variant-numeric: tabular-nums; }
/* El encuadre lo pone el contenido, no la tarjeta: .card no lleva padding y en los demás paneles lo
   aporta .relays o .tbl. Un párrafo suelto se queda pegado al borde si no lo trae él. */
.motorsempty { margin: 0; padding: 16px 20px; color: var(--ink-3); font-size: 13px; }
.motorgaps { display: flex; flex-wrap: wrap; gap: 20px; padding: 0 20px 16px; }
.motorgap { font-size: 12px; color: var(--ink-3); display: inline-flex; align-items: center; gap: 6px; }
.motorgap b { font-weight: 600; color: var(--ink); }
.motorgap b.off { color: var(--warn); }

@media (max-width: 1080px) {
    .sections { grid-template-columns: 1fr; }
    .relays { grid-template-columns: repeat(4, 1fr); }

    /* El hero pasa a una columna: el separador vertical entre celdas deja de tener sentido y se
       convierte en horizontal. Antes el hero no colapsaba (se salvaba por ser una sola fila de tres);
       con dos filas, seis celdas a 1080px no caben legibles. */
    .hero, .hero.tier2 { grid-template-columns: 1fr; }
    .hero > div + div { border-left: 0; border-top: 1px solid var(--line); }
}

/* ---------- Formularios de administración (req. 7) ---------- */

.subnav { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }


.field label.check {
    text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--ink);
    font-weight: 500; display: flex; align-items: center; gap: 8px; cursor: pointer;
}
.field label.check input[type=checkbox] {
    min-width: 0; width: 16px; height: 16px; margin: 0; padding: 0; accent-color: var(--brand);
}
.field .hint { font-size: 12px; color: var(--ink-3); font-weight: 400; text-transform: none; letter-spacing: 0; }
.valsum { color: var(--alert); font-size: 12.5px; }
.valsum ul { margin: 0; padding-left: 18px; }
.valsum:empty { display: none; }
.req { color: var(--alert); }

/* ---------- Credenciales / provisioning (API keys) ---------- */

.keybox {
    border: 1px solid var(--brand); border-radius: 12px; padding: 16px 20px; margin: 0 20px 16px;
    background: color-mix(in srgb, var(--brand) 7%, transparent);
}
.keybox-h { font-weight: 600; color: var(--brand); margin-bottom: 12px; }
.keybox .hint { display: block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin-bottom: 5px; }
.keyrow { display: flex; gap: 8px; align-items: center; margin-top: 4px; }
.keyrow input, .repjson {
    padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px;
    background: var(--card-2); color: var(--ink); font-size: 12.5px;
    font-family: var(--mono); font-variant-numeric: tabular-nums;
}
.keyrow input { flex: 1; min-width: 0; }
.repjson { width: 100%; resize: vertical; margin: 4px 0; line-height: 1.5; }

/* ---------- Mapa de la flota (req. 4) ---------- */

.fleetmap {
    height: 560px; width: 100%; border-radius: var(--r);
    border: 1px solid var(--line); overflow: hidden; background: var(--line-2);
    z-index: 0;
}
.maplegend {
    display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center;
    margin: 4px 0 14px; padding: 0 20px; font-size: 12.5px; color: var(--ink-2);
}
.mlg { display: inline-flex; align-items: center; gap: 7px; }
.mdot { width: 11px; height: 11px; border-radius: 50%; box-shadow: 0 0 0 2px var(--card); }
.mdot.alert { background: var(--alert); }
.mdot.warn { background: var(--warn); }
.mdot.ok { background: var(--verify); }
.mdot.neutral { background: var(--neutral); }
.mapunloc {
    margin-top: 14px; padding: 12px 14px; border-radius: 10px;
    background: var(--warn-bg); border: 1px solid var(--line);
    font-size: 12.5px; color: var(--ink-2); line-height: 1.6;
}
.mapunloc b { color: var(--ink); }

/* Popup de estación (dentro del contenedor Leaflet) */
.mpop { min-width: 200px; font-family: var(--sans); }
/* Colores FIJOS (no tokens): el popup se ve igual en claro y oscuro, siempre estilo claro. */
.mpop-h { font-size: 14px; font-weight: 700; color: #181B18; }
.mpop-sub { font-size: 12px; color: #2B2E2A; margin-bottom: 8px; }
.mpop-row { display: flex; justify-content: space-between; gap: 14px; font-size: 12.5px; padding: 2px 0; }
.mpop-row span { color: #2B2E2A; }
.mpop-row b { color: #181B18; font-variant-numeric: tabular-nums; }
.mpop-row.alert b { color: #AE3A2C; }
.mpop-link { display: inline-block; margin-top: 8px; font-size: 12.5px; font-weight: 600; color: #205FED; text-decoration: none; }
.mpop-link:hover { text-decoration: underline; }
.leaflet-popup-content { margin: 12px 14px; }
/* Fondo claro fijo en ambos temas (el popup no sigue el tema oscuro, a propósito). */
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
    background: #FFFFFF; color: #181B18;
    box-shadow: 0 12px 28px -14px rgba(0,0,0,.45);
}
.leaflet-popup-content-wrapper { border: 1px solid #CFD4CA; }
.leaflet-container a.leaflet-popup-close-button { color: #888E86; }

/* ---------- Avisos (campana + bandeja) ---------- */

.bell { position: relative; text-decoration: none; }
.bell.has { color: var(--alert); }
/* La campana es el control de notificaciones: un pelín mayor que las otras utilidades (20px) para dar presencia. */
.bell svg { width: 22px; height: 22px; }
.bell-count {
    position: absolute; top: -3px; right: -3px; min-width: 16px; height: 16px;
    padding: 0 4px; border-radius: 999px; background: var(--alert); color: #fff;
    font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
    letter-spacing: -.01em; box-shadow: 0 0 0 2px var(--card-2);
}

.rowactions { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.btn.sm { padding: 5px 10px; font-size: 12px; border-radius: 8px; }

/* Acciones de fila en tablas (avisos: Ver/Visto/Posponer · admin: Editar): azul Moviltest tenue con
   icono, que se rellena al pasar el ratón. */
.act { gap: 6px; transition: background .14s, border-color .14s, color .14s; }
.act svg { width: 14px; height: 14px; }
.btn.act-go {
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    border-color: color-mix(in srgb, var(--brand) 30%, transparent);
    color: var(--brand);
}
.btn.act-go:hover { background: var(--brand); border-color: var(--brand); color: #fff; }

.tag {
    display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
    background: color-mix(in srgb, var(--neutral) 20%, transparent); color: var(--ink-3);
    font-size: 10.5px; font-weight: 600; vertical-align: middle;
}

.tbl tr.muted td { opacity: .62; }
.tbl tr.muted a { color: inherit; }

/* ---------- Accesibilidad / motion ---------- */

:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

@media (max-width: 720px) {
    .app { grid-template-columns: 1fr; }
    .rail {
        position: fixed; bottom: 0; top: auto; left: 0; right: 0;
        height: auto; width: 100%; flex-direction: row; justify-content: space-around;
        border-right: 0; border-top: 1px solid var(--line); z-index: 30; padding: 8px 0;
    }
    .rail .brand, .rail .spacer, .nav .tip { display: none; }
    .nav { flex-direction: row; }
    .wrap { padding: 16px; padding-bottom: 80px; }
    .search { display: none; }
}
