/* =====================================================
   ERP EXPORTADORA — Dark Neon Design System
   ===================================================== */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* Accent neon — azul cielo claro */
  --primary:        #7dd3fc;
  --primary-d:      #38bdf8;
  --primary-glow:   rgba(125, 211, 252, 0.28);
  --primary-glow-s: rgba(125, 211, 252, 0.13);
  --danger:         #f87171;
  --danger-d:       #ef4444;
  --warning:        #fbbf24;
  --orange:         #fb923c;
  --success:        #34d399;
  --success-d:      #10b981;
  --purple:         #a78bfa;

  /* ── Alias de paleta usados en los módulos ──────────────────────────────
     `--green-700`, `--red-600` y `--yellow-700` se venían escribiendo en los
     módulos con un hexadecimal de respaldo: var(--green-700,#15803d). Nunca
     estuvieron definidas, así que SIEMPRE ganaba el respaldo — tres colores
     oscuros, pensados para fondo blanco, sobre el fondo oscuro del sistema.
     El número existía y no se leía, que es la peor forma de no mostrarlo.

     Apuntan a las variables semánticas, no a un hexadecimal propio: así siguen
     al tema solas y el próximo tema las hereda sin tocar nada. En el tema claro
     resuelven a los mismos tonos oscuros de siempre, así que ahí no cambia nada. */
  --green-700:      var(--success);
  --red-600:        var(--danger);
  --yellow-700:     var(--warning);
  --green-600:      var(--success-d);
  --ok:             var(--success);
  /* La monoespaciada, en un solo lugar. Ya se usaba como `var(--mono, monospace)` en dos partes
     sin estar definida: funcionaba por el respaldo, pero cada una caía en la del sistema y las
     columnas de números no alineaban igual entre pantallas. Es la misma de la clase `.mono`. */
  --mono:           'SF Mono', 'Fira Mono', 'Consolas', monospace;
  --red-500:        var(--danger-d);
  --red-400:        var(--danger);
  --accent:         var(--primary-d);
  --text:           var(--gray-700);
  --surface:        var(--bg-surface);
  --bg-secondary:   var(--bg-surface);
  /* El punto de una línea de tiempo se pinta con esto para tapar la línea que pasa por detrás:
     tiene que ser el fondo de la tarjeta, no un gris fijo — con `#1a1a1a` de respaldo, en el tema
     claro quedaba un punto negro. */
  --bg:             var(--bg-card);
  /* Lavado NEUTRO y translúcido: se apoya sobre lo que haya detrás. El respaldo era `#0002`
     —negro al 13%—, que sobre el fondo oscuro no se ve y sobre el claro sí. */
  --bg-soft:        rgba(148, 163, 184, .10);

  /* Dark palette */
  --gray-50:   #0f1629;
  --gray-100:  #111827;
  --gray-200:  #1e2a45;
  --gray-300:  #2d3e5f;
  --gray-400:  #64748b;
  --gray-500:  #94a3b8;
  --gray-600:  #cbd5e1;
  --gray-700:  #e2e8f0;
  --gray-800:  #f1f5f9;
  --white:     #f8faff;
  --gray-900:  #f8faff;

  /* Backgrounds */
  --bg-base:    #050a18;
  --bg-surface: #080f22;
  --bg-card:    rgba(14, 22, 45, 0.92);
  --bg-sidebar: #060c1e;
  --bg-header:  rgba(8, 15, 34, 0.96);
  --bg-input:   rgba(16, 25, 50, 0.8);
  --bg-modal:   rgba(8, 13, 30, 0.95);
  --bg-hover:   rgba(56, 189, 248, 0.07);
  --bg-active:  rgba(56, 189, 248, 0.12);

  /* Borders */
  --border:     rgba(56, 189, 248, 0.14);
  --border-md:  rgba(56, 189, 248, 0.22);
  --border-strong: rgba(56, 189, 248, 0.4);

  /* Shadows/Glow */
  --shadow:    0 2px 12px rgba(0,0,0,.5), 0 0 1px rgba(125,211,252,.08);
  --shadow-lg: 0 8px 32px rgba(0,0,0,.6), 0 0 2px rgba(56,189,248,.1);
  --glow-sm:   0 0 12px rgba(56, 189, 248, 0.15);
  --glow-md:   0 0 24px rgba(56, 189, 248, 0.25);
  --glow-lg:   0 0 40px rgba(56, 189, 248, 0.18);

  --sidebar-w: 260px;
  --header-h:  56px;
  --radius:      10px;
  --radius-sm:   6px;
  --radius-lg:   16px;
  --radius-pill: 999px;

  /* Estación Aurora: display para títulos/cifras grandes, mono para todo dato
     alineado en columna. 'inherit' de body no cambia — estas dos son roles
     nuevos que se piden explícitamente donde hacen falta. */
  --font-display: 'Chakra Petch', 'Plus Jakarta Sans', -apple-system, sans-serif;
  --font-mono:    'IBM Plex Mono', 'SF Mono', 'Fira Mono', 'Consolas', monospace;
}

/* ── TEMA CLARO TEAL ────────────────────────────────────
   Verde-azulado claro. Se activa con .light en <html>
   ──────────────────────────────────────────────────── */
html.light {
  /* Acento principal — teal */
  --primary:        #0f766e;
  --primary-d:      #0d9488;
  --primary-glow:   rgba(15, 118, 110, 0.2);
  --primary-glow-s: rgba(15, 118, 110, 0.1);
  --danger:         #dc2626;
  --danger-d:       #b91c1c;
  --warning:        #b45309;
  --orange:         #c2410c;
  --success:        #15803d;
  --success-d:      #166534;
  --purple:         #6d28d9;

  /* Grises — legibles sobre fondos claros */
  --gray-50:   #f0fdfa;
  --gray-100:  #ccfbf1;
  --gray-200:  #99f6e4;
  --gray-300:  #5eead4;
  --gray-400:  #64748b;
  --gray-500:  #475569;
  --gray-600:  #334155;
  --gray-700:  #1e293b;
  --gray-800:  #0f172a;
  --white:     #ffffff;
  --gray-900:  #0a0f1e;

  /* Fondos teal suave */
  --bg-base:    #f0fdfa;
  --bg-surface: #e6faf6;
  --bg-card:    rgba(255, 255, 255, 0.97);
  --bg-sidebar: #ffffff;
  --bg-header:  rgba(255, 255, 255, 0.98);
  --bg-input:   #ffffff;
  --bg-modal:   rgba(240, 253, 250, 0.99);
  --bg-hover:   rgba(15, 118, 110, 0.07);
  --bg-active:  rgba(15, 118, 110, 0.12);

  /* Bordes teal discretos */
  --border:        rgba(20, 184, 166, 0.25);
  --border-md:     rgba(15, 118, 110, 0.3);
  --border-strong: rgba(15, 118, 110, 0.5);

  --shadow:    0 1px 6px rgba(0,0,0,.08), 0 0 1px rgba(15,118,110,.08);
  --shadow-lg: 0 4px 24px rgba(0,0,0,.1), 0 1px 4px rgba(15,118,110,.06);
  --glow-sm:   0 0 8px rgba(15,118,110,.12);
  --glow-md:   0 0 0 rgba(15,118,110,0);
  --glow-lg:   0 0 0 rgba(15,118,110,0);
}

/* ── Ajustes estructurales para tema claro ──────────── */
html.light .sidebar {
  box-shadow: 2px 0 16px rgba(0,0,0,.06);
  border-right: 1px solid var(--border);
  background: #ffffff;
}
html.light .sidebar-header {
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 8%, transparent) 0%, transparent 100%);
  border-bottom-color: var(--border);
}
html.light .sidebar-header::after { display: none; }
html.light .nav-label {
  color: var(--primary);
  text-shadow: none;
  font-weight: 800;
  letter-spacing: .09em;
}
html.light .nav-link { color: var(--gray-500); }
html.light .nav-link:hover { color: var(--primary); background: var(--bg-hover); }
html.light .nav-link.active {
  color: var(--primary);
  background: var(--bg-active);
  box-shadow: inset 0 0 0 1px var(--border-md);
}
html.light .nav-link.active::after {
  background: var(--primary);
  box-shadow: none;
}
html.light .sidebar-footer { border-top-color: var(--border); }
html.light .empresa-panel-top {
  border-bottom-color: var(--border);
  background: color-mix(in srgb, var(--primary) 5%, transparent);
}
html.light .empresa-panel-nombre { color: var(--primary); text-shadow: none; }
html.light .empresa-panel-cambiar {
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  border-color: color-mix(in srgb, var(--primary) 25%, transparent);
  color: var(--primary);
}
html.light .empresa-panel-cambiar:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }

html.light .app-header {
  background: rgba(255,255,255,.98);
  border-bottom-color: var(--border);
  box-shadow: 0 1px 10px rgba(0,0,0,.07);
}
html.light .main-content {
  background: var(--bg-base);
  background-image: none;
}
html.light .card {
  background: #ffffff;
  border-color: var(--border);
  box-shadow: var(--shadow);
}
html.light .card:hover { border-color: var(--border-md); }
html.light .card::after { display: none; }

/* Scrollbar */
html.light ::-webkit-scrollbar-track { background: #e6faf6; }
html.light ::-webkit-scrollbar-thumb { background: #99f6e4; }
html.light ::-webkit-scrollbar-thumb:hover { background: var(--primary); box-shadow: none; }

/* Tablas */
html.light .data-table thead th {
  background: #e6faf6;
  color: var(--primary);
  border-bottom: 2px solid color-mix(in srgb, var(--primary) 20%, transparent);
}
html.light .data-table tbody td { border-bottom-color: rgba(20,184,166,.12); color: var(--gray-600); }
html.light .data-table tbody tr:hover td { background: var(--bg-hover); }

/* Inputs */
html.light .input,
html.light input[type="text"], html.light input[type="email"],
html.light input[type="password"], html.light input[type="number"],
html.light input[type="date"], html.light textarea, html.light select {
  background: #ffffff;
  border-color: color-mix(in srgb, var(--primary) 30%, transparent);
  color: var(--gray-700);
}
html.light .input:focus,
html.light input:focus, html.light textarea:focus, html.light select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent);
}
html.light .label, html.light label { color: var(--gray-600); }

/* ── BOTONES — sólidos con texto blanco ─────────────── */
html.light .btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--primary-d));
  color: #ffffff !important;
  border-color: transparent;
  box-shadow: 0 2px 8px color-mix(in srgb, var(--primary) 35%, transparent);
}
html.light .btn-primary:hover:not(:disabled) {
  background: linear-gradient(135deg, #0d6860, #0c8276);
  box-shadow: 0 4px 16px color-mix(in srgb, var(--primary) 40%, transparent);
  transform: translateY(-1px);
}
html.light .btn-primary::after { display: none; }

html.light .btn-secondary {
  background: var(--gray-600);
  color: #ffffff !important;
  border-color: var(--gray-600);
}
html.light .btn-secondary:hover:not(:disabled) {
  background: var(--gray-700);
  border-color: var(--gray-700);
}

html.light .btn-danger {
  background: var(--danger);
  color: #ffffff !important;
  border-color: var(--danger);
}
html.light .btn-danger:hover:not(:disabled) { background: var(--danger-d); border-color: var(--danger-d); }

html.light .btn-success {
  background: var(--success);
  color: #ffffff !important;
  border-color: var(--success);
}
html.light .btn-success:hover:not(:disabled) { background: var(--success-d); border-color: var(--success-d); }

html.light .btn-ghost {
  background: transparent;
  color: var(--gray-600) !important;
  border-color: transparent;
}
html.light .btn-ghost:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--primary) !important;
}

/* Botones pequeños mantienen el mismo esquema */
html.light .btn-sm, html.light .btn-xs { font-weight: 600; }

/* Relieve en tema claro */
html.light .btn-relieve {
  border-bottom-color: rgba(0,0,0,.25);
}

/* Modales */
html.light .modal-overlay { background: color-mix(in srgb, var(--gray-800) 40%, transparent); }
html.light .modal {
  background: #ffffff;
  border-color: var(--border);
  box-shadow: var(--shadow-lg);
}
html.light .modal-header {
  background: color-mix(in srgb, var(--primary) 4%, transparent);
  border-bottom-color: var(--border);
}
html.light .modal-footer { border-top-color: var(--border); }

/* Badges */
html.light .badge-blue    { background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary); border-color: color-mix(in srgb, var(--primary) 25%, transparent); }
html.light .badge-success { background: color-mix(in srgb, var(--success) 12%, transparent);  color: var(--success); border-color: color-mix(in srgb, var(--success) 25%, transparent); }
html.light .badge-warning { background: color-mix(in srgb, var(--warning) 12%, transparent);   color: var(--warning); border-color: color-mix(in srgb, var(--warning) 25%, transparent); }
html.light .badge-danger, html.light .badge-red { background: color-mix(in srgb, var(--danger) 10%, transparent); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 20%, transparent); }
html.light .badge-gray    { background: color-mix(in srgb, var(--gray-500) 10%, transparent);   color: var(--gray-500); border-color: color-mix(in srgb, var(--gray-500) 20%, transparent); }
html.light .badge-purple  { background: color-mix(in srgb, var(--purple) 10%, transparent);  color: var(--purple); border-color: color-mix(in srgb, var(--purple) 20%, transparent); }
html.light .badge-orange  { background: rgba(194,65,12,.1);   color: #c2410c; border-color: rgba(194,65,12,.2); }

/* Tabs */
html.light .tabs { border-bottom-color: color-mix(in srgb, var(--primary) 20%, transparent); }
html.light .tab-btn { color: var(--gray-500); }
html.light .tab-btn:hover { color: var(--primary); }
html.light .tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); font-weight: 700; }

/* Alerts */
html.light .alert-info    { background: color-mix(in srgb, var(--primary) 7%, transparent); color: var(--primary); border-color: color-mix(in srgb, var(--primary) 20%, transparent); }
html.light .alert-warning { background: color-mix(in srgb, var(--warning) 8%, transparent);   color: var(--warning); border-color: color-mix(in srgb, var(--warning) 20%, transparent); }
html.light .alert-success { background: color-mix(in srgb, var(--success) 8%, transparent);  color: var(--success); border-color: color-mix(in srgb, var(--success) 20%, transparent); }

/* Textos */
html.light .page-header h1 { color: var(--gray-800); text-shadow: none; }
html.light .app-header h2  { color: var(--gray-700); }

/* Autocomplete */
html.light .autocomplete-list {
  background: #ffffff;
  border-color: var(--border-md);
  box-shadow: var(--shadow-lg);
}
html.light .ac-item { color: var(--gray-600); }
html.light .ac-item:hover { background: var(--bg-hover); color: var(--primary); }

/* Botón toggle de tema */
.btn-theme {
  background: none;
  border: 1px solid var(--border-md);
  color: var(--gray-500);
  border-radius: var(--radius);
  padding: .3rem .6rem;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
  margin-left: .5rem;
}
.btn-theme:hover { border-color: var(--primary); color: var(--primary); }

html { font-size: 14px; }
body {
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  color: var(--gray-600);
  background: var(--bg-base);
  line-height: 1.5;
}

/* Scrollbar personalizado */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: var(--bg-surface); }
::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--primary); box-shadow: var(--glow-sm); }

/* ── Login ─────────────────────────────────────────── */
.login-body {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh;
  background: radial-gradient(ellipse 80% 60% at 50% 0%, color-mix(in srgb, var(--primary) 18%, transparent) 0%, transparent 65%),
              radial-gradient(ellipse 60% 50% at 80% 100%, rgba(99,102,241,.12) 0%, transparent 60%),
              var(--bg-base);
}
.login-card {
  background: var(--bg-card);
  border: 1px solid var(--border-md);
  border-radius: 16px;
  padding: 2.5rem;
  width: 100%;
  max-width: 400px;
  box-shadow: var(--shadow-lg), var(--glow-sm);
  backdrop-filter: blur(12px);
}
.login-logo  { display: flex; align-items: baseline; gap: .5rem; margin-bottom: 1.5rem; }
.logo-mark   { font-size: 1.4rem; font-weight: 800; color: var(--primary); text-shadow: var(--glow-sm); }
.logo-text   { font-size: 1rem; font-weight: 600; color: var(--gray-500); }
.login-title { font-size: 1.4rem; font-weight: 700; margin-bottom: 1.5rem; color: var(--gray-700); }
.login-footer { margin-top: 1.5rem; font-size: .75rem; color: var(--gray-400); text-align: center; }
.login-footer a { color: var(--primary); text-decoration: none; }
.login-footer a:hover { text-shadow: var(--glow-sm); }
.reg-section-title { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--gray-400); margin: 1rem 0 .5rem; border-top: 1px solid var(--border); padding-top: .75rem; }

/* ── App shell ──────────────────────────────────────── */
.app-body { display: flex; height: 100vh; overflow: hidden; background: var(--bg-base); }

/* Sidebar */
.sidebar {
  width: var(--sidebar-w);
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  color: var(--gray-600);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  flex-shrink: 0;
  transition: width .2s ease;
  box-shadow: 4px 0 24px rgba(0,0,0,.4), 2px 0 0 var(--border);
}
.sidebar.collapsed { width: 56px; }
.sidebar-header {
  display: flex; align-items: center; gap: .5rem;
  padding: 1rem;
  border-bottom: 1px solid var(--border);
  min-height: var(--header-h);
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 6%, transparent) 0%, transparent 100%);
}
.sidebar.collapsed .logo-text,
.sidebar.collapsed .logo-mark,
.sidebar.collapsed .nav-label,
.sidebar.collapsed .nav-link span { display: none; }
.sidebar.collapsed .sidebar-header { padding: .5rem; justify-content: center; gap: 0; }
.sidebar.collapsed .nav-link { justify-content: center; padding: .625rem; }
.sidebar-toggle { margin-left: auto; background: none; border: none; color: var(--gray-400); cursor: pointer; font-size: 1rem; transition: color .15s; }
.sidebar-toggle:hover { color: var(--primary); }

.nav-section { padding: .5rem 0; border-bottom: 1px solid color-mix(in srgb, var(--primary-d) 5%, transparent); }
.nav-label   {
  display: flex; align-items: center; justify-content: space-between;
  padding: .65rem 1rem .3rem;
  font-size: .72rem; text-transform: uppercase; letter-spacing: .1em;
  color: #ffffff; font-weight: 800;
  text-shadow: 0 0 10px color-mix(in srgb, var(--primary) 40%, transparent);
  cursor: pointer; user-select: none;
}
.nav-chevron { font-size: .85em; opacity: .6; transition: transform .18s; }
.nav-chevron::before { content: '▾'; }
.nav-section.section-collapsed .nav-chevron { transform: rotate(-90deg); }
.nav-section.section-collapsed .nav-link { display: none !important; }

/* ── Buscador del menú (filtra el árbol en vivo, tipo VS Code) ── */
.nav-search {
  position: sticky; top: 0; z-index: 6;
  display: flex; align-items: center; gap: .4rem;
  padding: .55rem .6rem; margin: 0 .25rem .2rem;
  background: var(--bg-sidebar);
}
.nav-search-ico { font-size: .85rem; opacity: .6; flex-shrink: 0; }
.nav-search input {
  flex: 1; min-width: 0;
  background: color-mix(in srgb, var(--gray-500) 10%, transparent);
  border: 1px solid var(--border);
  border-radius: 8px; color: inherit;
  padding: .38rem .55rem; font-size: .82rem; font-family: inherit;
}
.nav-search input::placeholder { color: var(--gray-400); }
.nav-search input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-glow-s, rgba(56,189,248,.2)); }
.nav-search input::-webkit-search-cancel-button { cursor: pointer; }
.sidebar.collapsed .nav-search { display: none; }   /* en modo ícono no hay lugar */
.nav-sin-resultados { display: none; padding: 1rem; text-align: center; font-size: .8rem; color: var(--gray-400); }

/* Durante la búsqueda: se muestran solo las coincidencias, expandidas.
   Las reglas de permiso (style.display:none inline) y de colapso (!important)
   quedan cubiertas: `.nav-match` solo se pone en links visibles por permiso, y
   `#sidebar.searching` gana por especificidad de ID al !important del colapso. */
#sidebar.searching .nav-section:not(.nav-sec-match) { display: none; }
#sidebar.searching .nav-subgroup:not(.nav-subgrp-match) { display: none; }
#sidebar.searching .nav-link[href]:not(.nav-match) { display: none; }
#sidebar.searching .nav-section.nav-sec-match .nav-link.nav-match { display: flex !important; }

