/* ═══════════════════════════════════════════════════════════════════
   NIVARIA MASTER — Sistema de diseño «Volcán y océano»
   Oscuro: basalto volcánico #16151a · teal atlántico #14b8a6
   Claro:  arena cálida #f8f4ec · verde atlántico #0e7d72 · barra basalto-verde
   Marca NIVAR.IA (blanco/azul/amarillo) intocable en ambos temas.
   ═══════════════════════════════════════════════════════════════════ */

/* ── TOKENS ──────────────────────────────────────────────────────── */
:root {
  --bg:          #16151a;
  --bg2:         #1e1d24;
  --bg3:         #26252d;
  --bg4:         #2e2c36;
  --sidebar:     #100f13;
  --border:      #34313c;
  --border2:     #453f4e;
  --accent:      #0f9e8e;
  --accent2:     #14b8a6;
  --accent3:     #2dd4bf;
  /* Acento para TEXTO sobre fondos (sustituye al azul var(--accent-text) cableado). */
  --accent-text: #2dd4bf;
  --accent-glow: rgba(20,184,166,0.22);
  --yellow:      #FFC107;
  --yellow2:     #FFD54F;
  /* ── NIVAR.IA brand colors ──────────────────────────────── */
  --nivar-ni:    #FFFFFF;
  --nivar-var:   #0768A9;
  --nivar-ia:    #FFCC00;
  --green:       #22c55e;
  --green-bg:    rgba(34,197,94,0.08);
  --green-border:rgba(34,197,94,0.2);
  --orange:      #f59e0b;
  --red:         #ef4444;
  --purple:      #a78bfa;
  /* Alias de estado (auditoría UX 2026-07-22): 34 sitios en JS los usaban como
     var(--danger,…)/var(--warning,…)/var(--ok,…) pero NO estaban definidos → caían
     siempre al hex fijo, sin adaptarse al tema. Referencian a las vars base, así
     que cambian solos entre claro/oscuro. */
  --danger:      var(--red);
  --warning:     var(--orange);
  --ok:          var(--green);
  --text:        #eae6de;
  --text2:       #9d97a3;
  /* --text3 subido de #6e6876 (~3.4:1) para cumplir el contraste AA en textos
     tenues (pistas, contadores). Auditoría UX 2026-07-22. */
  --text3:       #8a8494;
  --text4:       #4b4653;
  --radius:      10px;
  --radius-lg:   14px;
  --radius-xl:   18px;
  --sidebar-w:   228px;
  --sidebar-collapsed: 56px;
  --header-h:    56px;
  --tabs-h:      42px;
  --font:        'Inter', system-ui, -apple-system, sans-serif;
  /* Titulares con serifa (rasgo del estilo Volcán y océano). */
  --font-display: Georgia, 'Times New Roman', serif;
  --mono:        'JetBrains Mono', 'Fira Mono', 'Consolas', monospace;
  --shadow:      0 4px 24px rgba(0,0,0,0.4);
  --shadow-sm:   0 2px 8px rgba(0,0,0,0.3);
  --transition:  0.15s ease;
  --ui-scale:    1;
  --hover-overlay: rgba(255,255,255,0.02);
}

/* ── TEMA CLARO ──────────────────────────────────────────────────────
   Se activa poniendo data-theme="light" en <html> (gestionado por
   theme.js). Pensado sobre todo para usar la tablet al aire libre,
   donde el tema oscuro original es difícil de leer con luz directa.
   Reutiliza los mismos nombres de variable que el tema oscuro, así
   que cualquier regla CSS que ya use var(--bg), var(--text), etc.
   cambia de color automáticamente sin tocar nada más. Los colores de
   estado (verde/rojo/amarillo/naranja) y los de marca NIVAR.IA se
   mantienen iguales en ambos temas para no perder reconocibilidad. */
html[data-theme="light"] {
  --bg:          #f8f4ec;
  --bg2:         #fffdf7;
  --bg3:         #fbf7ee;
  --bg4:         #efe9dd;
  /* La barra lateral se queda en basalto-verde también en claro: es el rasgo
     de identidad del estilo (y el logo NIVAR.IA conserva su blanco de marca). */
  --sidebar:     #1f3a36;
  --border:      #e6ddcc;
  --border2:     #d2c6ae;
  --accent:      #0e7d72;
  --accent2:     #0f9184;
  --accent3:     #0a625a;
  --accent-text: #0a625a;
  --accent-glow: rgba(14,125,114,0.13);
  --yellow:      #9a6414;
  --yellow2:     #7a4f10;
  /* MARCA intocable también en claro: todos los contextos donde aparece
     NIVAR.IA (barra lateral, barra superior, insignia del asistente y pastilla
     del login) tienen fondo basalto-verde, así que el blanco/azul/amarillo
     de marca se mantiene tal cual — nunca se recolorea. */
  --nivar-ni:    #FFFFFF;
  --nivar-var:   #0768A9;
  --nivar-ia:    #FFCC00;
  --green:       #16a34a;
  --green-bg:    rgba(22,163,74,0.08);
  --green-border:rgba(22,163,74,0.25);
  --orange:      #c2660a;
  --red:         #dc2626;
  --purple:      #7c3aed;
  --text:        #2b2620;
  --text2:       #6f6659;
  /* --text3 oscurecido de #988d7c (~3.4:1) para contraste AA en tema claro. */
  --text3:       #7c7264;
  --text4:       #bfb49e;
  --shadow:      0 4px 24px rgba(60,50,30,0.10);
  --shadow-sm:   0 2px 8px rgba(60,50,30,0.08);
  --hover-overlay: rgba(60,50,30,0.04);
}
/* Interior de la barra lateral Y la barra superior en tema claro: fondo
   basalto-verde → sus textos, hovers y bordes usan una escala clara PROPIA
   (las variables se re-declaran SOLO dentro de esas barras; el resto de la
   pantalla no cambia). Regla de MARCA del dueño: NIVAR.IA vive siempre sobre
   fondo oscuro y sus colores blanco/azul/amarillo NUNCA se modifican. */
html[data-theme="light"] .sidebar,
html[data-theme="light"] .topbar {
  --bg2:    #27463f;
  --bg3:    rgba(255,255,255,0.09);
  --bg4:    rgba(255,255,255,0.14);
  --border: #2e544e;
  --border2:#3c6b63;
  --text:   #eef7f4;
  --text2:  #c3d9d4;
  --text3:  #9dbeb7;
  --text4:  #6f948c;
  --accent-text: #5eead4;
  --accent-glow: rgba(94,234,212,0.14);
  --hover-overlay: rgba(255,255,255,0.06);
}
html[data-theme="light"] .topbar {
  background: #1f3a36;
}
/* En tema claro, .login-screen usa un degradado pensado para fondo
   oscuro; lo suavizamos para que no quede chillón sobre blanco. */
html[data-theme="light"] .login-screen {
  background:
    linear-gradient(135deg, rgba(14,125,114,0.10), transparent 34%),
    radial-gradient(circle at 75% 20%, rgba(183,134,11,0.08), transparent 26%),
    var(--bg);
}

/* ── RESET ───────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { height: 100%; }
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  height: 100%;
  overflow: hidden;
  font-size: calc(13px * var(--ui-scale));
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font-family: var(--font); }
input, select, textarea { font-family: var(--font); }

.login-screen {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    linear-gradient(135deg, rgba(20,184,166,0.20), transparent 34%),
    radial-gradient(circle at 75% 20%, rgba(255,193,7,0.14), transparent 26%),
    var(--bg);
}
.login-panel {
  width: min(380px, calc(100vw - 32px));
  padding: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg2);
  box-shadow: var(--shadow);
}
.login-brand {
  font-weight: 900;
  font-size: 28px;
  font-family: var(--font-display);
  letter-spacing: 0;
  margin-bottom: 2px;
}
/* .login-brand .ni/var/ia colours are defined in the unified brand rule below */
.login-subtitle {
  color: var(--text2);
  font-size: 12px;
  margin-bottom: 22px;
}
.login-error {
  min-height: 18px;
  margin-top: 10px;
  color: var(--red);
  font-size: 11px;
}
.login-hint {
  margin-top: 10px;
  color: var(--text3);
  font-size: 10px;
}