/* Sub-grupo colapsable dentro de una sección (ej. "Departamento de cobranzas") */
.nav-subgroup { margin: .1rem 0; }
.nav-sublabel {
  display: flex; align-items: center; justify-content: space-between; gap: .4rem;
  padding: .4rem 1rem .3rem 1.15rem;
  margin-top: .2rem;
  font-size: .68rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--primary-d); font-weight: 800;
  cursor: pointer; user-select: none;
  border-left: 2px solid color-mix(in srgb, var(--primary-d) 50%, transparent);
}
.nav-sublabel:hover { color: var(--primary); }
/* Tema claro: subtítulos oscuros y en negrita para que se lean bien sobre fondo claro */
html.light .nav-sublabel { color: #0e6b7a; border-left-color: rgba(14,107,122,.4); }
html.light .nav-sublabel:hover { color: var(--primary); }
.nav-subgroup > .nav-link { padding-left: 1.9rem; }
/* Bloque anidado (Finanzas → Contabilidad → Libros IVA): un escalón más de sangría,
   para que en el menú lateral se lea la jerarquía y no parezcan todos del mismo nivel. */
.nav-subgroup .nav-subgroup > .nav-sublabel { padding-left: 1.9rem; font-size: .64rem; opacity: .85; }
.nav-subgroup .nav-subgroup > .nav-link { padding-left: 2.7rem; }
.sidebar.collapsed .nav-subgroup .nav-subgroup > .nav-link { padding-left: .625rem; }
.nav-subchevron { font-size: .8em; opacity: .6; transition: transform .18s; }
.nav-subchevron::before { content: '▾'; }
.nav-subgroup.subgroup-collapsed .nav-subchevron { transform: rotate(-90deg); }

/* <summary> con display:flex pierde el triángulo nativo del navegador (era list-item,
   ahora no) — mismo criterio que .nav-subchevron de arriba: una flechita propia que
   rota según [open]. La usan las listas plegables por mes (Planilla de hacienda,
   pedido del usuario 21-ago-2026: "comprimir esta pantalla por mes"). */
.pf-chevron { font-size: .8em; opacity: .6; transition: transform .18s; flex-shrink: 0; }
.pf-chevron::before { content: '▾'; }
details:not([open]) > summary .pf-chevron { transform: rotate(-90deg); }
.nav-subgroup.subgroup-collapsed .nav-link { display: none !important; }
/* Ocultar el subtítulo si su sección padre o el sidebar están colapsados */
.nav-section.section-collapsed .nav-sublabel { display: none; }
.sidebar.collapsed .nav-sublabel { display: none; }
.sidebar.collapsed .nav-subgroup > .nav-link { padding-left: .625rem; }

/* Tarjetas de cuenta bancaria clickeables (grilla) */
.cuenta-card:hover { box-shadow: 0 6px 18px rgba(0,0,0,.14); transform: translateY(-2px); border-color: var(--primary, #0ea5e9); }

/* Grilla de tarjetas genérica — listados de establecimientos, cuentas, indicadores,
   perfiles, etc. (21 pantallas la usan). Faltaba: sin esta regla cada `.card` caía en
   bloque, una abajo de la otra a lo ancho completo, en vez de acomodarse varias por
   fila — el mismo patrón de `.cuentas-grid`, para tarjetas con más contenido. */
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; align-items: start; }

/* Grilla de tiles compactos de cuentas — datos esenciales + saldo, en relieve e interactivos */
.cuentas-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; }
.cuenta-tile {
  cursor: pointer; padding: .95rem 1.05rem;
  border-radius: 14px;
  background: var(--bg-card, #fff);
  border: 1px solid var(--border, #e2e8f0);
  box-shadow: 0 2px 6px rgba(0,0,0,.10), 0 1px 2px rgba(0,0,0,.06);
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
  display: flex; flex-direction: column; gap: .3rem;
}
.cuenta-tile:hover, .cuenta-tile:focus-visible {
  box-shadow: 0 12px 26px rgba(0,0,0,.18), 0 4px 10px rgba(0,0,0,.10);
  transform: translateY(-3px);
  border-color: var(--primary, #0ea5e9);
  outline: none;
}
.cuenta-tile:active { transform: translateY(-1px); box-shadow: 0 6px 14px rgba(0,0,0,.14); }
.tile-head { display: flex; justify-content: space-between; align-items: center; }
.tile-moneda { font-size: .68rem; font-weight: 800; letter-spacing: .04em; color: var(--primary, #0ea5e9); border: 1px solid currentColor; border-radius: 20px; padding: .05rem .5rem; }
.tile-bank { font-weight: 700; font-size: .95rem; line-height: 1.2; }
.tile-num  { font-size: .76rem; color: var(--gray-500, #64748b); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile-saldo { display: flex; flex-direction: column; margin-top: .25rem; }
.tile-saldo-label  { font-size: .64rem; text-transform: uppercase; letter-spacing: .06em; color: var(--gray-400, #94a3b8); }
.tile-saldo-amount { font-family: var(--font-mono); font-size: 1.3rem; font-weight: 800; }
.tile-extracto { font-size: .74rem; color: var(--gray-500, #64748b); }
.tile-warn { font-size: .72rem; color: var(--warning); font-weight: 600; }
.tile-foot { display: flex; align-items: center; gap: .35rem; margin-top: .55rem; flex-wrap: wrap; }
.tile-open { margin-left: auto; font-size: .75rem; font-weight: 800; color: var(--primary, #0ea5e9); }
.nav-link {
  display: flex; align-items: center; gap: .625rem;
  padding: .5rem 1rem;
  color: var(--gray-500);
  text-decoration: none;
  font-size: .825rem;
  /* Solo color/fondo/sombra: `transition: all` animaba también margin y padding,
     y animar la caja del ítem empujaba la lista entera en cada hover. */
  transition: background-color .15s, color .15s, box-shadow .15s;
  position: relative;
}
.nav-link::before { content: attr(data-icon); font-size: .9rem; flex-shrink: 0; }
.nav-link:hover {
  background: var(--bg-hover);
  color: var(--primary);
  border-radius: var(--radius);
  /* Sin margin/padding en :hover — cambiar la geometría movía el ítem (en los
     desplegables del menú superior el margen base es 0, así que el azulejo saltaba
     bajo el cursor). El realce es solo color/fondo. */
}
.nav-link.active {
  background: var(--bg-active);
  color: var(--primary);
  border-radius: var(--radius);
  margin: 0 .5rem; padding: .5rem .5rem;
  box-shadow: inset 0 0 0 1px var(--border-md), var(--glow-sm);
  font-weight: 600;
}
.nav-link.active::after {
  content: '';
  position: absolute; right: 0; top: 20%; bottom: 20%;
  width: 3px; background: var(--primary);
  border-radius: 2px 0 0 2px;
  box-shadow: 0 0 8px var(--primary);
}

.sidebar-footer { margin-top: auto; padding: 1rem; border-top: 1px solid var(--border); }
.user-info { display: flex; flex-direction: column; margin-bottom: .5rem; }

/* Panel empresa */
.empresa-panel-top {
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 15%, transparent) 0%, color-mix(in srgb, var(--primary) 6%, transparent) 100%);
  border-bottom: 1px solid var(--border);
  padding: .6rem 1rem;
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  flex-shrink: 0;
}
.empresa-panel-info { display: flex; flex-direction: column; gap: .1rem; overflow: hidden; }
.empresa-panel-label { font-size: .6rem; text-transform: uppercase; letter-spacing: .08em; color: var(--gray-400); }
.empresa-panel-nombre { font-size: .8rem; font-weight: 700; color: var(--primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; text-shadow: var(--glow-sm); }
.empresa-panel-cambiar {
  background: color-mix(in srgb, var(--primary) 12%, transparent); border: 1px solid var(--border-md);
  color: var(--primary); border-radius: 6px; padding: .25rem .6rem;
  font-size: .72rem; font-weight: 600; cursor: pointer; flex-shrink: 0;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s; white-space: nowrap;
}
.empresa-panel-cambiar:hover { background: color-mix(in srgb, var(--primary) 22%, transparent); box-shadow: var(--glow-sm); }
.sidebar.collapsed .empresa-panel-info { display: none; }
.sidebar.collapsed .empresa-panel-top { justify-content: center; padding: .6rem; }
.sidebar.collapsed .empresa-panel-cambiar { padding: .25rem .4rem; font-size: .8rem; }

.empresa-list { list-style: none; }
.empresa-list-item { padding: .75rem 1.25rem; border-bottom: 1px solid var(--border); transition: background .12s; }
.empresa-list-item:last-child { border-bottom: none; }
.empresa-list-item:not(.empresa-activa):hover { background: var(--bg-hover); cursor: pointer; }
.empresa-activa { background: var(--bg-active); }
.empresa-list-nombre { font-weight: 600; font-size: .9rem; color: var(--gray-700); }
.empresa-list-sub { font-size: .75rem; color: var(--gray-500); margin-top: .15rem; }
.badge-activa { display: inline-block; font-size: .65rem; font-weight: 700; color: var(--primary); background: var(--primary-glow-s); border-radius: 4px; padding: .1rem .35rem; margin-top: .25rem; }
.user-info #userName { font-weight: 600; font-size: .85rem; color: var(--gray-700); }
.user-rol   { font-size: .7rem; color: var(--gray-400); }

/* Main area */
.app-main { flex: 1; display: flex; flex-direction: column; overflow: hidden; transition: margin-left .2s; }
.app-header {
  height: var(--header-h);
  background: var(--bg-header);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 1.5rem;
  box-shadow: 0 2px 16px rgba(0,0,0,.4), 0 0 1px var(--border);
  flex-shrink: 0;
  backdrop-filter: blur(8px);
}
.app-header h2 { font-size: 1.05rem; font-weight: 700; color: var(--gray-700); }
/* overflow-x:hidden explícito: si se deja "visible" (default), la especificación CSS
   fuerza a que compute como "auto" solo por tener overflow-y:auto — y ese scroll
   horizontal fantasma titila prendiéndose/apagándose cada vez que la barra vertical
   (9px) aparece o desaparece y corre el ancho disponible justo al límite. Las tablas
   anchas ya traen su propio "overflow-x:auto" envolvente (.table-container o el div
   que arma cada pantalla), así que acá no hace falta y solo generaba el parpadeo. */
.main-content { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 1.5rem; }

/* ── Page header ──────────────────────────────────── */
.page-header {
  display: flex; align-items: center; gap: 1rem;
  margin-bottom: 1.25rem; flex-wrap: wrap;
}
.page-header h1 {
  font-size: 1.25rem; font-weight: 700; color: var(--gray-700);
  flex: 1;
}

/* ── Agrupación de productos por tipo ────────────── */
.grupo-prod-header {
  display: flex; align-items: center; gap: .6rem;
  margin-bottom: .5rem;
  padding: .5rem .25rem;
  border-bottom: 2px solid var(--primary);
}
.grupo-prod-icono { font-size: 1.1rem; line-height: 1; }
.grupo-prod-titulo {
  font-size: .95rem; font-weight: 800;
  color: var(--primary); letter-spacing: .01em; flex: 1;
}
.grupo-prod-count {
  font-size: .75rem; font-weight: 600;
  color: var(--gray-400);
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: .1rem .6rem;
}
html.light .grupo-prod-titulo { color: var(--primary); }
html.light .grupo-prod-header { border-bottom-color: var(--primary); }

/* ── Agrupación movimientos por tipo de producto ──── */
.mv-grupo { margin-bottom: .5rem; }
.mv-grupo-header {
  display: flex; align-items: center; gap: .55rem;
  padding: .4rem .75rem;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: .375rem .375rem 0 0;
  cursor: pointer;
  user-select: none;
}
.mv-grupo-header:hover { background: var(--bg-card); }
.mv-grupo-titulo {
  font-size: .85rem; font-weight: 700;
  color: var(--text); flex: 1;
}
.mv-grupo-count {
  font-size: .72rem; font-weight: 600;
  color: var(--gray-400);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: .1rem .5rem;
}
.mv-grupo-chevron { font-size: .72rem; color: var(--gray-400); min-width: .8rem; text-align: center; }
.mv-grupo-body .data-table { border-top: none; border-radius: 0 0 .375rem .375rem; }

/* ── Módulo Balances ──────────────────────────────── */
.report-header { margin-bottom: .75rem; }
.report-titulo { font-size: 1.05rem; font-weight: 800; margin: 0 0 .15rem; color: var(--text); }
.report-sub    { font-size: .8rem; color: var(--gray-400); }
.report-table  { font-size: .82rem; }
.report-table .row-grupo, .data-table .row-grupo    { font-weight: 700; background: color-mix(in srgb, var(--primary) 16%, transparent); font-size: .8rem; letter-spacing: .03em; }
.report-table .row-grupo td, .data-table .row-grupo td {
  border-top: 2px solid var(--primary); border-bottom: 1px solid var(--border-md, var(--border));
}
.data-table .row-grupo.ge-grupo-toggle { cursor: pointer; user-select: none; }
.data-table .row-grupo.ge-grupo-toggle:hover td { background: color-mix(in srgb, var(--primary) 24%, transparent); }
.ge-chevron { display: inline-block; font-size: .75em; opacity: .65; transition: transform .15s; }
.ge-chevron.is-collapsed { transform: rotate(-90deg); }
.report-table .row-subtotal, .data-table .row-subtotal{ font-weight: 600; background: color-mix(in srgb, var(--success) 14%, transparent); font-size: .8rem; }
.report-table .row-subtotal td, .data-table .row-subtotal td {
  border-top: 1px solid var(--success); border-bottom: 3px double var(--success);
}
/* Separador mudo entre el subtotal de un grupo y el título del siguiente — sin esto, la
   doble raya verde del cierre tocaba directo la franja celeste del próximo título. */
.report-table .row-spacer td, .data-table .row-spacer td { height: 10px; padding: 0; border: none; background: transparent; }
/* Fila elegida en el drill-down de movimientos de Existencias (click para marcar antes de
   apretar F4) — mismo token que ya usa la fila activa del selector de empresa. */
.data-table tr.ge-fila-mov.row-activa td { background: var(--bg-active); }
.report-table .row-total   { font-weight: 800; background: var(--bg-hover); font-size: .9rem; }
.report-table .row-nivel2  { font-weight: 700; }
.report-seccion-titulo {
  padding: .5rem .75rem;
  font-weight: 700;
  font-size: .85rem;
  background: var(--bg-secondary);
  border-bottom: 2px solid var(--primary);
  letter-spacing: .04em;
}
.balance-general-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
.bim-usd { font-size: .75rem; }

@media (max-width: 900px) {
  .balance-general-grid { grid-template-columns: 1fr; }
}
@media print {
  .no-print { display: none !important; }
  .balance-general-grid { grid-template-columns: 1fr 1fr; gap: .5rem; }
  .report-titulo { font-size: 13pt; }
  .report-table  { font-size: 9pt; }
  .card { border: 1px solid #ccc !important; box-shadow: none !important; }
}

/* ── Activos Fijos ──────────────────────────────────── */
.dep-bar-wrap {
  display: flex; align-items: center; gap: .4rem; min-width: 90px;
}
.dep-bar-wrap span { font-size: .8rem; white-space: nowrap; color: var(--text-muted); }
.dep-bar {
  height: 6px; border-radius: 3px; flex-shrink: 0;
  background: linear-gradient(90deg, var(--success), var(--warning));
  transition: width .3s;
}

/* ── Cards ────────────────────────────────────────── */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: blur(4px);
  transition: box-shadow .2s, border-color .2s;
}
.card:hover { border-color: var(--border-md); }
.card-title { font-size: .95rem; font-weight: 700; margin-bottom: 1rem; color: var(--gray-700); }
.p-4  { padding: 1rem; }
.p-5  { padding: 1.25rem; }
.p-0  { padding: 0; }
.mb-4 { margin-bottom: 1rem; }
.mt-2 { margin-top: .5rem; }
.mt-3 { margin-top: .75rem; }
.mt-4 { margin-top: 1rem; }
.ml-4 { margin-left: 1rem; }
.overflow-hidden { overflow: hidden; }

/* ── Forms ────────────────────────────────────────── */
.form-group { display: flex; flex-direction: column; gap: .25rem; position: relative; }
.label { font-size: .8rem; font-weight: 600; color: var(--gray-600); }
label { font-size: .8rem; font-weight: 600; color: var(--gray-600); }
/* `.form-control` e `input:not([type])` van en la lista a propósito: los campos se
   estilaban SOLO por tipo, así que un `<input class="form-control">` sin atributo
   `type` no matcheaba ninguna regla y quedaba con el estilo crudo del navegador —una
   cajita blanca finita— al lado de sus hermanos bien formateados. Eran 528 campos en
   125 pantallas. El default de `type` es "text" para el navegador, pero NO para el
   selector de atributo: `input[type="text"]` exige que el atributo esté escrito. */
.input, .form-control, input:not([type]), input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], textarea, select {
  width: 100%; padding: .5rem .75rem;
  border: 1px solid var(--border-md);
  border-radius: var(--radius);
  font-size: .875rem; color: var(--gray-700);
  background: var(--bg-input);
  outline: none;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
  font-family: inherit;
}
.input:focus, .form-control:focus, input:not([type]):focus, input[type="text"]:focus, input[type="email"]:focus,
input[type="password"]:focus, input[type="number"]:focus,
input[type="date"]:focus, textarea:focus, select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary-glow-s), var(--glow-sm);
}
.input::placeholder, .form-control::placeholder { color: var(--gray-400); }
.input[disabled], input:disabled, select:disabled, textarea:disabled { background: var(--bg-surface); cursor: not-allowed; color: var(--gray-400); opacity: .6; }
textarea.input { resize: vertical; }
select.input { cursor: pointer; }
.select-sm { width: auto; min-width: 140px; }
/* Inputs de fecha COMPACTOS: no ocupan todo el ancho. Al ser inline-block con
   ancho automático, un rango Desde/Hasta queda uno al lado del otro en cualquier
   pantalla (antes se estiraban al 100% y quedaban apilados, ocupando mucho). */
input[type="date"] {
  width: auto;
  min-width: 148px;
  max-width: 100%;
  vertical-align: middle;
}
/* En una grilla de formulario (grid-2/grid-3) sí conviene que llene su celda. */
.grid-2 input[type="date"], .grid-3 input[type="date"], .form-group-full input[type="date"] { width: 100%; }
/* El ícono nativo (▾ calendario) que abre el selector de fecha/mes es oscuro por defecto del
   navegador: contra un input de fondo oscuro se vuelve casi invisible — hay un botón ahí,
   pero no se nota. Se invierte en tema oscuro y se le suma un fondo redondeado al pasar el
   mouse, para que se lea como clickeable en los dos temas. */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator {
  cursor: pointer; padding: .2rem; border-radius: 4px; opacity: .85;
}
html:not(.light) input[type="date"]::-webkit-calendar-picker-indicator,
html:not(.light) input[type="month"]::-webkit-calendar-picker-indicator {
  filter: invert(1) brightness(1.6);
}
input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="month"]::-webkit-calendar-picker-indicator:hover {
  background: color-mix(in srgb, var(--primary) 22%, transparent); opacity: 1;
}
.error-msg { color: var(--danger); font-size: .8rem; margin-top: .25rem; }

/* Filtros */
.filter-select, .filter-input {
  padding: .4rem .7rem;
  border: 1px solid var(--border-md);
  border-radius: var(--radius);
  font-size: .825rem; color: var(--gray-600);
  background: var(--bg-input);
  outline: none; cursor: pointer;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
  font-family: inherit;
}
.filter-select:focus, .filter-input:focus {
  border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-glow-s);
}

/* minmax(0,1fr) + min-width:0 = las columnas se encogen en vez de desbordar
   (si no, una tabla ancha empuja la 2ª columna fuera de la pantalla). */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; }
.grid-3 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; }
.grid-2 > *, .grid-3 > * { min-width: 0; }
/* Concepto largo truncado con "…" para que el monto quede siempre visible
   (el texto completo se ve en el tooltip y con doble clic en la fila). */
.cnc-concepto { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La referencia del extracto ("84 415884 38-CEN-SYS") se partía en 3 renglones y
   estiraba TODA la fila. En una línea, con puntos suspensivos; el valor completo
   queda en el title (hover). Concepto más angosto para que entren monto+ref+botón. */
.data-table.compacta .cnc-concepto { max-width: 150px; }
.cnc-ref { display: block; max-width: 146px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.col-span-2 { grid-column: span 2; }
.form-grid  { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px,1fr)); gap: 1rem; }
.filters-row, .filters-bar { display: flex; gap: .75rem; flex-wrap: wrap; align-items: flex-end; }

/* Acción rápida en tabla — botones icono */
.btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--radius-sm);
  background: none; border: 1px solid transparent;
  cursor: pointer; font-size: .9rem; transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s; font-family: inherit;
}
.btn-icon:hover { background: var(--bg-hover); border-color: var(--border-md); }
.btn-icon.text-success { color: var(--success); }
.btn-icon.text-success:hover { background: color-mix(in srgb, var(--success) 12%, transparent); border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.btn-icon.text-danger  { color: var(--danger); }
.btn-icon.text-danger:hover  { background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
/* Dentro de una fila de tabla el área táctil de 36px engorda cada renglón del
   sistema — las tablas son densas por diseño. Vuelve al tamaño anterior SOLO ahí;
   en toolbars/tarjetas/modales queda el 36px de arriba. */
.data-table .btn-icon { width: 28px; height: 28px; }

/* Form group que ocupa todo el ancho en grid */
.form-group-full { grid-column: 1 / -1; }

/* ── Formulario de CARGA (libros IVA, diario, asientos) ────────────────────
   Pantallas donde se tipea todo el día: campos más altos y con letra más grande
   para leer de un vistazo lo que se está cargando, en vez de forzar la vista sobre
   una cajita de 30px. Se aplica al contenedor y baja a todos sus campos. */
.form-carga input, .form-carga select, .form-carga textarea,
.form-carga .form-control, .form-carga .cb-input {
  font-size: 1rem;
  padding: .6rem .8rem;
  min-height: 2.75rem;
}
.form-carga label, .form-carga .label { font-size: .85rem; margin-bottom: .1rem; }
/* Números alineados a la derecha y con dígitos de ancho fijo: así las columnas de
   importes se leen en vertical, que es como se controla una carga. */
.form-carga input[type="number"] { text-align: right; font-variant-numeric: tabular-nums; }
/* En la grilla de líneas los campos van más compactos: entran muchas columnas. */
.form-carga .tabla-lineas input, .form-carga .tabla-lineas select,
.form-carga .tabla-lineas .cb-input { font-size: .95rem; min-height: 2.4rem; padding: .45rem .6rem; }

/* ── Buttons ──────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .5rem 1rem; border-radius: var(--radius);
  font-size: .875rem; font-weight: 500; cursor: pointer;
  border: 1px solid transparent;
  transition: color .2s, background-color .2s, border-color .2s, box-shadow .2s, transform .2s, opacity .2s; text-decoration: none;
  white-space: nowrap; font-family: inherit;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-d) 100%);
  color: #05101f;
  font-weight: 600;
  box-shadow: 0 2px 12px var(--primary-glow);
}
.btn-primary:hover:not(:disabled) {
  box-shadow: 0 4px 20px var(--primary-glow), var(--glow-md);
  transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) { transform: translateY(0); }
.btn-secondary {
  background: color-mix(in srgb, var(--primary) 8%, transparent); color: var(--gray-600);
  border-color: var(--border-md);
}
.btn-secondary:hover:not(:disabled) { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: var(--primary); color: var(--primary); }
.btn-danger {
  background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 30%, transparent);
}
.btn-danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 20%, transparent); box-shadow: 0 2px 12px color-mix(in srgb, var(--danger) 20%, transparent); }
.btn-ghost { background: transparent; color: var(--gray-500); border-color: transparent; }
.btn-ghost:hover:not(:disabled) { background: var(--bg-hover); color: var(--gray-700); }
.btn-success {
  background: color-mix(in srgb, var(--success) 12%, transparent); color: var(--success);
  border-color: color-mix(in srgb, var(--success) 30%, transparent);
}
.btn-success:hover:not(:disabled) { background: color-mix(in srgb, var(--success) 20%, transparent); }
.btn-sm  { padding: .25rem .625rem; font-size: .8rem; }
.btn-xs  { padding: .15rem .4rem !important; font-size: .7rem !important; }
.btn-full { width: 100%; justify-content: center; }

/* Botón grande con relieve 3D */
.btn-xl {
  padding: .9rem 2.75rem;
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: .03em;
}
.btn-relieve {
  border-bottom-width: 3px !important;
  box-shadow: 0 4px 0 rgba(0,0,0,.35), 0 6px 18px var(--primary-glow) !important;
  transform: translateY(-1px);
  transition: color .15s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease, transform .15s ease, opacity .15s ease !important;
}
.btn-relieve:hover:not(:disabled) {
  transform: translateY(-3px) !important;
  box-shadow: 0 6px 0 rgba(0,0,0,.3), 0 10px 28px var(--primary-glow) !important;
}
.btn-relieve:active:not(:disabled) {
  transform: translateY(2px) !important;
  box-shadow: 0 1px 0 rgba(0,0,0,.3), 0 2px 8px var(--primary-glow-s) !important;
  border-bottom-width: 1px !important;
}

/* ── Tables ───────────────────────────────────────── */
.table-container { overflow-x: auto; border-radius: var(--radius); }
/* Red de seguridad para las ~80 cajas que arman su propio scroll con estilo en línea
   (`<div style="max-height:38vh;overflow:auto"><table…>`): ahí el eje horizontal SÍ se
   usa (tablas anchas), así que no se puede tapar — lo que se hace es reservar el carril
   de la barra vertical para que su aparición no achique el ancho y encienda la horizontal
   en cascada (el titileo que reportó el usuario, 8-sep-2026). `scrollbar-gutter` no tiene
   efecto sobre lo que no scrollea, así que es inofensivo donde no corresponde. Se hace acá
   y no editando 80 archivos porque el patrón es siempre el mismo. */
[style*="overflow:auto"], [style*="overflow: auto"],
[style*="overflow-y:auto"], [style*="overflow-y: auto"] { scrollbar-gutter: stable; }
.data-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.data-table thead { background: color-mix(in srgb, var(--primary) 6%, transparent); }
.data-table th {
  padding: .46rem .8rem; text-align: left;
  font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--primary);
  border-bottom: 1px solid var(--border-md);
  white-space: nowrap;
}
/* Tabla COMPACTA: renglones bajos para ver muchas filas de una (conciliación
   bancaria, donde hay decenas de pendientes y se trabaja comparando). */
.data-table.compacta th { padding: .2rem .45rem; font-size: .62rem; }
.data-table.compacta td { padding: .08rem .45rem; font-size: .74rem; line-height: 1.15; }
/* Nada dentro de la fila debe estirarla: el concepto y los botones van a la altura
   del renglón, no al alto por defecto de un botón. */
.data-table.compacta .cnc-concepto { line-height: 1.15; }
.data-table.compacta .btn { padding: .05rem .35rem; font-size: .68rem; line-height: 1.2; }

/* Encabezado fijo dentro de una tabla scrolleable (ej. conciliación bancaria).
   Necesita fondo OPACO: el de .data-table thead es translúcido y las filas se
   verían por debajo al scrollear. */
.data-table thead.sticky-head th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-card, #0f172a);
}
html.light .data-table thead.sticky-head th { background: #e6faf6; }

.data-table td {
  padding: .42rem .8rem; line-height: 1.35;
  border-bottom: 1px solid color-mix(in srgb, var(--primary) 6%, transparent);
  vertical-align: middle; color: var(--gray-600);
}
.data-table tbody tr { transition: background .12s; }
.data-table tbody tr:hover { background: var(--bg-hover); }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tfoot td { background: color-mix(in srgb, var(--primary-d) 5%, transparent); font-weight: 700; border-top: 1px solid var(--border-md); color: var(--gray-700); }
/* ── Planilla tipo Excel: matriz de filas × columnas ──────────────────────────
   Pedido del usuario (3-sep-2026) para Ganadería → Ubicación y traslados: "que se vea
   como una planilla Excel con filas y columnas y se pueda ver bien". Antes las cantidades
   por categoría iban como texto corrido que envolvía en varias líneas — imposible de
   comparar entre ubicaciones de un vistazo.

   Lo que la hace sentir una planilla (y no una tabla más):
   · La PRIMERA columna (la etiqueta de la fila) queda fija al scrollear horizontal — sin
     eso, con muchos potreros dejás de saber de qué categoría es cada número.
   · El encabezado queda fijo al scrollear vertical (`sticky-head`, ya existía).
   · Los números en `.mono`, que ya trae tabular-nums: las columnas de dígitos alinean.
   Va SIEMPRE dentro de un .table-container (overflow-x:auto): las columnas crecen con la
   cantidad de ubicaciones, así que la tabla tiene que poder scrollear sola sin empujar la
   página (.main-content tiene overflow-x:hidden como tope). */
.data-table.planilla th:first-child,
.data-table.planilla td:first-child {
  position: sticky; left: 0; z-index: 1;
  /* --bg-surface y no --bg-card: la columna fija es la pared que tapa a las celdas que
     pasan por debajo al scrollear, así que tiene que ser 100% opaca. --bg-card lleva alpha
     (0.92 en oscuro, 0.97 en claro) y dejaba ver el fantasma del texto de atrás. */
  background: var(--bg-surface);
  border-right: 1px solid var(--border-strong);
}
.data-table.planilla thead th:first-child { z-index: 3; background: var(--bg-surface); }
/* La celda fija tiene fondo propio, así que el hover de la fila no la alcanzaría sola —
   se repite acá con el mismo tinte, mezclado sobre el opaco para no perder la pared. */
.data-table.planilla tbody tr:hover td:first-child { background: color-mix(in srgb, var(--primary) 7%, var(--bg-surface)); }
.data-table.planilla tfoot td:first-child { background: var(--bg-surface); }
/* Celda en cero: se deja vacía (como en Excel) pero el punto marca que la fila existe y
   que ahí hay un cero de verdad, no un dato que falta. */
.data-table.planilla .celda-cero { color: var(--gray-400); }

.row-warning   { background: color-mix(in srgb, var(--warning) 6%, transparent) !important; }
.row-highlight { background: color-mix(in srgb, var(--primary) 7%, transparent) !important; }
.row-danger    { background: color-mix(in srgb, var(--danger) 7%, transparent) !important; }
.row-muted     { opacity: .5; }
.text-right  { text-align: right; }
.data-table th.text-right { text-align: right; }
.text-center { text-align: center; }
.data-table th.text-center { text-align: center; }
.text-left   { text-align: left; }
.text-sm     { font-size: .8rem; }
.text-xs     { font-size: .72rem; }
.text-muted  { color: var(--gray-400); }
.text-gray   { color: var(--gray-400); }
.text-red    { color: var(--danger); }
/* Saldo NEGATIVO en una planilla de existencias — rojo y negrita, para encontrarlo de un
   vistazo y corregirlo (pedido del usuario, 3-sep-2026: el sistema ya no frena el
   movimiento que deja la existencia en negativo, lo deja pasar y lo marca acá). */
.saldo-negativo { color: var(--danger); font-weight: 800; }
.text-green  { color: var(--success); }
.text-orange { color: var(--warning); }

/* ── Columnas de entrada/salida (planillas de hacienda) ──────────────────────────
   Un cuadro con entradas y salidas mezcladas en la misma tabla se lee mejor si se
   nota, de un vistazo, dónde arranca cada bloque — sin depender del rótulo de la
   columna. */
.data-table .col-entrada { background: color-mix(in srgb, var(--success) 8%, transparent); }
.data-table .col-salida  { background: color-mix(in srgb, var(--danger) 8%, transparent); }
.data-table thead .col-entrada, .data-table tfoot .col-entrada { background: color-mix(in srgb, var(--success) 14%, transparent); }
.data-table thead .col-salida,  .data-table tfoot .col-salida  { background: color-mix(in srgb, var(--danger) 14%, transparent); }
.mono        { font-family: var(--font-mono); }
.fw-600      { font-weight: 600; }
.fw-700      { font-weight: 700; }

/* ── Badges ───────────────────────────────────────── */
.badge {
  display: inline-flex; align-items: center;
  padding: .2rem .55rem; border-radius: 9999px;
  font-size: .7rem; font-weight: 600; white-space: nowrap;
}
.badge-success, .badge-green  { background: color-mix(in srgb, var(--success) 15%, transparent); color: var(--success); border: 1px solid color-mix(in srgb, var(--success) 25%, transparent); }
.badge-primary, .badge-blue   { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); border: 1px solid var(--border); }
.badge-warning, .badge-yellow { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); border: 1px solid color-mix(in srgb, var(--warning) 25%, transparent); }
.badge-danger, .badge-red     { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent); }
.badge-gray, .badge-secondary { background: color-mix(in srgb, var(--gray-400) 15%, transparent); color: var(--gray-500); border: 1px solid color-mix(in srgb, var(--gray-400) 20%, transparent); }
.badge-purple                 { background: color-mix(in srgb, var(--purple) 14%, transparent); color: var(--purple); border: 1px solid color-mix(in srgb, var(--purple) 25%, transparent); }
.badge-orange                 { background: rgba(251,146,60,.14); color: #fb923c; border: 1px solid rgba(251,146,60,.25); }
.badge-info                   { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); border: 1px solid var(--border); }

/* ── KPIs / Dashboard ─────────────────────────────── */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.kpi-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: .25rem;
  transition: color .2s, background-color .2s, border-color .2s, box-shadow .2s, transform .2s, opacity .2s; position: relative; overflow: hidden;
}
.kpi-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--primary), transparent);
  opacity: 0; transition: opacity .2s;
}
.kpi-card:hover::before { opacity: 1; }
.kpi-card:hover { border-color: var(--border-md); box-shadow: var(--shadow-lg), var(--glow-sm); }
.kpi-card.kpi-alert   { border-left: 3px solid var(--danger); }
.kpi-card.kpi-warning { border-left: 3px solid var(--warning); }
.kpi-label { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--gray-400); }
.kpi-value { font-size: 1.4rem; font-weight: 700; color: var(--primary); font-feature-settings: 'tnum'; text-shadow: var(--glow-sm); }
.kpi-sub   { font-size: .72rem; color: var(--gray-400); }
.kpi-link  { font-size: .72rem; color: var(--primary); text-decoration: none; }
.dashboard-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.dashboard-row .flex-1 { flex: 1; min-width: 300px; }