/* ── SCROLLBAR ───────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; }
::-webkit-scrollbar-thumb:hover { background: var(--text4); }

/* ══════════════════════════════════════════════════════════════════
   LAYOUT PRINCIPAL
   ══════════════════════════════════════════════════════════════════ */
.app {
  display: flex;
  /* 100dvh = altura REAL visible en móvil (100vh incluye la zona de la barra
     del navegador: la app quedaba más alta que la pantalla y, con el
     overflow:hidden, la parte de abajo era inaccesible — sin scroll posible.
     En apaisado el efecto era brutal). El 100vh queda de fallback. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* ── SIDEBAR ─────────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  height: 100vh;
  height: 100dvh;
  transition: width var(--transition);
  overflow: hidden;
  z-index: 100;
}
.sidebar.collapsed { width: var(--sidebar-collapsed); }
.sidebar.collapsed .nav-label,
.sidebar.collapsed .nav-badge,
.sidebar.collapsed .sidebar-logo-text,
.sidebar.collapsed .nav-section-label,
.sidebar.collapsed .user-info,
.sidebar.collapsed .user-meta { display: none; }
.sidebar.collapsed .nav-item { justify-content: center; padding: 10px; }
.sidebar.collapsed .nav-item .nav-icon { margin: 0; }

/* Logo */
.sidebar-logo {
  padding: 14px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  min-height: 60px;
}
.sidebar-logo img {
  width: 36px; height: 36px;
  border-radius: 50%;
  flex-shrink: 0;
  object-fit: cover;
}
.sidebar-logo-text { overflow: hidden; white-space: nowrap; }
.logo-brand {
  font-size: 16px; font-weight: 800;
  font-family: var(--font-display);
  letter-spacing: 0;
  line-height: 1.1;
}
.logo-brand .ni  { color: var(--nivar-ni); }
.logo-brand .var { color: var(--nivar-var); }
.logo-brand .ia  { color: var(--nivar-ia); }
.logo-brand span { color: var(--yellow); }
.logo-suite {
  font-size: 10px; font-weight: 500;
  color: var(--text3);
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

/* Toggle sidebar */
.sidebar-toggle {
  position: absolute;
  top: 16px; right: -12px;
  width: 24px; height: 24px;
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  font-size: 10px;
  color: var(--text3);
  z-index: 101;
  transition: all var(--transition);
}
.sidebar-toggle:hover { background: var(--border); color: var(--text); }

/* Nav */
.sidebar-nav {
  flex: 1;
  padding: 8px 6px;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.nav-section-label {
  font-size: 10px; font-weight: 600;
  color: var(--text4);
  letter-spacing: 0.8px;
  text-transform: uppercase;
  padding: 10px 10px 3px;
  white-space: nowrap;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--text3);
  font-weight: 500;
  font-size: 13px;
  transition: all var(--transition);
  user-select: none;
  white-space: nowrap;
  position: relative;
}
.nav-item:hover { background: var(--bg3); color: var(--text2); }
.nav-item.active {
  background: var(--accent-glow);
  color: var(--accent-text);
  border-left: 2px solid var(--accent-text);
  padding-left: 8px;
}
.nav-icon {
  font-size: 15px;
  width: 18px; text-align: center;
  flex-shrink: 0;
}
.nav-label { flex: 1; }

/* Tooltip con el nombre del apartado cuando la barra lateral está comprimida.
   Posicionado con position:fixed vía JS (initSidebarTooltips en core.js) para
   que no lo recorte el scroll de la barra. */
.nav-tooltip {
  position: fixed; transform: translateY(-50%);
  background: var(--bg2); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 10px; font-size: 12px; font-weight: 600; white-space: nowrap;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .28);
  z-index: 3000; opacity: 0; pointer-events: none;
  transition: opacity .08s ease;
}
.nav-tooltip.show { opacity: 1; }

/* Chips de EPIs básicos predefinidos (ficha PRL del técnico). */
.epi-chip {
  background: var(--bg3); border: 1px solid var(--border); color: var(--text2);
  border-radius: 12px; padding: 3px 10px; font-size: 11px; cursor: pointer;
  transition: background .1s, color .1s, border-color .1s;
}
.epi-chip:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.nav-badge {
  background: var(--accent);
  color: #fff;
  font-size: 10px; font-weight: 700;
  padding: 1px 5px;
  border-radius: 10px;
  min-width: 18px; text-align: center;
}
.nav-badge.orange { background: var(--orange); }
.nav-badge.red { background: var(--red); }

/* User footer */
.sidebar-user {
  padding: 10px 12px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 9px;
  flex-shrink: 0;
}
.user-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent3));
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 12px; color: #fff;
  flex-shrink: 0;
  letter-spacing: -0.5px;
}
.user-info { flex: 1; overflow: hidden; }
.user-name { font-size: 12px; font-weight: 600; white-space: nowrap; }
.user-role { font-size: 10px; color: var(--text3); white-space: nowrap; }
.user-meta { display: flex; gap: 6px; }
.user-meta-btn {
  background: none; border: none;
  color: var(--text3); font-size: 13px;
  cursor: pointer; padding: 2px;
  border-radius: 4px;
  transition: color var(--transition);
}
.user-meta-btn:hover { color: var(--text); }

/* ── MAIN ────────────────────────────────────────────────────────── */
.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
  min-height: 0;
}

/* ── TOPBAR ──────────────────────────────────────────────────────── */
.topbar {
  height: var(--header-h);
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 18px;
  gap: 10px;
  flex-shrink: 0;
  overflow: hidden;
}
.topbar-empty {
  display: flex; align-items: center;
  gap: 12px; flex: 1;
}
.topbar-nivar {
  font-size: 18px; font-weight: 800;
  letter-spacing: -0.5px;
}
.topbar-nivar .ni  { color: var(--nivar-ni); }
.topbar-nivar .var { color: var(--nivar-var); }
.topbar-nivar .ia  { color: var(--nivar-ia); }
.topbar-tagline { font-size: 12px; color: var(--text3); }

.exp-ref {
  font-size: 14px; font-weight: 700;
  color: var(--text);
  font-family: var(--mono);
  letter-spacing: -0.3px;
  white-space: nowrap;
}
.topbar-sep { color: var(--text4); font-size: 14px; }
.topbar-chips { display: flex; gap: 6px; align-items: center; }
.chip {
  padding: 3px 9px;
  border-radius: 20px;
  font-size: 11px; font-weight: 600;
  background: var(--bg3);
  color: var(--text2);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.chip.blue  { background: rgba(15,158,142,0.18); color: var(--accent-text); border-color: rgba(15,158,142,0.3); }
.chip.green { background: rgba(34,197,94,0.12);  color: var(--green); border-color: rgba(34,197,94,0.25); }
.chip.orange{ background: rgba(245,158,11,0.12); color: var(--orange); border-color: rgba(245,158,11,0.25); }
.chip.red   { background: rgba(239,68,68,0.12);  color: var(--red); border-color: rgba(239,68,68,0.25); }

/* Progress en topbar */
.topbar-progress {
  display: flex; align-items: center; gap: 7px;
  margin-left: 8px;
}
.progress-wrap {
  width: 100px; height: 5px;
  background: var(--bg3); border-radius: 3px; overflow: hidden;
}
.progress-fill {
  height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--accent), #42a5f5);
  transition: width 0.4s ease;
}
.progress-pct { font-size: 12px; font-weight: 700; color: var(--accent-text); }

/* Semáforo */
.semaforo {
  display: flex; gap: 10px;
  align-items: center;
  padding: 0 10px;
}
.sem-item {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; color: var(--text3);
}
.sem-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.sem-dot.green  { background: var(--green);  box-shadow: 0 0 5px var(--green); }
.sem-dot.orange { background: var(--orange); box-shadow: 0 0 5px var(--orange); }
.sem-dot.red    { background: var(--red);    box-shadow: 0 0 5px var(--red); }