/* ── Tabs ─────────────────────────────────────────── */
.tabs { display: flex; gap: .25rem; margin-bottom: 1.25rem; border-bottom: 1px solid var(--border); padding-bottom: 0; }
.tab-btn {
  padding: .5rem 1.1rem; font-size: .85rem; font-weight: 600;
  background: none; border: none; cursor: pointer;
  color: var(--gray-500); border-radius: var(--radius) var(--radius) 0 0;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s; border-bottom: 2px solid transparent;
  margin-bottom: -1px; font-family: inherit;
}
.tab-btn:hover { color: var(--primary); }
.tab-btn.active {
  color: var(--primary); border-bottom-color: var(--primary);
  background: var(--bg-active); text-shadow: var(--glow-sm);
}

/* ── Modals ───────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(3, 6, 18, 0.75);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000; padding: 1rem;
}
.modal-box, .modal {
  background: var(--bg-modal);
  border: 1px solid var(--border-md);
  border-radius: 14px;
  width: 100%; max-width: min(94vw, 460px); max-height: 94vh;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg), var(--glow-sm);
  backdrop-filter: blur(12px);
}
/* min(vw, px): el techo en px no cambia en pantallas grandes (un modal no necesita
   crecer solo porque el monitor es de 32"), pero en pantallas angostas cede antes de
   desbordar — mismo patrón que ya probó gan-partes.js a mano, acá centralizado como
   default para que las pantallas que usan estas clases no tengan que resolverlo cada
   una por su cuenta. Antes eran max-width fijos en px sin resguardo (1-sep-2026). */
.modal-lg  { max-width: min(92vw, 640px); }
.modal-xl  { max-width: min(94vw, 900px); }
/* Para modales de grilla de detalle (asientos, subdiarios, movimientos...) que antes
   hackeaban su propio ancho con style.cssText — ver public/js/modules/movimientos.js y
   hermanos, migrados a size:'2xl' el 1-sep-2026. */
.modal-2xl { max-width: min(96vw, 1320px); }
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 6%, transparent) 0%, transparent 100%);
}
.modal-header h2 { font-size: 1rem; font-weight: 700; color: var(--gray-700); }
.modal-close {
  background: none; border: none; font-size: 1.3rem;
  cursor: pointer; color: var(--gray-400); line-height: 1;
  padding: .3rem; border-radius: 6px;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
}
.modal-close:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.modal-header-btns { display: flex; align-items: center; gap: .15rem; }
/* Pedido del usuario (21-ago-2026): "botón de minimizar sin cerrar" — mismo look que
   .modal-close (mismo tamaño, mismo hover), color de acento en vez de rojo: cerrar
   descarta, minimizar no. */
.modal-min {
  background: none; border: none; font-size: 1.1rem;
  cursor: pointer; color: var(--gray-400); line-height: 1;
  padding: .3rem; border-radius: 6px;
  transition: color .15s, background-color .15s;
}
.modal-min:hover { color: var(--primary); background: var(--primary-glow-s); }
/* La pastillita flotante que queda cuando un modal está minimizado — el modal sigue
   vivo en el DOM (nada de lo tipeado se pierde), solo oculto; esto es lo único visible
   mientras tanto, para volver a abrirlo. */
.modal-min-dock {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 1010;
  display: flex; flex-direction: column-reverse; gap: .5rem; align-items: flex-end;
}
.modal-min-pastilla {
  display: flex; align-items: center; gap: .5rem;
  background: var(--bg-modal); border: 1px solid var(--border-md); border-radius: 999px;
  padding: .55rem 1rem; font: inherit; font-size: .85rem; font-weight: 600; color: var(--gray-700);
  cursor: pointer; box-shadow: var(--shadow-lg), var(--glow-sm);
  max-width: 260px;
}
.modal-min-pastilla span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal-min-pastilla:hover { border-color: var(--primary); color: var(--primary); }
/* Las DOS reglas juntas matan el parpadeo de barras que reportó el usuario (8-sep-2026),
   el mismo que ya se había arreglado en .main-content:
   · overflow-x:hidden EXPLÍCITO — sin esto la especificación CSS obliga a que el eje X
     compute como "auto" solo por tener overflow-y:auto, y aparece una barra horizontal
     fantasma: la vertical roba ~9px de ancho → el contenido ya no entra a lo ancho →
     aparece la horizontal → roba alto → sobra menos alto → se realimenta y TITILA.
     El contenido ancho de verdad (tablas) va en .table-container, que trae su propio
     overflow-x:auto, así que acá no se pierde nada.
   · scrollbar-gutter:stable — reserva el carril de la barra vertical SIEMPRE, así un modal
     cuyo contenido crece en vivo (la vista previa de Préstamos, que arranca en un párrafo
     y pasa a una tabla) no corre el contenido cuando la barra entra o sale. */
.modal-body    { overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable; padding: 1.5rem; flex: 1; }
.modal-footer  {
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end; gap: .75rem;
  flex-shrink: 0;
  /* Modales con 3 botones ("Cancelar" + dos de guardar, ej. "Grabar y seguir") no
     entraban en una sola fila en el modal chico (460px) y el último quedaba cortado
     contra el borde. Sin flex-wrap el footer NUNCA bajaba de línea: desbordaba en
     silencio en vez de acomodarse. */
  flex-wrap: wrap;
}

/* ── Alerts ───────────────────────────────────────── */
.alert { padding: .75rem 1rem; border-radius: var(--radius); font-size: .875rem; margin-bottom: 1rem; }
.alert-warning { background: color-mix(in srgb, var(--warning) 10%, transparent); color: var(--warning); border: 1px solid color-mix(in srgb, var(--warning) 25%, transparent); }
.alert-error   { background: color-mix(in srgb, var(--danger) 10%, transparent); color: var(--danger); border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent); }
.alert-success { background: color-mix(in srgb, var(--success) 10%, transparent); color: var(--success); border: 1px solid color-mix(in srgb, var(--success) 25%, transparent); }