/* Calidad */
.topbar-quality {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; color: var(--text3);
}
.quality-wrap { width: 60px; height: 4px; background: var(--bg3); border-radius: 2px; }
.quality-fill { height: 100%; border-radius: 2px; background: var(--accent); }
.quality-pct  { font-size: 11px; font-weight: 700; }

.topbar-actions { margin-left: auto; display: flex; gap: 7px; align-items: center; }

/* ── BOTONES ─────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 7px 14px;
  border-radius: var(--radius);
  font-size: 12px; font-weight: 600;
  cursor: pointer; border: none;
  transition: all var(--transition);
  white-space: nowrap;
  user-select: none;
}
.btn:active { transform: scale(0.97); }
.btn-primary  { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent2); }
.btn-ghost    { background: var(--bg3); color: var(--text2); border: 1px solid var(--border); }
.btn-ghost:hover { background: var(--bg4); color: var(--text); }
.btn-danger   { background: rgba(239,68,68,0.12); color: var(--red); border: 1px solid rgba(239,68,68,0.25); }
.btn-danger:hover { background: rgba(239,68,68,0.2); }
.btn-success  { background: rgba(34,197,94,0.12); color: var(--green); border: 1px solid rgba(34,197,94,0.25); }
.btn-success:hover { background: rgba(34,197,94,0.2); }
/* Acción SECUNDARIA (p.ej. «Calcular»): neutral sólido, más presente que
   .btn-ghost pero sin ser el primario. Se usaba en ~15 sitios sin existir en el
   CSS → salían planos. Auditoría UX 2026-07-22. */
.btn-secondary { background: var(--bg4); color: var(--text); border: 1px solid var(--border2); }
.btn-secondary:hover { background: var(--border); color: var(--text); }
.btn-sm  { padding: 4px 10px; font-size: 11px; }
.btn-xs  { padding: 2px 7px; font-size: 10px; }
.btn-icon { padding: 7px; border-radius: var(--radius); }

/* ── TABS ────────────────────────────────────────────────────────── */
.tabs-bar {
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
  display: flex;
  padding: 0 18px;
  gap: 0;
  flex-shrink: 0;
  overflow-x: auto;
  overflow-y: hidden;
  min-height: var(--tabs-h);
}
.tabs-bar::-webkit-scrollbar { height: 0; }
.tab {
  padding: 0 14px;
  font-size: 12px; font-weight: 500;
  color: var(--text3);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  display: flex; align-items: center; gap: 5px;
  transition: all var(--transition);
  white-space: nowrap;
  user-select: none;
  min-height: var(--tabs-h);
}
.tab:hover { color: var(--text2); background: var(--hover-overlay); }
.tab.active { color: var(--accent-text); border-bottom-color: var(--accent-text); font-weight: 600; }
.tab-icon { font-size: 13px; }

/* ── Stepper del ciclo de vida del expediente (workflow.js) ──────── */
.wf-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 7px 18px;
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
  overflow: visible;   /* el desplegable "Método" debe poder salir de la tira */
  flex-shrink: 0;
}
/* Estado del método pintado EN las pestañas (una sola barra, sin duplicar). */
.tab-check { color: var(--green); font-weight: 700; font-size: 11px; margin-left: 1px; }
.tab.wf-next:not(.active) { color: var(--text2); border-bottom-color: rgba(245, 158, 11, .6); }
/* Guía compacta del ciclo de vida (siguiente paso + progreso + Método). */
.wf-next {
  font-size: 11px; color: var(--text2);
  padding: 4px 10px; border: 1px solid var(--border);
  border-radius: 999px; background: var(--bg3); white-space: nowrap;
}
.wf-next b { color: var(--text); }
.wf-next.nav { cursor: pointer; }
.wf-next.nav:hover { background: var(--hover-overlay); }
.wf-next.wf-done-all { color: var(--green); border: none; background: transparent; }
.wf-strip .wf-progress { margin-left: auto; }
.wf-metodo-wrap { position: relative; flex-shrink: 0; }
.wf-metodo-btn {
  font-size: 11px; color: var(--text2);
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 999px; padding: 4px 10px; cursor: pointer; white-space: nowrap;
}
.wf-metodo-btn:hover { color: var(--text); background: var(--hover-overlay); }
.wf-metodo-pop {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: 0 12px 40px rgba(0, 0, 0, .5);
  padding: 6px; min-width: 230px; max-height: 62vh; overflow-y: auto;
}
.wf-metodo-pop[hidden] { display: none; }
.wf-mrow {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 8px; border-radius: 6px;
  font-size: 12px; color: var(--text3); white-space: nowrap;
}
.wf-mrow.nav { cursor: pointer; }
.wf-mrow.nav:hover { background: var(--hover-overlay); color: var(--text2); }
.wf-mrow.done { color: var(--green); }
/* Los pasos hacen scroll horizontal propio; el progreso queda fijo a la derecha */
.wf-steps { display: flex; align-items: center; flex: 1; min-width: 0; overflow-x: auto; }
.wf-steps::-webkit-scrollbar { height: 0; }
.wf-step {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 3px 7px;
  border-radius: 6px;
  white-space: nowrap;
  color: var(--text3);
  font-size: 11px;
}
.wf-step.nav { cursor: pointer; }
.wf-step.nav:hover { background: var(--hover-overlay); color: var(--text2); }
.wf-step.done { color: var(--green); }
.wf-step.optional .wf-dot { border-style: dashed; }
.wf-opt { font-size: 9px; opacity: 0.6; margin-left: 2px; }
.wf-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg3);
  font-size: 10px;
  flex-shrink: 0;
}
.wf-step.done .wf-dot {
  background: rgba(34,197,94,0.12);
  border-color: rgba(34,197,94,0.4);
  color: var(--green);
  font-weight: 700;
}
.wf-link { width: 14px; height: 1px; background: var(--border); flex-shrink: 0; }
.wf-progress { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.wf-progress-bar {
  width: 90px; height: 5px;
  border-radius: 3px;
  background: var(--bg4);
  overflow: hidden;
}
.wf-progress-fill { height: 100%; background: var(--green); border-radius: 3px; }
.wf-progress-text { font-size: 10px; color: var(--text3); min-width: 28px; }

/* ── PÁGINA ──────────────────────────────────────────────────────── */
.page {
  flex: 1;
  overflow: hidden;
  display: none;
  min-height: 0;
  min-width: 0;
}
.page.active { display: flex; flex-direction: column; }

#page-expediente > [id^="exp-tab-"] {
  min-height: 0;
  min-width: 0;
}

/* ── CONTENT GRID (3 paneles) ────────────────────────────────────── */
.content-grid {
  flex: 1;
  display: grid;
  grid-template-columns: 280px 1fr 370px;
  overflow: hidden;
  min-height: 0;
  min-width: 0;
}
.content-grid.two-col {
  grid-template-columns: 320px 1fr;
}
.content-grid.one-col {
  grid-template-columns: 1fr;
}

.btn-volver-lista { display: none; }

/* ── PANEL ───────────────────────────────────────────────────────── */
.panel {
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  min-height: 0;
  min-width: 0;
}
.panel:last-child { border-right: none; }

.panel-header {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  background: var(--bg2);
  min-height: 44px;
}
.panel-title {
  font-size: 11px; font-weight: 700;
  color: var(--text2);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.panel-body {
  flex: 1; overflow-y: auto;
  padding: 12px;
  min-height: 0;
  min-width: 0;
}
.panel-footer {
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
  background: var(--bg2);
  position: sticky;
  bottom: 0;
  z-index: 4;
}

/* ── CARDS ───────────────────────────────────────────────────────── */
.card {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
}
.card-sm { padding: 12px; border-radius: var(--radius); }
.card-title { font-size: 12px; font-weight: 700; color: var(--text2); margin-bottom: 10px; }

/* ── STAT GRID ───────────────────────────────────────────────────── */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 10px;
}
.stat-item { }
.stat-label { font-size: 10px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.4px; }
.stat-value { font-size: 15px; font-weight: 700; font-family: var(--mono); color: var(--text); }
.stat-value.accent { color: var(--accent-text); }
.stat-value.green  { color: var(--green); }
.stat-value.yellow { color: var(--yellow); }

/* ── FORMULARIOS ─────────────────────────────────────────────────── */
.form-section { margin-bottom: 18px; }
.form-section-title {
  font-size: 10px; font-weight: 700;
  color: var(--text3);
  text-transform: uppercase; letter-spacing: 0.6px;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px; margin-bottom: 10px;
}
.form-row.single { grid-template-columns: 1fr; }
.form-row.triple { grid-template-columns: 1fr 1fr 1fr; }
/* El display:grid de arriba anularía el atributo hidden (los campos que solo
   aplican a ciertos trabajos, p.ej. "Instalación BT de origen" solo en EERR,
   se ocultan con hidden). Esta regla devuelve a hidden su significado. */
.form-row[hidden] { display: none; }

/* Croquis en modo dibujo a mano alzada: los elementos ya dibujados no
   capturan el puntero (ni clic en tramos ni arrastre de nodos), para que
   todo el gesto sea del trazo. */
#croquis-svg.croquis-drawing * { pointer-events: none; }
.form-group { display: flex; flex-direction: column; gap: 4px; }
.form-label { font-size: 11px; color: var(--text2); font-weight: 500; }
.form-label.required::after { content: ' *'; color: var(--red); }

.form-input, .form-select, .form-textarea {
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  padding: 7px 10px;
  font-size: 12px;
  font-family: var(--font);
  outline: none;
  transition: border-color var(--transition), background var(--transition);
  width: 100%;
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
  border-color: var(--accent2);
  background: rgba(15,158,142,0.05);
}
.form-input.error { border-color: var(--red); }
.form-input.success { border-color: var(--green); }
.form-textarea { resize: vertical; min-height: 80px; }
.form-hint { font-size: 10px; color: var(--text3); margin-top: 2px; }

/* Toggle tipo tramo */
.type-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.toggle-btn {
  padding: 8px 10px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg3);
  color: var(--text2);
  font-size: 12px; font-weight: 600;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 5px;
  transition: all var(--transition);
  font-family: var(--font);
}
.toggle-btn.active {
  background: rgba(15,158,142,0.2);
  border-color: var(--accent);
  color: var(--accent-text);
}

/* ── TABLAS ──────────────────────────────────────────────────────── */
.data-table {
  width: 100%; border-collapse: collapse;
  font-size: 12px;
}
.data-table th {
  padding: 8px 10px;
  text-align: left;
  font-size: 10px; font-weight: 700;
  color: var(--text3);
  text-transform: uppercase; letter-spacing: 0.5px;
  border-bottom: 1px solid var(--border);
  background: var(--bg2);
  white-space: nowrap;
}
.data-table td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text2);
  vertical-align: middle;
}
.data-table tr:hover td { background: var(--hover-overlay); }
.data-table tr.selected td { background: rgba(15,158,142,0.08); }
.data-table tr:last-child td { border-bottom: none; }
.data-table .mono { font-family: var(--mono); }
.data-table .actions { display: flex; gap: 4px; justify-content: flex-end; }

/* ── TRAMO LIST ──────────────────────────────────────────────────── */
.tramo-item {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 10px;
  border-radius: var(--radius);
  cursor: pointer;
  margin-bottom: 2px;
  border: 1px solid transparent;
  transition: all var(--transition);
}
.tramo-item:hover { background: var(--bg3); }
.tramo-item.selected {
  background: rgba(15,158,142,0.1);
  border-color: rgba(15,158,142,0.3);
}
.tramo-num {
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  color: var(--text3); width: 22px; flex-shrink: 0;
}
.tramo-check { font-size: 12px; flex-shrink: 0; }
.tramo-info { flex: 1; min-width: 0; }
.tramo-type { font-size: 12px; font-weight: 600; color: var(--text); }
.tramo-len  { font-size: 11px; color: var(--text3); font-family: var(--mono); }
.tramo-dir  { font-size: 16px; color: var(--text3); flex-shrink: 0; }
.tramo-summary-grid {
  background: var(--bg3); border-radius: var(--radius);
  padding: 10px 12px; margin-top: 8px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
}