/* Estado de Flujo de Efectivo (NIC 7) */
.fe-estado .fe-sec td       { font-weight: 700; padding-top: 14px; letter-spacing: .03em; color: var(--accent, #38bdf8); }
.fe-estado .fe-subtotal td  { border-top: 1px solid color-mix(in srgb, var(--gray-500) 28%, transparent); }
.fe-estado .fe-total td     { border-top: 2px solid color-mix(in srgb, var(--gray-500) 50%, transparent); border-bottom: 2px solid color-mix(in srgb, var(--gray-500) 50%, transparent); }
.fe-estado .fe-linea:hover td { background: color-mix(in srgb, var(--primary-d) 7%, transparent); }

/* Flujo de caja proyectado */
.pf-linea:hover td { background: color-mix(in srgb, var(--primary-d) 7%, transparent); }
.pf-alerta td { background: color-mix(in srgb, var(--danger) 10%, transparent); }
.pf-alerta-naranja td { background: color-mix(in srgb, var(--orange) 12%, transparent); }
/* Precio por cabeza editable en el mes ABIERTO del parte (8-sep-2026): una categoría que
   la planilla de esa estancia nunca tuvo llega sin precio y su Inicial Gs. queda en 0. Se
   avisa con el "＋ precio" en naranja en vez de un 0 mudo que se lee como dato cargado. */
.pv-precio {
  background: none; border: none; padding: 0; font: inherit; color: inherit;
  cursor: pointer; border-bottom: 1px dashed var(--border-md);
}
.pv-precio:hover { color: var(--primary); border-bottom-color: var(--primary); }
.pv-precio-falta { color: var(--orange); font-weight: 700; border-bottom-color: var(--orange); }
.alert-info    { background: color-mix(in srgb, var(--primary) 8%, transparent); color: var(--primary); border: 1px solid var(--border-md); }

/* ── Toast ────────────────────────────────────────── */
.toast-container { position: fixed; top: 1rem; right: 1rem; z-index: 9999; display: flex; flex-direction: column; gap: .5rem; }
.toast {
  padding: .75rem 1.25rem; border-radius: var(--radius);
  font-size: .875rem; color: var(--white);
  box-shadow: var(--shadow-lg);
  animation: slideIn .22s cubic-bezier(.34,1.26,.64,1);
  max-width: 340px;
  border: 1px solid rgba(255,255,255,.1);
  backdrop-filter: blur(8px);
  font-weight: 500;
}
.toast-success { background: color-mix(in srgb, var(--success-d) 90%, transparent); box-shadow: 0 4px 20px color-mix(in srgb, var(--success-d) 30%, transparent); }
.toast-error   { background: color-mix(in srgb, var(--danger-d) 90%, transparent); box-shadow: 0 4px 20px color-mix(in srgb, var(--danger-d) 30%, transparent); }
.toast-warning { background: rgba(245,158,11,.9); box-shadow: 0 4px 20px rgba(245,158,11,.3); color: #1a1000; }
/* `info` se usaba en varias pantallas sin tener estilo: quedaba texto blanco sobre
   un fondo transparente, ilegible. Toma el acento de la paleta activa. */
.toast-info    { background: var(--primary, rgba(59,130,246,.9)); box-shadow: 0 4px 20px rgba(59,130,246,.3); color: #fff; }
@keyframes slideIn { from { transform: translateX(110%) scale(.9); opacity: 0; } to { transform: translateX(0) scale(1); opacity: 1; } }

/* ── Spinner ──────────────────────────────────────── */
.spinner { display: inline-block; width: 1rem; height: 1rem; border: 2px solid color-mix(in srgb, var(--primary-d) 20%, transparent); border-top-color: var(--primary); border-radius: 50%; animation: spin .6s linear infinite; }
.spinner-lg { width: 2rem; height: 2rem; border-width: 3px; }
.loading { color: var(--gray-400); padding: 2rem; text-align: center; font-size: .9rem; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Misc utilities ───────────────────────────────── */
.hidden { display: none !important; }
.flex   { display: flex; }
.flex-1 { flex: 1; }
.justify-center { justify-content: center; }
/* Faltaban estas dos: se usan (junto con .flex) en 246 lugares del código —headers
   "título + acción" tipo <div class="flex justify-between items-center">— pero sin
   definición nunca separaban ni centraban nada. Con solo .flex puesta, el div SÍ es
   flex, pero cae en flex-start/stretch por defecto: el título y lo que va al lado
   quedan pegados, como "DetalleAgregá líneas con el +…" en gan-movimientos.js. */
.justify-between { justify-content: space-between; }
.items-center { align-items: center; }
.w-full { width: 100%; }
.py-10  { padding-top: 2.5rem; padding-bottom: 2.5rem; }
.py-16  { padding-top: 4rem; padding-bottom: 4rem; }
.gap-1  { gap: .25rem; }
.gap-2  { gap: .5rem; }
.gap-3  { gap: .75rem; }
.ml-auto { margin-left: auto; }
.mb-1 { margin-bottom: .25rem; }
.mb-2 { margin-bottom: .5rem; }
.mb-3 { margin-bottom: .75rem; }
.section-title { display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem; }

.empty-state {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; padding: 4rem 1rem;
  color: var(--gray-400); gap: .5rem; text-align: center;
}
.empty-state h2, .empty-state h3 { font-size: 1rem; font-weight: 600; color: var(--gray-500); }
.empty-state p { font-size: .875rem; }

.pagination {
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem 1rem; justify-content: flex-end;
  border-top: 1px solid var(--border);
}
.page-info  { font-size: .8rem; color: var(--gray-500); }

/* ── Info grid ────────────────────────────────────── */
.info-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: .75rem; background: color-mix(in srgb, var(--primary-d) 4%, transparent);
  padding: 1rem; border-radius: var(--radius);
  border: 1px solid var(--border);
}
.info-label { display: block; font-size: .7rem; font-weight: 700; text-transform: uppercase; color: var(--gray-400); margin-bottom: .2rem; letter-spacing: .05em; }
.info-val   { font-size: .875rem; color: var(--gray-700); }

/* ── Autocomplete ─────────────────────────────────── */
.autocomplete-list {
  position: absolute; z-index: 100;
  background: var(--bg-modal);
  border: 1px solid var(--border-md);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg), var(--glow-sm);
  max-height: 220px; overflow-y: auto; overflow-x: hidden;   /* ver .modal-body: sin el eje X explícito titila */
  width: 100%;
}
.ac-item { padding: .5rem .75rem; cursor: pointer; font-size: .875rem; color: var(--gray-600); transition: color .1s, background-color .1s, border-color .1s, box-shadow .1s, transform .1s, opacity .1s; }
.ac-item:hover { background: var(--bg-hover); color: var(--primary); }

/* ── Factura / Order item rows ────────────────────── */
.factura-item-row { display: flex; gap: .5rem; align-items: center; margin-bottom: .5rem; flex-wrap: wrap; }
.ajuste-item { display: grid; grid-template-columns: 1fr 100px 120px; gap: .5rem; margin-bottom: .5rem; }

/* ── Tipo cambio ──────────────────────────────────── */
.tc-row { display: flex; gap: 1rem; align-items: center; padding: .5rem 0; border-bottom: 1px solid var(--border); font-size: .875rem; }
.tc-codigo { font-weight: 700; font-family: monospace; width: 40px; color: var(--primary); }
.tc-nombre { color: var(--gray-500); flex: 1; }
.tc-compra, .tc-venta { font-family: monospace; color: var(--gray-600); }

/* ── Totales box ──────────────────────────────────── */
.totales-box { display: flex; align-items: center; padding: .75rem; background: color-mix(in srgb, var(--primary-d) 5%, transparent); border-radius: var(--radius); font-size: .9rem; border: 1px solid var(--border); }
.iva-resumen { display: flex; gap: 1.5rem; padding: .5rem; background: color-mix(in srgb, var(--primary-d) 4%, transparent); border-radius: var(--radius); font-size: .8rem; color: var(--gray-500); }

/* ── Confirm dialog ───────────────────────────────── */
.confirm-overlay { position: fixed; inset: 0; background: rgba(3,6,18,.75); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; z-index: 2000; }
.confirm-box { background: var(--bg-modal); border: 1px solid var(--border-md); border-radius: 14px; padding: 1.5rem; max-width: 380px; width: 90%; box-shadow: var(--shadow-lg), var(--glow-sm); }
.confirm-box p { font-size: .95rem; margin-bottom: 1.25rem; color: var(--gray-600); }
.confirm-actions { display: flex; gap: .75rem; justify-content: flex-end; }

/* ── Import Excel ─────────────────────────────────── */
.import-instrucciones { background: color-mix(in srgb, var(--primary) 6%, transparent); border: 1px solid var(--border-md); border-radius: var(--radius); padding: 1rem; margin-bottom: 1rem; color: var(--gray-600); }
.import-cols-demo { display: flex; gap: .5rem; margin-top: .75rem; flex-wrap: wrap; }
.import-col { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 6px; padding: .5rem .75rem; text-align: center; min-width: 120px; font-size: .8rem; color: var(--gray-600); }
.import-col-num { display: inline-block; background: var(--primary); color: #05101f; width: 20px; height: 20px; border-radius: 4px; font-size: .7rem; font-weight: 700; line-height: 20px; margin-bottom: .25rem; }
.import-drop-zone {
  border: 2px dashed var(--border-md); border-radius: 10px;
  padding: 2rem 1rem; text-align: center; cursor: pointer;
  transition: color .2s, background-color .2s, border-color .2s, box-shadow .2s, transform .2s, opacity .2s; background: color-mix(in srgb, var(--primary-d) 4%, transparent); outline: none;
}
.import-drop-zone:hover, .import-drop-zone:focus, .import-drop-zone.drag-over {
  border-color: var(--primary); background: color-mix(in srgb, var(--primary) 8%, transparent);
  box-shadow: var(--glow-sm);
}
.import-drop-icon  { font-size: 2.5rem; margin-bottom: .5rem; }
.import-drop-title { font-weight: 600; font-size: .95rem; color: var(--gray-700); }
.import-drop-sub   { font-size: .8rem; color: var(--gray-400); margin-top: .25rem; }
.import-resumen { display: flex; gap: .75rem; align-items: center; margin-bottom: .75rem; }
/* Acá el scroll horizontal SÍ hace falta (la previa de importación puede traer muchas
   columnas): se deja explícito en los dos ejes y con el carril reservado, así los dos
   conviven sin realimentarse — ver la nota de .modal-body. */
.import-preview-wrap { max-height: 280px; overflow-y: auto; overflow-x: auto; scrollbar-gutter: stable; border: 1px solid var(--border); border-radius: var(--radius); }
.import-row-error td { background: color-mix(in srgb, var(--danger) 10%, transparent) !important; color: var(--danger); }

kbd { background: var(--bg-surface); border: 1px solid var(--border-md); border-radius: 4px; padding: .1rem .35rem; font-family: monospace; font-size: .85em; color: var(--gray-600); }
.input-with-badge { position: relative; }
.input-badge { position: absolute; right: .5rem; top: 50%; transform: translateY(-50%); font-size: .65rem; color: var(--gray-400); font-family: monospace; pointer-events: none; }
.input-sm { padding: .3rem .5rem !important; font-size: .8rem !important; }
.cfg-preview-box { background: color-mix(in srgb, var(--primary-d) 4%, transparent); border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem; }
.cfg-preview-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }
.cfg-chip { display: flex; align-items: center; gap: .35rem; font-size: .8rem; color: var(--gray-600); }
.cfg-chip code { background: var(--bg-surface); border: 1px solid var(--border); padding: .1rem .35rem; border-radius: 4px; font-size: .8rem; color: var(--primary); }

/* ── Help button ──────────────────────────────────── */
.btn-help {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--primary-glow-s); color: var(--primary);
  border: 1px solid var(--border-md); cursor: pointer;
  font-weight: 700; font-size: 1rem;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
  margin-right: .5rem;
}
.btn-help:hover { background: var(--primary-glow); box-shadow: var(--glow-sm); }

/* ── Help modal ───────────────────────────────────── */
.help-overlay {
  position: fixed; inset: 0; background: rgba(3,6,18,.75);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  z-index: 3000; padding: 1rem;
}
.help-modal {
  background: var(--bg-modal); border: 1px solid var(--border-md);
  border-radius: 14px;
  width: 100%; max-width: 560px; max-height: 90vh;
  overflow: hidden; display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg), var(--glow-sm);
  backdrop-filter: blur(12px);
}
.help-header {
  display: flex; align-items: center; gap: .75rem;
  padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--border);
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 7%, transparent) 0%, transparent 100%);
}
.help-icon  { font-size: 1.5rem; flex-shrink: 0; }
.help-title { font-size: 1.05rem; font-weight: 700; color: var(--gray-700); flex: 1; }
.help-close { background: none; border: none; cursor: pointer; color: var(--gray-400); font-size: 1.1rem; padding: .25rem; border-radius: 4px; transition: color .15s; }
.help-close:hover { color: var(--danger); }
.help-body  { padding: 1.5rem; overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable; }   /* eje X explícito: ver .modal-body */
.help-desc  { color: var(--gray-500); margin-bottom: 1.25rem; line-height: 1.6; font-size: .9rem; }
.help-section-title { font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--primary); margin-bottom: .75rem; margin-top: 1.25rem; }
.help-steps { list-style: none; display: flex; flex-direction: column; gap: .6rem; }
.help-steps li { display: flex; gap: .75rem; align-items: flex-start; font-size: .875rem; color: var(--gray-600); line-height: 1.5; }
.help-step-num { width: 22px; height: 22px; border-radius: 50%; background: var(--primary); color: #05101f; font-size: .7rem; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: .1rem; }
.help-tips { list-style: none; display: flex; flex-direction: column; gap: .5rem; }
.help-tips li { font-size: .875rem; color: var(--gray-500); padding-left: 1.25rem; position: relative; line-height: 1.5; }
.help-tips li::before { content: '✓'; position: absolute; left: 0; color: var(--success); font-weight: 700; }

/* ── Perfiles de acceso ────────────────────────────── */
.perfiles-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; margin-top: 1rem; }
.perfil-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; padding: 1rem;
  display: flex; flex-direction: column; gap: .5rem;
  transition: color .2s, background-color .2s, border-color .2s, box-shadow .2s, transform .2s, opacity .2s;
}
.perfil-card:hover { border-color: var(--border-md); box-shadow: var(--shadow), var(--glow-sm); transform: translateY(-2px); }
.perfil-card.perfil-admin { border-color: color-mix(in srgb, var(--success) 30%, transparent); }
.perfil-card-header { display: flex; align-items: center; gap: .5rem; }
.perfil-nombre { font-weight: 700; font-size: 1rem; flex: 1; color: var(--gray-700); }
.perfil-desc { font-size: .85rem; color: var(--gray-500); min-height: 1.2em; }
.perfil-stats { display: flex; justify-content: space-between; font-size: .8rem; color: var(--gray-400); }
.perfil-actions { display: flex; gap: .5rem; margin-top: .25rem; }

.modulos-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: .75rem; max-height: 380px; overflow-y: auto; overflow-x: hidden;   /* eje X explícito: ver .modal-body */
  border: 1px solid var(--border); border-radius: 6px;
  padding: .75rem; background: color-mix(in srgb, var(--primary-d) 3%, transparent);
}
.modulos-seccion { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 6px; padding: .6rem; }
.modulos-seccion-header { margin-bottom: .4rem; padding-bottom: .3rem; border-bottom: 1px solid var(--border); }
.modulos-list { display: flex; flex-direction: column; gap: .25rem; }
.modulo-item { display: flex; align-items: center; gap: .35rem; font-size: .82rem; color: var(--gray-600); cursor: pointer; padding: 2px 0; }
.modulo-item:hover { color: var(--primary); }
.modulo-item input[type="checkbox"] { cursor: pointer; accent-color: var(--primary); }
.info-banner { background: color-mix(in srgb, var(--primary) 7%, transparent); border: 1px solid var(--border-md); border-radius: 6px; padding: .6rem .9rem; font-size: .875rem; color: var(--primary); }

/* ── Destellos y animaciones ─────────────────────── */

/* Keyframes */
@keyframes glow-pulse {
  0%, 100% { opacity: .35; }
  50%       { opacity: .85; }
}
@keyframes shimmer-sweep {
  0%   { transform: translateX(-200%); opacity: 0; }
  20%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { transform: translateX(300%); opacity: 0; }
}
@keyframes border-flow {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}
@keyframes dot-float {
  0%, 100% { transform: translateY(0) scale(1); opacity: .5; }
  50%       { transform: translateY(-5px) scale(1.15); opacity: 1; }
}

/* Fondo: patrón de puntos muy sutil en el área de contenido */
.main-content {
  background-image: radial-gradient(color-mix(in srgb, var(--primary) 4.5%, transparent) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* Sidebar: orbe brillante en el área del logo */
.sidebar-header {
  position: relative; overflow: hidden;
}
.sidebar-header::after {
  content: '';
  position: absolute; right: -18px; top: 50%;
  transform: translateY(-50%);
  width: 70px; height: 70px;
  background: radial-gradient(circle, color-mix(in srgb, var(--primary) 22%, transparent) 0%, transparent 68%);
  border-radius: 50%;
  animation: glow-pulse 3s ease-in-out infinite;
  pointer-events: none;
}

/* Cards: línea de brillo que cruza la parte superior */
.card {
  position: relative;
}
.card::after {
  content: '';
  position: absolute; top: 0; left: 0;
  width: 45%; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 75%, transparent), transparent);
  transform: translateX(-200%);
  animation: shimmer-sweep 6s ease-in-out infinite;
  pointer-events: none;
}
.card:nth-child(2)::after  { animation-delay: 1.8s; }
.card:nth-child(3)::after  { animation-delay: 3.6s; }
.card:nth-child(4)::after  { animation-delay: 5.2s; }
.card:nth-child(5)::after  { animation-delay: 2.4s; }

/* KPI cards: destello extra pulsante en el valor */
.kpi-value {
  animation: glow-pulse 3.5s ease-in-out infinite;
}

/* Nav link activo: texto brillante */
.nav-link.active {
  text-shadow: 0 0 14px color-mix(in srgb, var(--primary) 50%, transparent);
}
.nav-link.active::after {
  box-shadow: 0 0 10px color-mix(in srgb, var(--primary) 80%, transparent), 0 0 20px color-mix(in srgb, var(--primary) 40%, transparent);
}

/* App header: borde inferior con destello */
.app-header {
  position: relative;
}
.app-header::after {
  content: '';
  position: absolute; bottom: -1px; left: 10%; right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 60%, transparent), transparent);
  animation: glow-pulse 4s ease-in-out infinite;
  pointer-events: none;
}

/* Botón primary: brillo que recorre el botón */
.btn-primary {
  position: relative; overflow: hidden;
}
.btn-primary::after {
  content: '';
  position: absolute; top: 0; left: -100%;
  width: 40%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.18), transparent);
  transform: skewX(-15deg);
  animation: shimmer-sweep 3.5s ease-in-out infinite;
  pointer-events: none;
}

/* Logo mark: destello */
.logo-mark {
  position: relative;
  animation: glow-pulse 2.5s ease-in-out infinite;
}

/* Destellos en modal header */
.modal-header {
  position: relative; overflow: hidden;
}
.modal-header::after {
  content: '';
  position: absolute; bottom: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 40%, transparent), transparent);
  animation: glow-pulse 3s ease-in-out infinite;
  pointer-events: none;
}

/* Sidebar: tres puntos de luz decorativos */
.sidebar-footer::before {
  content: '◆  ◆  ◆';
  display: block;
  text-align: center;
  font-size: .45rem;
  color: color-mix(in srgb, var(--primary) 30%, transparent);
  letter-spacing: .4rem;
  margin-bottom: .5rem;
  animation: glow-pulse 4s ease-in-out infinite;
}

/* ── Hamburger (mobile only) ─────────────────────── */
.btn-hamburger {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  background: none; border: none;
  color: var(--gray-600); font-size: 1.3rem;
  cursor: pointer; border-radius: var(--radius);
  flex-shrink: 0; transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
}
.btn-hamburger:hover { background: var(--bg-hover); color: var(--primary); }

/* ── Volver (encabezado) ─────────────────────────────
   Era un `btn-ghost` con la flecha sola: estaba, pero nadie lo encontraba. Sin
   borde ni etiqueta, pegado al título, se leía como parte del texto. Con caja
   propia y la palabra "Volver" se ve que es un botón y qué hace. */
.btn-volver {
  display: inline-flex; align-items: center; gap: .3rem;
  font: inherit; font-size: .8rem; font-weight: 600;
  padding: .3rem .65rem; border-radius: 8px;
  background: var(--bg-hover); border: 1px solid var(--border-md);
  color: var(--gray-600); cursor: pointer;
  flex-shrink: 0; white-space: nowrap; transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .15s, opacity .15s;
}
.btn-volver:hover { background: var(--bg-active); border-color: var(--primary); color: var(--primary); }
/* En pantallas angostas queda solo la flecha: ahí el título vale más que la palabra. */
@media (max-width: 640px) { .btn-volver span { display: none; } }

/* ── Header right ────────────────────────────────── */
.header-right { display: flex; align-items: center; gap: .75rem; }

/* ── Responsive — Tablet grande (≤ 1200px) ───────────── */
@media (max-width: 1200px) {
  :root { --sidebar-w: 230px; }
  .kpi-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}

/* ── Responsive — Tablet (≤ 1024px) ─────────────────── */
@media (max-width: 1024px) {
  :root { --sidebar-w: 210px; }
  .main-content { padding: 1rem; }
  .grid-3 { grid-template-columns: 1fr 1fr; }
  .modal-xl { max-width: 95vw; }
  .data-table { font-size: .8rem; }
  .data-table th, .data-table td { padding: .36rem .6rem; }
}

/* ══════════════════════════════════════════════════════════════
   RIEL DE ÍCONOS (nav-rail) — el menú se reduce a una barra de íconos
   de 56px y se expande al pasar el mouse, flotando SOBRE el contenido
   (no lo empuja). Todo detrás de body.nav-rail: sin esa clase, el
   sidebar se comporta igual que siempre. Solo desktop (≥769px).
   ═════════════════════════════════════════════════════════════ */
@media (min-width: 769px) {
  /* El sidebar sale del flujo y flota; el contenido reserva 56px a la izquierda. */
  body.nav-rail .sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; z-index: 200;
    width: var(--rail-w, 56px); overflow: hidden;
    transition: width .16s ease, box-shadow .16s ease;
  }
  body.nav-rail .app-main { margin-left: var(--rail-w, 56px); }

  /* Al pasar el mouse (o al “espiar” con Ctrl+K) se expande sobre el contenido. */
  body.nav-rail .sidebar:hover,
  body.nav-rail .sidebar.rail-peek {
    width: var(--sidebar-w);
    box-shadow: 8px 0 34px -12px rgba(0,0,0,.5), var(--glow-sm);
  }

  /* Angosto: solo íconos. Los textos siguen en el DOM (fade), recortados por overflow. */
  body.nav-rail .sidebar .nav-txt,
  body.nav-rail .sidebar .nav-label,
  body.nav-rail .sidebar .nav-sublabel,
  body.nav-rail .sidebar .logo-text,
  body.nav-rail .sidebar .nav-search,
  body.nav-rail .sidebar .empresa-panel-info,
  body.nav-rail .sidebar .empresa-panel-cambiar,
  body.nav-rail .sidebar .sidebar-footer,
  body.nav-rail .sidebar .nav-chevron {
    opacity: 0; transition: opacity .12s ease; pointer-events: none;
    white-space: nowrap;
  }
  /* Expandido (hover o peek de Ctrl+K): reaparece todo. */
  body.nav-rail .sidebar:hover .nav-txt,
  body.nav-rail .sidebar:hover .nav-label,
  body.nav-rail .sidebar:hover .nav-sublabel,
  body.nav-rail .sidebar:hover .logo-text,
  body.nav-rail .sidebar:hover .nav-search,
  body.nav-rail .sidebar:hover .empresa-panel-info,
  body.nav-rail .sidebar:hover .empresa-panel-cambiar,
  body.nav-rail .sidebar:hover .sidebar-footer,
  body.nav-rail .sidebar:hover .nav-chevron,
  body.nav-rail .sidebar.rail-peek .nav-txt,
  body.nav-rail .sidebar.rail-peek .nav-label,
  body.nav-rail .sidebar.rail-peek .nav-sublabel,
  body.nav-rail .sidebar.rail-peek .nav-search {
    opacity: 1; pointer-events: auto;
  }

  /* Ícono centrado en la barra angosta; al expandir, el texto aparece a su lado. */
  body.nav-rail .sidebar .nav-link { justify-content: flex-start; padding-left: 17px; gap: .7rem; }
  body.nav-rail .sidebar .nav-label { display: block; padding-left: 17px; }
  body.nav-rail .sidebar .sidebar-footer { position: absolute; bottom: 0; left: 0; right: 0; }

  /* Pista sutil de que se expande (una flechita al borde derecho del riel). */
  body.nav-rail .sidebar::after {
    content: "›"; position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
    color: var(--gray-400); font-size: 1.1rem; opacity: .5; transition: opacity .12s;
  }
  body.nav-rail .sidebar:hover::after,
  body.nav-rail .sidebar.rail-peek::after { opacity: 0; }
}