/* ── CROQUIS ─────────────────────────────────────────────────────── */
.croquis-wrap {
  position: relative; background: var(--bg);
  flex: 1; overflow: hidden;
  display: flex; flex-direction: column;
}
.croquis-toolbar {
  position: absolute; top: 10px; right: 10px;
  display: flex; gap: 6px; z-index: 10;
  align-items: center;
}
.view-toggle {
  display: flex;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.view-btn {
  padding: 5px 11px; font-size: 11px; font-weight: 600;
  color: var(--text3); cursor: pointer;
  transition: all var(--transition); user-select: none;
}
.view-btn.active { background: var(--accent); color: #fff; }
.croquis-export { position: relative; }
.croquis-export-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 20;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 4px;
  display: flex; flex-direction: column; gap: 2px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.28);
}
.croquis-export-menu .btn { justify-content: flex-start; white-space: nowrap; }
.croquis-canvas {
  flex: 1; width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
}
.croquis-legend {
  position: absolute; bottom: 12px; right: 12px;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 8px 12px;
  display: flex; flex-direction: column; gap: 4px;
}
.legend-title {
  font-size: 9px; font-weight: 700; color: var(--text3);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 2px;
}
.legend-item { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text2); }
.legend-line { width: 18px; height: 2px; border-radius: 1px; flex-shrink: 0; }
.croquis-3d-preview {
  position: absolute; bottom: 12px; left: 12px;
  width: 160px; height: 120px;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.preview-label {
  position: absolute; top: 5px; left: 8px;
  font-size: 9px; font-weight: 700;
  color: var(--text3); text-transform: uppercase; letter-spacing: 0.4px;
}

/* ── STATUS BAR ──────────────────────────────────────────────────── */
.status-bar {
  padding: 8px 14px;
  border-top: 1px solid var(--green-border);
  background: var(--green-bg);
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.status-bar.warning {
  border-top-color: rgba(245,158,11,0.25);
  background: rgba(245,158,11,0.06);
}
.status-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.status-dot.green  { background: var(--green); }
.status-dot.orange { background: var(--orange); }
.status-text { font-size: 11px; color: var(--green); font-weight: 500; flex: 1; }
.status-text.orange { color: var(--orange); }

/* ── NIVAR.IA BADGE ──────────────────────────────────────────────── */
/* Helper reutilizable para renderizar NIVAR.IA con colores de marca */
.nivar-brand { font-weight: 800; letter-spacing: -0.5px; }
.nivar-brand .ni,
.logo-brand .ni,
.topbar-nivar .ni,
.nivar-badge-text .ni,
.login-brand .ni { color: #FFFFFF !important; }
.nivar-brand .var,
.logo-brand .var,
.topbar-nivar .var,
.nivar-badge-text .var,
.login-brand .var { color: #0768A9 !important; }
.nivar-brand .ia,
.logo-brand .ia,
.topbar-nivar .ia,
.nivar-badge-text .ia,
.login-brand .ia { color: #FFCC00 !important; }
/* Tema claro: las partes "NI" de NIVAR.IA se dibujan en blanco (pensado para
   fondo oscuro) y sobre el fondo blanco del tema claro serían invisibles.
   Las forzamos a un gris medio para que tengan contraste. Solo afecta al tema
   claro; el modo oscuro mantiene el blanco de marca. */
/* Regla de MARCA (dueño): los colores de NIVAR.IA no se modifican NUNCA.
   En tema claro ya no hace falta recolorear el "NI": la barra superior y la
   lateral son basalto-verde, y el login lleva la marca sobre pastilla oscura. */
/* Cualquier NIVAR.IA suelto en zonas de contenido claras (banner del
   asistente del panel, pantalla del asistente…) va sobre la misma pastilla
   basalto: el blanco de marca nunca se queda invisible ni se recolorea. */
html[data-theme="light"] .nivar-brand {
  background: #1f3a36;
  display: inline-block;
  padding: 1px 8px;
  border-radius: 8px;
  line-height: 1.5;
}
/* El del login (lleva también .nivar-brand) va después para que su pastilla
   grande mande sobre la genérica. */
html[data-theme="light"] .login-brand {
  background: #1f3a36;
  display: inline-block;
  padding: 4px 16px;
  border-radius: var(--radius-lg);
  line-height: 1.3;
}
.nivar-badge {
  /* En la barra superior (junto a la versión), no flotante: así no tapa botones. */
  flex-shrink: 0; align-self: center;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: 24px; padding: 6px 14px;
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; white-space: nowrap;
  cursor: pointer;
  transition: all var(--transition);
}
.nivar-badge:hover { border-color: var(--accent); }
.nivar-pulse {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--green); flex-shrink: 0;
  animation: pulse 2s infinite;
}
@keyframes pulse { 0%,100%{opacity:1;} 50%{opacity:0.35;} }
.nivar-badge-text { color: var(--text2); }
.nivar-badge-text .ni  { color: var(--nivar-ni); }
.nivar-badge-text .var { color: var(--nivar-var); }
.nivar-badge-text .ia  { color: var(--nivar-ia); }

/* ── TOAST ───────────────────────────────────────────────────────── */
.toast-container {
  position: fixed; top: 16px; right: 16px;
  z-index: 1000; display: flex;
  flex-direction: column; gap: 8px;
}
.toast {
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 12px 16px;
  display: flex; align-items: center; gap: 10px;
  box-shadow: var(--shadow);
  font-size: 13px; min-width: 280px;
  animation: slideIn 0.2s ease;
}
@keyframes slideIn { from{transform:translateX(100%);opacity:0;} to{transform:translateX(0);opacity:1;} }
.toast.success { border-left: 3px solid var(--green); }
.toast.error   { border-left: 3px solid var(--red); }
.toast.info    { border-left: 3px solid var(--accent); }
.toast-icon { font-size: 16px; flex-shrink: 0; }
.toast-close { margin-left: auto; cursor: pointer; color: var(--text3); font-size: 16px; }

/* ── MODAL ───────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 500; display: none;
  align-items: center; justify-content: center;
  backdrop-filter: blur(3px);
}
.modal-overlay.open { display: flex; }
.modal {
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 24px; min-width: 400px; max-width: 90vw;
  max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px); overflow-y: auto;
  box-shadow: var(--shadow);
  animation: fadeUp 0.2s ease;
  scrollbar-gutter: stable;
}
@keyframes fadeUp { from{transform:translateY(16px);opacity:0;} to{transform:translateY(0);opacity:1;} }
.modal-header {
  display: flex; align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}
.modal-title { font-size: 16px; font-weight: 700; font-family: var(--font-display); letter-spacing: 0.01em; }
.modal-close { cursor: pointer; color: var(--text3); font-size: 20px; background:none; border:none; }
.modal-footer {
  display: flex; justify-content: flex-end; gap: 8px;
  margin-top: 20px; padding-top: 16px;
  border-top: 1px solid var(--border);
  position: sticky; bottom: -24px;
  background: linear-gradient(180deg, rgba(24,28,39,0.92), var(--bg2) 30%);
  padding-bottom: 4px;
  z-index: 5;
}

/* ── EMPTY STATE ─────────────────────────────────────────────────── */
.empty-state {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  height: 100%; gap: 12px;
  color: var(--text3);
}
.empty-icon { font-size: 40px; opacity: 0.4; }
.empty-title { font-size: 15px; font-weight: 600; color: var(--text2); }
.empty-sub   { font-size: 12px; text-align: center; max-width: 260px; }

/* ── DASHBOARD ───────────────────────────────────────────────────── */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px; padding: 16px;
}
.kpi-card {
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 16px;
}
.kpi-label { font-size: 11px; color: var(--text3); margin-bottom: 4px; }
.kpi-value { font-size: 28px; font-weight: 800; font-family: var(--mono); line-height: 1; }
.kpi-value.blue   { color: var(--accent-text); }
.kpi-value.green  { color: var(--green); }
.kpi-value.orange { color: var(--orange); }
.kpi-value.red    { color: var(--red); }
.kpi-link { font-size: 11px; color: var(--accent3); margin-top: 4px; cursor: pointer; }
.kpi-link:hover { text-decoration: underline; }

/* ── SEARCH ──────────────────────────────────────────────────────── */
.search-wrap {
  position: relative;
  display: flex; align-items: center;
}
.search-icon {
  position: absolute; left: 10px;
  color: var(--text3); font-size: 14px;
  pointer-events: none;
}
.search-input {
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius); color: var(--text);
  padding: 7px 10px 7px 32px;
  font-size: 12px; outline: none;
  width: 100%;
  transition: border-color var(--transition);
}
.search-input:focus { border-color: var(--accent2); }
.search-input::placeholder { color: var(--text3); }

/* ── ÁNGULO VISUAL ───────────────────────────────────────────────── */
.angulo-box {
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px;
  display: flex; align-items: center; gap: 12px;
}
.angulo-deg { font-size: 24px; font-weight: 800; color: var(--yellow); font-family: var(--mono); }
.angulo-hint { font-size: 11px; color: var(--text3); line-height: 1.5; }

/* ── PANEL LATERAL DEL ASISTENTE NIVAR.IA (dentro del expediente) ── */
.nivar-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 450;
  width: min(400px, 96vw);
  background: var(--bg2); border-left: 1px solid var(--border);
  display: flex; flex-direction: column;
  box-shadow: -6px 0 24px rgba(0,0,0,0.35);
}
.nivar-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  font-size: 13px; color: var(--text);
}
.nivar-panel-body { flex: 1; overflow-y: auto; padding: 14px; }
.nivar-panel-input {
  display: flex; gap: 8px; padding: 10px 14px;
  border-top: 1px solid var(--border);
}
.nivar-panel-input .form-input { flex: 1; }

/* Sugerencias del panel: una fila de preguntas con scroll horizontal */
.nivar-panel-sugs {
  display: flex; gap: 6px; padding: 8px 10px;
  border-top: 1px solid var(--border);
  overflow-x: auto; flex-shrink: 0;
  scrollbar-width: thin;
}
.nivar-panel-sugs .btn {
  white-space: nowrap; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: 99px;
  font-size: 10px; padding: 4px 10px;
}

/* Indicador «pensando…» del chat (tres puntos que laten) */
.nivar-typing { display: inline-flex; gap: 4px; align-items: center; }
.nivar-typing span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text3); opacity: .35;
  animation: nivar-blink 1.2s infinite both;
}
.nivar-typing span:nth-child(2) { animation-delay: .2s; }
.nivar-typing span:nth-child(3) { animation-delay: .4s; }
@keyframes nivar-blink {
  0%, 80%, 100% { opacity: .25; }
  40%           { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .nivar-typing span { animation: none; opacity: .6; }
}

@media (max-width: 768px), (max-height: 520px) {
  .nivar-panel { width: 100vw; height: 100dvh; }
}

/* ── GRUPOS DE PESTAÑAS DEL EXPEDIENTE (Obra / Cierre / Más) ──
   Las pestañas agrupadas quedan en el DOM (workflow.js las sigue marcando,
   ordenando y ocultando) pero fuera de la barra; su botón de grupo las
   sirve en un desplegable. El !important evita que el inline display de la
   visibilidad por método las re-muestre en la barra. */
#exp-tabs .tab.tab-grouped { display: none !important; }
/* Orden flex explícito: workflow.js re-appendChildea las pestañas al
   restaurar/personalizar el método y los botones de grupo quedarían
   delante; con order pintan SIEMPRE al final (y antes de la flecha ›). */
.tab-group-btn[data-group="obra"] { order: 90; }
.tab-group-btn[data-group="cierre"] { order: 91; }
.tab-group-btn[data-group="mas"] { order: 92; }
.tab-group-btn {
  display: flex; align-items: center; gap: 6px;
  padding: 0 14px; min-height: 40px; cursor: pointer;
  font-size: 12px; color: var(--text2); white-space: nowrap;
  border-bottom: 2px solid transparent; flex-shrink: 0;
  transition: color var(--transition);
}
.tab-group-btn:hover { color: var(--text); }
.tab-group-btn.active { color: var(--accent-text); border-bottom-color: var(--accent2); }
.tab-group-btn.wf-next { color: var(--yellow); }
.tab-group-btn.wf-done .tgb-label::after { content: ' ✓'; color: var(--green); }
.tgb-caret { font-size: 9px; color: var(--text3); }
.exp-tab-group-pop {
  position: fixed; z-index: 500; min-width: 210px;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.etg-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: var(--radius);
  font-size: 12px; color: var(--text2); cursor: pointer;
}
.etg-row:hover { background: var(--bg3); }
.etg-row.active { color: var(--accent-text); background: var(--bg3); }
.etg-row.next { color: var(--yellow); }
.etg-check { margin-left: auto; color: var(--green); }

/* ── BARRA DE PESTAÑAS DEL EXPEDIENTE: desborde navegable ── */
#exp-tabs {
  scroll-behavior: smooth;
  scrollbar-width: thin;
}
/* Flechas ‹ › pegadas a los bordes del scroller (sticky + order flex:
   siempre pintan en los extremos aunque workflow.js reordene pestañas). */