/* ══════════════════════════════════════════════════════════════
   BARRA SUPERIOR (nav-top) — el menú va arriba, en menús desplegables
   tipo Excel/Word, y el contenido usa TODO el ancho. Detrás de
   body.nav-top: sin esa clase, nada de esto aplica. Solo desktop.
   ═════════════════════════════════════════════════════════════ */
.topnav { display: none; }

@media (min-width: 769px) {
  body.nav-top .sidebar { display: none; }
  body.nav-top .topnav {
    display: flex; align-items: center; gap: .1rem;
    padding: .3rem .6rem; background: var(--bg-sidebar);
    border-bottom: 1px solid var(--border); position: relative; z-index: 60;
    min-height: 46px; flex-wrap: nowrap;
  }
  .tn-brand { display: flex; align-items: center; gap: .45rem; font-weight: 800; margin-right: .5rem; white-space: nowrap; }
  .tn-brand .logo-mark { font-size: .95rem; }
  .tn-brand-txt { font-size: .92rem; color: var(--gray-700); }

  /* UNA sola línea: marca + menús + buscador/empresa/usuario, todo alineado.
     Las secciones que no entran viven dentro del menú "Más ▾" (ver renderTopNav),
     así que acá no hace falta envolver ni recortar (recortar se comería los
     desplegables, que son position:absolute). */
  .tn-menus { display: flex; align-items: center; gap: .05rem; flex: 0 1 auto; min-width: 0; flex-wrap: nowrap; }
  .tn-menu { position: relative; flex-shrink: 0; }
  /* "Más ▾" ahora arma UNA PESTAÑA por departamento (reflowTopNav), igual que un
     departamento con áreas propias, así que hereda las reglas del ribbon y no lleva
     nada especial.
     Acá vivían tres reglas de la época en que "Más" era una lista vertical a dos
     columnas: `column-count: 2` —inerte desde que el panel es flex— y, peor,
     `.tn-tabs { display: none }` + `.tn-pane { display: block }`, que escondían las
     pestañas y mostraban TODOS los departamentos de una. Era exactamente el desorden
     que se venía arrastrando. Se quitaron. */
  .tn-dd-mas { min-width: 26rem; }
  /* Botones con contorno y en el color de la paleta elegida (--primary* siguen el
     acento del selector 🎨, en claro y en oscuro). */
  .tn-menu-btn {
    font: inherit; font-size: .84rem; font-weight: 600; color: var(--primary);
    background: var(--primary-glow-s); border: 1px solid var(--primary-glow);
    border-radius: 8px; padding: .34rem .7rem; margin: .1rem; cursor: pointer;
    white-space: nowrap; transition: background-color .12s, border-color .12s;
  }
  .tn-menu-btn::after { content: " ▾"; font-size: .62rem; color: var(--primary); opacity: .65; }
  .tn-menu-btn:hover, .tn-menu.open .tn-menu-btn {
    background: var(--primary-glow); border-color: var(--primary); color: var(--primary);
  }

  .tn-dd {
    position: absolute; top: 100%; left: 0; margin-top: 3px; min-width: 13rem;
    /* OPACO a propósito. Con el fondo de tarjeta (92% de opacidad) el menú dejaba
       ver el encabezado y el contenido por detrás: el ← y el título de la pantalla
       se leían mezclados con los azulejos del menú, y parecía que no estaban. */
    background: var(--bg-sidebar); border: 1px solid var(--border);
    border-radius: 10px; box-shadow: 0 16px 40px -12px rgba(0,0,0,.5), var(--glow-sm);
    padding: .3rem; display: none; z-index: 70; max-height: 70vh; overflow-y: auto; overflow-x: hidden;   /* eje X explícito: ver .modal-body */
  }
  .tn-menu.open .tn-dd { display: block; }
  /* Los links del menú: fila simple con su ícono (sin la caja decorativa del sidebar). */
  .tn-dd .nav-link { border-radius: 7px; margin: 0; padding: .4rem .55rem; font-size: .84rem; color: var(--gray-600); }
  .tn-dd .nav-link:hover { background: var(--bg-hover); color: var(--primary); transform: none; box-shadow: none; }
  .tn-dd .nav-link::before { background: none !important; box-shadow: none !important; padding: 0; width: auto; }
  .tn-dd .nav-subgroup { margin-top: .2rem; padding-top: .2rem; border-top: 1px solid var(--border-soft, var(--border)); }
  .tn-dd .nav-sublabel { display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--gray-400); padding: .2rem .55rem; }

  .tn-spacer { flex: 1 1 auto; min-width: .4rem; }   /* empuja buscador/empresa/usuario al borde derecho */
  .tn-btn {
    font: inherit; font-size: .8rem; color: var(--gray-600); background: none;
    border: 1px solid transparent; border-radius: 8px; padding: .32rem .6rem; cursor: pointer;
    display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap;
  }
  .tn-btn:hover { background: var(--bg-hover); color: var(--primary); }
  .tn-btn kbd, .tn-item kbd { font-family: var(--mono, monospace); font-size: .64rem; background: var(--bg-hover); border: 1px solid var(--border); border-radius: 4px; padding: 0 .28rem; margin-left: .3rem; }

  .tn-usermenu { position: relative; }
  .tn-dd-right { left: auto; right: 0; min-width: 12rem; }
  .tn-usermenu .tn-dd { display: none; }
  .tn-usermenu #tnUserDd.open { display: block; }
  .tn-user-info { padding: .4rem .55rem .5rem; border-bottom: 1px solid var(--border); margin-bottom: .25rem; }
  .tn-user-info b { display: block; font-size: .85rem; }
  .tn-user-info span { font-size: .7rem; color: var(--gray-400); text-transform: uppercase; letter-spacing: .04em; }
  .tn-item { display: block; padding: .42rem .55rem; border-radius: 7px; font-size: .83rem; color: var(--gray-600); cursor: pointer; text-decoration: none; }
  .tn-item:hover { background: var(--bg-hover); color: var(--primary); }

  /* En modo barra, el header ya no necesita el botón de menú móvil ni el volver duplicado. */
  body.nav-top .app-header { padding-top: .5rem; }

  /* ── Menú RIBBON (banda horizontal estilo CONTASYS) ────────────────────────
     Se activa con body.nav-ribbon. El desplegable de cada sección deja de ser una
     lista angosta y pasa a una BANDA a todo el ancho, con azulejos (ícono grande +
     etiqueta) agrupados en COLUMNAS (los sub-grupos del catálogo). El .tn-menu se
     vuelve estático para que el .tn-dd se posicione contra la barra (.topnav es
     position:relative) y ocupe todo el ancho. No afecta el menú de usuario. */
  body.nav-ribbon .tn-menus > .tn-menu { position: static; }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd {
    left: 0; right: 0; top: 100%; margin-top: 0; min-width: 0;
    border-radius: 0 0 14px 14px; padding: .55rem .9rem;
    box-shadow: 0 22px 46px -14px rgba(0,0,0,.55); display: none;
  }
  body.nav-ribbon .tn-menus > .tn-menu.open > .tn-dd {
    display: flex; flex-wrap: wrap; align-items: flex-start; gap: .3rem .6rem;
    animation: tnRibbonIn .16s ease;
  }
  @keyframes tnRibbonIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: none; } }

  /* Azulejo COMPACTO: ícono arriba, etiqueta debajo, centrado.
     La cinta se comía media pantalla. La culpa no era de la cantidad de módulos
     sino del tamaño del azulejo: con 88px de ancho y 64px de alto mínimo, un
     departamento de 20 módulos no entraba en una banda y se partía en dos o tres,
     y encima cada grupo tenía el ancho topeado, así que forzaba saltos de línea
     que nadie pedía. Achicado, el mismo departamento entra en UNA banda. */
  /* El azulejo se ajusta A SU TEXTO en vez de tener un ancho fijo.
     Con 74px fijos, «Liquidaciones» no entraba y se leía «Liquidacion / es»: la palabra se
     partía al medio. Un ancho fijo para todos obliga a elegir entre cortar las etiquetas largas
     o desperdiciar la mitad del azulejo en las cortas.
     Ahora crece hasta donde haga falta —el tope entra la palabra más larga del menú, que es
     «Establecimientos»— y las cortas siguen angostas, así que la cinta no se estira. */
  /* Pedido del usuario (20-ago-2026): sin fondo ni borde de reposo, el azulejo se leía
     como un ícono decorativo — "parece un dibujo" — y confundía al usuario de estancia,
     que no tiene por qué asumir que hace falta pasar el mouse para descubrir que es un
     botón. Ahora tiene el mismo lenguaje visual que .btn-secondary (fondo tenue + borde
     visible) DESDE EL REPOSO, no solo al hover. */
  /* Pedido del usuario (21-ago-2026): "que los botones tengan relieve para que parezcan
     botones físicos que oprimir, para que el operario de campo no se confunda" — el fondo
     tenue del 20-ago ya lo distinguía de un ícono decorativo, pero seguía plano. Ahora
     tiene una sombra baja fija (como un botón real levantado de la superficie), que al
     :hover se levanta un poco más y al :active se aplana —el gesto de apretar un botón—
     en vez de solo cambiar de color. */
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link {
    display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
    text-align: center; width: auto; min-width: 70px; max-width: 110px;
    min-height: 0; padding: .3rem .25rem; gap: .15rem;
    border-radius: 8px; color: var(--gray-600);
    background: color-mix(in srgb, var(--primary) 6%, transparent);
    border: 1px solid var(--border-md);
    box-shadow: 0 2px 0 color-mix(in srgb, var(--border-md) 85%, transparent), 0 2px 4px -2px rgba(0,0,0,.4);
    transition: transform .08s ease, box-shadow .08s ease;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link::before { font-size: 1.25rem; line-height: 1; }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link .nav-txt {
    font-size: .69rem; line-height: 1.15; white-space: normal;
    /* `word-break: break-word` era el que cortaba: parte DENTRO de la palabra en cuanto no entra,
       y además deja que el azulejo se encoja hasta una letra. `overflow-wrap: break-word` sólo
       parte si una palabra sola no entra ni en su propio renglón — que con el tope de arriba no
       pasa con ninguna del menú. El corte al medio queda como último recurso, no como norma. */
    word-break: normal; overflow-wrap: break-word; hyphens: none;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link:hover {
    background: var(--primary-glow-s); color: var(--primary); transform: translateY(-1px);
    box-shadow: 0 3px 0 color-mix(in srgb, var(--primary) 55%, transparent), 0 4px 7px -3px rgba(0,0,0,.45);
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link:active {
    transform: translateY(1px);
    box-shadow: 0 0 0 transparent, 0 1px 2px -1px rgba(0,0,0,.35);
  }

  /* ── DÓNDE ESTÁS PARADO ────────────────────────────────────────────────────
     La cinta fija se queda abierta donde la dejaste, y eso está bien: se puede
     hojear otro departamento sin salir de la pantalla, igual que en Excel. Lo que
     estaba mal es que no marcaba NADA, así que la cinta parecía estar diciendo en
     qué módulo estás cuando en realidad mostraba el último que miraste.
     `setActiveNav` ya le pone .active al azulejo de la pantalla abierta; acá se le
     devuelve el estilo, que las reglas del azulejo le pisaban por ser más
     específicas. La raya de abajo, y no un fondo fuerte, para que se lea como
     «estás acá» y no como «esto está seleccionado para hacer algo». */
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link.active {
    background: var(--bg-active); color: var(--primary); font-weight: 700;
    box-shadow: inset 0 -2px 0 var(--primary);
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-link.active::after { display: none; }

  /* El área y el departamento donde vive esa pantalla, marcados con un punto. Así,
     hojeando otra sección, se sigue viendo de dónde saliste sin tener que volver. */
  body.nav-ribbon .tn-menus .tn-dd .tn-tab.aqui::before,
  body.nav-ribbon .tn-menu-btn.aqui::before {
    content: '•'; color: var(--primary); font-weight: 900; margin-right: .28rem;
  }
  body.nav-ribbon .tn-menu-btn.aqui {
    border-color: var(--primary); background: var(--primary-glow);
  }

  /* ── Cinta FIJA (como Excel) ──────────────────────────────────────────────
     El panel sigue posicionado bajo la barra, pero se le RESERVA su altura para que
     no tape el contenido: el resto de la pantalla baja. `--ribbon-h` la mide el JS al
     abrir la sección y al cambiar el tamaño de la ventana (0 = cinta oculta). */
  body.nav-ribbon.ribbon-fijo .app-header { margin-top: var(--ribbon-h, 0px); }
  /* Fija: la cinta se apoya en la barra (sin esquinas ni sombra flotante). */
  body.nav-ribbon.ribbon-fijo .tn-menus > .tn-menu.open > .tn-dd {
    border-radius: 0; box-shadow: 0 6px 14px -10px rgba(0,0,0,.5);
    border-bottom: 1px solid var(--border); animation: none;
  }
  /* "Fijar menú" pasó a ser una fila del desplegable de usuario (menos botones sueltos en
     la cinta, ver construirTopNav) — se resalta la fila en vez de un ícono aparte. */
  body.ribbon-fijo #tnPin { color: var(--primary); background: var(--bg-active); }

  /* ── Sub-departamentos como pestañas ─────────────────────────────────────
     Departamentos con áreas propias (Finanzas → Tesorería / Cobranzas /
     Contabilidad): se entra al departamento y se elige el área. Una sola visible
     por vez, así el panel no crece sin control y el alto no salta. */
  /* Selector por DESCENDENCIA, no por hijo directo: cuando un departamento no entra en
     la barra, reflowTopNav lo mete adentro de "Más ▾" y sus pestañas dejan de colgar
     del panel. Con `>` las reglas dejaban de aplicar y el departamento aparecía vacío
     —solo el nombre, sin un módulo—. */
  body.nav-ribbon .tn-menus .tn-dd .tn-tabs {
    display: flex; flex-wrap: wrap; gap: .25rem; width: 100%;
    border-bottom: 1px solid var(--border); padding-bottom: .35rem; margin-bottom: 0;
  }
  .tn-tab {
    font: inherit; font-size: .75rem; font-weight: 600; letter-spacing: .01em;
    background: none; border: 1px solid transparent; border-radius: 7px;
    padding: .24rem .7rem; color: var(--gray-500); cursor: pointer;
  }
  .tn-tab:hover { color: var(--primary); background: var(--primary-glow-s); }
  .tn-tab.act {
    color: var(--primary); background: var(--bg-active); border-color: var(--border-md);
  }

  /* ── UN TONO POR NIVEL ─────────────────────────────────────────────────────
     La cinta tiene tres niveles anidados —departamento, área y los azulejos— y los
     tres salían del mismo color. Puestos uno encima del otro el ojo los lee como
     tres filas sueltas, sin saber cuál cuelga de cuál: hay que leer los nombres
     para entender la jerarquía, que es justo lo que una barra de navegación tiene
     que ahorrar.
     El tono BAJA a medida que se baja de nivel, así la pertenencia se ve de un
     vistazo. Sale de --primary con color-mix, así que sigue el acento del 🎨 y
     funciona igual en los trece ambientes y en los dos temas: no hay ningún color
     fijo que se quede clavado cuando el resto cambia.
     Los márgenes negativos cancelan el padding de la cinta para que cada banda
     llegue de borde a borde; a media pantalla se leería como un recuadro suelto. */
  body.nav-ribbon .tn-menus .tn-dd > .tn-tabs {
    background: color-mix(in srgb, var(--primary) 30%, transparent);
    margin: -.55rem -.9rem .3rem; padding: .5rem .9rem .42rem;
    border-bottom: 1px solid var(--border-md);
  }
  body.nav-ribbon .tn-menus .tn-dd > .tn-panes > .tn-pane > .tn-tabs {
    background: color-mix(in srgb, var(--primary) 15%, transparent);
    margin: 0 -.9rem .4rem; padding: .36rem .9rem;
    border-bottom: 1px solid var(--border);
  }
  /* El tercer nivel es el fondo de la cinta, sin teñir: es el final de la escalera. */

  /* El texto de las pestañas, un paso más contrastado. Sobre una banda teñida al 30 % el
     gris del medio (--gray-500) cae a 4,19 en tema oscuro, por debajo de lo legible.
     --gray-600 se aleja del medio en LOS DOS temas —más claro en oscuro, más oscuro en
     claro— así que sube el contraste de los dos lados a la vez: 6,4 y 9,5. */
  body.nav-ribbon .tn-menus .tn-dd .tn-tab { color: var(--gray-600); }

  /* La pestaña activa tiene que ganarle al tono de SU banda, no al de la cinta:
     sobre un fondo ya teñido, el --bg-active de antes casi no se distinguía. */
  body.nav-ribbon .tn-menus .tn-dd .tn-tab.act {
    background: var(--bg-card); border-color: var(--primary);
    box-shadow: 0 1px 3px color-mix(in srgb, var(--primary) 25%, transparent);
  }
  body.nav-ribbon .tn-menus .tn-dd .tn-panes { width: 100%; }
  body.nav-ribbon .tn-menus .tn-dd .tn-panes > .tn-pane { display: none; }
  body.nav-ribbon .tn-menus .tn-dd .tn-panes > .tn-pane.act {
    display: flex; flex-wrap: wrap; align-items: flex-start; gap: .3rem 1.4rem;
    padding-top: .4rem;
  }

  /* Sub-grupo = columna: azulejos juntos + el nombre del grupo centrado abajo,
     con separador vertical entre columnas (como los bloques de CONTASYS).
     El tope de ancho es GENEROSO a propósito: apretarlo (estaba en 296px, tres
     azulejos) partía los grupos largos en tres filas y era lo que estiraba la
     cinta hacia abajo. Ancha, la banda crece a lo LARGO —que es donde sobra
     lugar— y no a lo alto. En pantallas chicas el flex-wrap la parte solo.
     900px: con 620px, un grupo de 7 azulejos con etiquetas largas —"Cargar
     movimiento" (Reclasificación (paso de categoría), Salida: faena / consumo…)—
     igual se partía en dos filas aunque la cinta entera tuviera todo el ancho de
     la pantalla libre al lado. 900px entran los 7 en una sola fila SIN partirse
     ENTRE SÍ (eso es el max-width de acá abajo, el tope INTERNO del grupo).
     Probé flex:1 (16-ago) para que un grupo solo en su fila —"Cargar movimiento"
     sin compañía— creciera y ocupara la banda vacía en vez de quedar pegado a la
     izquierda. Pero flex:1 reparte el sobrante POR IGUAL entre todas las columnas
     de la fila, sin mirar cuánto contenido tiene cada una: "Tableros", con solo 2
     azulejos, crecía tanto como "Existencias" con 5, y ese ancho de más —que no
     necesitaba— era lo que le comía a la fila el lugar que "Cargar movimiento"
     necesitaba para entrar junto a los demás. Sacado: cada columna vuelve a medir
     lo que su contenido pide, ni más, así entran más grupos por fila (que es lo
     que hace falta acá) y el que quede solo al final de la cinta, si queda,
     se ve como el margen normal de un menú — no distinto de Excel/Word.

     20-ago: eso resolvía el tope INTERNO de cada grupo, pero no el problema de
     que "Cargar movimiento" (Hacienda) igual se cayera a una fila propia DEBAJO
     de "Tableros"/"Existencias" — el ancho SUMADO de los tres ya no entraba en
     una sola fila del contenedor externo. Se achicó el azulejo (116px → 110px de
     tope, ver .nav-link más abajo — el piso lo pone test-menu-etiquetas.mjs, la
     palabra más larga del menú no entra en menos) y los gaps entre grupos, para
     que la suma de los tres quepa junto en una banda ancha en vez de partirse en
     dos filas.

     20-ago (segunda vuelta): el usuario mostró que TODAVÍA quedaba espacio vacío
     a la derecha de "Tableros"/"Existencias" con "Cargar movimiento" (7 azulejos)
     cayendo igual a su fila propia — el hueco visible era MENOR a lo que ese
     grupo necesita en una sola fila (~800px), aunque a simple vista pareciera
     alcanzar. flex-wrap no reordena: si el siguiente grupo no entra ENTERO en lo
     que queda de la fila actual, se va entero a la fila de abajo, por más que ese
     hueco se vea grande. La solución no es seguir angostando el azulejo (ya está
     en el piso de test-menu-etiquetas.mjs) sino dejar que un grupo LARGO parta
     sus propios azulejos en más de una fila INTERNA (angosto y alto en vez de
     ancho y bajo) — así "Cargar movimiento" ocupa ~470px en vez de ~800px y entra
     al lado de los otros dos en el hueco real que queda.

     21-ago: el usuario mostró Ganadería → Hacienda con hueco de sobra a la
     derecha de "Existencias" (5 azulejos: "Trazabilidad" solo, colgado en su
     propia fila interna) y de "Cargar movimiento" (7 azulejos: los 3 últimos
     -mortandad/reclasificación/traslado- en fila propia debajo de los 4
     primeros) — pidió que se acomoden aprovechando ese lugar. 470px daba justo
     para 4 azulejos angostos por fila; subido a 700px entran los 5 de
     Existencias en una sola fila (solo necesita ~560px, el tope no la estira
     de más porque cada grupo mide lo que su CONTENIDO pide, no el tope), pero
     a "Cargar movimiento" (7) le entraban 6 y el 7° (Traslado) quedaba solo
     abajo, separado de "Reclasificación" (paso de categoría) — el usuario pidió
     que quedaran uno al lado del otro, ya que en el orden del menú siempre
     fueron vecinos (son las dos operaciones que NO entran ni salen cabezas de
     la explotación, solo las mueven de categoría o de estancia). Subido a
     800px entran los 7 en una sola fila: la suma real de los tres grupos en
     esta fila ronda ~1640px, cerca pero todavía por debajo del ancho que hizo
     fallar el intento de 900px de esa vuelta (~1680px+, y ese cálculo era con
     el azulejo viejo de 116px, 6px más ancho que el actual). Si todavía se
     parte, el próximo paso es angostar el gap entre grupos antes que seguir
     subiendo este número. */
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup {
    display: flex; flex-wrap: wrap; align-content: flex-start; justify-content: center;
    gap: .15rem; margin: 0; padding: 0 1.1rem 0 0; border: none;
    border-right: 1px solid var(--border); max-width: 800px;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup:last-child { border-right: none; padding-right: 0; }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-sublabel {
    order: 9; flex-basis: 100%; width: 100%; text-align: center; margin: .2rem 0 0;
    padding: .2rem 0 0; border-top: 1px solid var(--border-soft, var(--border));
    font-size: .62rem; text-transform: uppercase; letter-spacing: .06em; color: var(--gray-400);
  }

  /* ── Grupo en LISTA (en vez de azulejos) ──────────────────────────────────
     Pedido del usuario (31-ago-2026), mostrando el menú "Reportes" de un sistema
     viejo (una lista vertical larga, tipo dropdown clásico) y pidiendo "algo así
     pero con mejor aspecto, este tiene un aspecto muy antiguo": para un grupo con
     MUCHOS ítems de texto (informes, balances…), una columna angosta que se lee de
     arriba a abajo es más clara que apretar azulejos cuadrados — y de paso no
     compite por ancho horizontal con sus grupos vecinos, que es justo lo que
     forzaba a "Mayor y balances" a pelearse con "Configuración" por la fila.
     Opt-in por grupo (`lista: true` en el catálogo), no reemplaza los azulejos en
     general — para pocos ítems, el azulejo sigue siendo más rápido de escanear.

     Pedido del usuario (31-ago-2026, segunda vuelta): "que sea desplegable y
     contraible" — es un <details>/<summary> (mismo patrón que ya usa Movimientos de
     hacienda), con el chevron .pf-chevron que ya existe. Arranca abierto: es un menú
     que se cierra solo al salir del desplegable, no una tabla larga que valga la pena
     recordar plegada entre sesiones. */
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista {
    flex-direction: column; flex-wrap: nowrap; align-items: stretch; justify-content: flex-start;
    gap: .1rem; max-width: 230px; min-width: 190px;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-sublabel {
    /* La regla general de .nav-sublabel (azulejos) lo manda al pie con order:9 — acá
       tiene que quedar arriba, como título del desplegable, no pie de página. */
    order: -1;
    display: flex; align-items: center; justify-content: space-between; cursor: pointer;
    list-style: none; text-align: left; margin: 0 0 .3rem; padding: 0 0 .3rem;
    border-top: none; border-bottom: 1px solid var(--border-soft, var(--border));
    font-weight: 700; letter-spacing: .04em;
  }
  /* Chrome/Edge dibujan un triángulo propio en <summary> además del nuestro (.pf-chevron):
     hay que apagarlo o quedan dos flechitas una al lado de la otra. */
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-sublabel::-webkit-details-marker { display: none; }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-sublabel:hover { color: var(--primary); }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-link {
    flex-direction: row; align-items: center; justify-content: flex-start;
    text-align: left; width: 100%; min-width: 0; max-width: none;
    padding: .32rem .5rem; gap: .5rem; border-radius: 7px;
    background: transparent; border: none; box-shadow: none;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-link::before { font-size: 1.05rem; }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-link .nav-txt {
    font-size: .78rem; line-height: 1.2; white-space: nowrap; text-align: left;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-link:hover {
    background: var(--primary-glow-s); color: var(--primary); transform: none; box-shadow: none;
  }
  body.nav-ribbon .tn-menus > .tn-menu > .tn-dd .nav-subgroup.nav-lista .nav-link:active { transform: none; }

  /* ── "Más ▾": los departamentos que no entraron en la barra ─────────────────
     Cada uno se mete adentro de un envoltorio que reusaba TAL CUAL el estilo de
     bloque. Con eso quedaban dos niveles idénticos: el nombre del departamento
     caía abajo (order:9), del mismo tamaño, mismo color y con la misma línea que
     el nombre de un bloque interno, y no había forma de saber qué colgaba de qué.
     Acá el departamento pasa a ENCABEZAR su bloque. */
  /* "Más ▾" no necesita CSS propio: reflowTopNav le arma pestañas y paneles con la
     MISMA estructura que un departamento con áreas, así que hereda todo lo de arriba.
     Antes tenía su propio envoltorio por departamento y ahí empezaban los problemas —
     dos niveles de rótulos idénticos, topes de ancho heredados, bloques apilados—. La
     mejor regla especial resultó ser ninguna. */
}

/* Command palette (Ctrl+K en modo barra superior) */
.cmdk-bg { position: fixed; inset: 0; background: rgba(6,10,16,.5); z-index: 900; display: none; }
.cmdk-bg.open { display: block; }
.cmdk { position: absolute; top: 12%; left: 50%; transform: translateX(-50%); width: min(34rem, 92%);
        background: var(--bg-card, #0f172a); border: 1px solid var(--border); border-radius: 14px;
        box-shadow: 0 30px 80px -20px rgba(0,0,0,.75); overflow: hidden; }
.cmdk input { width: 100%; border: none; border-bottom: 1px solid var(--border); padding: .85rem 1.1rem;
              font: inherit; font-size: 1rem; background: transparent; color: var(--gray-800, inherit); }
.cmdk input:focus { outline: none; }
.cmdk-res { max-height: 320px; overflow-y: auto; overflow-x: hidden; padding: .35rem; }   /* eje X explícito: ver .modal-body */
.cmdk-row { display: flex; align-items: center; gap: .5rem; padding: .55rem .65rem; border-radius: 9px; font-size: .9rem; cursor: pointer; color: var(--gray-700, inherit); }
.cmdk-row.sel { background: var(--bg-active); color: var(--primary); }
.cmdk-row .cmdk-sec { margin-left: auto; font-size: .7rem; color: var(--gray-400); }
.cmdk-empty { color: var(--gray-400); cursor: default; }

/* ── Responsive — Mobile (≤ 768px) ──────────────────── */
@media (max-width: 768px) {
  .topnav { display: none !important; }   /* en móvil se usa el drawer, no la barra */
  .btn-hamburger { display: flex; }
  .sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; z-index: 500;
    width: var(--sidebar-w) !important;
    transform: translateX(-100%);
    transition: transform .25s ease;
  }
  .sidebar.open { transform: translateX(0); box-shadow: 6px 0 30px rgba(0,0,0,.6), var(--glow-sm); }
  .sidebar-toggle { display: none; }
  .app-body { display: block; }
  .app-main { margin-left: 0 !important; height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
  .main-content { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 1rem; }
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  .col-span-2 { grid-column: span 1; }
  .kpi-grid { grid-template-columns: 1fr 1fr; }
  .card.p-0 { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .data-table { min-width: 560px; }
  .data-table th, .data-table td { padding: .5rem .6rem; white-space: nowrap; }
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal-box, .modal-lg, .modal-xl { max-width: 100% !important; width: 100% !important; max-height: 93vh; border-radius: 18px 18px 0 0 !important; }
  .modal-body { padding: 1rem; }
  .modal-header, .modal-footer { padding: .9rem 1rem; }
  .app-header { padding: 0 .75rem; gap: .5rem; }
  .app-header h2 { font-size: .95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 140px; }
  .header-right .btn { padding: .35rem .65rem; font-size: .78rem; }
  .login-card { padding: 1.75rem 1.25rem; margin: 1rem; }
  .toast-container { left: .5rem; right: .5rem; top: auto; bottom: 1rem; }
  .toast { max-width: 100%; }
  .filters-row { gap: .5rem; }
  .filters-row .input, .filters-row select { font-size: .8rem; }
  .pagination { justify-content: center; padding: .5rem; font-size: .8rem; }
  .empresa-panel-nombre { max-width: 120px; }
  .dashboard-row { flex-direction: column; }
  .dashboard-row .flex-1 { min-width: 100%; }
}

/* ── Escala de breakpoints de este archivo (1-sep-2026) ──────────────────────────
   768 / 1024 / 1200 / 1440 / 1920 / 2560 — cualquier @media NUEVO en este archivo
   debería alinearse a uno de estos valores en vez de inventar uno más (hoy conviven
   9 valores sueltos sin un criterio único: 480/560/640/768/900/1024/1200/1440/1920,
   más otros @media propios en algunos módulos de public/js/modules/ — esos NO se
   tocan acá, solo se documenta la escala para lo que se agregue de ahora en más). */

/* ── Responsive — Mobile pequeño (≤ 480px) ───────────── */
@media (max-width: 480px) {
  .kpi-grid { grid-template-columns: 1fr; }
  .kpi-value { font-size: 1.15rem; }
  .filters-row > * { width: 100%; }
  .modal-footer { flex-direction: column-reverse; }
  .modal-footer .btn { width: 100%; justify-content: center; }
  .app-header h2 { font-size: .85rem; max-width: 110px; }
  .header-right .btn span { display: none; }
  .perfiles-grid { grid-template-columns: 1fr; }
}

/* ── Responsive — Smart TV / pantalla grande (≥ 1440px) ─ */
@media (min-width: 1440px) {
  html { font-size: 15px; }
  :root { --sidebar-w: 280px; }
  .main-content { padding: 2rem; }
  .kpi-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
}

@media (min-width: 1920px) {
  html { font-size: 16px; }
  :root { --sidebar-w: 300px; }
  .main-content { padding: 2.5rem 3rem; }
  /* En pantallas grandes (TV/55") NO agrandar los renglones: subimos la tipografía
     para que se lea de lejos, pero el alto de fila queda cómodo, no enorme. */
  .data-table { font-size: .9rem; }
  .data-table th, .data-table td { padding: .5rem .95rem; }
}

/* ── Responsive — Monitor grande / 32" (≥ 2560px) ──────
   Antes de esto no había NINGÚN ajuste por encima de 1920px: un monitor de 2560 o
   3840px (32", 4K) heredaba las mismas reglas que uno de 1920, sin ningún criterio
   propio (1-sep-2026). No se le pone techo de ancho a .main-content/.card: la mayoría
   de las pantallas son tablas/grillas densas en datos, donde más ancho es información
   útil, no texto de lectura que convenga angostar.
   SIN font-size acá a propósito: verificado con computed styles (Playwright) que
   cualquier html{font-size} de este bloque de "Responsive" queda pisado de todos modos
   por la regla incondicional de la línea ~2900 ("Tipografía más grande, pedido del
   usuario") — los escalones 1440/1920 de arriba tienen el mismo problema, ver nota ahí. */
@media (min-width: 2560px) {
  :root { --sidebar-w: 320px; }
  .main-content { padding: 3rem 3.5rem; }
}

/* ═══════════════════════════════════════════════════════════
   CAPA DE PULIDO VISUAL — tipografía premium, números tabulares,
   transición de carga y micro-realces. Va al final para ganar en
   la cascada sin reescribir reglas anteriores.
   ═══════════════════════════════════════════════════════════ */

/* Render tipográfico premium */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  letter-spacing: -.005em;
}
h1, h2, h3, .card-title, .page-header h1, .app-header h2,
.kpi-value, .modal-title, .nav-label, .login-title, .logo-text {
  letter-spacing: -.018em;
  font-family: var(--font-display);
}

/* Cifras alineadas y legibles (finanzas) */
.kpi-value, .tile-saldo-amount, .tile-num, .mono, .amount,
.data-table td.text-right, .data-table th.text-right,
.data-table td.mono, .data-table .num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* Radios un poco más suaves y modernos — ahora sobre los tokens de la escala
   (--radius-sm/--radius/--radius-lg), no hardcodeados: subir un tono en :root
   ya no exige tocar esta capa aparte. */
.card, .kpi-card, .modal, .cuenta-tile { border-radius: var(--radius-lg); }
.btn, .input, input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], textarea, select,
.filter-select, .filter-input { border-radius: var(--radius); }
.btn-sm { border-radius: var(--radius-sm); }

/* Sombras/relieve más pulidos en las tarjetas */
.card { box-shadow: 0 1px 2px rgba(0,0,0,.28), 0 8px 24px -12px rgba(0,0,0,.5); }
html.light .card { box-shadow: 0 1px 2px color-mix(in srgb, var(--gray-800) 6%, transparent), 0 10px 26px -14px color-mix(in srgb, var(--gray-800) 18%, transparent); }

/* KPI cards: superficie con leve degradé + realce al pasar el mouse */
.kpi-card {
  background: linear-gradient(158deg, var(--bg-card) 0%, color-mix(in srgb, var(--primary-d) 5%, transparent) 130%);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.kpi-card:hover { transform: translateY(-3px); }
html.light .kpi-card {
  background: linear-gradient(158deg, #ffffff 0%, color-mix(in srgb, var(--primary) 5%, transparent) 130%);
}

/* Botones: transición suave al presionar */
.btn { transition: transform .12s ease, box-shadow .18s ease, background .18s ease, border-color .18s ease, color .15s ease; }
.btn:active:not(:disabled) { transform: translateY(1px) scale(.99); }

/* Deshabilitado INEQUÍVOCO: gris, sin color ni sombra (antes parecía activo) */
.btn:disabled {
  filter: grayscale(1);
  opacity: .45;
  box-shadow: none !important;
  transform: none !important;
}

/* Encabezado de página con acento vertical */
.page-header h1 {
  padding-left: .7rem;
  border-left: 3px solid var(--primary);
  line-height: 1.15;
}
html.light .page-header h1 { border-left-color: var(--primary); }

/* Transición de carga entre pantallas (el router reemplaza #main-content) */
@media (prefers-reduced-motion: no-preference) {
  .main-content { animation: ic-page-in .32s cubic-bezier(.22,.61,.36,1) both; }
  @keyframes ic-page-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
  /* Filas de tabla y tarjetas entran escalonadas, sutil */
  .kpi-card { animation: ic-rise .4s ease both; }
  .kpi-card:nth-child(2) { animation-delay: .04s; }
  .kpi-card:nth-child(3) { animation-delay: .08s; }
  .kpi-card:nth-child(4) { animation-delay: .12s; }
  .kpi-card:nth-child(5) { animation-delay: .16s; }
  .kpi-card:nth-child(6) { animation-delay: .20s; }
  @keyframes ic-rise {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
  }
}

/* ── Dashboard premium ─────────────────────────────── */
.dash-hero {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-bottom: 1.1rem; flex-wrap: wrap;
}
.dash-hero-saludo { font-size: 1.45rem; font-weight: 500; color: var(--gray-700); letter-spacing: -.02em; }
.dash-hero-saludo b { font-weight: 800; color: var(--primary); }
.dash-hero-fecha { font-size: .82rem; color: var(--gray-400); margin-top: .15rem; }

.kpi-card { position: relative; }
.kpi-ico {
  position: absolute; top: .7rem; right: .75rem;
  font-size: 1.15rem; opacity: .55; filter: grayscale(.2);
}

.dash-accesos { margin: .25rem 0 1.5rem; }
.dash-accesos-t {
  display: block; font-size: .7rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .08em; color: var(--gray-400); margin-bottom: .5rem;
}
.dash-accesos-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem;
}
.dash-acceso {
  display: flex; align-items: center; gap: .5rem;
  padding: .6rem .75rem; border-radius: 12px;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--gray-600); text-decoration: none;
  font-size: .8rem; font-weight: 600;
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease, color .15s ease;
  white-space: nowrap; overflow: hidden;
}
.dash-acceso span:last-child { overflow: hidden; text-overflow: ellipsis; }
.dash-acceso:hover {
  transform: translateY(-2px);
  border-color: var(--primary);
  color: var(--primary);
  box-shadow: var(--shadow), var(--glow-sm);
}
.dash-acceso-ico { font-size: 1rem; flex-shrink: 0; }

.dash-top { display: flex; flex-direction: column; gap: .65rem; }
.dash-top-item { display: flex; align-items: center; gap: .6rem; }
.dash-top-rank {
  width: 24px; height: 24px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: .75rem; font-weight: 800;
  background: var(--bg-hover); color: var(--gray-500);
  border: 1px solid var(--border);
}
.dash-top-rank.r1 { background: color-mix(in srgb, var(--warning) 15%, transparent); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 35%, transparent); }
.dash-top-rank.r2 { background: color-mix(in srgb, var(--gray-500) 15%, transparent); color: var(--gray-500); border-color: color-mix(in srgb, var(--gray-500) 35%, transparent); }
.dash-top-rank.r3 { background: color-mix(in srgb, var(--warning) 15%, transparent);  color: #d97706; border-color: color-mix(in srgb, var(--warning) 35%, transparent); }
html.light .dash-top-rank.r1 { color: var(--warning); }
html.light .dash-top-rank.r2 { color: var(--gray-500); }
.dash-top-info { flex: 1; min-width: 0; }
.dash-top-nombre {
  font-size: .8rem; font-weight: 600; color: var(--gray-600);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dash-top-bar {
  height: 5px; border-radius: 99px; background: var(--bg-hover);
  margin-top: .25rem; overflow: hidden;
}
.dash-top-bar span {
  display: block; height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--primary-d), var(--primary));
}
.dash-top-monto {
  font-size: .78rem; font-weight: 700; color: var(--gray-700);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

@media (max-width: 640px) {
  .dash-hero-saludo { font-size: 1.15rem; }
  .dash-accesos-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}

/* ═══════════════════════════════════════════════════════════
   INTERIOR CINEMATOGRÁFICO — el aspecto "Netflix" dentro del
   sistema: sidebar, fondo ambiente, modales, tablas y tabs.
   Capa final: gana la cascada sin reescribir los estilos base.
   ═══════════════════════════════════════════════════════════ */

/* ── Fondo ambiente del área de trabajo (tema oscuro) ── */
.main-content {
  background:
    radial-gradient(ellipse 65% 45% at 85% -8%, color-mix(in srgb, var(--primary-d) 10%, transparent) 0%, transparent 60%),
    radial-gradient(ellipse 50% 40% at 0% 110%, rgba(99,102,241,.08) 0%, transparent 60%),
    var(--bg-base);
}
html.light .main-content {
  background:
    radial-gradient(ellipse 65% 45% at 85% -8%, color-mix(in srgb, var(--primary-d) 7%, transparent) 0%, transparent 60%),
    var(--bg-base);
}

/* ── Sidebar cinematográfico ── */
.sidebar {
  background: linear-gradient(180deg, #081226 0%, var(--bg-sidebar) 34%, #050b1c 100%);
}
html.light .sidebar { background: #ffffff; }
.nav-label {
  font-size: .66rem;
  letter-spacing: .14em;
  opacity: .92;
}
.nav-link {
  border-radius: 10px;
  margin: .1rem .5rem;
  padding: .5rem .55rem;
  font-weight: 500;
}
.nav-link::before { font-size: 1.02rem; }
.nav-link:hover {
  /* SIN margin/padding/transform en hover: cualquier cambio de geometría movía el ítem.
     En el sidebar el margen coincidía con el de base (no se notaba), pero en los
     desplegables del menú superior el margen base es 0, así que re-fijarlo acá hacía
     SALTAR el azulejo bajo el cursor. El realce es solo la barra lateral. */
  box-shadow: inset 3px 0 0 var(--primary);
}
.nav-link.active {
  margin: .1rem .5rem; padding: .5rem .55rem;
  background: linear-gradient(90deg, color-mix(in srgb, var(--primary-d) 20%, transparent) 0%, color-mix(in srgb, var(--primary-d) 6%, transparent) 100%);
  font-weight: 700;
}
/* El ítem activo no pierde su contorno ni su brillo cuando además está bajo el mouse. */
.nav-link.active:hover {
  box-shadow: inset 3px 0 0 var(--primary), inset 0 0 0 1px var(--border-md), var(--glow-sm);
}
html.light .nav-link.active {
  background: linear-gradient(90deg, color-mix(in srgb, var(--primary) 16%, transparent) 0%, color-mix(in srgb, var(--primary) 5%, transparent) 100%);
}
.empresa-panel-top {
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary-d) 16%, transparent) 0%, rgba(99,102,241,.08) 100%);
  border-bottom: 1px solid var(--border-md);
}
html.light .empresa-panel-top { background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 10%, transparent) 0%, color-mix(in srgb, var(--primary) 3%, transparent) 100%); }

/* ── Header con más vidrio ── */
.app-header { backdrop-filter: blur(14px) saturate(1.15); }

/* ── Modales cinematográficos ── */
.modal-overlay {
  background: rgba(2, 5, 14, 0.72);
  backdrop-filter: blur(7px) saturate(1.05);
}
html.light .modal-overlay { background: rgba(10, 24, 40, 0.45); }
.modal-box, .modal {
  border-radius: 18px;
  box-shadow: 0 40px 90px -24px rgba(0,0,0,.9), 0 0 0 1px color-mix(in srgb, var(--primary) 6%, transparent);
}
html.light .modal-box, html.light .modal {
  box-shadow: 0 30px 70px -22px rgba(10,24,40,.45);
}
@media (prefers-reduced-motion: no-preference) {
  .modal-box, .modal { animation: ic-modal-in .26s cubic-bezier(.22,1.1,.36,1) both; }
  @keyframes ic-modal-in {
    from { opacity: 0; transform: translateY(18px) scale(.97); }
    to   { opacity: 1; transform: none; }
  }
}

/* ── Tablas con jerarquía de cine ── */
.data-table thead th {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  font-weight: 800;
  /* Raya azul eléctrico que separa el título de columnas del cuerpo (identidad visual). */
  border-bottom: 2px solid #2f81f7;
  box-shadow: 0 1px 0 rgba(47,129,247,.35);
}
.data-table tbody tr:hover td { box-shadow: inset 3px 0 0 var(--primary); }
.data-table tbody tr:hover { background: var(--bg-hover); }

/* ── Tabs tipo píldora (segmented control) ── */
.tabs {
  gap: .3rem; border-bottom: none;
  background: var(--bg-hover);
  border: 1px solid var(--border);
  border-radius: 12px; padding: .28rem;
  width: fit-content; max-width: 100%;
  overflow-x: auto;
}
.tab-btn {
  border-radius: 9px; border-bottom: none; margin-bottom: 0;
  padding: .42rem 1rem; white-space: nowrap;
}
.tab-btn.active {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-d) 100%);
  color: #05101f; text-shadow: none;
  border-bottom: none;
  box-shadow: 0 2px 10px var(--primary-glow);
}
html.light .tab-btn.active { color: #ffffff; }

/* ── Encabezado de modal más marcado ── */
.modal-header h2 { letter-spacing: -.015em; font-size: 1.05rem; }

/* ── Badges un toque más pill ── */
.badge { border-radius: 20px; font-weight: 700; }

/* ── Tarjetas de cuenta bancaria: color propio por cuenta ──
   El JS pone --h (0-360) derivado de banco+número; cada cuenta
   tiene su degradé y su relieve de color estable. */
.cuenta-tile {
  background:
    linear-gradient(160deg, hsla(var(--h,200),55%,52%,.16), hsla(var(--h,200),60%,25%,.08)),
    var(--bg-card);
  border: 1px solid hsla(var(--h,200),50%,58%,.38);
  border-left: 5px solid hsl(var(--h,200),65%,55%);
  box-shadow: 0 2px 6px rgba(0,0,0,.12), inset 0 1px 0 hsla(var(--h,200),70%,70%,.12);
}
.cuenta-tile:hover, .cuenta-tile:focus-visible {
  border-color: hsl(var(--h,200),70%,58%);
  border-left-color: hsl(var(--h,200),75%,60%);
  box-shadow: 0 14px 28px -10px hsla(var(--h,200),60%,35%,.55);
}
.cuenta-tile .tile-moneda { color: hsl(var(--h,200),75%,68%); }
.cuenta-tile .tile-open   { color: hsl(var(--h,200),75%,68%); }
html.light .cuenta-tile {
  background:
    linear-gradient(160deg, hsla(var(--h,200),60%,55%,.13), hsla(var(--h,200),55%,50%,.03)),
    #ffffff;
  border: 1px solid hsla(var(--h,200),45%,45%,.35);
  border-left: 5px solid hsl(var(--h,200),55%,45%);
  box-shadow: 0 2px 6px color-mix(in srgb, var(--gray-800) 8%, transparent);
}
html.light .cuenta-tile:hover, html.light .cuenta-tile:focus-visible {
  box-shadow: 0 14px 28px -12px hsla(var(--h,200),50%,35%,.35);
}
html.light .cuenta-tile .tile-moneda { color: hsl(var(--h,200),60%,35%); }
html.light .cuenta-tile .tile-open   { color: hsl(var(--h,200),60%,35%); }

/* ── Identidad de color por cuenta en el DETALLE y la CONCILIACIÓN ──
   El JS pone --h según la paleta elegida (o el hash si es automático).
   Tiñe el marco/encabezado; NO toca los colores semánticos de la
   conciliación (rojo/ámbar/verde), que siguen significando lo mismo. */
.cuenta-cromada {
  border-left: 5px solid hsl(var(--h,200),65%,55%) !important;
  background:
    linear-gradient(160deg, hsla(var(--h,200),55%,52%,.12), transparent 55%),
    var(--bg-card);
}
.cuenta-cromada > .flex > strong,
.cuenta-cromada .cuenta-cromada-tit { color: hsl(var(--h,200),72%,64%); }
html.light .cuenta-cromada > .flex > strong,
html.light .cuenta-cromada .cuenta-cromada-tit { color: hsl(var(--h,200),58%,40%); }
/* Datos de identidad de la cuenta (nro, titular, cuenta contable): verde negrita y
   legible en modo oscuro (antes iban en gris apagado y no se leían). La clase SOLO
   pinta color y peso — no cambia el tamaño de la fuente. */
.txt-cta-verde { color: #22c55e; font-weight: 700; }
html.light .txt-cta-verde { color: var(--success); }
/* Barra de pestañas / zona de trabajo del banco: acento superior con el color de la cuenta */
.banco-work { border-top: 3px solid hsl(var(--h,200),65%,55%); border-radius: 0 0 4px 4px; padding-top: 3px; }
.banco-tinte-chip {
  display:inline-block; width:14px; height:14px; border-radius:4px; vertical-align:-2px;
  background: hsl(var(--h,200),65%,55%); border:1px solid hsla(var(--h,200),60%,70%,.6);
}

/* ── Selector de paletas de color ─────────── */
.paleta-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:.5rem; }
.paleta-swatch {
  display:flex; align-items:center; gap:.5rem; cursor:pointer; text-align:left;
  padding:.5rem .6rem; border-radius:10px; font-size:.82rem;
  border:1.5px solid var(--border,#334155); background:var(--bg-card);
  transition: border-color .12s ease, transform .12s ease;
}
.paleta-swatch:hover { transform: translateY(-1px); border-color: hsl(var(--h,200),60%,55%); }
.paleta-swatch.sel { border-color: hsl(var(--h,200),70%,58%); box-shadow:0 0 0 2px hsla(var(--h,200),65%,55%,.35); }
.paleta-chip {
  width:22px; height:22px; border-radius:6px; flex:0 0 auto;
  background: linear-gradient(160deg, hsl(var(--h,200),65%,58%), hsl(var(--h,200),60%,40%));
  border:1px solid hsla(var(--h,200),60%,70%,.5);
}
.paleta-swatch[data-key="auto"] .paleta-chip {
  background: conic-gradient(from 0deg, var(--danger-d), #f59e0b, #22c55e, #06b6d4, #6366f1, #d946ef, var(--danger-d));
}

/* ── Selector de AMBIENTES (paletas de fondo) ─────────── */
/* La miniatura se pinta con los tokens reales del ambiente (ver icVarsAmbiente), así el
   preview muestra el fondo, la barra lateral y una tarjeta tal como van a quedar. */
.amb-fam { font-size:.72rem; text-transform:uppercase; letter-spacing:.07em;
  color:var(--gray-400); margin:.7rem 0 .35rem; }
.amb-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:.5rem; }
.amb-swatch {
  display:flex; flex-direction:column; align-items:stretch; gap:.35rem; cursor:pointer;
  padding:.4rem; border-radius:10px; text-align:left;
  border:1.5px solid var(--border,#334155); background:var(--bg-card);
  transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.amb-swatch:hover { transform: translateY(-1px); border-color: var(--border-strong); }
.amb-swatch.sel { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-glow); }
.amb-nombre { font-size:.76rem; color:var(--gray-600); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.amb-mini { position:relative; display:block; height:44px; border-radius:7px; overflow:hidden;
  border:1px solid rgba(128,128,128,.28); }
.amb-mini-side { position:absolute; left:0; top:0; bottom:0; width:26%; }
.amb-mini-card { position:absolute; left:34%; right:9%; top:26%; height:44%;
  border-radius:3px; border:1px solid; }

/* ── Consola del propietario — estilo Netflix ─────────── */
.con-hero {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  margin: .5rem 0 1.5rem;
}
.con-hero-k {
  font-size: .7rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .1em; color: var(--primary); margin-bottom: .35rem;
}
.con-hero-t {
  font-size: clamp(1.4rem, 3.5vw, 2.1rem); font-weight: 800;
  color: var(--gray-800); letter-spacing: -.02em; line-height: 1.15;
  margin: 0 0 .3rem; text-wrap: balance;
}
.con-hero-s { font-size: .88rem; color: var(--gray-400); margin: 0; }

.con-emp {
  position: relative; border-radius: 16px; padding: 1.1rem;
  display: flex; flex-direction: column; gap: .3rem;
  background:
    linear-gradient(165deg, hsla(var(--h),55%,50%,.28), hsla(var(--h),60%,18%,.22)),
    var(--bg-card);
  border: 1px solid hsla(var(--h),55%,60%,.30);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.con-emp:hover {
  transform: translateY(-4px) scale(1.015);
  box-shadow: 0 18px 40px -16px rgba(0,0,0,.65);
  border-color: hsla(var(--h),70%,65%,.6);
}
html.light .con-emp {
  background:
    linear-gradient(165deg, hsla(var(--h),60%,55%,.16), hsla(var(--h),55%,45%,.05)),
    #ffffff;
  border-color: hsla(var(--h),45%,45%,.35);
}
html.light .con-emp:hover { box-shadow: 0 16px 34px -18px color-mix(in srgb, var(--gray-800) 35%, transparent); }
.con-emp-off { opacity: .55; filter: grayscale(.5); }
.con-emp-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: .2rem; }
.con-emp-ico {
  font-size: 2rem; line-height: 1;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.35));
}
.con-emp-nombre {
  font-size: 1.05rem; font-weight: 800; color: var(--gray-800);
  letter-spacing: -.015em; line-height: 1.2;
}
.con-emp-sub { font-size: .76rem; color: var(--gray-500); }
.con-emp-meta { font-size: .74rem; color: var(--gray-400); margin-bottom: .5rem; }
.con-emp-acciones { margin-top: auto; }

/* ═══════════════════════════════════════════════════════════
   AURORA FUTURISTA — capa final de la interfaz de carga.
   Look pedido: oscuro profundo, resplandor cálido de atardecer
   como AMBIENTE, tarjetas flotantes redondeadas con borde
   luminoso, sidebar con íconos en chips de color, inputs y
   botones con glow. El acento de ACCIÓN sigue siendo celeste
   (decisión de identidad); el naranja es solo atmósfera.
   ═══════════════════════════════════════════════════════════ */

/* ── Ambiente: banda de atardecer arriba + frío abajo ── */
.main-content {
  background:
    radial-gradient(ellipse 75% 52% at 85% -14%, rgba(251,146,60,.26) 0%, rgba(244,63,94,.10) 45%, transparent 68%),
    radial-gradient(ellipse 60% 46% at 5% -10%, color-mix(in srgb, var(--primary-d) 22%, transparent) 0%, transparent 62%),
    radial-gradient(ellipse 58% 48% at 104% 114%, color-mix(in srgb, var(--purple) 16%, transparent) 0%, transparent 62%),
    radial-gradient(ellipse 46% 34% at -6% 110%, color-mix(in srgb, var(--primary-d) 10%, transparent) 0%, transparent 60%),
    var(--bg-base);
}
html.light .main-content {
  background:
    radial-gradient(ellipse 75% 52% at 85% -14%, rgba(251,146,60,.13) 0%, transparent 62%),
    radial-gradient(ellipse 60% 46% at 5% -10%, color-mix(in srgb, var(--primary-d) 12%, transparent) 0%, transparent 62%),
    var(--bg-base);
}

/* ── Sidebar: íconos en chips de color por sección ── */
.nav-link::before {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: 9px; font-size: .82rem;
  background: linear-gradient(145deg, hsla(var(--nav-h,205),80%,62%,.34), hsla(var(--nav-h,205),80%,45%,.10));
  box-shadow: inset 0 0 0 1px hsla(var(--nav-h,205),80%,68%,.42), 0 0 10px -4px hsla(var(--nav-h,205),85%,60%,.5);
}
.nav-link:hover::before {
  background: linear-gradient(145deg, hsla(var(--nav-h,205),85%,64%,.48), hsla(var(--nav-h,205),85%,48%,.16));
  box-shadow: inset 0 0 0 1px hsla(var(--nav-h,205),85%,70%,.6), 0 0 16px -2px hsla(var(--nav-h,205),90%,60%,.65);
}
.nav-link.active::before {
  background: linear-gradient(145deg, hsla(var(--nav-h,205),90%,62%,.6), hsla(var(--nav-h,205),90%,45%,.26));
  box-shadow: inset 0 0 0 1px hsla(var(--nav-h,205),90%,72%,.75), 0 0 18px -2px hsla(var(--nav-h,205),95%,60%,.75);
}
/* Hue por sección (orden del NAV) — la paleta arcoíris del mock */
.nav-section:nth-of-type(1)  { --nav-h: 205; }  /* Principal — celeste  */
.nav-section:nth-of-type(2)  { --nav-h: 152; }  /* Maestros — verde     */
.nav-section:nth-of-type(3)  { --nav-h: 45;  }  /* Inventario — ámbar   */
.nav-section:nth-of-type(4)  { --nav-h: 25;  }  /* Compras — naranja    */
.nav-section:nth-of-type(5)  { --nav-h: 12;  }  /* Producción — coral   */
.nav-section:nth-of-type(6)  { --nav-h: 280; }  /* RRHH — violeta       */
.nav-section:nth-of-type(7)  { --nav-h: 335; }  /* Ventas — rosa        */
.nav-section:nth-of-type(8)  { --nav-h: 190; }  /* Finanzas — cian      */
.nav-section:nth-of-type(9)  { --nav-h: 60;  }  /* Tesorería — dorado   */
.nav-section:nth-of-type(10) { --nav-h: 260; }  /* Contabilidad — índigo*/
.nav-section:nth-of-type(11) { --nav-h: 320; }  /* Reportes — magenta   */
.nav-section:nth-of-type(12) { --nav-h: 215; }  /* Administración — azul*/
.nav-section:nth-of-type(13) { --nav-h: 0;   }  /* Sistema — rojo       */
html.light .nav-link::before {
  background: linear-gradient(145deg, hsla(var(--nav-h,205),65%,52%,.16), hsla(var(--nav-h,205),65%,40%,.05));
  box-shadow: inset 0 0 0 1px hsla(var(--nav-h,205),55%,45%,.28);
}
html.light .nav-link.active::before {
  background: linear-gradient(145deg, hsla(var(--nav-h,205),70%,50%,.30), hsla(var(--nav-h,205),70%,38%,.12));
  box-shadow: inset 0 0 0 1px hsla(var(--nav-h,205),60%,42%,.5);
}

/* Sidebar con profundidad extra y aurora al pie */
.sidebar {
  background:
    radial-gradient(ellipse 130% 26% at 50% 103%, rgba(251,146,60,.14) 0%, rgba(244,63,94,.05) 50%, transparent 74%),
    radial-gradient(ellipse 120% 18% at 50% -4%, color-mix(in srgb, var(--primary-d) 10%, transparent) 0%, transparent 70%),
    linear-gradient(180deg, #0a142c 0%, var(--bg-sidebar) 38%, #050b1c 100%);
}
html.light .sidebar { background: #ffffff; }

/* ── Tarjetas flotantes con borde luminoso ── */
.card {
  border-radius: 16px;
  border: 1px solid color-mix(in srgb, var(--primary) 22%, transparent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--primary) 10%, transparent) 0%, color-mix(in srgb, var(--primary) 0%, transparent) 34%),
    var(--bg-card);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),
    0 22px 48px -20px rgba(0,0,0,.9),
    0 0 22px -14px color-mix(in srgb, var(--primary-d) 30%, transparent);
  transition: border-color .22s ease, box-shadow .22s ease, transform .22s ease;
}
.card:hover {
  border-color: color-mix(in srgb, var(--primary) 38%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.09),
    0 26px 56px -20px rgba(0,0,0,.95),
    0 0 34px -10px color-mix(in srgb, var(--primary-d) 50%, transparent);
}
html.light .card {
  border: 1px solid color-mix(in srgb, var(--primary) 13%, transparent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 3%, transparent) 0%, rgba(255,255,255,0) 30%), var(--bg-card);
  box-shadow: 0 10px 28px -18px rgba(10,24,40,.28);
}
html.light .card:hover {
  border-color: color-mix(in srgb, var(--primary) 25%, transparent);
  box-shadow: 0 14px 34px -18px rgba(10,24,40,.32), 0 0 22px -14px color-mix(in srgb, var(--primary-d) 28%, transparent);
}

/* KPI cards: mismo tratamiento + esquinas más suaves */
.kpi-card {
  border-radius: 16px;
  border: 1px solid color-mix(in srgb, var(--primary) 24%, transparent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--primary) 9%, transparent) 0%, color-mix(in srgb, var(--primary) 0%, transparent) 40%),
    var(--bg-card);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 18px 40px -18px rgba(0,0,0,.85), 0 0 20px -12px color-mix(in srgb, var(--primary-d) 32%, transparent);
}
html.light .kpi-card {
  border: 1px solid color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: 0 10px 26px -18px rgba(10,24,40,.25);
}