.tabs-scroll-btn {
  position: sticky; z-index: 5; flex-shrink: 0; align-self: stretch;
  border: none; cursor: pointer; padding: 0 6px;
  font-size: 16px; color: var(--text2);
  background: var(--bg2);
  box-shadow: 0 0 10px 6px var(--bg2);
}
.tabs-scroll-btn:hover { color: var(--text); }
.tabs-scroll-izq { left: 0; order: -1; }
.tabs-scroll-der { right: 0; order: 99; }

/* ── CONTRAER EL MENÚ: botón integrado en el propio lateral ── */
.sidebar-logo { display: flex; align-items: center; justify-content: space-between; }
.sidebar-collapse-btn {
  background: none; border: none; cursor: pointer;
  color: var(--text3); font-size: 14px; padding: 4px 8px;
  border-radius: var(--radius);
}
.sidebar-collapse-btn:hover { background: var(--bg3); color: var(--text); }
.sidebar.collapsed .sidebar-collapse-btn { margin: 0 auto; }
/* El ☰ de la barra superior es SOLO para el cajón móvil. */
.topbar-menu-btn { display: none; }
@media (max-width: 768px), (max-height: 520px) {
  .topbar-menu-btn { display: inline-flex; margin-right: 6px; }
}

/* ── GRUPOS DESPLEGABLES DEL LATERAL (Finanzas / Recursos / Empresa) ── */
.nav-group-body { display: none; }
.nav-group.open .nav-group-body { display: block; }
.nav-group-body .nav-item { padding-left: 26px; }
.nav-chevron {
  margin-left: auto; font-size: 10px; color: var(--text3);
  transition: transform var(--transition);
}
.nav-group.open .nav-chevron { transform: rotate(180deg); }
.nav-group-toggle { cursor: pointer; }
/* Barra comprimida (solo iconos): sin sitio para sangrías ni chevrons. */
@media (max-width: 1024px) {
  .nav-group-body .nav-item { padding-left: 10px; }
  .nav-chevron { display: none; }
}
body.drawer-open .sidebar .nav-chevron { display: inline; }
body.drawer-open .sidebar .nav-group-body .nav-item { padding-left: 26px; }

/* ── PESTAÑAS DE SECCIÓN (Agenda↔Hoy↔Fichar · Posventa↔Contratos) ── */
.section-pills {
  display: flex; gap: 6px; flex-wrap: wrap; flex-shrink: 0;
  padding: 8px 16px; background: var(--bg2);
  border-bottom: 1px solid var(--border);
}
.section-pill {
  font-size: 12px; padding: 5px 12px; border-radius: 999px;
  background: var(--bg3); color: var(--text2);
  border: 1px solid var(--border); cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.section-pill:hover { background: var(--bg4); }
.section-pill.active {
  background: var(--accent2); color: #fff; border-color: var(--accent2);
  cursor: default;
}

/* ── BUSCADOR GLOBAL de la barra superior ── */
.topbar-search { flex: 0 1 320px; margin: 0 10px; }
.topbar-lupa { display: none; }   /* la lupa solo existe en móvil */
.topbar-bell { display: none; position: relative; }   /* la campana móvil, ídem */
@media (max-width: 768px) {
  .topbar-bell { display: inline-flex; flex-shrink: 0; }
  /* En móvil la barra es compacta: el buscador vive detrás de la LUPA.
     Al tocarla se despliega como fila fija bajo la barra (y la lupa
     vuelve a cerrarlo). Así el buscador global también existe en móvil. */
  .topbar-search { display: none; }
  .topbar-lupa { display: inline-flex; flex-shrink: 0; }
  body.gsearch-open .topbar-search {
    display: flex;
    position: fixed; top: 54px; left: 8px; right: 8px; z-index: 455;
    margin: 0; flex: none;
    background: var(--bg2); border: 1px solid var(--border);
    border-radius: var(--radius-lg); padding: 4px 6px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  }
}

/* ══════════════════════════════════════════════════════════════════
   RESPONSIVE — TABLET (≤1024px)
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {
  :root { --sidebar-w: 56px; }
  .sidebar { width: 56px; }
  .sidebar .nav-label,
  .sidebar .nav-badge,
  .sidebar .sidebar-logo-text,
  .sidebar .nav-section-label,
  .sidebar .user-info,
  .sidebar .user-meta { display: none; }
  .sidebar .nav-item { justify-content: center; padding: 10px; }
  .sidebar .nav-icon { margin: 0; }

  .content-grid { grid-template-columns: 1fr; }
  .content-grid .panel:not(:first-child) { display: none; }
  .content-grid.show-detail .panel:nth-child(2) { display: flex; }
  /* En detalle, la lista se oculta (una cosa a la vez, como una app móvil). */
  .content-grid.show-detail .panel:first-child { display: none; }
  /* Tercer estado: ver el CROQUIS (panel 3) a pantalla completa. */
  .content-grid.show-croquis .panel { display: none; }
  .content-grid.show-croquis .panel:nth-child(3) { display: flex; }
  .btn-volver-lista { display: inline-flex; }

  .topbar { padding: 0 12px; }
  .semaforo { display: none; }
  .topbar-quality { display: none; }
  /* Aire al final del scroll: sin él, el botón flotante «Parte» tapaba los
     últimos campos del formulario (visto en un Xiaomi en producción). */
  .panel-body { padding-bottom: 96px; }
  /* Estados vacíos compactos: el icono gigante desplazaba los datos reales. */
  .empty-state { height: auto !important; min-height: 0; padding: 18px 12px; }
  .empty-icon { font-size: 28px; }

  .dashboard-grid { grid-template-columns: repeat(2,1fr); }
}

/* ── TABLET VERTICAL (≤768px) ────────────────────────────────────── */
@media (max-width: 768px) {
  .sidebar { display: none; }
  .bottom-nav {
    display: flex !important;
    position: fixed; bottom: 0; left: 0; right: 0;
    background: var(--sidebar); border-top: 1px solid var(--border);
    height: 56px; z-index: 200;
    align-items: center; justify-content: space-around;
  }
  .main { padding-bottom: 56px; }
  .topbar { height: 48px; }
  .exp-ref { font-size: 12px; }
  .topbar-chips { display: none; }
  .dashboard-grid { grid-template-columns: 1fr 1fr; padding: 10px; gap: 8px; }
  /* En pantallas estrechas solo el punto verde (el texto satura la barra). */
  .nivar-badge { padding: 6px 8px; }
  .nivar-badge .nivar-badge-text { display: none; }
}