/* ── Interfaz de carga: inputs con glow de foco ── */
.input, select.input, textarea.input,
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], input[type="month"], select, textarea {
  border-radius: 10px;
  transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
.input:focus, select.input:focus, textarea.input:focus,
input[type="text"]:focus, input[type="email"]:focus, input[type="password"]:focus,
input[type="number"]:focus, input[type="date"]:focus, input[type="month"]:focus,
select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary-d);
  box-shadow: 0 0 0 3px var(--primary-glow-s), 0 0 22px -8px var(--primary-glow);
  background: rgba(16, 25, 50, 0.95);
}
html.light .input:focus, html.light select:focus, html.light textarea:focus,
html.light input[type="text"]:focus, html.light input[type="number"]:focus,
html.light input[type="date"]:focus, html.light input[type="month"]:focus {
  background: #ffffff;
}
.label { letter-spacing: .01em; }

/* ── Botones con gradiente y glow ── */
.btn { border-radius: var(--radius); }
.btn-primary {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-d) 58%, #2f7ce8 130%);
  box-shadow: 0 5px 20px -7px color-mix(in srgb, var(--primary-d) 60%, transparent), inset 0 1px 0 rgba(255,255,255,.28);
}
.btn-primary:hover:not(:disabled) {
  box-shadow: 0 8px 26px -8px color-mix(in srgb, var(--primary-d) 78%, transparent), inset 0 1px 0 rgba(255,255,255,.3);
}
html.light .btn-primary {
  background: linear-gradient(135deg, #14b8a6 0%, var(--primary) 100%);
  box-shadow: 0 5px 18px -7px color-mix(in srgb, var(--primary) 55%, transparent);
}
.btn-secondary {
  border-radius: 11px;
  backdrop-filter: blur(4px);
}

/* ── Modales: hilo de aurora en el borde superior ── */
.modal-box, .modal { position: relative; }
.modal-box::after, .modal::after {
  content: '';
  position: absolute; top: 0; left: 20px; right: 20px; height: 2px;
  border-radius: 2px; pointer-events: none;
  background: linear-gradient(90deg,
    transparent, color-mix(in srgb, var(--primary) 75%, transparent) 22%, color-mix(in srgb, var(--purple) 55%, transparent) 55%, rgba(251,146,60,.5) 80%, transparent);
}

/* ── Contenedores de tabla flotantes ── */
.table-container { border-radius: var(--radius-lg); overflow: hidden; }

/* ── Título de página con degradé ── */
#pageTitle {
  background: linear-gradient(92deg, var(--gray-900) 30%, var(--primary) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  font-weight: 800; letter-spacing: -.02em;
}
html.light #pageTitle {
  background: linear-gradient(92deg, #0b3b52 40%, var(--primary) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ── Hero del dashboard: la banda de atardecer del mock ── */
.dash-hero {
  position: relative; overflow: hidden;
  padding: 1.9rem 2rem;
  border-radius: 22px;
  border: 1px solid rgba(251,146,60,.28);
  background:
    radial-gradient(ellipse 62% 150% at 88% 12%, rgba(251,146,60,.55) 0%, rgba(244,63,94,.28) 40%, rgba(168,85,247,.10) 62%, transparent 78%),
    radial-gradient(ellipse 45% 110% at 62% 105%, color-mix(in srgb, var(--purple) 22%, transparent) 0%, transparent 65%),
    radial-gradient(ellipse 40% 90% at 5% 0%, color-mix(in srgb, var(--primary-d) 16%, transparent) 0%, transparent 60%),
    linear-gradient(115deg, #0b1730 0%, #0e1c3e 55%, #171236 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.09),
    0 28px 60px -24px rgba(0,0,0,.9),
    0 0 44px -16px rgba(251,146,60,.35);
}
.dash-hero::before {
  content: '';
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(circle 3px at 82% 26%, rgba(255,255,255,.7) 0%, transparent 100%),
    radial-gradient(circle 2px at 90% 60%, rgba(255,255,255,.5) 0%, transparent 100%),
    radial-gradient(circle 2px at 72% 18%, color-mix(in srgb, var(--primary) 75%, transparent) 0%, transparent 100%),
    radial-gradient(circle 2.5px at 60% 70%, rgba(251,146,60,.6) 0%, transparent 100%),
    radial-gradient(circle 1.5px at 46% 30%, rgba(255,255,255,.4) 0%, transparent 100%),
    radial-gradient(circle 2px at 95% 35%, rgba(253,186,116,.6) 0%, transparent 100%);
}
.dash-hero::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px; pointer-events: none;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 70%, transparent) 28%, color-mix(in srgb, var(--purple) 50%, transparent) 55%, rgba(251,146,60,.7) 78%, transparent);
  filter: blur(.4px);
}
.dash-hero-saludo { font-size: 1.7rem; color: #f2f6ff; position: relative; text-shadow: 0 2px 18px rgba(0,0,0,.4); }
.dash-hero-fecha { position: relative; color: #b9c6e4; }
html.light .dash-hero {
  border: 1px solid rgba(234,120,56,.25);
  background:
    radial-gradient(ellipse 62% 140% at 88% 15%, rgba(251,146,60,.32) 0%, rgba(244,63,94,.10) 50%, transparent 74%),
    linear-gradient(115deg, #f0fdfa 0%, #e6f7f4 55%, #f3edff 100%);
  box-shadow: 0 18px 40px -22px rgba(10,24,40,.35), 0 0 30px -14px rgba(251,146,60,.3);
}
html.light .dash-hero-fecha { color: #4a6076; }
html.light .dash-hero-saludo { color: #0b3b52; }

/* ── Accesos rápidos: chips con el ícono iluminado ── */
.dash-acceso { border-radius: 12px; }
.dash-acceso-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: 9px; font-size: .84rem;
  background: linear-gradient(145deg, color-mix(in srgb, var(--primary) 32%, transparent), color-mix(in srgb, var(--primary-d) 10%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 40%, transparent), 0 0 10px -4px color-mix(in srgb, var(--primary-d) 45%, transparent);
}
.dash-acceso:hover { border-color: color-mix(in srgb, var(--primary) 50%, transparent); box-shadow: 0 0 24px -8px color-mix(in srgb, var(--primary-d) 65%, transparent); }
html.light .dash-acceso-ico {
  background: linear-gradient(145deg, color-mix(in srgb, var(--primary) 14%, transparent), color-mix(in srgb, var(--primary) 4%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 25%, transparent);
}

/* ── Scrollbars con estilo (WebKit) ── */
.main-content ::-webkit-scrollbar, .main-content::-webkit-scrollbar,
.sidebar-nav::-webkit-scrollbar, .modal-body::-webkit-scrollbar {
  width: 9px; height: 9px;
}
.main-content ::-webkit-scrollbar-thumb, .main-content::-webkit-scrollbar-thumb,
.sidebar-nav::-webkit-scrollbar-thumb, .modal-body::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 28%, transparent), rgba(99,102,241,.22));
  border-radius: 8px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.main-content ::-webkit-scrollbar-thumb:hover, .sidebar-nav::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--primary) 45%, transparent); background-clip: padding-box;
}
.main-content ::-webkit-scrollbar-track { background: transparent; }
html.light .main-content ::-webkit-scrollbar-thumb,
html.light .sidebar-nav::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--primary) 30%, transparent); background-clip: padding-box;
  border: 2px solid transparent; border-radius: 8px;
}