/* ── MÓVIL (≤768px de ancho O pantalla baja): FLUJO DE DOCUMENTO ──────
   En el móvil el «marco fijo con ranuras de scroll» no funciona: el
   overflow:hidden del body ANULA el scroll táctil de la página en Chrome
   móvil (el gesto no encuentra nada que desplazar) y los paneles con su
   propia ranura dejan zonas inaccesibles. En móvil la app se comporta
   como una página web normal: html/body scrollean DE VERDAD, cabecera y
   pestañas se apartan al deslizar (Chrome esconde su barra → más sitio)
   y solo la navegación inferior queda fija. Vale para vertical (ancho
   ≤768) y para apaisado (alto ≤520). */
@media (max-width: 768px), (max-height: 520px) {
  html { height: auto; }
  body { height: auto; min-height: 100dvh; overflow: auto; }
  .app, .sidebar { height: auto; min-height: 100dvh; overflow: visible; }
  .main { height: auto; overflow: visible; padding-bottom: 72px; }
  .page, [id^="exp-tab-"] { overflow: visible !important; height: auto; }
  .content-grid { overflow: visible; height: auto; }
  .panel { height: auto; overflow: visible; }
  .panel-body { overflow-y: visible; }
  /* TODOS los paneles visibles, APILADOS en vertical. El patrón
     «solo el primer panel y un botón para ver el resto» dejaba datos
     inaccesibles en las pestañas sin botón (visto en producción: en
     Resumen era imposible llegar a los datos del cliente o de la cita).
     Apilados, TODO se alcanza scrolleando. */
  .content-grid { display: flex; flex-direction: column; }
  .content-grid .panel,
  .content-grid .panel:not(:first-child),
  .content-grid.show-detail .panel,
  .content-grid.show-detail .panel:first-child,
  .content-grid.show-croquis .panel { display: flex; }
  .content-grid .panel { border-right: none; border-bottom: 1px solid var(--border2); }
  .btn-volver-lista { display: none !important; }
  /* Parrillas de MARCO generadas por JS con estilos inline
     (`grid-template-columns:...;height:100%[;overflow:hidden]`): están por
     toda la app (Resumen, Visita, Presupuesto, Técnicos…). En un móvil la
     columna flexible quedaba aplastada (vista de 47 px en producción) y el
     alto fijo + overflow escondían el resto. En móvil: UNA columna, alto
     libre, sin recortes. El !important es necesario porque son inline. */
  .main div[style*="grid-template-columns"][style*="height:100%"],
  .main div[style*="grid-template-columns"][style*="overflow:hidden"],
  .main div[style*="grid-template-columns"][style*="flex:1"] {
    grid-template-columns: 1fr !important;
    height: auto !important;
    overflow: visible !important;
  }
  .main div[style*="height:100%"][style*="overflow:hidden"] {
    height: auto !important;
    overflow: visible !important;
  }
  /* CAJÓN LATERAL: en móvil la sidebar está oculta y el ☰ no hacía nada —
     17 de las 22 secciones (Fichar, Clientes, Facturación, Tesorería…)
     eran inalcanzables. El ☰ la abre como panel fijo sobre un velo;
     tocar el velo o elegir un apartado la cierra (toggleDrawer en core.js). */
  body.drawer-open .sidebar {
    display: flex !important;
    position: fixed; top: 0; left: 0; bottom: 0;
    width: min(300px, 85vw); height: 100dvh; min-height: 0;
    overflow-y: auto; z-index: 400;
    box-shadow: 4px 0 24px rgba(0,0,0,0.45);
  }
  body.drawer-open .sidebar .nav-label,
  body.drawer-open .sidebar .nav-badge,
  body.drawer-open .sidebar .sidebar-logo-text,
  body.drawer-open .sidebar .nav-section-label,
  body.drawer-open .sidebar .user-info,
  body.drawer-open .sidebar .user-meta { display: revert; }
  body.drawer-open .sidebar .nav-item { justify-content: flex-start; padding: 10px 14px; }
  body.drawer-open .sidebar .nav-icon { margin-right: 10px; }
  #drawer-velo {
    position: fixed; inset: 0; z-index: 390;
    background: rgba(0,0,0,0.45); display: none;
  }
  /* Filas de formulario a UNA columna: las rejillas 1fr 1fr con campos de
     min-width:220px (Reglamentario, Seguridad, fichas técnicas…) no pueden
     encoger a 375px y desbordaban de lado dentro de su pestaña. */
  .form-row, .form-row.triple { grid-template-columns: 1fr !important; }
  /* Barra del método: sus tres bloques (siguiente paso + progreso + botón)
     suman más que la pantalla y ensanchaban TODO el documento. Envuelven. */
  .wf-strip { flex-wrap: wrap; }
  /* Los panes de pestaña son display:flex EN FILA: su hijo raíz es un flex
     item cuyo ancho crece hasta su contenido mínimo (Fotos 611px, Seguridad
     460px…) y ensancha el documento. En móvil: pane en columna e hijos
     encogibles al ancho de pantalla. */
  [id^="exp-tab-"] { flex-direction: column; }
  [id^="exp-tab-"] > * { min-width: 0; max-width: 100%; }
  /* Botonera del presupuesto (Facturar / Nueva versión / Lista de compra):
     en fila fija desbordaba; envuelve a dos líneas. */
  #ppto-actions { flex-wrap: wrap; }
  /* Cabecera del listado de expedientes (buscador + filtros + botones):
     con los filtros sumaba 540px en fila fija y ensanchaba el documento. */
  .exp-list-toolbar { flex-wrap: wrap; }
  .exp-list-toolbar .search-wrap { flex: 1 1 100%; max-width: none; }
  /* Modales con min-width fijo (440-680px) más anchos que la pantalla:
     en móvil ocupan el ancho disponible y su contenido hace scroll. */
  .modal {
    min-width: 0 !important;
    width: min(96vw, 640px);
    max-height: 92dvh; overflow-y: auto;
  }
}

/* ── MÓVIL APAISADO (pantalla baja): compactar además el cromo ──────
   En ~340px de alto cada píxel de barra cuenta: la barra de método se
   oculta (su información sigue en la pestaña Resumen y el menú Método)
   y cabecera/pestañas/navegación se estrechan. */
@media (max-height: 520px) {
  .wf-strip { display: none !important; }
  .topbar { height: 40px; }
  .tab { min-height: 34px; padding-top: 4px; padding-bottom: 4px; }
  .bottom-nav { height: 44px; }
  .main { padding-bottom: 64px; }
  .bottom-nav-btn { padding: 2px 10px; }
  .bottom-nav-btn .b-icon { font-size: 16px; }
  #fab-parte { bottom: 52px !important; padding: 8px 14px !important; }
}

/* Partidas del presupuesto: la parrilla de líneas es más ancha que un
   móvil — scrollea ELLA, no la pestaña entera. */
#ppto-lines-wrap { overflow-x: auto; }

/* ── AYUDA CONTEXTUAL «¿Qué hago aquí?» ──────────────────────────── */
#btn-ayuda {
  width: 28px; height: 28px; padding: 0; flex-shrink: 0;
  border-radius: 50%; border: 1px solid var(--border);
  font-weight: 700; color: var(--text3);
}
#ayuda-pop {
  position: fixed; top: 58px; right: 12px; z-index: 465;
  width: min(340px, calc(100vw - 24px));
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 14px 16px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.45);
}
#ayuda-pop .ayuda-titulo { font-size: 13px; font-weight: 700; margin-bottom: 6px; }
#ayuda-pop .ayuda-texto  { font-size: 12px; color: var(--text2); line-height: 1.55; }
#ayuda-pop .ayuda-pie    { font-size: 11px; color: var(--text3); margin-top: 10px;
  border-top: 1px solid var(--border); padding-top: 8px; }
#ayuda-pop .ayuda-enlace { color: var(--accent-text); cursor: pointer; font-weight: 600; }