/* ── Estados vacíos con más aire ── */
.empty-state, [class*="empty"] .empty-icon { letter-spacing: 0; }
.empty-state { padding: 2.4rem 1rem; }

/* ── Header con reflejo de atardecer (todas las pantallas) ── */
.app-header {
  background:
    radial-gradient(ellipse 45% 160% at 92% 0%, rgba(251,146,60,.14) 0%, transparent 65%),
    radial-gradient(ellipse 35% 140% at 30% 0%, color-mix(in srgb, var(--primary-d) 10%, transparent) 0%, transparent 60%),
    var(--bg-header);
}
html.light .app-header {
  background:
    radial-gradient(ellipse 45% 160% at 92% 0%, rgba(251,146,60,.08) 0%, transparent 65%),
    rgba(255,255,255,.98);
}

/* ── Tablas: cabecera con leve brillo ── */
.table-container { border: 1px solid color-mix(in srgb, var(--primary) 14%, transparent); }
table thead th {
  background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 7%, transparent) 0%, color-mix(in srgb, var(--primary) 2%, transparent) 100%);
}
html.light .table-container { border-color: color-mix(in srgb, var(--primary) 14%, transparent); }
html.light table thead th { background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 5%, transparent) 0%, color-mix(in srgb, var(--primary) 1.5%, transparent) 100%); }

/* ── Tipografía más grande (pedido del usuario) ──
   La raíz pasa de 16px a 17px: TODO el sistema escala ~6%
   (textos, inputs, tablas) porque los tamaños están en rem.
   El menú lateral sube un punto extra por ser el más chico.
   Hallazgo (1-sep-2026, verificado con computed styles): esta regla es incondicional y
   viene DESPUÉS en el archivo, así que pisa cualquier html{font-size} de los escalones
   "Responsive — Smart TV / pantalla grande" (1440/1920/2560px) de más arriba — esos
   escalones hoy solo mueven --sidebar-w y el padding, el font-size que declaran ahí no
   hace nada. No se toca en esta ronda (es la preferencia de tipografía del usuario,
   tema aparte de la responsividad de ancho); se deja esta nota para no repetir la
   confusión de creer que sí escalan. */
html { font-size: 17px; }
.nav-link { font-size: .95rem; }
.nav-link::before { font-size: .95rem; }
.nav-label { font-size: .8rem; }
.nav-sublabel { font-size: .75rem; }
.dash-acceso { font-size: .95rem; }
@media (max-width: 768px) { html { font-size: 16px; } }

/* ── Accesibilidad: sin sorpresas si el usuario pide menos movimiento ── */
@media (prefers-reduced-motion: reduce) {
  .card, .card:hover { transition: none; }
}

/* ── QUE EL PANEL SE RECORTE DEL FONDO (pedido del usuario) ─────────────────
   El tema claro tenía el fondo de trabajo casi blanco (#f0fdfa) y la tarjeta
   blanca encima. Dos blancos con un borde de 13% de opacidad entre medio: la
   pantalla entera se leía como una sola hoja y no se veía dónde empieza y dónde
   termina cada panel. Se corrigen las TRES cosas que producen ese efecto —el
   fondo, el borde y el título— porque arreglar una sola no alcanza.

   El encabezado se aplica en LOS DOS TEMAS. Si viviera sólo en el claro, el
   oscuro se quedaría con el diseño viejo y la diferencia saltaría al cambiar de
   tema; sale de tres variables —fondo de la franja, color del texto y línea de
   abajo— y cada tema pone las suyas. En el oscuro la franja va más CLARA que la
   tarjeta y en el claro más OSCURA: en los dos casos se despega, que es lo único
   que importa. */
:root {
  --panel-cab-bg: rgba(125,211,252,.10);
  --panel-cab-fg: var(--gray-800);
  --panel-cab-bd: rgba(125,211,252,.18);
}
html.light {
  --panel-cab-bg: #b5d9d4;
  --panel-cab-fg: #1f4742;
  --panel-cab-bd: rgba(15,118,110,.34);
}

/* 1 · El fondo de trabajo baja un tono. Es lo que hace flotar a la tarjeta:
       mientras el fondo sea blanco, ningún borde alcanza para separarla.
       ESTO ES UN RESPALDO, no el valor que se ve: ambientes.js pinta --bg-base
       INLINE en <html> y el inline le gana a cualquier regla de esta hoja. El
       valor real se deriva del ambiente elegido (l − 9); acá sólo queda por si
       ese script no llegara a correr. Cambiar este número no cambia la pantalla
       —se probó, y por eso el fondo seguía viéndose blanco—. */
html.light { --bg-base: #dfecea; }

/* 2 · El borde de la tarjeta, visible sin ser una caja. */
html.light .card { border-color: color-mix(in srgb, var(--primary) 20%, transparent); }

/* 3 · El título del panel deja de ser un renglón más de texto y pasa a ser una
       CABECERA con fondo propio, de punta a punta del panel.
       Se toma también el primer h2/h3 de la tarjeta porque la mitad de los
       módulos escribe el título así, sin la clase. Los paneles centrados quedan
       afuera: la cabecera alineada a la izquierda de un contenido centrado se ve
       como un error. */
/* Un título que NO abre el panel —el que va en una fila junto a los filtros, por
   ejemplo— toma el color y nada más: si se saliera del padding rompería su fila. */
.card-title { color: var(--panel-cab-fg); font-weight: 700; }

.card:not(.text-center) > .card-title:first-child,
.card:not(.text-center) > h2:first-child,
.card:not(.text-center) > h3:first-child,
/* Buena parte del sistema abre el panel con una FILA —título a la izquierda,
   botones o filtros a la derecha— en vez de un título suelto. Sin esta línea la
   franja salía en unas tarjetas sí y en otras no, que es peor que no tenerla.
   El título tiene que ser el primer hijo de esa fila: así una fila de filtros sin
   título no se confunde con una cabecera. */
.card:not(.text-center) > div:first-child:has(> h2:first-child, > h3:first-child, > .card-title:first-child) {
  color: var(--panel-cab-fg);
  font-weight: 700;
  background: var(--panel-cab-bg);
  border-bottom: 1px solid var(--panel-cab-bd);
  /* La franja tiene que salir del padding de la tarjeta para llegar a los dos
     bordes. El !important es para ganarle al `style="margin:0"` que casi cien
     pantallas escriben en el título: sin eso, en unas la franja llegaría al borde
     y en otras no, que es peor que no tenerla. */
  margin: calc(var(--card-pad) * -1) calc(var(--card-pad) * -1) var(--card-pad) !important;
  padding: .5rem max(var(--card-pad), .85rem);
  /* 15px y no 16: por dentro del borde de 1px de la tarjeta. */
  border-radius: 15px 15px 0 0;
}

/* Cuánto hay que salirse para llegar al borde. `.p-2` y `.p-3` NO EXISTEN en esta
   hoja —las usan 146 tarjetas y nunca tuvieron padding—, así que para esas el
   valor correcto es cero: la franja ya nace pegada al borde. Se deja así a
   propósito; definirlas ahora movería el contenido de esas 146 pantallas de una
   vez, y eso es un cambio para mirar aparte. */
.card      { --card-pad: 0rem; }
.card.p-4  { --card-pad: 1rem; }
.card.p-5  { --card-pad: 1.25rem; }

/* 4 · La cabecera de la tabla, con peso suficiente para leerse como cabecera.
       Venía en #e6faf6, a dos puntos del blanco de la tarjeta. Sale de las mismas
       variables que la del panel: son la misma idea a dos escalas, y con un
       hexadecimal propio se quedaba en turquesa al cambiar de ambiente. */
html.light .data-table thead th {
  background: var(--panel-cab-bg);
  color: var(--panel-cab-fg);
  border-bottom: 1px solid var(--panel-cab-bd);
}

/* 5 · Los ENCABEZADOS DE LA PANTALLA toman el mismo color: la barra de menús de
       arriba y la del título. Eran blancos sobre fondo casi blanco, así que la
       pantalla empezaba sin un borde donde apoyar la vista. Salen de la misma
       variable que las cabeceras de panel, así que las tres cosas cambian juntas
       al elegir otro ambiente en 🎨 Apariencia. */
html.light body.nav-top .topnav {
  background: var(--panel-cab-bg);
  border-bottom-color: var(--panel-cab-bd);
}
html.light .app-header {
  background: var(--panel-cab-bg);
  border-bottom-color: var(--panel-cab-bd);
}
/* El rótulo de cada grupo del menú (RESUMEN, CAJA, VALORES EN CARTERA) con el
   mismo color de texto: es el mismo rango de encabezado, un nivel más abajo. */
html.light .nav-sublabel { color: var(--panel-cab-fg); }

/* ── Inicio en MOSAICOS (presentación estilo pantalla de inicio) ─────────────
   Tiles de color PLENO con texto blanco en los dos temas —como la pantalla que
   trajo el usuario de ejemplo—: acá el color es el contenido, no decoración.
   El matiz viaja por tile en --h; nada de hex sueltos. */
.mos-wrap { padding: .25rem 0 2rem; }
.mos-titulo { font-size: 2rem; font-weight: 300; letter-spacing: -.01em; margin: 0 0 .8rem .15rem; color: var(--gray-800); }
.mos-sec { margin-bottom: 1.5rem; }
.mos-sec-label { font-size: .75rem; text-transform: uppercase; letter-spacing: .07em; color: var(--gray-500); margin: 0 0 .45rem .15rem; }
.mos-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }
.mos-tile {
  position: relative; aspect-ratio: 1; border-radius: 4px; overflow: hidden;
  display: flex; flex-direction: column; padding: .6rem .7rem;
  background: hsl(var(--h) 58% 42%); color: white; text-decoration: none;
  transition: transform .12s ease, filter .12s ease;
}
.mos-tile:hover { filter: brightness(1.13); transform: scale(1.03); z-index: 1; }
.mos-tile:active { transform: scale(.96); }
.mos-tile:focus-visible { outline: 2px solid white; outline-offset: -4px; }
.mos-tile .mos-ico { font-size: 1.9rem; line-height: 1; margin: auto 0; filter: grayscale(1) brightness(6); }
.mos-tile .mos-nom { font-size: .74rem; font-weight: 600; line-height: 1.15; text-shadow: 0 1px 2px rgba(0,0,0,.3); }
.mos-tile.ancho { grid-column: span 2; aspect-ratio: auto; min-height: 118px; }
html.light .mos-tile { background: hsl(var(--h) 52% 45%); }
@media (max-width: 640px) { .mos-grid { grid-template-columns: repeat(auto-fill, minmax(94px, 1fr)); } .mos-tile.ancho { grid-column: span 2; } }
@media (prefers-reduced-motion: reduce) { .mos-tile, .mos-tile:hover, .mos-tile:active { transition: none; transform: none; } }

/* Mini-vistas del selector de Presentación (panel 🎨) */
.pres-swatch { display: flex; flex-direction: column; align-items: center; gap: .35rem; padding: .5rem .6rem; border: 1px solid var(--border-md); border-radius: 8px; background: transparent; cursor: pointer; color: var(--gray-600); }
.pres-swatch.sel { border-color: var(--primary-d); color: var(--primary-d); box-shadow: var(--glow-sm); }
.pres-mini { width: 84px; height: 52px; border-radius: 4px; background: var(--bg-surface); border: 1px solid var(--border); display: grid; padding: 4px; gap: 3px; }
.pres-mini.clasica { grid-template-columns: 18px 1fr; }
.pres-mini.clasica .pm-side { background: var(--bg-sidebar); border: 1px solid var(--border); border-radius: 2px; }
.pres-mini.clasica .pm-body { display: grid; gap: 3px; }
.pres-mini.clasica .pm-row { background: var(--bg-hover); border-radius: 2px; }
.pres-mini.mosaicos { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 1fr; }
.pres-mini.mosaicos span { border-radius: 2px; background: hsl(var(--h) 58% 46%); }
.pres-mini.mosaicos span.a { grid-column: span 2; }

/* ── Presentación MOSAICOS: el mosaico ES el menú ────────────────────────────
   Pedido del usuario: con la presentación Mosaicos, la cinta de departamentos
   no debe verse — se navega desde los tiles. Se esconden los menús y el 📌;
   QUEDAN la búsqueda Ctrl+K y el usuario/empresa (ahí viven cambiar de empresa
   y cerrar sesión). El encabezado suma el botón ⊞ Inicio para volver al mosaico.
   En modo menú lateral (sin cinta) el lateral se conserva: es el único lugar
   con la salida de sesión. */
body.pres-mosaicos #topnav .tn-menus,
body.pres-mosaicos #topnav #tnPin { display: none !important; }

/* Modo "Elegir tiles" del inicio en mosaicos: cada mosaico con su casilla;
   lo destildado queda apagado (editando) y desaparece del inicio (en uso). */
.mos-tile .mos-check {
  position: absolute; top: .4rem; right: .45rem; width: 1.05rem; height: 1.05rem;
  accent-color: white; cursor: pointer;
}
.mos-tile.oculto { opacity: .32; filter: saturate(.4); }

/* Números que cambian sin que la columna baile: tabulares en tablas y monoespaciado
   (skill de interfaz: font-variant-numeric en contadores, precios y totales). */
.data-table, .mono { font-variant-numeric: tabular-nums; }

/* Foco visible con teclado (skill de interfaz): quien navega con Tab tiene que
   VER dónde está. Solo :focus-visible — el clic con mouse no dibuja anillo. */
.btn:focus-visible, .tab-btn:focus-visible, .tn-menu-btn:focus-visible,
.btn-theme:focus-visible, .cfg-bloque:focus-within {
  outline: 2px solid var(--primary-d);
  outline-offset: 2px;
}

/* Los números van a la DERECHA (pedido del usuario en el cuadro del parte): la
   clase .num ya ponía dígitos tabulares pero nunca alineó — 17 módulos la usan
   y las cifras quedaban a la izquierda, imposibles de comparar por columna. */
.data-table td.num, .data-table th.num { text-align: right; }

/* ── Barra de desplazamiento VISIBLE (pedido del usuario: "casi no se ve") ─────
   Más ancha (14px) y con el acento PLENO: celeste vivo sobre fondo oscuro, teal
   oscuro sobre claro — el token se da vuelta solo. Va al FINAL para pisar las
   tres capas anteriores (la global de 5px, la del contenido al 28% y la clara). */
::-webkit-scrollbar,
.main-content ::-webkit-scrollbar, .main-content::-webkit-scrollbar,
.sidebar-nav::-webkit-scrollbar, .modal-body::-webkit-scrollbar {
  width: 16px; height: 14px;
}
::-webkit-scrollbar-track, html.light ::-webkit-scrollbar-track {
  background: color-mix(in srgb, var(--gray-300) 30%, transparent);
  border-radius: 8px;
}
::-webkit-scrollbar-thumb, html.light ::-webkit-scrollbar-thumb,
.main-content ::-webkit-scrollbar-thumb, .main-content::-webkit-scrollbar-thumb,
.sidebar-nav::-webkit-scrollbar-thumb, .modal-body::-webkit-scrollbar-thumb {
  background: var(--primary-d);
  border-radius: 8px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover, html.light ::-webkit-scrollbar-thumb:hover,
.main-content ::-webkit-scrollbar-thumb:hover, .sidebar-nav::-webkit-scrollbar-thumb:hover {
  background: var(--primary);
  background-clip: padding-box;
  box-shadow: none;
}
/* Firefox: mismo criterio con la propiedad estándar — pero SOLO Firefox. En
   Chrome/Edge modernos, scrollbar-color APAGA los estilos ::-webkit-scrollbar y
   pone la barra finita overlay que se desvanece sola — exactamente el "no
   permanece y es difícil ubicar el mouse" que reportó el usuario. El @supports
   la esconde de todo navegador que entienda ::-webkit-scrollbar. */
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-color: var(--primary-d) color-mix(in srgb, var(--gray-300) 30%, transparent); scrollbar-width: auto; }
}

/* ── Tabla larga con encabezado ANCLADO (pedido del usuario en el parte) ──────
   El contenedor scrollea y el thead queda pegado arriba; el tfoot (totales)
   pegado abajo — el contador nunca pierde de vista ni los títulos ni el total. */
.tabla-fija { max-height: 66vh; overflow: auto; scrollbar-gutter: stable; }   /* los dos ejes a propósito; el carril reservado evita que se realimenten */
/* Se ancla el THEAD entero (no cada th): así el encabezado de DOS filas del
   parte a mano —ENTRADAS/SALIDAS agrupadas arriba, conceptos abajo— viaja junto. */
.tabla-fija thead {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-surface);
  box-shadow: 0 1px 0 var(--border-md);
}
.tabla-fija thead th { background: var(--bg-surface); }
.tabla-fija tfoot td {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--bg-surface);
  box-shadow: 0 -1px 0 var(--border-md);
}