/* ── BÚSQUEDA GLOBAL: desplegable de resultados en vivo ──────────── */
#gs-pop {
  position: fixed; z-index: 460;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 10px 30px rgba(0,0,0,0.4);
  max-height: min(420px, 70vh); overflow-y: auto;
  padding: 4px;
}
.gs-grupo {
  font-size: 10px; font-weight: 700; color: var(--text3);
  text-transform: uppercase; letter-spacing: .5px;
  padding: 8px 10px 4px;
}
.gs-fila {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: var(--radius);
  cursor: pointer; font-size: 12px;
}
.gs-fila:hover, .gs-fila.gs-activa { background: var(--bg3); }
.gs-icono { flex-shrink: 0; }
.gs-principal { color: var(--text); font-weight: 600; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-secundario { margin-left: auto; color: var(--text3); font-size: 10px;
  flex-shrink: 0; }
.gs-pie { border-top: 1px solid var(--border); margin-top: 4px;
  color: var(--accent-text); font-size: 11px; }
@media (max-width: 768px) {
  #gs-pop { left: 8px !important; right: 8px; width: auto !important; }
}

/* Barra de navegación inferior (móvil/tablet) */
.bottom-nav { display: none; }
.bottom-nav-btn {
  display: flex; flex-direction: column;
  align-items: center; gap: 2px;
  color: var(--text3); cursor: pointer;
  font-size: 10px; padding: 8px 12px;
  border-radius: var(--radius);
  transition: color var(--transition);
}
.bottom-nav-btn.active { color: var(--accent-text); }
.bottom-nav-btn .b-icon { font-size: 20px; }

/* ── PWA / TOUCH ─────────────────────────────────────────────────── */
@media (hover: none) {
  .btn { padding: 9px 16px; }
  /* Objetivos táctiles ≥40-44px en dispositivos sin puntero (móvil/tablet en
     obra). Antes solo .btn/.tab/.form-* → iconos y pastillas quedaban ~24-30px.
     Auditoría UX 2026-07-22. */
  .btn-icon { padding: 10px; min-width: 44px; min-height: 44px; justify-content: center; }
  .btn-sm { padding: 8px 14px; font-size: 12px; }
  .btn-xs { padding: 6px 12px; font-size: 11px; }
  .view-btn { padding: 10px 14px; min-height: 44px; }
  .section-pill { padding: 8px 14px; min-height: 40px; }
  .user-meta-btn, .topbar-lupa, .topbar-bell, #btn-ayuda, #btn-sidebar-collapse {
    min-width: 40px; min-height: 40px;
  }
  .tab { min-height: 48px; }
  .tramo-item { padding: 12px 10px; }
  .form-input, .form-select { padding: 10px 12px; font-size: 14px; }
}

/* ══════════════════════════════════════════════════════════════════
   VALIDACIÓN DE CAMPOS — reglas permanentes
   Complementan los estilos inline que aplica NVAL.js.
   El atributo data-val-state lo escribe NVAL tras validar.
   ══════════════════════════════════════════════════════════════════ */

/* Transición suave en todos los campos validados */
[data-val] {
  transition: border-color var(--transition), background-color var(--transition);
}

/* Estado OK — verde tenue */
[data-val-state="ok"] {
  border-color: var(--green) !important;
  background-color: rgba(34,197,94,0.08) !important;
}

/* Estado error — rojo tenue */
[data-val-state="error"] {
  border-color: var(--red) !important;
  background-color: rgba(239,68,68,0.10) !important;
}

/* Icono hint junto al label cuando hay error */
[data-val-state="error"] + .form-val-hint {
  display: block;
  color: var(--red);
  font-size: 10px;
  margin-top: 2px;
  line-height: 1.4;
}
.form-val-hint { display: none; }

/* ══════════════════════════════════════════════════════════════════
   SELECT NATIVOS — contraste y aspecto en tema oscuro
   Se aplica a todos los <select class="form-select"> que NO hayan
   sido convertidos por SmartSelect (los que mantienen display:block).
   ══════════════════════════════════════════════════════════════════ */

.form-select {
  cursor: pointer;
  /* Forzar colores en todos los motores */
  background-color: var(--bg3);
  color: var(--text);
  /* Flecha personalizada — evita la flecha del sistema que puede ser invisible */
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%235a6278'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}

.form-select:focus {
  border-color: var(--accent2);
  background-color: rgba(15,158,142,0.06);
}

/* Opciones del desplegable nativo */
.form-select option {
  background-color: var(--bg3);
  color: var(--text);
  font-size: 12px;
  padding: 6px 10px;
}

.form-select optgroup {
  background-color: var(--bg4);
  color: var(--text3);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* Select desactivado */
.form-select:disabled,
.form-input:disabled,
.form-textarea:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Select de solo lectura (simulado con pointer-events) */
.form-select[readonly] {
  pointer-events: none;
  opacity: 0.6;
}

/* ══════════════════════════════════════════════════════════════════
   INPUTS DE SOLO LECTURA (geo-autofill, municipio, isla, etc.)
   ══════════════════════════════════════════════════════════════════ */
.form-input[readonly] {
  background-color: var(--bg4);
  color: var(--text3);
  cursor: default;
  border-color: var(--border);
}
.form-input[readonly]:focus {
  border-color: var(--border);
  background-color: var(--bg4);
}

/* ── Animación spinner para indicador de guardado ── */
@keyframes nivSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ── Halo de aviso (perímetro rojo) ─────────────────────────────────────────
   Refuerzo VISUAL de los avisos bloqueantes: cambios sin guardar al cambiar de
   pantalla y datos importantes que faltan. ACOMPAÑA al toast/diálogo que ya
   sale (no lo sustituye). Overlay de todo el viewport, no captura clics; pulsa
   en rojo y se desvanece solo. Lo dispara nivariaAlertHalo() (core.js). */
#nivaria-alert-halo {
  position: fixed; inset: 0; z-index: 99999; pointer-events: none; opacity: 0;
  box-shadow: inset 0 0 0 3px var(--red), inset 0 0 60px 10px rgba(239, 68, 68, .30);
}
#nivaria-alert-halo.on { animation: nivariaHaloPulse 1.15s ease-out both; }
@keyframes nivariaHaloPulse {
  0% { opacity: 0; } 10% { opacity: 1; } 45% { opacity: .5; }
  65% { opacity: .9; } 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  #nivaria-alert-halo.on { animation: nivariaHaloFade .9s ease-out both; }
  @keyframes nivariaHaloFade { 0% { opacity: .85; } 100% { opacity: 0; } }
}

/* ── Impresión (printHtml → #print-area) ──────────────────────────────
   #print-area está oculto en pantalla y solo se muestra al imprimir; el
   resto de la app se oculta. Tablas legibles en blanco y negro. */
.print-only { display: none; }
#print-area table { width: 100%; border-collapse: collapse; font-size: 12px; }
#print-area th, #print-area td { border: 1px solid #999; padding: 4px 6px; text-align: left; vertical-align: top; }
#print-area th { background: #eee; }
#print-area h3 { font-size: 13px; margin: 14px 0 6px; }
@media print {
  body > *:not(#print-area) { display: none !important; }
  #print-area { display: block !important; position: static; padding: 0; color: #000; background: #fff; }
  @page { margin: 14mm; }
}

/* ── ACCESIBILIDAD (auditoría UX 2026-07-22) ──────────────────────────
   Foco de teclado SIEMPRE visible: el resto del CSS quita el outline en
   varios sitios y muchos controles clicables no tenían indicador. Con
   :focus-visible solo se muestra al navegar con teclado, no al hacer clic
   con el ratón. Cubre botones, enlaces, campos, y los divs/spans que actúan
   como nav/pestañas/acciones (data-page/data-nav/role, .nav-item, .tab). */
:focus-visible,
a:focus-visible, button:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
[tabindex]:focus-visible, [role="button"]:focus-visible, [role="tab"]:focus-visible,
[role="link"]:focus-visible, .nav-item:focus-visible, .tab:focus-visible {
  outline: 2px solid var(--accent2);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Respeto AMPLIO de «reducir movimiento»: antes solo se neutralizaban 2
   animaciones concretas; ahora se cortan todas (pulsos, spinners, slides). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
