/* assets/style.css — Dark Navy Theme */
/* Las fuentes (Inter + Material Symbols) se cargan vía <link rel="preconnect"> +
   <link rel="stylesheet"> en theme-boot.php (en el <head>, antes de este archivo),
   NO por @import aquí — el @import forzaba 3 saltos seriales render-blocking. */

/* ── DESIGN TOKENS ─────────────────────────────────────────────
   Tokens para los colores más reutilizados. Esta sección sienta base
   para light-mode / theming custom; los archivos legacy siguen con
   hex hardcodeado y resuelven idéntico. Migración incremental: cuando
   tocás un selector, considerá usar var() en vez del hex. */
:root {
  color-scheme: dark;
  /* Surfaces */
  --bg-page:        #0b1929;
  --bg-topbar:      #081425;
  --surface-0:      #0a1726;   /* deepest bg / wells */
  --surface-1:      #0f2137;   /* card / modal / panel default */
  --surface-2:      #0a1a30;   /* input / table-head / nested */
  --surface-3:      #0f2844;   /* hover lift / active row */
  --surface-raised: #162a40;   /* raised chip / elevated nested */
  /* Borders */
  --border-1:       #1a3554;
  --border-2:       #1e3d5f;
  --border-3:       #1e3a5f;   /* hover / focus border */
  --border-strong:  #2a4a70;
  /* Text */
  --text-strong:    #e0e8f0;
  --text-default:   #c8d6e5;
  --text-subtle:    #a0b8d0;
  --text-soft:      #8aa2c8;
  --text-dimmed:    #7a8da0;
  --text-muted:     #7a8da0;
  /* Accents (primary / status) */
  --accent:         #4a9ff5;
  --accent-bright:  #3b82f6;
  --accent-2:       #1877f2;
  --accent-rgb:     74, 159, 245;  /* = --accent en RGB → glows rgba(var(--accent-rgb),α); lo redefine cada preset */
  --accent-bright-rgb: 59, 130, 246;  /* = --accent-bright (#3b82f6) en RGB */
  --accent-2-rgb:      24, 119, 242;  /* = --accent-2 (#1877f2) en RGB */
  --success:        #3ddd7e;
  --warning:        #ffaa44;
  --warning-bright: #ffa502;
  --danger:         #ff6b6b;
  --notif-bg:       #dc2626; /* §310: globo de avisos — blanco sobre --danger (#ff6b6b) daba 2.8:1 */
  --info:           #66aaff;
  --purple:         #aa88ff;
  /* Status tints (badges / alertas): -bg = fondo, -bd = borde */
  --success-bg:     #082818;
  --success-bd:     #1a4030;
  --danger-bg:      #200808;
  --danger-bd:      #4a1818;
  --warning-bg:     #1e1408;
  --warning-bd:     #4a3010;
  --info-bg:        #082028;
  --info-bd:        #0c2a2e;
  --purple-bg:      #12082a;
  --purple-bd:      #3a1a60;
  /* Gráficas del Tablero de Dirección (§295): entra = acento, sale = naranja (se distinguen por
     tono Y luminosidad), "bien" = verde. */
  --chart-in:       #60a5fa;
  --chart-in-soft:  #1e3a8a;
  --chart-in-2:     #3b82f6;
  --chart-in-3:     #2563eb;
  --chart-in-4:     #1d4ed8;
  --chart-in-5:     #1e40af;
  --chart-out:      #fb923c;
  --chart-out-soft: #7c3a17;
  --chart-good:     #4ade80;
  --chart-good-soft:#14532d;
  --chart-warn:     #fbbf24;
  --chart-warn-soft:#78510f;
  --chart-danger:   #f87171;
  --chart-danger-soft:#7f1d1d;
  --chart-neutro:   #3a4a5e;
  --chart-grid:     #22303f;
  /* Shadows */
  --shadow-rgb:     0, 0, 0;        /* base de sombras: box-shadow usa rgba(var(--shadow-rgb), α) */
  --bg-page-rgb:    11, 25, 41;     /* para scrims / barras sticky con alfa */
  /* Touch / motion */
  --touch-target:   44px;
}

/* ── MODO CLARO · data-theme="light" en <html> (§ light-mode, fase 1) ─────────
   El modo OSCURO es el default y queda INTACTO: cada token de :root conserva su
   hex original, así toda la UI migrada a var() resuelve al MISMO color que antes.
   Aquí solo se re-mapea la paleta para claro. La migración es 1:1 (un token por
   color estructural) para que el oscuro sea pixel-idéntico y verificable.
   Pendiente fase 2 (tras QA visual): tintes one-off de badges/alertas + login
   (index.php) + portal cliente que aún usan hex crudo (≈30% de los usos). */
:root[data-theme="light"] {
  color-scheme: light;
  /* Surfaces */
  --bg-page:        #f1f4f9;
  --bg-topbar:      #ffffff;
  --surface-0:      #e9eef5;
  --surface-1:      #ffffff;
  --surface-2:      #f0f3f8;
  --surface-3:      #e6edf6;
  --surface-raised: #eef2f8;
  /* Borders */
  --border-1:       #d7dfea;
  --border-2:       #c7d2e0;
  --border-3:       #cdd8e6;
  --border-strong:  #aebfd3;
  /* Text */
  --text-strong:    #0e1f33;
  --text-default:   #1f2d3d;
  --text-subtle:    #45566a;
  --text-soft:      #56687d;
  --text-dimmed:    #5b6a7d;
  --text-muted:     #5b6a7d;
  /* Accents (ajustados para contraste AA sobre fondo claro) */
  --accent:         #2563eb;
  --accent-bright:  #3b82f6;
  --accent-2:       #1d4ed8;
  --accent-rgb:     37, 99, 235;
  --accent-bright-rgb: 59, 130, 246;
  --accent-2-rgb:      29, 78, 216;
  --success:        #15803d;
  --warning:        #b45309;
  --warning-bright: #c2710c;
  --danger:         #dc2626;
  --notif-bg:       #dc2626;
  --info:           #1d6fd0;
  --purple:         #7c3aed;
  /* Status tints (claro) */
  --success-bg:     #dcfce7;
  --success-bd:     #86efac;
  --danger-bg:      #fee2e2;
  --danger-bd:      #fca5a5;
  --warning-bg:     #fef3c7;
  --warning-bd:     #fcd34d;
  --info-bg:        #cffafe;
  --info-bd:        #67e8f9;
  --purple-bg:      #ede9fe;
  --purple-bd:      #c4b5fd;
  /* Gráficas del Tablero de Dirección (§295) */
  --chart-in:       #2563eb;
  --chart-in-soft:  #bfd3fb;
  --chart-in-2:     #3b82f6;
  --chart-in-3:     #60a5fa;
  --chart-in-4:     #93c5fd;
  --chart-in-5:     #bfdbfe;
  --chart-out:      #ea580c;
  --chart-out-soft: #fdc9a8;
  --chart-good:     #15803d;
  --chart-good-soft:#bbf7d0;
  --chart-warn:     #d97706;
  --chart-warn-soft:#fcd34d;
  --chart-danger:   #b91c1c;
  --chart-danger-soft:#fca5a5;
  --chart-neutro:   #cbd5e1;
  --chart-grid:     #e3e9f1;
  /* Shadows — más suaves sobre claro */
  --shadow-rgb:     20, 40, 70;     /* sombras azul-gris suaves, no negro duro */
  --bg-page-rgb:    241, 244, 249;
}

/* ── Presets de acento (data-accent en <html>; sin atributo / "azul" = base). ──
   Cada preset redefine --accent / -bright / -2 / -rgb para OSCURO y CLARO,
   curados para contraste AA (botón primario = texto blanco sobre --accent-2;
   texto-acento sobre superficie). Los aplica window.applyBranding (app.js) y
   theme-boot.php (anti-flash desde localStorage). Doc: configuracion.md (Marca). */
:root[data-accent="azul"]                          { --accent:#4a9ff5; --accent-bright:#3b82f6; --accent-2:#1877f2; --accent-rgb:74,159,245; }
:root[data-theme="light"][data-accent="azul"]      { --accent:#2563eb; --accent-bright:#3b82f6; --accent-2:#1d4ed8; --accent-rgb:37,99,235; }
:root[data-accent="teal"]                          { --accent:#2dd4bf; --accent-bright:#14b8a6; --accent-2:#0f766e; --accent-rgb:45,212,191; }
:root[data-theme="light"][data-accent="teal"]      { --accent:#0f766e; --accent-bright:#0d9488; --accent-2:#115e59; --accent-rgb:15,118,110; }
:root[data-accent="violeta"]                       { --accent:#a78bfa; --accent-bright:#8b5cf6; --accent-2:#7c3aed; --accent-rgb:167,139,250; }
:root[data-theme="light"][data-accent="violeta"]   { --accent:#7c3aed; --accent-bright:#8b5cf6; --accent-2:#6d28d9; --accent-rgb:124,58,237; }
:root[data-accent="esmeralda"]                     { --accent:#34d399; --accent-bright:#10b981; --accent-2:#059669; --accent-rgb:52,211,153; }
:root[data-theme="light"][data-accent="esmeralda"] { --accent:#047857; --accent-bright:#059669; --accent-2:#065f46; --accent-rgb:4,120,87; }
:root[data-accent="ambar"]                         { --accent:#fbbf24; --accent-bright:#f59e0b; --accent-2:#b45309; --accent-rgb:251,191,36; }
:root[data-theme="light"][data-accent="ambar"]     { --accent:#b45309; --accent-bright:#d97706; --accent-2:#92400e; --accent-rgb:180,83,9; }
:root[data-accent="rosa"]                          { --accent:#fb7185; --accent-bright:#f43f5e; --accent-2:#e11d48; --accent-rgb:251,113,133; }
:root[data-theme="light"][data-accent="rosa"]      { --accent:#be123c; --accent-bright:#e11d48; --accent-2:#9f1239; --accent-rgb:190,18,60; }
/* rojo = rojo de marca #e30613 (blanco encima 4.88:1, AA). Convive con --danger: los botones
   de borrar son tenues (.btn-del/.btn-danger: fondo claro + texto rojo) y llevan texto/ícono. */
:root[data-accent="rojo"]                          { --accent:#ff4d55; --accent-bright:#ff1f2b; --accent-2:#e30613; --accent-rgb:255,77,85; }
:root[data-theme="light"][data-accent="rojo"]      { --accent:#e30613; --accent-bright:#ff1f2b; --accent-2:#e30613; --accent-rgb:227,6,19; }
/* Con acento rojo, el --danger claro (#dc2626) quedaba casi igual al botón primario: en claro pasa a
   guinda (blanco encima 8.0:1, sobre su -bg 6.7:1). En oscuro no: ya se distinguen (#ff6b6b) y el
   guinda como texto sobre la superficie oscura reprobaría AA (2.0:1). Decisión del dueño (demo ALDI Rojo). */
:root[data-theme="light"][data-accent="rojo"]      { --danger:#9f1239; --danger-bg:#ffe4e6; --danger-bd:#fda4af; }
/* En cualquier preset (no-azul) los glows bright/-2 siguen al acento activo:
   colapsan al --accent-rgb del preset (un solo tono coherente). El default
   (sin atributo data-accent) conserva los 3 valores distintos de :root →
   fidelidad visual exacta del tema azul base. (Code-review Marca #1/#7.) */
:root[data-accent]:not([data-accent="azul"]) { --accent-bright-rgb: var(--accent-rgb); --accent-2-rgb: var(--accent-rgb); }

/* ── UI de Marca (Configuración → Marca) ── */
.brand-accent-row { display:flex; flex-wrap:wrap; gap:10px; }
.brand-accent { display:inline-flex; align-items:center; gap:8px; padding:8px 13px; border:1.5px solid var(--border-strong); border-radius:9px; background:var(--surface-1); color:var(--text-default); cursor:pointer; font-size:13px; transition:border-color .15s, background .15s; }
.brand-accent:hover { border-color:var(--accent); }
.brand-accent.sel { border-color:var(--accent); background:var(--surface-3); font-weight:600; }
.brand-accent-dot { width:16px; height:16px; border-radius:50%; background:var(--sw,#3b82f6); box-shadow:0 0 0 2px rgba(var(--shadow-rgb),.18); flex-shrink:0; }
.brand-prev { margin-top:8px; min-height:34px; display:flex; align-items:center; }
.brand-prev img { max-height:42px; max-width:170px; border-radius:6px; background:var(--surface-1); padding:4px; border:1px solid var(--border-1); }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: "Inter", "Segoe UI", sans-serif;
  font-size: 16px;
  background: var(--bg-page);
  color: var(--text-default);
  min-height: 100vh;
  min-height: 100dvh; /* iOS: ignora barra de URL retráctil */
}

/* ── MATERIAL SYMBOLS helper ── */
.mi {
  font-family: 'Material Symbols Outlined';
  font-style: normal;
  font-weight: normal;
  font-size: 18px;
  line-height: 1;
  vertical-align: middle;
  display: inline-flex;
  align-items: center;
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
  /* §446: el nombre del ícono es una LIGADURA ("person" → el dibujo). Dentro de un rótulo en
     mayúsculas (`.fg label`: uppercase + letter-spacing) se heredaba "PERSON" con letras separadas,
     la ligadura no se formaba y se veía el texto. El ícono no hereda nada de eso. */
  text-transform: none;
  letter-spacing: normal;
  white-space: nowrap;
  word-wrap: normal;
  font-feature-settings: 'liga';
}

/* ── TOPBAR ── */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 0 28px; height: 62px;
  background: var(--bg-topbar);
  border-bottom: 1px solid var(--border-1);
  position: sticky; top: 0; z-index: 20;
  box-shadow: 0 1px 8px rgba(var(--shadow-rgb),.3);
}
.topbar h1 {
  font-size: 18px; font-weight: 800;
  color: var(--text-strong); letter-spacing: -0.5px;
  display: flex; align-items: center; gap: 8px;
}
.topbar h1 span { color: var(--accent); }
/* Marca clickeable → lleva al dashboard (home). */
.topbar h1.brand-home { cursor: pointer; transition: opacity .15s; }
/* §235: "Portal de Clientes" / "Portal de Proveedores" antes del nombre o logo del tenant */
.topbar h1.brand-home .brand-prefix { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); margin-right: 8px; vertical-align: middle; }
@media (max-width: 480px) { .topbar h1.brand-home .brand-prefix { display: none; } }
.topbar h1.brand-home:hover { opacity: .8; }
.topbar h1.brand-home:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--text-muted); }
.topbar .right strong { color: var(--text-strong); font-weight: 600; }
/* Botón Soporte del topbar del portal cliente (cliente.php:24). Su CSS quedó
   huérfano al limpiar §84 (que era sobre admin.php); se reestablece (auditoría D0a). */
.topbar-soporte-btn { display: inline-flex; align-items: center; gap: 6px; background: var(--surface-1); border: 1px solid var(--border-1); color: var(--text-default); border-radius: 8px; padding: 7px 12px; font-size: 13px; font-weight: 600; cursor: pointer; font-family: inherit; transition: border-color .15s, color .15s; }
.topbar-soporte-btn:hover { border-color: var(--accent-bright); color: var(--text-strong); }
.topbar-soporte-btn .mi { font-size: 18px; color: var(--accent); }
/* Bajo ~1100 px la barra no cabe (marca + logo del cliente + atajos + tema + avisos + cuenta): los
   atajos Soporte/Facturación se retiran —siguen en el menú lateral— antes que dejarlos como iconos sin
   texto o encimados. Antes se encimaban con el logo y a 800 px había scroll horizontal. */
@media (max-width: 1100px) { .topbar .topbar-soporte-btn { display: none; } }

/* ── LAYOUT ── */
.layout { display: flex; height: calc(100vh - 62px); height: calc(100dvh - 62px); overflow: hidden; }
/* D7-fix: con un banner sticky arriba (vista Dirección / impersonate), descontar
   su altura del layout para que el body no desborde ni el banner tape el topbar
   al hacer scroll. --topbanner-h la mide el JS (el texto puede envolver). */
body.has-topbanner .layout { height: calc(100vh - 62px - var(--topbanner-h, 36px)); height: calc(100dvh - 62px - var(--topbanner-h, 36px)); }

.sidebar {
  width: 240px; flex-shrink: 0;
  background: var(--bg-topbar);
  border-right: 1px solid var(--border-1);
  padding: 16px 12px;
  display: flex; flex-direction: column; gap: 2px;
  overflow-y: auto;
  /* overflow-x: hidden es CRÍTICO. Sin él, al fijar overflow-y:auto el CSS
     coacciona overflow-x a 'auto' → un nav-item ancho (o un label largo)
     genera scroll horizontal, y ese offset RECORTA los encabezados de grupo
     por la IZQUIERDA (bug reportado: "M/ERACIONES/MON/MPRAS"). Clip mata el
     scroll horizontal; los labels largos se truncan con ellipsis (regla abajo).
     El modo iconos colapsado usa `overflow: visible` (shorthand, más específico)
     para dejar salir los tooltips flotantes — no lo afecta este hidden. */
  overflow-x: hidden;
  /* Quirk de flexbox: un hijo flex con overflow:auto NO se engancha si su
     min-height es 'auto' (default), porque su altura mínima se calcula del
     contenido y no se constreñe a la del padre. Con min-height:0 forzamos
     que la altura del sidebar = altura del .layout, y overflow-y:auto
     scrollea internamente cuando el nav es más largo que la pantalla. */
  min-height: 0;
}

.nav-section-title {
  font-size: 11px; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 1.2px;
  padding: 12px 14px 6px;
}

.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; border-radius: 8px;
  cursor: pointer; font-size: 13px; font-weight: 500; color: var(--text-muted);
  transition: .15s; border: 1px solid transparent;
  text-decoration: none; white-space: nowrap;
}
.nav-item .mi { font-size: 20px; color: var(--text-muted); transition: .15s; }
/* Label largo (el <span> sin clase, junto al icono) se trunca con ellipsis en
   vez de forzar el ancho del sidebar → evita el overflow horizontal. Es flex
   item: min-width:0 permite que encoja por debajo de su contenido. */
.nav-item > span:not([class]) {
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.nav-item:hover { background: var(--surface-1); color: var(--accent); }
.nav-item:hover .mi { color: var(--accent); }
.nav-item.active {
  background: var(--surface-3); color: var(--accent);
  border-color: var(--border-strong);
  font-weight: 600;
}
.nav-item.active .mi { color: var(--accent); }

.content {
  flex: 1; padding: 32px; overflow-y: auto; background: var(--bg-page);
  --sh-pad-top: 32px; /* §pto5: alto del padding-top, lo hereda .section-header */
  /* Mismo quirk que .sidebar: sin min-height:0, el flex item .content puede
     crecer al alto natural de su contenido en vez de ceñirse al .layout, y
     el overflow-y:auto pierde efecto. */
  min-height: 0;
  /* Habilitamos container queries: hijos pueden responder al ancho real
     del .content (no al viewport). Crítico cuando el sidebar está
     abierto/cerrado o el dashboard se embebe en un drawer angosto. */
  container-type: inline-size; container-name: app-content;
  /* Evita el rubber-band de iOS al hacer pull-to-refresh — el browser
     sino "rebota" la página entera y nuestro handler no se siente nativo. */
  overscroll-behavior-y: contain;
}

/* ── BUTTONS ── */
.btn {
  border: none; border-radius: 8px; padding: 9px 20px;
  font-size: 13px; font-weight: 600; cursor: pointer; transition: .2s;
  font-family: inherit; display: inline-flex; align-items: center; gap: 6px;
}
.btn .mi { font-size: 16px; }
@media (hover: hover) {
  .btn:hover { opacity: .9; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(var(--shadow-rgb),.3); }
}
.btn:active { transform: translateY(0); }
.btn:disabled { opacity: .35; cursor: not-allowed; transform: none; box-shadow: none; }
.btn:focus-visible, .btn-sm:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn-primary { background: var(--accent-2); color: #fff; box-shadow: 0 2px 8px rgba(var(--accent-2-rgb),.3); }
.btn-primary:hover { background: var(--accent); box-shadow: 0 4px 16px rgba(var(--accent-2-rgb),.4); }
.btn-ghost { background: var(--surface-1); border: 1px solid var(--border-1); color: var(--text-subtle); }
.btn-ghost:hover { background: var(--surface-raised); border-color: var(--border-strong); color: var(--text-strong); }
.btn-danger { background: var(--danger-bg); border: 1px solid var(--danger-bd); color: var(--danger); }

.btn-sm { padding: 5px 12px; font-size: 12px; border-radius: 6px; border: none; cursor: pointer; transition: .15s; font-family: inherit; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; }
.btn-sm .mi { font-size: 14px; }
.btn-view { background: var(--surface-1); color: var(--text-default); border: 1px solid var(--border-1); }
.btn-view:hover { background: var(--surface-raised); }
.btn-edit { background: var(--surface-1); color: var(--accent); border: 1px solid var(--border-strong); }
.btn-edit:hover { background: var(--surface-3); }
.btn-del  { background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger-bd); }
.btn-del:hover  { background: var(--danger-bg); }
.btn-success { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.btn-success:hover { background: var(--success-bg); }

/* ── CARDS ── */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 28px; }
.card {
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: 12px; padding: 22px 24px;
  position: relative; overflow: hidden;
  transition: border-color .2s, box-shadow .2s;
  box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.2);
}
.card:hover { border-color: var(--border-strong); box-shadow: 0 4px 16px rgba(var(--shadow-rgb),.3); }
.card-clickable { cursor: pointer; user-select: none; }
.card-clickable:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.card-clickable:active { transform: translateY(0); }
.card::before { content:''; position:absolute; top:0; left:0; right:0; height:3px; background:linear-gradient(90deg,var(--accent-2),var(--accent)); opacity:0; transition:opacity .2s; }
.card:hover::before { opacity:1; }
.card .lbl { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; font-weight: 700; }
.card .val { font-size: clamp(22px, 1.6vw + 16px, 28px); font-weight: 800; color: var(--accent); line-height: 1; }
.card .hint { font-size: 12px; color: var(--text-muted); margin-top: 6px; }

/* ── TABLE ── */
.table-wrap {
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: 12px; overflow: hidden; overflow-x: auto;
  margin-bottom: 20px;
  box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.2);
}
.table-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--border-strong); gap: 12px; flex-wrap: wrap;
  background: var(--surface-2);
}
/* Variante de `.table-head` para pantallas que envuelven su tabla en `.info-card`
   (padding:24px propio) en vez de `.table-wrap` (sin padding). "Sangra" hacia los 4
   bordes del padre para lograr el mismo look de barra con fondo+borde — mismo criterio
   que `.modal-btns` cancelando el padding de `.modal` (DECISIONES.md §158). Nace de un
   bug real: ~19 pantallas de addons reinventaban el header a mano con
   `style="display:flex;justify-content:space-between"` suelto — sin fondo ni borde,
   dejaba un hueco vacío enorme entre el título y el buscador (§161, DECISIONES.md).
   Los hijos (título, buscador, botones) NO cambian — solo el div que los envuelve. */
.card-table-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  margin: -24px -24px 16px; padding: 14px 24px;
  background: var(--surface-2); border-bottom: 1px solid var(--border-strong);
  border-radius: 12px 12px 0 0;
}

/* ── Paginator (setupPagination, ver utils.js) ── */
.paginator {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding: 10px 20px; border-top: 1px solid var(--border-strong);
  background: var(--surface-2); font-size: 12px; color: var(--text-subtle);
}
.paginator:empty { display: none; }
.paginator .pg-info { font-weight: 600; color: var(--text-default); }
.paginator .pg-nav { display: flex; align-items: center; gap: 4px; }
.paginator .pg-nav .btn { min-width: 32px; padding: 4px 8px; font-size: 14px; line-height: 1; }
.paginator .pg-nav .btn[disabled] { opacity: .35; cursor: default; pointer-events: none; }
.paginator .pg-page { padding: 0 8px; color: var(--text-default); font-variant-numeric: tabular-nums; }
.paginator .pg-size {
  background: var(--surface-2); border: 1px solid var(--border-2); color: var(--text-default);
  padding: 4px 8px; border-radius: 6px; font-size: 12px; cursor: pointer;
}
.paginator .pg-size:hover { border-color: var(--border-strong); }
.table-head h3 { font-size: 14px; font-weight: 700; color: var(--text-strong); }
/* §217 — encabezado normalizado por el paginador: dos renglones fijos. */
/* `justify-content: space-between` heredado de .table-head NO estira la columna del grid: la
   pista quedaba al ancho del contenido (296px) y "+ Filtro" caía debajo del buscador aunque
   sobrara medio metro (visto en el sitio, §220). Una columna explícita que ocupa todo. */
.table-head.pg-head, .card-table-head.pg-head { display: grid; grid-template-columns: minmax(0, 1fr); justify-content: stretch; gap: 10px; }
.pg-head .th-r1, .pg-head .th-r2 { min-width: 0; width: 100%; }
.pg-head .th-r1 { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pg-head .th-titulo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pg-head .th-titulo h3 { margin: 0; }
.pg-head .th-hint { font-size: 12.5px; color: var(--text-muted); font-weight: 400; }
.pg-head .th-acciones { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.pg-head .th-r2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pg-head .th-r2 .search-input { flex: 0 1 260px; min-width: 160px; margin: 0; }
.pg-head .th-r2 .smart-filters { display: contents; }
.pg-head .th-r2 .sf-chips:empty { display: none; }
/* §219 — columna Vigencia */
.rango { white-space: nowrap; }
.rango-flecha { color: var(--text-dimmed); padding: 0 3px; }
.rango-sinfin { display: inline-block; padding: 1px 8px; border-radius: 20px; font-size: 11px; font-weight: 700; background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-bd); vertical-align: 1px; }
.sf-rango { display: grid; gap: 8px; padding: 10px 12px; }
.sf-rango label { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--text-subtle); }
.sf-rango input[type="date"] { font: inherit; font-size: 12.5px; padding: 4px 6px; border: 1px solid var(--border-2); border-radius: 6px; background: var(--surface-1); color: var(--text-default); }
@media (max-width: 640px) { .pg-head .th-r2 .search-input { flex-basis: 100%; } .pg-head .th-acciones { margin-left: 0; width: 100%; } }
.smart-filters { display:flex; gap:8px; flex-wrap:wrap; padding:10px 20px; border-bottom:1px solid var(--border-strong); background:var(--surface-2); }
.smart-filter { background:var(--bg-page); border:1px solid var(--border-2); border-radius:6px; padding:5px 10px; color:var(--text-subtle); font-size:11px; cursor:pointer; outline:none; }
.smart-filter:focus { border-color:var(--accent-bright); }
.table-footer { padding: 12px 20px; text-align: center; border-top: 1px solid var(--border-strong); }

.search-input {
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 7px 14px 7px 36px; color: var(--text-strong); font-size: 12px; outline: none;
  transition: .2s; min-width: 200px; font-family: inherit;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%235a7090' viewBox='0 0 16 16'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.099zm-5.242 1.156a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: 10px center;
}
.search-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); }
.search-input::placeholder { color: var(--text-muted); }

/* `.select-compact` — mismo look-and-feel de `.search-input` (caja/borde/tema)
   para `<select>` de filtro (periodo, régimen, empresa, proyecto…), SIN la
   lupa ni el padding-izq reservado para ella: esos vienen de fábrica en
   `.search-input`, pensados para `<input>` de búsqueda de texto. Antes ~28
   `<select>` en 6 módulos reusaban `.search-input` tal cual → una lupa
   decorativa (que no busca nada) en cada selector de Año/Mes/Régimen/Empresa
   de Tesorería (Panorama Fiscal completo + Conciliación bancaria), reportado
   por el dueño como "se ve como un campo roto". Ver DECISIONES.md. */
.select-compact {
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 7px 14px; color: var(--text-strong); font-size: 12px; outline: none;
  transition: .2s; min-width: 120px; font-family: inherit;
}
.select-compact:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); }

table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; padding: 11px 18px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .8px; color: var(--text-muted); border-bottom: 1px solid var(--border-strong);
  font-weight: 700; white-space: nowrap; user-select: none;
  background: var(--surface-2);
}
th.sortable { cursor: pointer; transition: color .15s; }
th.sortable:hover { color: var(--accent); }
th.sortable::after { content: ' \2195'; font-size: 11px; opacity: .55; }
th.sort-asc::after  { content: ' \2191'; opacity: 1; color: var(--accent); }
th.sort-desc::after { content: ' \2193'; opacity: 1; color: var(--accent); }

td { padding: 12px 18px; font-size: 14px; border-bottom: 1px solid var(--border-1); color: var(--text-subtle); }

/* ── Smart filters as chips (Linear/Folk 2026) ── */
.smart-filters-chips {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  padding: 10px 20px; background: var(--surface-1); border-bottom: 1px solid var(--border-strong);
}
.sf-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.sf-hidden-select { display: none; }
.sf-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--border-1); color: var(--text-default);
  border: 1px solid var(--border-strong); border-radius: 16px;
  padding: 3px 4px 3px 10px; font-size: 12px; font-weight: 500;
  line-height: 1.4;
}
.sf-chip-label { color: var(--text-soft); font-weight: 600; }
.sf-chip-value { color: var(--text-default); }
.sf-chip-remove {
  background: none; border: none; color: var(--text-soft); cursor: pointer;
  padding: 0 4px; font-size: 15px; line-height: 1; border-radius: 50%;
  width: 18px; height: 18px; display: inline-flex; align-items: center;
  justify-content: center; transition: background .12s, color .12s;
}
.sf-chip-remove:hover { background: rgba(255,107,107,.15); color: var(--danger); }
.sf-add-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px; font-size: 12px;
  border: 1px dashed var(--border-strong); border-radius: 16px;
  color: var(--text-soft); background: transparent;
}
.sf-add-btn:hover { background: var(--surface-1); border-style: solid; color: var(--text-default); }
.sf-add-btn .mi { font-size: 14px; }

.sf-menu-popover {
  position: fixed; z-index: 9999; min-width: 220px; max-width: 280px;
  background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 8px;
  box-shadow: 0 8px 32px rgba(var(--shadow-rgb),.4);
  padding: 4px; max-height: 60vh; overflow-y: auto;
}
.sf-menu-header {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; text-transform: uppercase; letter-spacing: .8px;
  color: var(--text-muted); padding: 8px 10px 6px; font-weight: 700;
}
.sf-menu-back {
  background: none; border: none; cursor: pointer; padding: 2px;
  color: var(--text-soft); border-radius: 4px; display: flex; align-items: center;
}
.sf-menu-back:hover { background: var(--surface-raised); color: var(--text-default); }
.sf-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: none; cursor: pointer; text-align: left;
  padding: 6px 10px; border-radius: 6px; color: var(--text-default); font-size: 13px;
  transition: background .12s;
}
.sf-menu-item:hover { background: var(--surface-raised); }
.sf-menu-item .mi { color: var(--text-muted); font-size: 14px; }

/* ── Column visibility popover (Linear/Airtable 2026) ── */
.col-vis-popover {
  position: fixed; z-index: 9999; width: 240px;
  background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 8px;
  box-shadow: 0 8px 32px rgba(var(--shadow-rgb),.4);
  padding: 6px; max-height: 60vh; overflow-y: auto;
}
.col-vis-header {
  font-size: 11px; text-transform: uppercase; letter-spacing: .8px;
  color: var(--text-muted); padding: 8px 10px 6px; font-weight: 700;
}
.col-vis-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 6px; cursor: pointer;
  color: var(--text-default); font-size: 13px; transition: background .12s;
}
.col-vis-row:hover { background: var(--surface-raised); }
.col-vis-row input[type="checkbox"] { cursor: pointer; }
.col-vis-footer {
  border-top: 1px solid var(--border-1); margin-top: 6px; padding-top: 6px;
  display: flex; justify-content: flex-end;
}

/* ── Saved Views popover (Linear/Airtable 2026) ── */
.views-popover {
  position: fixed; z-index: 9999; width: 260px;
  background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 8px;
  box-shadow: 0 8px 32px rgba(var(--shadow-rgb),.4);
  padding: 6px; max-height: 60vh; overflow-y: auto;
}
.views-header {
  font-size: 11px; text-transform: uppercase; letter-spacing: .8px;
  color: var(--text-muted); padding: 8px 10px 6px; font-weight: 700;
}
.views-empty {
  padding: 12px 10px; color: var(--text-muted); font-size: 12px; font-style: italic; text-align: center;
}
.views-item {
  display: flex; align-items: center; gap: 4px;
  border-radius: 6px; transition: background .12s;
}
.views-item:hover { background: var(--surface-raised); }
.views-item-load {
  flex: 1; background: none; border: none; cursor: pointer; text-align: left;
  padding: 7px 10px; color: var(--text-default); font-size: 13px;
}
.views-item-del {
  background: none; border: none; cursor: pointer;
  padding: 6px 8px; color: var(--text-muted); border-radius: 4px;
}
.views-item-del:hover { color: var(--danger); background: rgba(255,107,107,.1); }
.views-footer {
  border-top: 1px solid var(--border-1); margin-top: 6px; padding-top: 8px; padding-bottom: 4px;
  display: flex; justify-content: center;
}
.views-footer .btn { width: 95%; }

tr:last-child td { border-bottom: none; }
@media (hover: hover) {
  tr:hover td { background: var(--surface-3); }
  tr.clickable:hover td { background: var(--surface-3); cursor: pointer; }
}
tr[onclick]:focus-visible,
tr.clickable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; background: var(--surface-3); }
tr[onclick]:focus-visible td,
tr.clickable:focus-visible td { background: var(--surface-3); }
.link-cell { color: var(--accent); cursor: pointer; font-weight: 500; }
.link-cell::after { content: 'open_in_new'; font-family: 'Material Symbols Outlined'; font-size: 13px; margin-left: 3px; vertical-align: -1px; opacity: .55; }
.link-cell:hover { text-decoration: underline; text-underline-offset: 2px; }
.link-cell:hover::after { opacity: .85; }

.td-actions { display: flex; gap: 8px; align-items: center; }
.td-actions .btn-sm { min-height: 32px; } /* D12: blanco de clic más cómodo para 40+ (antes ~26px) */
.empty-row { text-align: center; color: var(--text-muted); padding: 48px; font-size: 13px; }
.empty-row .empty-row-action { margin-top: 12px; }  /* §201: botón de la acción bajo el mensaje vacío */

/* ── Acciones de fila estilo WordPress (tablas v3) ─────────────────────────
   El título es un enlace (= "Ver"); las acciones viven DEBAJO del título,
   ocultas por default y reveladas al pasar el mouse por la fila (desktop) o
   SIEMPRE en touch (decisión del dueño). El relocator `_pgApplyWpRows`
   (utils.js) mueve la tira de acciones aquí y oculta la columna "Acciones"
   original, en tablas cuya celda de título está marcada con `.td-title`. */
.td-title .row-title {
  color: var(--accent); cursor: pointer; text-decoration: none; outline-offset: 2px;
}
.td-title .row-title:hover { text-decoration: underline; text-underline-offset: 2px; }
/* A11y: row-title / link-cell son <a> sin href; el relocator les pone tabindex.
   Indicador de foco por teclado para que se vea cuál está enfocado. */
.row-title:focus-visible, .link-cell:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px;
}
.row-actions {
  display: flex; flex-wrap: wrap; gap: 2px 9px; align-items: center;
  margin-top: 3px; min-height: 17px;
  /* §201 (decisión del dueño sobre captura): la tira se ve SIEMPRE, en tono tenue, y a
     pleno al pasar el mouse o enfocar la fila. Antes era opacity:0 + visibility:hidden
     hasta el hover: en escritorio nadie descubría que existía (P1 del playbook:
     "visible por default, no sólo en :hover"), y para el público 40+ una acción que
     hay que adivinar es una acción que no existe. Al estar visibles quedan también en
     el tab-order, que es lo correcto para teclado. */
  opacity: .55;
  transition: opacity .12s ease;
}
tr:hover .td-title .row-actions,
tr:focus-within .td-title .row-actions {
  opacity: 1;
}
.row-actions .ra-link {
  background: none; border: none; padding: 0; cursor: pointer; font-family: inherit;
  font-size: 12.5px; color: var(--text-muted); line-height: 1.4;
  display: inline-flex; align-items: center; gap: 3px;
}
.row-actions .ra-link:hover { color: var(--accent); text-decoration: underline; }
.row-actions .ra-link.danger:hover { color: var(--danger); }
.row-actions .ra-link .mi { font-size: 15px; }
.row-actions .ra-link:not(:first-child)::before {
  content: "·"; color: var(--text-muted); margin-right: 9px; pointer-events: none; cursor: default;
}
/* Oculta la columna de acciones original (celda + th) en tablas convertidas. */
.wp-actions-hidden { display: none !important; }
/* Touch / sin hover: acciones a pleno siempre (no hay hover que las suba). */
@media (hover: none) {
  .row-actions { opacity: 1; }
}

/* ── BADGES ── */
.badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 700; white-space: nowrap; }

/* Inline-editable pill (Quick win #7) — patrón Attio. Click en el pill
   abre un popover con las opciones del catálogo. Hover muestra un
   chevron sutil para indicar que es clickeable. */
.badge.edit-pill {
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 2px;
  padding-right: 4px;
  transition: filter .12s ease, box-shadow .12s ease;
  user-select: none;
}
.badge.edit-pill .edit-pill-chev {
  font-size: 14px !important;
  opacity: .4;
  margin-left: -2px;
  transition: opacity .12s ease;
}
.badge.edit-pill:hover { filter: brightness(1.15); box-shadow: 0 0 0 1px rgba(var(--accent-rgb),.5); }
.badge.edit-pill:hover .edit-pill-chev,
.badge.edit-pill:focus-visible .edit-pill-chev,
.badge.edit-pill.edit-pill-open .edit-pill-chev { opacity: .7; }
.badge.edit-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.badge.edit-pill.edit-pill-open { box-shadow: 0 0 0 2px rgba(var(--accent-rgb),.7); }
.badge.edit-pill.saving { opacity: .55; pointer-events: none; }
/* En modo Dirección desactivamos la edición inline (vista read-only). */
body.viewmode-directivo .badge.edit-pill { cursor: default; pointer-events: none; }
body.viewmode-directivo .badge.edit-pill .edit-pill-chev { display: none; }
/* En modo Dirección, los tabs del modal de Colaborador para "Acceso al portal"
   y "Asignaciones" desaparecen — la edición de credenciales y la vista de
   asignaciones operativas no aplican al perfil ejecutivo. Si el modal abre,
   solo se ve "Información" en read-only (los botones primary ya están ocultos). */
body.viewmode-directivo #col-tab-acceso,
body.viewmode-directivo #col-tab-asignaciones,
body.viewmode-directivo .modal-tab[data-tab="acceso"],
body.viewmode-directivo .modal-tab[data-tab="asignaciones"] { display: none !important; }
@media (hover: none) {
  /* Touch: el chevron siempre visible para indicar que es clickeable. */
  .badge.edit-pill .edit-pill-chev { opacity: .7; }
}

/* Popover de opciones — flotante, posición calculada en JS. */
.inline-edit-popover {
  position: fixed;
  z-index: 200;
  min-width: 180px; max-width: 280px;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(var(--shadow-rgb),.45), 0 2px 6px rgba(var(--shadow-rgb),.3);
  padding: 4px;
  display: flex; flex-direction: column; gap: 2px;
  max-height: min(60vh, 360px); overflow-y: auto;
  animation: inlineEditPopIn .14s ease-out;
}
@keyframes inlineEditPopIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.inline-edit-popover.pop-up { animation-name: inlineEditPopUpIn; }
@keyframes inlineEditPopUpIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.inline-edit-option {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 10px;
  background: transparent; border: 1px solid transparent; border-radius: 7px;
  color: var(--text-default); font-size: 13px; text-align: left;
  cursor: pointer; transition: background .1s ease, border-color .1s ease;
}
.inline-edit-option:hover,
.inline-edit-option:focus-visible {
  background: var(--surface-raised); border-color: var(--border-strong); outline: none;
}
.inline-edit-option.is-current { background: var(--surface-raised); }
.inline-edit-option .mi { color: var(--accent); }
.inline-edit-option-pill { font-size: 11px; }

.badge-Activo,.badge-Pagado     { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Liquidado                { background:var(--info-bg); color:var(--info); border:1px solid var(--info-bd); }
.badge-Inactivo,.badge-Cancelado{ background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-bd); }
.badge-Moroso,.badge-Vencido    { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-Pendiente                { background:var(--surface-1); color:var(--info); border:1px solid var(--border-strong); }
.badge-EnRenovacion             { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-Vigente                  { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
/* §236: semáforo de vigencia del portal externo ("Por vencer" → clase sin espacio) */
.badge-Porvencer                { background:var(--warning-bg); color:var(--warning); border:1px dashed var(--warning-bd); }
.badge-Principal                { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-Facturacion,.badge-Facturación { background:var(--surface-1); color:var(--info); border:1px solid var(--border-strong); }
.badge-Fiscal                   { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-Digital,.badge-SEO,.badge-Web,.badge-Branding,.badge-Publicidad { background:var(--info-bg); color:var(--info); border:1px solid var(--border-strong); }
.badge-Hosting,.badge-Produccion,.badge-Consultoria { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-Estandar,.badge-Estándar { background:var(--surface-1); color:var(--info); border:1px solid var(--border-strong); }
.badge-Preferencial             { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Volumen                  { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-Unico,.badge-Único       { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-Aplicado   { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Parcial    { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-Pendientedepago { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-PorTimbrar { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-EnNegociacion { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-EnRevision { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-Prospecto  { background:var(--surface-1); color:var(--info); border:1px solid var(--border-strong); }
.badge-PropuestaEnviada { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-Cerrada    { background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-bd); }
.badge-Porfacturar { background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }
.badge-Borrador   { background:var(--surface-1); color:var(--text-default); border:1px solid var(--border-3); }
.badge-Timbrada   { background:var(--info-bg); color:var(--info); border:1px solid var(--border-strong); }
.badge-Enviada    { background:var(--surface-1); color:var(--info); border:1px solid var(--border-strong); }
.badge-Pagada     { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Cancelada  { background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-bd); }
.badge-Archivado  { background:var(--surface-1); color:var(--text-default); border:1px solid var(--border-3); }
.badge-Condonado  { background:var(--purple-bg); color:var(--purple); border:1px solid var(--purple-bd); }
.badge-Perdido    { background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-bd); }
.badge-Activa     { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Aceptada,.badge-Completada { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Rechazada  { background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-bd); }
.badge-Programado { background:var(--surface-1); color:var(--info); border:1px solid var(--border-strong); }
/* §estados-de-venta (ventas 1.9.0): los dos ejes derivados de la venta.
   Ojo: la clase la deriva `badge()` (app.js) quitando espacios y acentos del valor,
   así que "En renovación" → .badge-Enrenovacion (distinta de la ya existente
   .badge-EnRenovacion, que es el valor 'En Renovacion' del catálogo de acuerdos).
   `.badge-Porfacturar`, `.badge-Parcial`, `.badge-Vigente` y `.badge-Completada` ya
   existen arriba y se reusan tal cual. */
.badge-Norequiere,.badge-Sincobro,.badge-Concluido { background:var(--surface-1); color:var(--text-dimmed); border:1px solid var(--border-3); }
.badge-Facturada,.badge-Cobrada,.badge-Alcorriente { background:var(--success-bg); color:var(--success); border:1px solid var(--success-bd); }
.badge-Conatraso,.badge-Facturacancelada   { background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-bd); }
.badge-Enrenovacion{ background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-bd); }

/* ── MODAL ── */
.overlay { position:fixed; inset:0; background:rgba(0,10,20,.65); display:none; align-items:center; justify-content:center; z-index:100; backdrop-filter:blur(4px); }
.overlay.open { display:flex; animation:fadeIn .15s ease; }
@keyframes fadeIn { from{opacity:0} to{opacity:1} }

.modal {
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: 16px;
  padding: 32px 32px 0; width: 580px; max-width: 92vw; max-height: 90vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 18px;
  box-shadow: 0 20px 60px rgba(var(--shadow-rgb),.4);
  animation: slideUp .2s ease;
  /* Debe seguir al `padding` de arriba: el footer sticky sangra hacia este
     padding para taparlo (ver .modal-btns). Si cambias el padding, cambia esto. */
  --modal-pad: 32px;
}
/* D14: variante amplia para formularios pesados (Colaborador, Venta, …). */
.modal.modal-wide { width: 1100px; max-width: 96vw; }
@media (max-width: 768px) { .modal.modal-wide { width: 100vw; max-width: 100vw; } }
@keyframes slideUp { from{opacity:0;transform:translateY(16px)} to{opacity:1;transform:translateY(0)} }

/* Diálogo APILADO: se dibuja ENCIMA de un modal abierto sin destruirlo
   (`dialogoApilable` en app.js). Sustituye a los `confirm()` nativos, que
   congelan el hilo del navegador mientras están arriba. z-index por encima de
   .overlay (100) y del drawer (120); el fondo va un poco más oscuro para que se
   note que hay dos capas, y sin blur extra (el de abajo ya difumina la página). */
/* z-index por encima de TODO lo apilable del Portal: overlay de modal (100),
   bulk-edit (1500/1600), drawer (8000/8001) y command palette (9000/9001). Es el
   único elemento que puede aparecer sobre cualquiera de ellos — por eso sustituye
   a los `confirm()` nativos, que estaban ahí precisamente por ser "siempre al
   frente" (y a cambio congelaban el navegador). */
.overlay-apilada { z-index: 9500; background: rgba(0,10,20,.55); backdrop-filter: none; }
.modal-apilado { width: 460px; padding-bottom: 0; }
/* §320: diálogo apilado con una tabla (comparación "Ligar y completar"): 460px cortaba la última columna. */
.modal-apilado.modal-apilado-ancho { width: 720px; max-width: 96vw; }

/* ── Buscador en desplegables largos (§select-buscable) ──────────────────────
   El <select> nativo sigue en el DOM como fuente de verdad (ver app.js); aquí
   sólo se lo oculta y se estila el trigger + el popover. Todo por tokens → tema
   claro/oscuro sin hardcodear. El trigger imita a `.fg select` para no mover el
   layout al enhancear. */
.ss-native { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0; opacity: 0; pointer-events: none; }
.ss-trigger {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 10px 14px; color: var(--text-strong); font-size: 13px; font-family: inherit;
  cursor: pointer; transition: .2s;
}
.ss-trigger:hover:not(.ss-disabled) { border-color: var(--border-strong); }
.ss-trigger:focus-visible, .ss-trigger.ss-open {
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15);
  background: var(--surface-3); outline: none;
}
.ss-trigger .ss-value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-trigger .ss-value.ss-ph { color: var(--text-dimmed); }
.ss-trigger .ss-caret { font-size: 18px; color: var(--text-muted); flex: none; }
.ss-trigger.ss-disabled { opacity: .55; cursor: not-allowed; }

.ss-pop {
  position: fixed; z-index: 9600; display: flex; flex-direction: column; overflow: hidden;
  min-width: 240px; max-width: calc(100vw - 16px);
  background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 10px;
  box-shadow: 0 12px 40px rgba(var(--shadow-rgb),.45); animation: fadeIn .12s ease;
}
.ss-search { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border-2); background: var(--surface-2); }
.ss-search-ic { font-size: 18px; color: var(--text-muted); flex: none; }
.ss-search input { flex: 1; border: none; background: transparent; color: var(--text-strong); font-size: 14px; outline: none; font-family: inherit; }
.ss-list { position: relative; overflow-y: auto; max-height: 300px; padding: 4px; overscroll-behavior: contain; }
.ss-opt { display: flex; align-items: center; gap: 8px; min-height: 38px; padding: 8px 10px; border-radius: 6px; cursor: pointer; font-size: 13px; color: var(--text-strong); }
.ss-opt.active { background: rgba(var(--accent-rgb),.14); }
.ss-opt.ss-sel { font-weight: 600; }
.ss-opt-lbl { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-opt-ic { font-size: 16px; color: var(--accent); flex: none; }
.ss-opt-chk { font-size: 16px; color: var(--accent); flex: none; }
.ss-opt-dis { opacity: .5; cursor: default; }
.ss-clear { color: var(--text-muted); border-bottom: 1px solid var(--border-2); border-radius: 0; margin-bottom: 2px; }
.ss-clear .ss-opt-ic { color: var(--text-muted); }
.ss-group { padding: 8px 10px 4px; font-size: 10px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--text-dimmed); }
.ss-empty { padding: 18px 10px; text-align: center; color: var(--text-muted); font-size: 13px; }
.modal h3 { font-size: 17px; font-weight: 800; color: var(--text-strong); }
/* D16: Guardar/Cancelar siempre visibles aunque el modal tenga scroll — sticky
   al fondo del .modal. Full-bleed SOLO horizontal (margin negativo lateral) para
   cubrir el padding lateral; el aire inferior lo da el propio padding-bottom del
   footer. El .modal ya NO lleva padding-bottom (padding: 32px 32px 0), así que el
   footer se pega al fondo del scrollport SIN dejar franja por donde se cuele el
   contenido (bug anterior: margin-bottom negativo dejaba 32px de hueco). El
   overflow del modal recorta las esquinas del footer a su border-radius. openModal
   garantiza que .modal-btns sea el ÚLTIMO hijo (si un modal mete campos después,
   los reubica antes) para que el footer nunca flote sobre contenido. */
.modal-btns {
  display: flex; gap: 10px; justify-content: flex-end;
  position: sticky; bottom: 0;
  margin: 0 calc(-1 * var(--modal-pad, 32px));
  padding: 14px var(--modal-pad, 32px) var(--modal-pad, 32px);
  background: var(--surface-1);
  border-top: 1px solid var(--border-1);
}
/* §636: quién cambió el registro, discreto, al final del formulario (core/historial.js). */
.hist-pie { margin: 18px 0 12px; display: flex; gap: 4px; align-items: baseline; flex-wrap: wrap; }
.hist-pie details { width: 100%; }
.hist-pie summary { cursor: pointer; list-style-position: outside; }
.hist-pie summary .mi { vertical-align: -3px; }
.hist-pie-item { margin: 8px 0 0 18px; padding-left: 10px; border-left: 2px solid var(--border-2); }
.hist-pie-item .text-sm { color: var(--text-muted); }

/* Countdown footer para modales informativos (closeModalWithCountdown).
   El usuario ve cuándo se va a cerrar y puede cerrar antes con el botón.
   La barra usa CSS animation (no transition) para evitar el quirk de
   "transition no se aplica si el initial value se setea en el mismo
   tick que el final value". --modal-countdown-duration la inyecta el
   JS para que el helper sea reusable a cualquier duración. */
.modal-countdown {
  display: flex; flex-direction: column; gap: 10px;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--border-3);
}
.modal-countdown-bar {
  height: 4px; background: var(--border-1); border-radius: 2px; overflow: hidden;
}
.modal-countdown-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent));
  animation: modalCountdownFill var(--modal-countdown-duration, 10s) linear forwards;
}
@keyframes modalCountdownFill {
  from { width: 100%; }
  to   { width: 0%; }
}
.modal-countdown-row {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  font-size: 12px; color: var(--text-soft);
}
.modal-countdown-num { color: var(--text-default); font-variant-numeric: tabular-nums; min-width: 1.5em; display: inline-block; text-align: right; }

/* ── FORM ── */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.form-grid .full { grid-column: 1 / -1; }
.fg { display: flex; flex-direction: column; gap: 6px; }
/* D15: validación inline — marca el campo en rojo y muestra el motivo debajo. */
.fg.has-error input, .fg.has-error select, .fg.has-error textarea { border-color: var(--danger) !important; box-shadow: 0 0 0 1px rgba(239,68,68,.25); }
/* Un select enhanceado está oculto (.ss-native): el borde de error debe caer en su
   trigger visible, no en el select escondido. */
.fg.has-error .ss-trigger { border-color: var(--danger) !important; box-shadow: 0 0 0 1px rgba(239,68,68,.25); }
.field-error { color: var(--danger); font-size: 12px; margin-top: 1px; display: flex; align-items: center; gap: 4px; }
.field-error .mi { font-size: 15px; }
.fg label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 700; display: flex; align-items: center; gap: 0; }
.tip { display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;background:var(--border-1);color:var(--text-muted);font-size:10px;font-weight:700;cursor:help;position:relative;margin-left:4px;vertical-align:middle;flex-shrink:0; }
.tip::after { content:attr(data-tip);position:absolute;bottom:calc(100% + 6px);left:50%;transform:translateX(-50%);background:var(--bg-topbar);border:1px solid var(--border-1);color:var(--text-subtle);font-size:11px;padding:8px 12px;border-radius:6px;white-space:pre-wrap;max-width:280px;min-width:180px;z-index:9999;pointer-events:none;opacity:0;transition:opacity .15s;text-transform:none;letter-spacing:0;font-weight:400;line-height:1.5; }
.tip:hover::after { opacity:1; }
.fg input,.fg select,.fg textarea {
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  padding: 10px 14px; color: var(--text-strong); font-size: 13px; outline: none;
  transition: .2s; font-family: inherit; width: 100%;
}
.fg input:focus,.fg select:focus,.fg textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); background: var(--surface-3);
}
.fg select option { background: var(--surface-1); color: var(--text-strong); }
/* Checkbox/radio dentro de .fg NO deben estirarse al width:100% de la regla de
   arriba — eso los aplasta (los "chips" de rol/empresa quedan como barras). Una
   sola regla global retira la clase de curitas inline repetidas (.cust-bool,
   .role-addon-row, col-rol-check…). §7pts-9 R-code-review. */
.fg input[type="checkbox"], .fg input[type="radio"] { width: auto; }

/* ── LOADING ── */
.spinner { display:inline-block; width:18px; height:18px; border:2px solid var(--border-1); border-top-color:var(--accent); border-radius:50%; animation:spin .7s linear infinite; vertical-align:middle; margin-right:8px; }
@keyframes spin { to{transform:rotate(360deg)} }
/* `.loading` (spinner centrado en medio de la pantalla) se RETIRÓ (§189): el único
   indicador de espera del portal es el pill inferior `#net-pill`. Si necesitas un
   placeholder mientras llega el contenido, usa `loading()` (skeleton) o el bloque
   `.loading-shell` de abajo. `tools/check-loading-ui.js` bloquea reintroducirlo. */

/* ── SKELETON / SHIMMER ─────────────────────────────────────────
   loading() renderiza una silueta para reducir el "perceived loading
   time" (Linear, NN/g 2026). El spinner+mensaje vive en un pill
   flotante para mid-flow ("Guardando…", "Eliminando…"). */
.skeleton {
  background: linear-gradient(90deg, var(--surface-1) 0%, var(--surface-raised) 50%, var(--surface-1) 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: 8px;
}
@keyframes skeleton-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.skeleton-line { height: 12px; margin: 8px 0; }
.skeleton-line.short  { width: 40%; }
.skeleton-line.medium { width: 70%; }
.skeleton-card { height: 110px; margin: 12px 0; }
.skeleton-row  { height: 38px; margin: 4px 0; }
/* Anti-flash: shell y pill empiezan invisibles y aparecen tras 100ms.
   Las cargas <100ms (cache hits, datos en memoria) no muestran nada
   — evita el destello molesto. setContent reemplaza el shell antes
   del fade-in si la respuesta llega rápido. */
.loading-shell {
  padding: 4px; position: relative;
  opacity: 0; animation: shellFadeIn .15s ease-out 100ms forwards;
}
.loading-pill {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--surface-1); border: 1px solid var(--border-1); padding: 8px 16px;
  border-radius: 24px; display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text-default); z-index: 50;
  box-shadow: 0 6px 20px rgba(var(--shadow-rgb),.4);
  opacity: 0; animation: pillFadeIn .18s ease 100ms forwards;
}
.loading-pill .spinner { margin-right: 0; }
@keyframes shellFadeIn { to { opacity: 1; } }
@keyframes pillFadeIn { to { opacity: 1; } }
/* §189 — el pill GLOBAL (`#net-pill`, lo crea app.js y vive en <body>): por
   encima de modales/scrims/drawers (bulk 1600, coach 3000, drawer 8000, ⌘K 9000,
   apilada 9500) para que "Guardando…" se vea desde dentro de un modal, y por
   debajo del toast (9700) y los tooltips (9999). `hidden` lo apaga; al volver a
   mostrarse, el keyframe pillFadeIn vuelve a correr (fade-in suave). */
.net-pill { z-index: 9650; }
.net-pill[hidden] { display: none; }
/* Con la barra de pestañas inferior (portal cliente en móvil) el pill sube para no
   quedar debajo de ella. */
body:has(.bottom-tabs) .net-pill,
body.has-bottom-tabs .net-pill { bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }

/* ── PAGE TITLE ── */
.page-title {
  /* Escala fluida: 18 px en 360 px de viewport → 22 px en 1024+. Sin saltos. */
  font-size: clamp(18px, 1.1vw + 16px, 22px);
  font-weight: 800; margin-bottom: 24px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  color: var(--text-strong);
}
.page-title .mi { font-size: clamp(22px, 0.6vw + 20px, 26px); color: var(--accent); }
.page-title .title-actions { margin-left: auto; display: flex; gap: 8px; }

/* §pto5 — Header de sección FIJO: el page-title + las tabs quedan sticky arriba
   y solo el contenido scrollea, así las acciones del título y las pestañas
   están siempre visibles. El wrapper `.section-header` lo arma setContent()
   envolviendo el page-title + las tabs líderes → cero cambios por módulo.
   Sin negative margins a propósito: el header vive dentro del padding de
   `.content` (que cambia por breakpoint) y, como el contenido tiene el mismo
   ancho, lo cubre al pasar por debajo sin fugas laterales. z-index 12 = sobre
   el contenido (0) y el busy-strip (10), bajo overlays/drawers/cmdk (100+) y
   el topbar (20, otro stacking context). */
/* El sticky no puede anclarse más arriba que el content-box de su scroller, y
   el padding-top de .content empuja ese borde hacia abajo → el header quedaría
   anclado debajo del tope y el contenido se asomaría en ese hueco. Solución:
   cuando hay header, .content cede su padding-top (abajo) y el header lo repone
   como padding propio (pintado como fondo) → ancla a ras y cubre el tramo. */
.content:has(> .section-header) { padding-top: 0; }
.section-header {
  position: sticky;
  top: 0;
  z-index: 12;
  background: var(--bg-page);
  padding-top: var(--sh-pad-top, 32px);  /* repone el padding-top que cedió .content */
  padding-bottom: 18px;
}
.section-header > .page-title { margin-bottom: 16px; }
.section-header > .page-title:last-child { margin-bottom: 0; }
.section-header > .tabs { margin-bottom: 0; }

/* §pto4 — Cascada de categorías (un select por nivel, apilados). */
.cat-cascade { display: flex; flex-direction: column; gap: 8px; }
.cat-cascade-sel { width: 100%; }
/* §Proveedores — encabezados de sección dentro del modal de proveedor. */
.prv-sec {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 700; color: var(--text-strong);
  margin: 18px 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--border-1);
}
.prv-sec:first-of-type { margin-top: 6px; }
.prv-sec .mi { color: var(--accent); }
/* §Proveedores F3 — form inline de alta/edición de contacto/dirección. */
.prv-subform { margin-top: 10px; padding: 14px; border: 1px solid var(--border-2); border-radius: 10px; background: var(--surface-2); }
.prv-subform .ck-row { display: flex; align-items: center; gap: 6px; text-transform: none; font-weight: 400; }
.prv-subform .ck-row input { width: auto; flex: 0 0 auto; }
/* §Proveedores — Opción A: cada nivel rotulado con su padre + ruta (breadcrumb). */
.cat-cascade-row { display: flex; flex-direction: column; gap: 3px; }
.cat-cascade-lbl { font-size: 11px; font-weight: 600; color: var(--text-dimmed); }
.cat-cascade-path {
  margin-top: 2px; padding: 7px 10px; border-radius: 8px;
  background: rgba(var(--accent-rgb), 0.10); border: 1px dashed var(--accent);
  color: var(--accent); font-size: 13px; font-weight: 600;
  display: flex; align-items: center; gap: 5px;
}

/* §pto1/2 — Widget de Documentos por tipo (espacio dedicado en cliente/proveedor). */
.doc-widget { display: flex; flex-direction: column; gap: 10px; }
.doc-uploader { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.doc-tipo-select { flex: 1 1 200px; min-width: 160px; }
.doc-uploader .doc-search { flex: 1 1 160px; min-width: 140px; }
.doc-upload-btn { cursor: pointer; white-space: nowrap; }
.doc-list { display: flex; flex-direction: column; gap: 6px; }
.doc-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; background: var(--surface-3);
  border: 1px solid var(--border-1); border-radius: 8px;
}
.doc-tipo-badge { flex: 0 0 auto; }
.doc-item .doc-name { flex: 1 1 auto; min-width: 0; color: var(--text-default); text-decoration: none; font-size: 13px; }
.doc-item .doc-name:hover { color: var(--accent); text-decoration: underline; }
.doc-item .doc-del { flex: 0 0 auto; color: var(--text-dimmed); }
.doc-item .doc-del:hover { color: var(--danger); }
/* Ver / Descargar. Antes el único botón visible del renglón era el de borrar —
   lo único evidente que podías hacerle a un archivo era eliminarlo— y el nombre
   colgaba de downloadUrl, así que no había forma de sólo verlo. */
.doc-item .doc-act {
  flex: 0 0 auto; color: var(--text-dimmed);
  display: inline-flex; align-items: center; text-decoration: none;
}
.doc-item .doc-act:hover { color: var(--accent); }

/* §511 — "Se guardará en: <empresa>" arriba de un alta (core: _seGuardaraEn en app.js). */
.se-guardara-en {
  display: flex; align-items: center; gap: 6px; margin: -4px 0 12px; padding: 8px 12px;
  border-radius: 8px; font-size: 14px; color: var(--text-strong);
  background: var(--info-bg); border: 1px solid var(--info-bd);
}
.se-guardara-en[hidden] { display: none; }
.se-guardara-en .mi { color: var(--info); }

/* §pto3 — Pista de campo de empresa bloqueado (heredado del topbar). */
.lock-hint {
  display: flex; align-items: center; gap: 5px;
  margin-top: 5px; font-size: 12px; color: var(--text-dimmed);
}
.lock-hint .mi { font-size: 14px; }
.lock-hint a.link-cell { cursor: pointer; }

/* Bloque de formulario cuya función depende de un addon APAGADO: se ve, se explica,
   no se usa (regla ocultar-vs-deshabilitar: estado del tenant, no de rol). */
.form-block-off { opacity: .65; }

/* ── DETAIL VIEW ── */
/* Breadcrumb */
.breadcrumb {
  display: flex; align-items: center; gap: 8px;
  color: var(--text-muted); font-size: 13px; margin-bottom: 20px; font-weight: 500;
}
.breadcrumb .bc-link { cursor: pointer; color: var(--accent); }
.breadcrumb .bc-link:hover { text-decoration: underline; }
.breadcrumb .bc-sep { color: var(--text-muted); }
.breadcrumb span:last-child { color: var(--text-strong); font-weight: 700; }

/* Copyable info items */
.info-item.copyable { cursor: pointer; border-radius: 8px; padding: 4px; margin: -4px; transition: background .15s; }
.info-item.copyable:hover { background: var(--surface-3); }
.info-item.copyable:hover .lbl { color: var(--accent); }

.detail-header {
  background: var(--surface-1);
  border: 1px solid var(--border-1);
  border-radius: 14px;
  padding: 28px 32px; margin-bottom: 24px;
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.2);
}
.detail-avatar {
  width: 60px; height: 60px; border-radius: 14px; flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent-2), var(--accent));
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 800; color: #fff;
}
.detail-info .detail-name { font-size: 20px; font-weight: 800; color: var(--text-strong); }
.detail-info .detail-meta { font-size: 13px; color: var(--text-muted); margin-top: 4px; }
.detail-header-actions { margin-left: auto; display: flex; gap: 10px; }

/* ── INFO CARD ── */
.info-card {
  background: var(--surface-1); border: 1px solid var(--border-1);
  border-radius: 12px; padding: 24px; margin-bottom: 20px;
  box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.2);
}
.info-card h3 {
  font-size: 11px; color: var(--text-muted); font-weight: 700; margin-bottom: 18px;
  text-transform: uppercase; letter-spacing: 1px;
  display: flex; align-items: center; gap: 10px;
}
.info-card h3::after { content:''; flex:1; height:1px; background:var(--border-1); }
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; }
.info-item .lbl { font-size: 11px; color: var(--text-muted); margin-bottom: 4px; text-transform: uppercase; letter-spacing: .5px; }
.info-item .val { font-size: 13px; color: var(--text-strong); font-weight: 500; }

/* ── TABS ── */
.tabs { display:flex; gap:3px; margin-bottom:24px; border-bottom:1px solid var(--border-1); }
.tab {
  padding:9px 20px; font-size:13px; font-weight:600; color:var(--text-muted);
  cursor:pointer; border-radius:8px 8px 0 0;
  border:1px solid transparent; border-bottom:none; transition:.15s; user-select:none;
}
.tab:hover { color:var(--accent); background:var(--surface-1); }
.tab.active { color:var(--accent); background:var(--surface-1); border-color:var(--border-1); border-bottom-color:var(--surface-1); margin-bottom:-1px; }

/* §344 — Pestañas de GRUPO (Configuración / Herramientas, que salieron del
   sidebar al menú de cuenta). Navegan entre SECCIONES, no entre pestañas de un
   módulo → forma de píldora, distinta de .tabs, para que no se confundan cuando
   la sección trae sus propias pestañas debajo (p. ej. Importar datos). La pinta
   `_syncMenuGrupoTabs` (admin.php). Desborda con scroll propio, nunca la página. */
.menu-grupo-tabs {
  display: flex; align-items: center; gap: 6px; flex-wrap: nowrap;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
  margin-bottom: 20px; padding-bottom: 2px;
}
.section-header > .menu-grupo-tabs { margin-bottom: 16px; }
.menu-grupo-tabs .mgt-label {
  display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0;
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted); margin-right: 6px;
}
.menu-grupo-tabs .mgt-label .mi { font-size: 16px; }
.menu-grupo-tab {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  min-height: 40px; padding: 6px 16px; border-radius: 999px;
  border: 1px solid var(--border-1); background: var(--surface-1);
  color: var(--text-default); font-family: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; white-space: nowrap; transition: .15s;
}
.menu-grupo-tab .mi { font-size: 18px; color: var(--text-muted); }
.menu-grupo-tab:hover { color: var(--accent); border-color: var(--border-strong); }
.menu-grupo-tab:hover .mi { color: var(--accent); }
.menu-grupo-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.menu-grupo-tab.active { background: rgba(var(--accent-rgb), .12); border-color: var(--accent); color: var(--accent); }
.menu-grupo-tab.active .mi { color: var(--accent); }
@media (max-width: 600px) {
  /* En angosto el rótulo del grupo ya lo dice la entrada del menú de cuenta:
     se quita para que quepan las pestañas (la activa se trae a la vista en JS). */
  .menu-grupo-tabs .mgt-label { display: none; }
  .menu-grupo-tabs { scrollbar-width: none; }
  .menu-grupo-tabs::-webkit-scrollbar { height: 0; }
}

/* ── TOAST ──
   bottom-LEFT (movido de right, 2026-08-18) — a propósito, para dejar la
   esquina bottom-right SOLO para `.ayuda-btn` (`bottom:24px`, al ras). El
   toast se dispara en casi cualquier guardado del portal Y se apila hacia
   arriba en cada acción seguida (ver `toast()` en app.js) — con las dos cosas
   en la misma esquina, un apilón real podía tapar/rozar el botón de Ayuda;
   separarlos de esquina es más robusto que un offset vertical (no depende de
   cuántos toasts se acumulen). Ver el comentario de `.ayuda-btn` más abajo. */
.toast {
  position:fixed; bottom:28px; left:28px;
  background:var(--surface-1); border:1px solid var(--border-1);
  color:var(--text-strong); padding:13px 22px; border-radius:10px;
  /* z-index 9700: el toast es por definición la capa transitoria MÁS alta —
     por encima de todo backdrop/overlay (.qe-backdrop 1500, bulk edit 1500/1600,
     .coach-overlay 3000, .drawer-scrim 8000, .cmdk-scrim 9000, .overlay-apilada
     9500, .ss-pop 9600) y solo debajo de los tooltips (.tip 9999). Antes era 200
     y quedaba TAPADO por los seis (§180): en bulk edit ningún aviso se vio jamás
     hasta 2.43.3, y en QuickEdit un "Error al guardar" salía atenuado bajo el
     scrim con su clic-para-cerrar tragado por el backdrop. */
  font-size:13px; font-weight:600; z-index:9700;
  animation:slideUp .3s ease; box-shadow:0 8px 24px rgba(var(--shadow-rgb),.3);
  display: flex; align-items: center; gap: 8px;
  /* pointer-events:auto explícito (es el default; lo dejamos claro) + descartable
     con un clic (cursor:pointer; la lógica vive en app.js toast()). */
  pointer-events: auto; cursor: pointer;
}
.toast.ok   { border-left: 4px solid var(--success); color: var(--success); }
.toast.err  { border-left: 4px solid var(--danger); color: var(--danger); }
.toast.info { border-left: 4px solid var(--info); color: var(--info); }
.toast.warn { border-left: 4px solid var(--warning); color: var(--warning); }

/* Configuración: barra de acciones sticky al fondo del scroll container.
   El usuario no necesita scrollear hasta abajo para guardar.
   Mantiene margins/paddings simples para no romper en mobile (donde el
   .content tiene padding distinto al desktop). */
/* El sticky `bottom:0` se constriñe al content-box de .content; con su
   padding-bottom el content-box termina N px sobre el viewport → hueco bajo la
   barra. Un margin negativo NO lo arregla (el clamp mide el border-box, no el
   margin-box). Solución: anular el padding-bottom de .content SOLO cuando la
   barra está presente, así el content-box llega al fondo real y la barra queda
   a ras. El aire inferior lo da el propio padding de la barra. */
.content:has(.cfg-sticky-actions) { padding-bottom: 0; }
.cfg-sticky-actions {
  position: sticky; bottom: 0; z-index: 5;
  /* Ancho completo (§344): antes 860px centrado; con la fila de pestañas de
     Configuración arriba, la página angosta se veía descuadrada. */
  margin: 24px 0 0;
  padding: 12px 0 16px;
  background: var(--bg-page);
  border-top: 1px solid var(--border-strong);
}

/* Misma mecánica que .cfg-sticky-actions (el comentario de arriba explica el
   porqué del content:has() → padding-bottom:0), para pantallas de página completa de ancho
   normal (reportes/resultados, ej. conciliación bancaria). `.modal-btns` NO
   sirve aquí: su margin negativo y su sticky asumen que vive dentro de
   `.modal` (que tiene su propio padding-bottom:0 delegado al footer) — en
   `.content` eso descuadra el ancho y la barra termina flotando encima de
   la última fila de una tabla larga en vez de quedar a ras debajo. */
.content:has(.page-sticky-actions) { padding-bottom: 0; }
.page-sticky-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  position: sticky; bottom: 0; z-index: 5;
  margin-top: 24px;
  padding: 12px 0 16px;
  background: var(--bg-page);
  border-top: 1px solid var(--border-strong);
}
/* Las barras fijas de ancho completo terminan bajo el botón flotante de Ayuda
   (`.ayuda-btn`, fijo abajo a la derecha): sin esta reserva tapaba el botón
   principal ("Guardar Configuración"). 120px ≈ ancho del botón (106) que invade
   la barra + aire. Sólo cuando Ayuda está en la página (§344). */
body:has(.ayuda-btn) .cfg-sticky-actions,
body:has(.ayuda-btn) .page-sticky-actions { padding-right: 120px; }
@media (max-width: 768px) {
  .page-sticky-actions { flex-direction: column-reverse; align-items: stretch; gap: 8px; }
  .page-sticky-actions .btn { width: 100%; justify-content: center; min-height: 40px; }
}

.toast-action {
  background: transparent; border: 1px solid currentColor;
  color: inherit; padding: 4px 10px; border-radius: 6px;
  font-size: 12px; font-weight: 600; cursor: pointer;
  margin-left: 4px; white-space: nowrap;
}
.toast-action:hover { background: rgba(255,255,255,.08); }
/* §203: los toasts de error se quedan; llevan ✕ y se "sacuden" si el mismo error se repite. */
.toast-close {
  background: none; border: none; color: inherit; opacity: .7; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 4px; margin-left: 6px; border-radius: 4px;
}
.toast-close:hover { opacity: 1; background: rgba(var(--shadow-rgb), .12); }
.toast.err { font-weight: 500; max-width: min(560px, calc(100vw - 56px)); line-height: 1.4; }
@keyframes toastBump { 0% { transform: scale(1); } 50% { transform: scale(1.03); } 100% { transform: scale(1); } }
.toast-bump { animation: toastBump .25s ease; }

/* ── Company Switcher ── */
.cs-wrap { position:relative; }
.cs-btn {
  display:flex; align-items:center; gap:10px;
  background:var(--surface-2); border:1px solid var(--border-1);
  border-radius:10px; padding:7px 14px 7px 10px;
  cursor:pointer; transition:.2s; color:var(--text-strong);
  min-width:200px; justify-content:space-between;
}
.cs-btn:hover { border-color:var(--accent); background:var(--surface-3); }
.cs-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cs-btn-left { display:flex; align-items:center; gap:10px; }
.cs-avatar {
  width:32px; height:32px; border-radius:8px;
  background:linear-gradient(135deg,var(--accent-2),var(--accent));
  display:flex; align-items:center; justify-content:center;
  font-size:13px; font-weight:800; color:#fff; flex-shrink:0;
}
.cs-info { display:flex; flex-direction:column; line-height:1.3; }
.cs-username { font-size:10px; color:var(--text-muted); }
.cs-name { font-size:13px; font-weight:700; max-width:140px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cs-arrow { font-size:9px; color:var(--text-muted); transition:.3s; flex-shrink:0; }
.cs-wrap.open .cs-arrow { transform:rotate(180deg); color:var(--accent); }
.cs-dropdown {
  display:none; position:absolute; top:calc(100% + 6px); right:0;
  background:var(--surface-1); border:1px solid var(--border-1);
  border-radius:12px; min-width:260px; z-index:100;
  box-shadow:0 12px 40px rgba(var(--shadow-rgb),.4); overflow:hidden;
}
.cs-wrap.open .cs-dropdown { display:block; animation:fadeDown .15s ease; }
@keyframes fadeDown { from{opacity:0;transform:translateY(-6px)} to{opacity:1;transform:translateY(0)} }
.cs-user-header { padding:14px 16px; border-bottom:1px solid var(--border-strong); display:flex; align-items:center; gap:12px; }
.cs-user-avatar {
  width:38px; height:38px; border-radius:10px;
  background:linear-gradient(135deg,var(--accent-2),var(--accent));
  display:flex; align-items:center; justify-content:center;
  font-size:15px; font-weight:800; color:#fff; flex-shrink:0;
}
.cs-user-info .cs-user-name { font-size:13px; font-weight:700; color:var(--text-strong); }
.cs-user-info .cs-user-sub  { font-size:11px; color:var(--text-muted); margin-top:2px; }
.cs-section-title { padding:8px 16px 4px; font-size:10px; color:var(--text-muted); text-transform:uppercase; letter-spacing:1px; font-weight:700; }
.cs-option { display:flex; align-items:center; gap:12px; padding:10px 16px; cursor:pointer; font-size:13px; transition:.15s; color:var(--text-subtle); }
.cs-option:hover { background:var(--surface-3); color:var(--accent); }
.cs-option.active { color:var(--accent); background:var(--surface-3); }
.cs-opt-avatar {
  width:30px; height:30px; border-radius:8px; flex-shrink:0;
  background:var(--surface-1); display:flex; align-items:center;
  justify-content:center; font-size:12px; font-weight:800; color:var(--accent);
}
.cs-option.active .cs-opt-avatar { background:var(--surface-3); }
.cs-opt-info { display:flex; flex-direction:column; flex:1; min-width:0; }
.cs-opt-name { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cs-opt-rfc  { font-size:10px; color:var(--text-muted); margin-top:1px; }
.cs-check    { font-size:12px; color:var(--accent); flex-shrink:0; }
.cs-divider  { height:1px; background:var(--surface-raised); margin:4px 0; }
.cs-logout-opt {
  display:flex; align-items:center; gap:12px;
  padding:10px 16px 14px; cursor:pointer; font-size:13px; color:var(--text-muted); transition:.15s;
}
.cs-logout-opt:hover { color:var(--danger); background:var(--danger-bg); }

/* ── SWITCH TOGGLE ── */
.switch-track { position:absolute;inset:0;border-radius:12px;background:var(--border-1);transition:background .2s,box-shadow .2s;cursor:pointer; }
.switch-track.on { background:var(--accent-2); }
.switch-track > div { position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(var(--shadow-rgb),.3);transition:left .2s; }
.switch-track.on > div { left:22px; }

/* ── DASHBOARD ── */
.dash-welcome {
  background: linear-gradient(135deg, var(--surface-3) 0%, var(--surface-3) 50%, var(--surface-2) 100%);
  border: 1px solid var(--border-1);
  border-radius: 16px; padding: 28px 32px;
  margin-bottom: 24px; display: flex; align-items: center;
  justify-content: space-between; flex-wrap: wrap; gap: 16px;
  box-shadow: 0 4px 20px rgba(var(--shadow-rgb),.4);
}
.dash-welcome-title { font-size: clamp(18px, 1.4vw + 14px, 22px); font-weight: 800; color: var(--text-strong); }
.dash-welcome-sub { font-size: 13px; color: var(--text-muted); margin-top: 6px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dash-chip { font-weight: 700; font-size: 13px; }
.dash-sep { color: var(--text-muted); }
.dash-welcome select,
.dash-welcome input[type="date"],
.dash-welcome button { background: var(--bg-topbar) !important; border-color: var(--border-1) !important; color: var(--text-muted) !important; }
.dash-welcome > div:last-child { flex-shrink: 0; }

.dash-hero-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px; margin-bottom: 24px;
}
/* Container query: ajusta # de columnas según ancho del .content,
   no del viewport. Funciona aunque el sidebar reduzca el espacio. */
@container app-content (max-width: 720px) {
  .dash-hero-cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .portal-action-cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .info-grid { grid-template-columns: 1fr 1fr; }
  .summary-cards { grid-template-columns: repeat(2, 1fr); }
  .fiscal-grid { grid-template-columns: 1fr; }
  /* Kanban: en contenedor angosto, columnas más finas para que se vean al menos 2 */
  .kanban-col { flex: 0 0 230px; }
}
@container app-content (max-width: 460px) {
  .dash-hero-cards, .cards, .portal-action-cards,
  .info-grid { grid-template-columns: 1fr; }
  .kanban-col { flex: 0 0 86%; }
}
.dash-hero-card {
  background: var(--surface-1); border: 1px solid var(--border-1);
  border-radius: 14px; padding: 22px 20px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 10px; cursor: pointer;
  transition: .2s; position: relative; overflow: hidden;
  box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.2);
}
.dash-hero-card:hover { border-color: var(--border-strong); box-shadow: 0 8px 24px rgba(var(--shadow-rgb),.3); transform: translateY(-2px); }
.dash-hero-icon {
  width: 52px; height: 52px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; flex-shrink: 0;
}
.dash-hero-icon .mi { font-size: 26px; }
.dash-hero-label { font-size: 12px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; }
.dash-hero-val { font-size: clamp(20px, 1.2vw + 16px, 24px); font-weight: 800; color: var(--text-strong); line-height: 1; }
.dash-hero-unit { font-size: 13px; font-weight: 600; color: var(--text-muted); margin-left: 2px; }
.dash-hero-sub { font-size: 11px; color: var(--text-muted); margin-top: 4px; min-height: 16px; }
.dash-hero-action { font-size: 12px; color: var(--accent); font-weight: 600; display: flex; align-items: center; gap: 4px; margin-top: 4px; }

.dash-bottom-row { display: grid; grid-template-columns: 1fr 340px; gap: 20px; margin-bottom: 24px; }
.dash-bottom-row-single { grid-template-columns: 1fr; }

/* ── Introducer cards (Shopify-style progressive disclosure, §71) ────
   Vista global = 7 introducer cards en grid. Cada card es la "puerta"
   a una página #detalle-<tema> con todos los dashBlocks del tema.
   Diseño: similar a hero pero con CTA explícito de drill-down. Patrón
   Shopify Informes y estadísticas adaptado a 7 temas core del CRM. */
.dash-intro-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
.dash-intro-card {
  background: var(--surface-1);
  border: 1px solid var(--border-3);
  border-radius: 10px;
  padding: 16px 18px;
  cursor: pointer;
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
  display: flex; flex-direction: column; gap: 6px;
  min-height: 140px;
}
.dash-intro-card:hover,
.dash-intro-card:focus-visible {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: 0 6px 18px rgba(var(--shadow-rgb),.25);
  outline: none;
}
.dash-intro-card:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.35), 0 6px 18px rgba(var(--shadow-rgb),.25);
}
/* Touch (sin hover real): feedback al tap. La card se hunde ligeramente
   al presionar y el border se aclara, indicando que el tap fue capturado. */
.dash-intro-card:active {
  transform: translateY(0);
  border-color: var(--accent);
}
@media (hover: none) {
  /* Sin hover (móvil/tablet): no usar el lift permanente, pero mantener el
     feedback :active. El CTA queda siempre visible para indicar drill. */
  .dash-intro-card:hover { transform: none; box-shadow: none; border-color: var(--border-3); }
}
.dash-intro-head {
  display: flex; align-items: center; gap: 8px;
}
.dash-intro-icon { font-size: 22px; color: var(--theme-color, var(--accent)); }
.dash-intro-label {
  font-size: 12px; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .5px;
}
.dash-intro-val {
  font-size: 24px; font-weight: 800; color: var(--text-strong);
  line-height: 1.1; margin-top: 2px;
}
.dash-intro-unit {
  font-size: 13px; font-weight: 600; color: var(--text-muted);
  margin-left: 2px;
}
.dash-intro-sub {
  font-size: 12px; color: var(--text-muted); min-height: 16px;
}
.dash-intro-card .dash-spark {
  margin-top: 4px;
}
.dash-intro-cta {
  font-size: 12px; color: var(--accent); font-weight: 600;
  display: flex; align-items: center; gap: 4px;
  margin-top: auto; padding-top: 6px;
}
.dash-intro-empty {
  opacity: .7;
}
.dash-intro-empty .dash-intro-val {
  font-size: 20px; color: var(--text-muted);
}

/* ── Lanzador operativo (centro de mando, §launcher) ─────────────────
   Vista Operación: carriles (Fijados / Más usados) de módulos + bento de
   áreas con acción rápida. Es OTRA superficie que la vista Dirección
   (keynote cards). Pensado para el público 40+: tiles ≥44px, labels ≥14px,
   foco visible, acciones persistentes (no solo-hover, §85 P1/P2). */
.dash-launcher { display: flex; flex-direction: column; gap: 22px; margin-bottom: 24px; }
.dash-lane-head {
  font-size: 12px; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .5px;
  display: flex; align-items: center; gap: 6px; margin-bottom: 10px;
}
.dash-lane-head .mi { color: var(--accent); }
.dash-lane-items { display: flex; flex-wrap: wrap; gap: 10px; }
/* Tarjeta-botón compartida del lanzador operativo: carriles (.dash-lane-tile,
   Fijados/Más usados) y acciones rápidas (.dash-quick-btn). La base y los
   estados de interacción eran idénticos en ambas; se comparten aquí. Cada clase
   solo difiere en display/gap (y .dash-lane-tile en position, para el ⭐). */
.dash-lane-tile, .dash-quick-btn {
  align-items: center;
  background: var(--surface-1); border: 1px solid var(--border-3); border-radius: 10px;
  padding: 10px 14px; min-height: 44px; cursor: pointer; color: var(--text-strong);
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.dash-lane-tile { position: relative; display: flex; gap: 10px; }
.dash-lane-tile:hover, .dash-quick-btn:hover { transform: translateY(-1px); border-color: var(--border-strong); box-shadow: 0 4px 12px rgba(var(--shadow-rgb),.22); }
.dash-lane-tile:focus-visible, .dash-quick-btn:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.35); }
/* Icono + etiqueta compartidos con .dash-quick-ic/.dash-quick-lbl (acciones rápidas). */
.dash-lane-tile-icon, .dash-quick-ic { font-size: 20px; color: var(--accent); }
.dash-lane-tile-label, .dash-quick-lbl { font-size: 14px; font-weight: 600; }
.dash-lane-tile-label { white-space: nowrap; }
.dash-lane-star {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; margin-left: 2px;
  color: var(--text-muted); cursor: pointer; border-radius: 6px;
}
.dash-lane-star:hover { color: var(--warning); background: rgba(245,196,81,.12); }
.dash-lane-star:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(245,196,81,.5); }
.dash-lane-star.on { color: var(--warning); }

/* "Por área": bento. Reusa .dash-intro-card pero con auto-fill + densidad
   para que el hero (span 2) no deje huecos. ≤1-2 heroes (§research). */
.dash-launch-grid {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  grid-auto-flow: dense;
}
.dash-launch-grid .dash-launch-hero { grid-column: span 2; }
@media (max-width: 620px) { .dash-launch-grid .dash-launch-hero { grid-column: auto; } }
.dash-launch-actions { margin-top: auto; padding-top: 10px; }
.dash-launch-open {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(var(--accent-rgb),.12); border: 1px solid var(--border-strong); border-radius: 8px;
  color: var(--text-default); font-size: 12px; font-weight: 600;
  padding: 7px 12px; min-height: 34px; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.dash-launch-open:hover { background: rgba(var(--accent-rgb),.2); border-color: var(--accent); color: var(--text-strong); }
.dash-launch-open:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.35); }

/* ── Acciones rápidas (operativo) — botones "+ Nuevo X" ── */
.dash-quick { margin-bottom: 22px; }
.dash-quick-grid { display: flex; flex-wrap: wrap; gap: 10px; }
/* Base, :hover/:focus-visible, icono (.dash-quick-ic) y etiqueta (.dash-quick-lbl)
   compartidos con .dash-lane-tile/.dash-lane-tile-icon/.dash-lane-tile-label (ver arriba). */
.dash-quick-btn { display: inline-flex; gap: 8px; }
.dash-quick-plus { color: var(--text-subtle); margin-left: 2px; }

/* ── Todos los módulos (operativo) — quick-nav agrupado ── */
.dash-mods { margin-bottom: 24px; }
.dash-mods-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.dash-mods-group { background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 10px; padding: 12px 14px; }
.dash-mods-group-title { font-size: 11px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 8px; }
.dash-mods-items { display: flex; flex-direction: column; gap: 2px; }
.dash-mod-link { display: flex; align-items: center; gap: 10px; padding: 8px; min-height: 40px; border-radius: 7px; cursor: pointer; color: var(--text-default); font-size: 14px; transition: background .12s ease, color .12s ease; }
.dash-mod-link:hover { background: var(--surface-raised); color: var(--text-strong); }
.dash-mod-link:focus-visible { outline: none; background: var(--surface-raised); box-shadow: 0 0 0 2px rgba(var(--accent-rgb),.4) inset; }
.dash-mod-ic { font-size: 19px; color: var(--text-subtle); }
.dash-mod-link:hover .dash-mod-ic { color: var(--accent); }

/* ── KPI snapshot (Dirección hero + reutilizable) — patrón BI ── */
.dash-kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-bottom: 22px; }
.dash-kpi-row-big { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; margin-bottom: 28px; }
.dash-kpi {
  background: var(--surface-1); border: 1px solid var(--border-3); border-left: 4px solid var(--theme-color, var(--accent));
  border-radius: 12px; padding: 16px 18px; cursor: pointer;
  display: flex; flex-direction: column; gap: 4px;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.dash-kpi:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(var(--shadow-rgb),.3); }
.dash-kpi:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.35); }
.dash-kpi-head { display: flex; align-items: center; gap: 7px; }
.dash-kpi-ic { font-size: 20px; color: var(--theme-color, var(--accent)); }
.dash-kpi-lbl { font-size: 12px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; }
.dash-kpi-val { font-size: 26px; font-weight: 800; color: var(--text-strong); line-height: 1.1; margin-top: 2px; }
.dash-kpi-unit { font-size: 13px; font-weight: 600; color: var(--text-muted); margin-left: 2px; }
.dash-kpi-sub { font-size: 12px; color: var(--text-muted); }
.dash-kpi-big { padding: 22px 24px; border-radius: 14px; }
.dash-kpi-big .dash-kpi-val { font-size: 40px; letter-spacing: -.5px; }
.dash-kpi-big .dash-kpi-ic { font-size: 26px; }
.dash-kpi .dash-spark { margin-top: 6px; }
@media (max-width: 600px) { .dash-kpi-big .dash-kpi-val { font-size: 32px; } }

/* ── Pastilla de estado "¿bueno o malo?" (Gen X: icono + texto, no solo color) ── */
.dash-status {
  display: inline-flex; align-items: center; gap: 4px; width: fit-content;
  font-size: 12px; font-weight: 700; line-height: 1; letter-spacing: .2px;
  padding: 4px 9px; border-radius: 999px; margin-top: 4px;
}
.dash-status .mi { font-size: 15px; }
.dash-status-danger  { color: var(--danger); background: rgba(239,68,68,.15); }
.dash-status-warning { color: var(--warning); background: rgba(245,158,11,.16); }
.dash-status-success { color: var(--success); background: rgba(16,185,129,.15); }
.dash-kpi-big .dash-status { font-size: 13px; padding: 5px 11px; }

/* Rango de fechas resuelto bajo el selector de periodo (claridad de qué se ve) */
.dash-period-range { font-size: 13px; color: var(--text-muted); font-weight: 600; }

/* ── Vista Dirección: introducer cards como PROTAGONISTAS (§72) ─────
   En Operativo las cards son un grid de scan rápido (3-4 por fila,
   tamaño compacto). En Dirección son el centro de gravedad de la
   pantalla: 2 cards por fila, padding generoso, tipografía masiva,
   border-left de color tema, glow al hover. Cada card debe sentirse
   como una diapositiva de presentación ejecutiva, no como un tile
   de operación.
   El director quiere IMPACTO inmediato — un solo vistazo y ya sabe
   cómo va cada tema. Cero ruido (sparkline oculta, CTA oculta — toda
   la card es clickable), cero micro-data. Solo la pregunta y la
   respuesta. Patrón Apple Keynote / Bloomberg Terminal exec mode. */
body.viewmode-directivo .dash-intro-grid {
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
  margin-bottom: 32px;
}
@media (max-width: 900px) {
  body.viewmode-directivo .dash-intro-grid {
    grid-template-columns: 1fr;
  }
}
body.viewmode-directivo .dash-intro-card {
  padding: 36px 40px;
  min-height: 220px;
  border-radius: 14px;
  /* Border-left de 5px usando el color del tema. Esto es lo que
     distingue cada card visualmente — verde para Ingresos, cyan para
     Caja, rojo para CxP, etc. La var --theme-color se inyecta inline
     desde el HTML del card. */
  border: 1px solid var(--border-3);
  border-left: 5px solid var(--theme-color, var(--accent));
  /* Gradient sutil que tinta el bg con el color del tema (5% opacity
     simulado vía mezcla manual sobre el dark navy base). El efecto
     final es perceptible pero no chillón. */
  background:
    linear-gradient(135deg, rgba(255,255,255,0.02) 0%, rgba(255,255,255,0) 100%),
    var(--surface-1);
  /* Sombra exterior reposada — los cards "flotan" sutilmente sobre
     el fondo, como sería esperable en una vista de presentación. */
  box-shadow: 0 2px 12px rgba(var(--shadow-rgb),.15);
  display: flex; flex-direction: column;
  gap: 4px;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
body.viewmode-directivo .dash-intro-card:hover,
body.viewmode-directivo .dash-intro-card:focus-visible {
  /* Hover dramático: lift mayor + glow del color del tema. Inversión
     completa del efecto operativo (que era discreto). */
  transform: translateY(-4px);
  box-shadow:
    0 12px 32px rgba(0,0,0,.35),
    0 0 0 1px var(--theme-color, var(--accent)),
    0 0 24px -4px var(--theme-color, var(--accent));
  outline: none;
}
body.viewmode-directivo .dash-intro-head {
  margin-bottom: 12px;
}
body.viewmode-directivo .dash-intro-icon {
  font-size: 32px;
  /* El icono se vuelve mucho más prominente — eyebrow visual antes
     del número. Solid color, no opacity. */
}
body.viewmode-directivo .dash-intro-label {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: var(--text-default);
}
body.viewmode-directivo .dash-intro-val {
  font-size: 56px;
  font-weight: 800;
  line-height: 1;
  margin-top: 4px;
  letter-spacing: -1px;
  /* Sin tone classes para que el número siempre sea blanco-impactante
     en Dirección. La crisis se comunica con el sub-text, no pintando
     el número de rojo (que distrae del "cuánto"). EXCEPCIÓN: si la
     headline retornó tone='danger' (caja en sobregiro), sí pintamos
     porque ahí la crisis ES el dato. */
}
body.viewmode-directivo .dash-intro-val.text-danger { color: var(--danger); }
body.viewmode-directivo .dash-intro-val.text-success { color: inherit; }
body.viewmode-directivo .dash-intro-val.text-warning { color: inherit; }
body.viewmode-directivo .dash-intro-unit {
  font-size: 20px;
  font-weight: 600;
  color: var(--text-muted);
  margin-left: 4px;
}
body.viewmode-directivo .dash-intro-sub {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-default);
  margin-top: 10px;
  min-height: 20px;
}
body.viewmode-directivo .dash-intro-card .dash-spark { display: none; }
body.viewmode-directivo .dash-intro-cta { display: none; }
/* Empty cards en Dirección mantienen la estructura pero con border-left
   atenuado y bg más uniforme — comunican "este tema aún no aporta dato"
   sin gritar. */
body.viewmode-directivo .dash-intro-card.dash-intro-empty {
  opacity: .55;
  border-left-color: var(--border-strong);
}
body.viewmode-directivo .dash-intro-card.dash-intro-empty .dash-intro-icon {
  color: var(--text-soft);
}
body.viewmode-directivo .dash-intro-card.dash-intro-empty .dash-intro-val {
  font-size: 36px;
  color: var(--text-muted);
}

/* Welcome banner en Dirección: jerarquía visual más fuerte, el nombre
   de empresa cobra protagonismo (es el headline de la "portada"). */
body.viewmode-directivo .dash-welcome {
  padding: 28px 32px;
  margin-bottom: 24px;
  background: linear-gradient(135deg, var(--surface-1) 0%, var(--surface-raised) 100%);
  border-radius: 14px;
  border: 1px solid var(--border-3);
}
body.viewmode-directivo .dash-welcome-title {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -.5px;
}
body.viewmode-directivo .dash-welcome-sub {
  font-size: 15px;
  margin-top: 4px;
  color: var(--text-default);
}

/* ── Páginas detalle por tema (Shopify-style) ───────────────────────
   Header con back button + título coloreado + descripción. Los blocks
   del tema se renderean abajo con su estilo nativo (hero/metric/chart). */
.dash-detail-header {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 18px; padding-bottom: 14px;
  border-bottom: 1px solid var(--border-3);
}
.dash-detail-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 22px; font-weight: 700; color: var(--text-strong);
}
.dash-detail-title .mi { font-size: 28px; }
.dash-detail-desc {
  font-size: 13px; color: var(--text-muted);
}
.dash-detail-spacer { flex: 1 1 auto; }
.dash-detail-alerts {
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 16px;
}
.dash-detail-empty {
  text-align: center; padding: 60px 20px; color: var(--text-muted);
}
.dash-detail-empty .dash-empty-icon .mi {
  font-size: 56px;
}
.dash-detail-empty .dash-empty-title {
  font-size: 18px; font-weight: 700; color: var(--text-default); margin: 12px 0 6px;
}
.dash-detail-empty .dash-empty-desc {
  margin-bottom: 18px;
}

/* @media print: en detail pages también ocultar sidebar/topbar */
@media print {
  .dash-intro-grid, .dash-intro-card { display: none !important; }
  .dash-detail-header button { display: none !important; }
}
@media (max-width: 900px) { .dash-bottom-row { grid-template-columns: 1fr; } }

/* ── Executive bands (modo Dirección, audience='directivo') ──────────
   Cards full-width que viven arriba de los hero cards. Tipografía
   generosa, padding amplio — el ejecutivo lee a 80cm de distancia,
   no a 30cm como el operador. Patrón Domo Stories / SAP SAC Stories. */
.dash-exec-band {
  background: linear-gradient(135deg, var(--surface-1) 0%, var(--surface-raised) 100%);
  border: 1px solid var(--border-3);
  border-radius: 10px;
  padding: 22px 26px;
  margin-bottom: 18px;
  box-shadow: 0 4px 14px rgba(var(--shadow-rgb),.18);
}
.dash-exec-band-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-3);
}
.dash-exec-band-head .mi { font-size: 22px; }
.dash-exec-band-title {
  font-size: 16px; font-weight: 700; color: var(--text-strong);
  letter-spacing: .2px;
}
.dash-exec-band-sub {
  font-size: 12px; color: var(--text-muted); font-weight: 500;
  margin-left: 8px;
}

/* Resumen ejecutivo (narrativa) */
.dash-exec-summary-body p { margin: 0 0 8px 0; }
.dash-exec-summary-line {
  font-size: 15px; line-height: 1.55; color: var(--text-default);
}
.dash-exec-summary-line strong { color: var(--text-strong); font-weight: 700; }
.dash-exec-summary-line:last-child { margin-bottom: 0; }

/* Concentración de riesgo (3 columnas paralelas) */
.dash-exec-concent-grid {
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 18px;
}
@media (max-width: 900px) {
  .dash-exec-concent-grid { grid-template-columns: 1fr; }
}
.dash-exec-concent-col-title {
  font-size: 12px; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .5px;
  margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid var(--border-3);
}
.dash-exec-concent-table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
.dash-exec-concent-table td { padding: 6px 4px; vertical-align: middle; }
.dash-exec-concent-rank {
  color: var(--text-muted); font-weight: 700; width: 18px;
}
.dash-exec-concent-name {
  color: var(--text-default); font-weight: 600;
  max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-exec-concent-val {
  color: var(--text-strong); font-weight: 700; text-align: right;
  font-family: ui-monospace, monospace;
  font-size: 12.5px;
}
.dash-exec-concent-pct {
  color: var(--text-muted); font-size: 11.5px; text-align: right;
  width: 38px;
}
.dash-exec-concent-empty {
  color: var(--text-muted); font-style: italic; font-size: 12px; padding: 12px 0;
}

/* Trend 12m chart */
.dash-exec-trend-legend {
  display: flex; gap: 14px; margin-left: auto;
  font-size: 11px; color: var(--text-muted);
}
.dash-exec-trend-legend span {
  display: inline-flex; align-items: center; gap: 5px;
}
.dash-exec-trend-dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
}
.dash-exec-trend-svg {
  width: 100%; height: auto; display: block;
  max-height: 240px;
}

/* En modo Operativo las bands ejecutivas no se renderizan (el dispatcher
   filtra por audience), pero por si acaso quedan en el DOM, esconder.
   En Directivo, además, los hero cards usan más padding y tipografía
   ligeramente mayor — la card ejecutiva ya da el contexto, el hero
   amplifica el dato. */
body:not(.viewmode-directivo) .dash-exec-band { display: none; }
body.viewmode-directivo .dash-exec-band { display: block; }

/* Anotaciones (Baremetrics-style): dots sobre el chart + lista CRUD debajo. */
.dash-exec-trend-annot circle { transition: r .15s ease, stroke-width .15s ease; }
.dash-exec-trend-annot circle:hover { stroke-width: 3; }
.dash-exec-annot-add { margin-left: 12px; }
.dash-exec-annot-list {
  margin-top: 12px; border-top: 1px solid var(--border-3); padding-top: 12px;
  max-height: 240px; overflow-y: auto;
}
.dash-exec-annot-row {
  display: grid; grid-template-columns: 14px 80px 110px 1fr auto;
  gap: 10px; align-items: center; padding: 6px 4px;
  border-bottom: 1px dashed var(--border-1);
  font-size: 13px;
}
.dash-exec-annot-row:last-child { border-bottom: none; }
.dash-exec-annot-dot {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  border: 2px solid var(--surface-1);
}
.dash-exec-annot-date { color: var(--text-muted); font-family: ui-monospace, monospace; font-size: 12px; }
.dash-exec-annot-metric {
  color: var(--text-muted); font-size: 11px; text-transform: uppercase;
  letter-spacing: .4px; font-weight: 600;
}
.dash-exec-annot-text { color: var(--text-default); }
.dash-exec-annot-actions { display: inline-flex; gap: 4px; }
.dash-exec-annot-actions .btn-icon {
  background: none; border: none; cursor: pointer; padding: 2px 6px;
  border-radius: 4px; font-size: 13px; color: var(--text-muted);
}
.dash-exec-annot-actions .btn-icon:hover { background: var(--border-3); color: var(--text-strong); }
.dash-exec-annot-empty {
  color: var(--text-muted); font-style: italic; font-size: 13px; padding: 12px 0;
  text-align: center;
}
.dash-exec-annot-empty .btn-link {
  background: none; border: none; color: var(--accent); cursor: pointer;
  font-style: normal; padding: 0 4px; font-weight: 600;
}
.dash-exec-annot-empty .btn-link:hover { text-decoration: underline; }

/* Botón "Exportar QBR" en welcome banner solo en Directivo */
.dash-export-qbr {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: 12px;
}
body:not(.viewmode-directivo) .dash-export-qbr { display: none; }

/* ── @media print: layout QBR imprimible (Fase C) ─────────────────────
   Cuando el usuario hace Ctrl+P en Dirección, este CSS ajusta para
   producir un PDF/impresión limpia: oculta chrome operacional, convierte
   dark theme a light, asegura saltos de página entre secciones grandes,
   y mantiene las bandas ejecutivas + KPIs + insights legibles. Sin libs
   de PDF — el browser hace todo. */
@media print {
  /* Imprime SIEMPRE en claro, sea cual sea el tema activo: forzamos los tokens a
     valores claros dentro del scope de impresión (en vez de revertir cada var() a
     un hex). Cubre :root (oscuro, sin atributo) y :root[data-theme] (claro). */
  :root, :root[data-theme] {
    --bg-page: #ffffff; --bg-topbar: #ffffff;
    --surface-0: #f1f5f9; --surface-1: #ffffff; --surface-2: #f8fafc;
    --surface-3: #f1f5f9; --surface-raised: #f8fafc;
    --border-1: #d7dfea; --border-2: #cbd5e1; --border-3: #cbd5e1; --border-strong: #94a3b8;
    --text-strong: #0f172a; --text-default: #1a2540; --text-subtle: #334155;
    --text-soft: #475569; --text-dimmed: #475569; --text-muted: #475569;
    --shadow-rgb: 0, 0, 0;
  }
  /* Forzar fondo claro y tipografía legible */
  body, html {
    background: #fff !important;
    color: var(--text-muted) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  body * { box-shadow: none !important; }

  /* Ocultar todo lo que NO es contenido ejecutivo */
  .sidebar, .topbar, .nav-toggle, .nav-overlay,
  .dash-bottom-row, .dash-export-qbr,
  #dash-deferred, .loading-pill, .loading-shell,
  .modal-bg, .modal-card, .toast, .toast-stack,
  .qe-drawer, .cmdk-bg, .cmdk-modal,
  .dash-empty-global, .dash-hero-action {
    display: none !important;
  }

  /* Layout main: full-width sin margenes laterales del sidebar */
  .layout-shell, .content-wrap, #content {
    margin: 0 !important; padding: 0 !important;
    max-width: 100% !important; width: 100% !important;
  }
  #content { padding: 14mm !important; }

  /* Welcome banner */
  .dash-welcome {
    background: var(--surface-raised) !important; border: 1px solid var(--border-strong) !important;
    color: var(--text-muted) !important; padding: 14px 18px !important;
    margin-bottom: 18px !important;
  }
  .dash-welcome-title { color: var(--text-muted) !important; font-size: 22px !important; }
  .dash-welcome-sub, .dash-chip { color: var(--text-muted) !important; }
  .dash-chip { background: var(--surface-raised) !important; }

  /* Daily summary */
  .dash-summary {
    background: var(--surface-raised) !important; border-left: 4px solid var(--warning) !important;
    color: var(--text-muted) !important;
  }

  /* Insights panel */
  .dash-insights-panel, .dash-insight-card {
    background: var(--surface-raised) !important; border: 1px solid var(--border-strong) !important;
    color: var(--text-muted) !important; page-break-inside: avoid;
  }
  .dash-insight-title { color: var(--text-muted) !important; }
  .dash-insight-desc { color: var(--text-muted) !important; }

  /* Bandas ejecutivas */
  .dash-exec-band {
    background: #fff !important;
    border: 1px solid var(--border-strong) !important;
    color: var(--text-muted) !important;
    page-break-inside: avoid;
    margin-bottom: 14mm !important;
  }
  .dash-exec-band-head {
    border-bottom: 1px solid var(--border-strong) !important;
  }
  .dash-exec-band-title { color: var(--text-muted) !important; }
  .dash-exec-band-sub { color: var(--text-soft) !important; }
  .dash-exec-summary-line, .dash-exec-summary-line strong { color: var(--text-muted) !important; }
  .dash-exec-concent-col-title {
    color: var(--text-muted) !important; border-bottom: 1px solid var(--border-strong) !important;
  }
  .dash-exec-concent-name { color: var(--text-muted) !important; }
  .dash-exec-concent-val { color: var(--text-muted) !important; }
  .dash-exec-concent-pct, .dash-exec-concent-rank { color: var(--text-soft) !important; }
  .dash-exec-trend-legend, .dash-exec-trend-legend span { color: var(--text-muted) !important; }
  .dash-exec-trend-svg text { fill: var(--text-muted) !important; }
  .dash-exec-trend-svg line { stroke: var(--text-strong) !important; }
  .dash-exec-annot-row {
    color: var(--text-muted) !important;
    border-bottom: 1px solid var(--border-strong) !important;
  }
  .dash-exec-annot-text { color: var(--text-muted) !important; }
  .dash-exec-annot-date, .dash-exec-annot-metric { color: var(--text-soft) !important; }
  .dash-exec-annot-actions { display: none !important; }
  .dash-exec-annot-add { display: none !important; }

  /* Hero cards: 2 columnas, fondo claro */
  .dash-hero-cards { grid-template-columns: 1fr 1fr !important; gap: 8mm !important; }
  .dash-hero-card {
    background: #fff !important;
    border: 1px solid var(--border-strong) !important;
    color: var(--text-muted) !important;
    page-break-inside: avoid;
  }
  .dash-hero-label { color: var(--text-muted) !important; }
  .dash-hero-val { color: var(--text-muted) !important; }
  .dash-hero-sub { color: var(--text-soft) !important; }
  .dash-hero-icon { filter: grayscale(.2); }

  /* Salto de página entre bandas grandes para que el QBR se imprima limpio */
  .dash-exec-trend { page-break-before: auto; }
  .dash-exec-concent { page-break-before: auto; }

  /* Anular text-success/danger/warning con colores impresos legibles */
  .text-success { color: var(--success) !important; }
  .text-warning { color: var(--warning) !important; }
  .text-danger  { color: var(--danger) !important; }
  .text-muted, .text-dimmed { color: var(--text-soft) !important; }

  /* Configuración de página */
  @page {
    size: A4 portrait;
    margin: 8mm;
  }
}

.dash-chart { padding: 8px 0; }
.dash-chart-bars {
  display: flex; align-items: flex-end; justify-content: space-around;
  gap: 12px; height: 180px; padding: 0 8px;
}
.dash-chart-col {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  gap: 6px; min-width: 0; height: 100%;
  justify-content: flex-end;
}
.dash-chart-val { color: var(--text-default); white-space: nowrap; }
.dash-chart-bar {
  width: 100%; max-width: 48px; min-height: 4px;
  background: linear-gradient(180deg, var(--accent-bright) 0%, var(--accent) 100%);
  border-radius: 6px 6px 0 0;
  transition: height .3s ease;
}
.dash-chart-label { color: var(--text-muted); white-space: nowrap; }
.dash-chart-bar-proj {
  background: repeating-linear-gradient(135deg, rgba(var(--accent-bright-rgb),.25) 0px, rgba(var(--accent-bright-rgb),.25) 4px, rgba(var(--accent-2-rgb),.19) 4px, rgba(var(--accent-2-rgb),.19) 8px);
  border: 1.5px dashed rgba(var(--accent-bright-rgb),.5);
}
.dash-forecast-legend {
  display: flex; gap: 20px; padding: 0 8px 4px;
  font-size: 12px; color: var(--text-default);
}
.dash-legend-item { display: flex; align-items: center; gap: 6px; }
.dash-legend-dot {
  width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0;
}
.dash-legend-real { background: linear-gradient(180deg, var(--accent-bright) 0%, var(--accent) 100%); }
.dash-legend-proj {
  background: repeating-linear-gradient(135deg, rgba(var(--accent-bright-rgb),.25) 0px, rgba(var(--accent-bright-rgb),.25) 4px, rgba(var(--accent-2-rgb),.19) 4px, rgba(var(--accent-2-rgb),.19) 8px);
  border: 1.5px dashed rgba(var(--accent-bright-rgb),.5);
}

.dash-metrics-card, .dash-alerts-card {
  background: var(--surface-1); border: 1px solid var(--border-1);
  border-radius: 14px; padding: 24px;
  box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.2);
}
.dash-section-title {
  font-size: 14px; font-weight: 700; color: var(--text-strong);
  margin-bottom: 18px; display: flex; align-items: center; gap: 8px;
}
.dash-metrics-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.dash-metric {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 12px; padding: 18px 16px;
  display: flex; flex-direction: column; gap: 4px;
  position: relative; transition: background .15s, border-color .15s;
}
.dash-metric.clickable { cursor: pointer; }
.dash-metric.clickable:hover { background: var(--surface-raised); border-color: var(--border-strong); }
.dash-metric-label { font-size: 12px; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .5px; }
.dash-metric-val { font-size: clamp(20px, 1.4vw + 16px, 26px); font-weight: 800; color: var(--text-strong); }
.dash-metric-icons { position: absolute; top: 14px; right: 14px; opacity: .5; }
.dash-metric-spark { margin-top: 4px; line-height: 0; opacity: .85; }
.dash-metric-spark svg { display: block; }

.dash-alerts-list { display: flex; flex-direction: column; gap: 10px; }
.dash-alert-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; background: var(--surface-2);
  border: 1px solid var(--border-1); border-radius: 10px;
  transition: background .15s;
}
.dash-alert-item.clickable { cursor: pointer; }
.dash-alert-item.clickable:hover { background: var(--surface-raised); border-color: var(--border-strong); }
.dash-alert-title { font-size: 13px; font-weight: 700; color: var(--text-strong); }
.dash-alert-desc { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* ── ICON PICKER ── */
.icon-picker-wrap { position: relative; }
.icon-picker-preview {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  cursor: pointer; transition: .2s; min-height: 48px;
}
.icon-picker-preview:hover { border-color: var(--accent); background: var(--surface-3); }
.icon-picker-preview .mi { font-size: 28px; color: var(--accent); }
.icon-picker-preview img { width: 32px; height: 32px; object-fit: contain; border-radius: 6px; }
.icon-picker-preview .placeholder { color: var(--text-muted); font-size: 13px; }

.icon-picker-dropdown {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(var(--shadow-rgb),.4); z-index: 50;
  padding: 14px; max-height: 360px; overflow-y: auto;
  display: none;
}
.icon-picker-dropdown.open { display: block; animation: fadeDown .15s ease; }
.icon-picker-search {
  width: 100%; padding: 8px 12px; border: 1px solid var(--border-2);
  border-radius: 8px; font-size: 12px; margin-bottom: 10px;
  outline: none; font-family: inherit; background: var(--surface-2); color: var(--text-strong);
}
.icon-picker-search:focus { border-color: var(--accent); }
.icon-picker-tabs { display: flex; gap: 4px; margin-bottom: 10px; }
.icon-picker-tab {
  padding: 5px 12px; font-size: 11px; font-weight: 600;
  border-radius: 6px; cursor: pointer; border: 1px solid var(--border-1);
  color: var(--text-muted); transition: .15s; background: var(--surface-2);
}
.icon-picker-tab.active { background: var(--accent-2); color: #fff; border-color: var(--accent-2); }
.icon-picker-grid {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px;
}
.icon-picker-item {
  width: 100%; aspect-ratio: 1; display: flex; align-items: center;
  justify-content: center; border-radius: 8px; cursor: pointer;
  transition: .15s; border: 2px solid transparent;
}
.icon-picker-item:hover { background: var(--surface-3); border-color: var(--border-strong); }
.icon-picker-item.selected { background: var(--surface-3); border-color: var(--accent); }
.icon-picker-item .mi { font-size: 22px; color: var(--text-subtle); }
.icon-picker-item:hover .mi { color: var(--accent); }
.icon-picker-item.selected .mi { color: var(--accent); }
.icon-picker-upload {
  display: flex; align-items: center; gap: 8px;
  padding: 10px; border: 2px dashed var(--border-2); border-radius: 8px;
  cursor: pointer; margin-top: 8px; transition: .15s;
  font-size: 12px; color: var(--text-muted);
}
.icon-picker-upload:hover { border-color: var(--accent); background: var(--surface-3); color: var(--accent); }

/* ── SCROLLBAR ── */
::-webkit-scrollbar { width:5px; height:5px; }
::-webkit-scrollbar-track { background:transparent; }
::-webkit-scrollbar-thumb { background:var(--border-1); border-radius:3px; }
::-webkit-scrollbar-thumb:hover { background:var(--border-strong); }

/* ════════════════════════════════════════════════════════════
   UTILITY CLASSES — replaces inline styles throughout the app
   ════════════════════════════════════════════════════════════ */

/* ── Color text utilities ── */
.text-success       { color: var(--success); }
.text-success-bright{ color: var(--success); }
.text-info          { color: var(--accent); }
.text-warning       { color: var(--warning); }
.text-danger        { color: var(--danger); }
.text-danger-bright { color: var(--danger); }
.text-purple        { color: var(--purple); }
.text-purple-pastel { color: var(--purple); }
.text-muted         { color: var(--text-muted); }
.text-dimmed        { color: var(--text-muted); }
.text-subtle        { color: var(--text-subtle); }
.text-dark          { color: var(--text-strong); }
.text-amber         { color: var(--warning); }
.text-teal          { color: var(--info); }
.text-orange        { color: var(--warning); }
.text-cobalt        { color: var(--warning); }
.text-crimson       { color: var(--danger); }
.text-right         { text-align: right; }
.text-center        { text-align: center; }

/* ── Typography utilities ── */
.mono        { font-family: monospace; }
.text-xxs    { font-size: 12px; }
.text-xs     { font-size: 13px; }
.text-sm     { font-size: 14px; }
.text-md     { font-size: 15px; }
.text-lg     { font-size: 15px; }
.text-xl     { font-size: 18px; }
.text-2xl    { font-size: 20px; }
.text-3xl    { font-size: 22px; }
.text-4xl    { font-size: 26px; }
.fw-normal   { font-weight: 400; }
.fw-medium   { font-weight: 500; }
.fw-semibold { font-weight: 600; }
.fw-bold     { font-weight: 700; }
.fw-extrabold{ font-weight: 800; }
.uppercase   { text-transform: uppercase; }
.tracking-wide { letter-spacing: .6px; }
.nowrap      { white-space: nowrap; }
.truncate    { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-center { text-align: center; }

/* ── Layout utilities ── */
.flex-row    { display: flex; align-items: center; }
.flex-col    { display: flex; flex-direction: column; }
.flex-wrap   { flex-wrap: wrap; }
.flex-1      { flex: 1; }
.flex-shrink-0 { flex-shrink: 0; }
.items-start { align-items: flex-start; }
.items-center{ align-items: center; }
.justify-end { justify-content: flex-end; }
.justify-between { justify-content: space-between; }
.gap-0  { gap: 0; }
.gap-4  { gap: 4px; }
.gap-6  { gap: 6px; }
.gap-8  { gap: 8px; }
.gap-10 { gap: 10px; }
.gap-12 { gap: 12px; }
.gap-14 { gap: 14px; }
.gap-16 { gap: 16px; }
.gap-20 { gap: 20px; }
.gap-24 { gap: 24px; }
.w-full  { width: 100%; }
.max-w-280 { max-width: 280px; }
.max-w-220 { max-width: 220px; }
.max-w-700 { max-width: 700px; }
.max-w-860 { max-width: 860px; }
.ml-auto { margin-left: auto; }
.mx-auto { margin-left: auto; margin-right: auto; }
.mt-4    { margin-top: 4px; }
.mt-6    { margin-top: 6px; }
.mt-8    { margin-top: 8px; }
.mt-12   { margin-top: 12px; }
.mt-14   { margin-top: 14px; }
.mt-16   { margin-top: 16px; }
.mb-2    { margin-bottom: 2px; }
.mb-4    { margin-bottom: 4px; }
.mb-6    { margin-bottom: 6px; }
.mb-8    { margin-bottom: 8px; }
.mb-10   { margin-bottom: 10px; }
.mb-12   { margin-bottom: 12px; }
.mb-14   { margin-bottom: 14px; }
.mb-16   { margin-bottom: 16px; }
.mb-20   { margin-bottom: 20px; }
.p-0     { padding: 0; }
.p-4     { padding: 4px; }
.px-12   { padding-left: 12px; padding-right: 12px; }
.py-4    { padding-top: 4px; padding-bottom: 4px; }
.pt-14   { padding-top: 14px; }
.hidden  { display: none !important; }
.relative{ position: relative; }

/* ── Preview mode ──────────────────────────────────────────── */
#preview-banner { background: var(--warning-bg); color: var(--text-strong); padding: 7px 16px; font-size: .85rem; display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; position: sticky; top: 0; z-index: 10001; border-bottom: 1px solid var(--warning-bd); }
/* §573: con el aviso de vista previa, el topbar (sticky) se pega debajo del aviso, no encima */
body.crm-preview .topbar { top: var(--preview-h, 32px); }
#preview-banner strong { color: var(--text-strong); }
#preview-banner a { color: var(--accent); text-decoration: none; font-weight: 600; }
#preview-banner a:hover { text-decoration: underline; }

/* ── Misc utilities ── */
.cursor-pointer { cursor: pointer; }
.opacity-50 { opacity: .5; }
.opacity-55 { opacity: .55; }
.opacity-60 { opacity: .6; }
.border-top-sep { border-top: 1px solid var(--border-1); padding-top: 14px; margin-top: 4px; }
.lh-17   { line-height: 1.7; }

/* ════════════════════════════════════════════════════════════
   ICON SIZING & COLOR MODIFIERS
   ════════════════════════════════════════════════════════════ */
.mi-sm  { font-size: 14px; }
.mi-lg  { font-size: 20px; }
.mi-xl  { font-size: 24px; }
.mi-2xl { font-size: 28px; }
.mi-blue    { color: var(--accent); }
.mi-purple  { color: var(--purple); }
.mi-amber   { color: var(--warning); }
.mi-danger  { color: var(--danger); }
.mi-success { color: var(--success); }
.mi-muted   { color: var(--border-1); }
.mi-star    { color: var(--warning); }
.emoji-md   { font-size: 20px; }
.emoji-lg   { font-size: 24px; }

/* ── LOGO / AVATAR THUMBNAILS ── */
.tbl-logo {
  width: 34px; height: 34px; border-radius: 6px;
  background: #fff; display: inline-flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0; vertical-align: middle;
}
.tbl-logo img {
  width: 100%; height: 100%; object-fit: contain;
}
.tbl-logo-fallback {
  width: 34px; height: 34px; border-radius: 6px;
  background: linear-gradient(135deg, var(--border-1), var(--surface-raised));
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; color: var(--accent);
  flex-shrink: 0; vertical-align: middle; letter-spacing: .5px;
}
.tbl-logo-lg {
  width: 56px; height: 56px; border-radius: 10px;
  background: #fff; display: inline-flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
}
.tbl-logo-lg img {
  width: 100%; height: 100%; object-fit: contain;
}
.tbl-logo-fallback-lg {
  width: 56px; height: 56px; border-radius: 10px;
  background: linear-gradient(135deg, var(--border-1), var(--surface-raised));
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; color: var(--accent);
  flex-shrink: 0; letter-spacing: .5px;
}
.tbl-cell-logo { display: flex; align-items: center; gap: 10px; }
.tbl-icon-img { width: 28px; height: 28px; border-radius: 6px; object-fit: contain; background: #fff; padding: 2px; }

/* ════════════════════════════════════════════════════════════
   COMPONENT CLASSES — reusable across modules
   ════════════════════════════════════════════════════════════ */

/* ── Button variants ── */
.btn-csv       { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.btn-csv:hover { background: var(--success-bg); }
.btn-action-warn   { background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-bd); }
.btn-action-danger { background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger-bd); }
.btn-action-success{ background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.btn-action-blue   { background: var(--surface-1); color: var(--accent); border: 1px solid var(--border-strong); }
.btn-action-blue:hover { background: var(--surface-3); }
/* ── Diálogo de elección (archivar / eliminar y similares) ──────────────────
   Tarjetas de acción grandes y legibles: icono en cuadro tintado + título +
   subtítulo. Sustituye a los botones con emoji (📦/🗑) + estilos inline que se
   veían baratos e inconsistentes con el resto del portal (§choice-dialog).
   El "Cancelar" va dentro de un .modal-btns propio → recupera el padding
   inferior del modal (.modal usa `padding-bottom:0` y delega el fondo al footer
   sticky), que antes faltaba y dejaba el botón pegado al borde. */
.choice-list { display: flex; flex-direction: column; gap: 10px; }
.choice-card {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  padding: 14px 16px; border-radius: 12px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--border-1);
  transition: border-color .15s, background .15s, transform .1s, box-shadow .15s;
}
.choice-card:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(var(--shadow-rgb), .18); }
.choice-card-ic {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
}
.choice-card-ic .mi { font-size: 23px; }
.choice-card-tx { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.choice-card-t { font-weight: 700; font-size: 14.5px; color: var(--text-strong); }
.choice-card-s { font-size: 12.5px; color: var(--text-muted); line-height: 1.4; }
.choice-card-ok .choice-card-ic { background: var(--success-bg); color: var(--success); }
.choice-card-ok:hover { border-color: var(--success); }
.choice-card-danger .choice-card-ic { background: var(--danger-bg); color: var(--danger); }
.choice-card-danger .choice-card-t { color: var(--danger); }
.choice-card-danger:hover { border-color: var(--danger); }
/* Aviso de dependencias dentro del diálogo */
.choice-warn {
  display: flex; gap: 10px; align-items: flex-start;
  background: var(--warning-bg); border: 1px solid var(--warning-bd);
  border-radius: 10px; padding: 12px 14px; color: var(--warning);
  font-size: 13px; line-height: 1.5;
}
.choice-warn .mi { font-size: 20px; flex-shrink: 0; margin-top: 1px; }
.choice-warn-t { font-weight: 700; margin-bottom: 3px; }
/* §416: el plan de lo que se va con el registro (qué se va · qué no se toca · qué no deja seguir) */
.del-plan { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.choice-warn-info { background: var(--info-bg); border-color: var(--info-bd); color: var(--info); }
.choice-warn-danger { background: var(--danger-bg); border-color: var(--danger-bd); color: var(--danger); }
.choice-card:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }
.choice-card:disabled:hover { border-color: var(--border-1); }
/* §417: fila que el buscador trajo del historial y no es del periodo elegido arriba */
.pg-fuera-tag {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: 12px; font-weight: 500; line-height: 1.5; white-space: nowrap; vertical-align: middle;
  color: var(--text-dimmed); background: var(--surface-2); border: 1px solid var(--border-2);
}

.btn-duplicate { background: var(--surface-1); color: var(--accent); border: 1px solid var(--border-strong); }
.btn-renew     { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.btn-renew:hover { background: var(--success-bg); }
.btn-reset-pass{ background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-bd); }
.btn-activate  { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.btn-delete-confirm { background: var(--danger); color: #fff; border: none; }
.btn-delete-confirm:disabled { opacity: .5; }

/* ── Folio / ID display ── */
.folio-display {
  padding: 10px 14px; background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: 8px; font-family: monospace; color: var(--accent);
}

/* ── Totals section ── */
.totals-section {
  margin-top: 16px; background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 10px; padding: 14px;
}
.totals-label { margin-bottom: 8px; font-size: 11px; color: var(--accent); font-weight: 600; }

/* ── Section label ── */
.section-label {
  margin: 16px 0 8px; font-size: 11px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .8px; font-weight: 700;
}

/* ── Detail row (services in venta modal) ── */
.det-row { display: grid; grid-template-columns: 2fr 2fr 1fr 1fr auto; gap: 8px; align-items: end; }
/* Concepto de la línea: renglón propio a todo lo ancho (2º renglón del grid).
   No cabe como 5ª columna sin apretar los otros 4 campos por debajo de lo
   legible (§85 P-legibilidad). Con `1 / -1` también funciona en el grid de
   2 columnas del breakpoint móvil. */
.det-row .fg-desc { grid-column: 1 / -1; }
.det-row .fg-desc input { width: 100%; }

/* ── Service tag pill ── */
.srv-tag {
  font-size: 11px; background: var(--success-bg); color: var(--success);
  padding: 2px 7px; border-radius: 10px; margin: 1px; display: inline-block;
}

/* ── IVA / financial values ── */
.val-iva   { color: var(--warning); font-weight: 700; }
.val-total { color: var(--success); font-weight: 700; }

/* ── Totals row (IVA + Total inline) ── */
.totals-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 8px 12px; background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 8px; }
.totals-iva-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; font-size: 12px; color: var(--text-muted); font-weight: 600; }
.totals-iva-toggle .val-iva { margin-left: 4px; font-size: 13px; }
.totals-total { display: flex; align-items: center; gap: 10px; }
.totals-total-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 700; }
.totals-total .val-total { font-size: 16px; }

/* ── Collapsible category groups ── */
.cat-group-header.cat-collapsible:hover { background: var(--surface-raised); border-radius: 8px; }
.cat-group-body { transition: none; }
.cat-group-body.collapsed { display: none; }

/* ── IVA checkbox ── */
.fg label.iva-check-label { display: flex; align-items: center; gap: 7px; cursor: pointer; user-select: none; font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .6px; font-weight: 700; overflow: visible; white-space: nowrap; }
.iva-checkbox    { width: 14px; height: 14px; cursor: pointer; accent-color: var(--accent); flex-shrink: 0; }
.iva-checkbox-lg { width: 16px; height: 16px; cursor: pointer; accent-color: var(--accent); flex-shrink: 0; }
.checkbox-accent-success { width: 16px; height: 16px; cursor: pointer; accent-color: var(--success); flex-shrink: 0; }

/* ── Checkbox inline con título + ayuda en case normal (§171/§172) ──
   Para opciones secundarias tipo "Disponible para todo el grupo": un
   <label class="full check-inline"> normal (NO .fg label, evita heredar el
   mayúsculas/11px de las etiquetas de campo — se veía "horrible" a esa
   longitud) con el checkbox alineado arriba del texto y un sub-texto de
   ayuda claramente atenuado, no compitiendo con el título. */
.check-inline { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; padding: 4px 0; }
.check-inline input[type="checkbox"] { margin-top: 3px; flex-shrink: 0; accent-color: var(--accent); }
.check-inline .check-inline-title { display: block; font-size: 13px; color: var(--text-strong); font-weight: 600; }
.check-inline .check-inline-sub { display: block; font-size: 11px; color: var(--text-muted); font-weight: 400; margin-top: 1px; }

/* ── Create agreement box ── */
.create-agreement-box {
  display: flex; align-items: center; gap: 10px;
  margin-top: 14px; padding: 12px 14px;
  background: var(--success-bg); border: 1px solid var(--success-bd); border-radius: 8px;
}
.create-agreement-label { cursor: pointer; margin: 0; font-size: 13px; color: var(--success); font-weight: 600; }
.create-agreement-hint  { font-size: 11px; color: var(--text-muted); }

/* ── Card color accents (top border) ── */
.card.card-success::before { background: linear-gradient(90deg,var(--success),var(--success)); opacity:1; }
.card.card-danger::before  { background: linear-gradient(90deg,var(--danger),var(--danger)); opacity:1; }
.card.card-warning::before { background: linear-gradient(90deg,var(--warning),var(--warning)); opacity:1; }
.card.card-info::before    { background: linear-gradient(90deg,var(--accent-2),var(--accent)); opacity:1; }
.card.card-purple::before  { background: linear-gradient(90deg,var(--purple),var(--purple)); opacity:1; }

/* ── Card sub text ── */
.card-sub { font-size: 10px; color: var(--text-muted); margin-top: 4px; }

/* ── Period selector ── */
.periodo-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 16px; }
.periodo-label-text { font-size: 12px; color: var(--text-muted); }
.periodo-select {
  font-size: 12px; padding: 6px 12px; background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: 8px; color: var(--text-strong); cursor: pointer;
}
.periodo-input {
  font-size: 12px; padding: 5px 10px; background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: 8px; color: var(--text-strong);
}
.periodo-arrow { color: var(--text-muted); font-size: 12px; }

/* ── Role badge ── */
.role-badge { padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 600; }
.role-Superadmin { background: var(--purple-bg); color: var(--purple); border: 1px solid var(--purple-bd); }
.role-Ventas     { background: var(--surface-1); color: var(--info); border: 1px solid var(--border-strong); }
.role-Cobranza   { background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-bd); }
.role-Soporte    { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }

/* ── Log action colors ── */
.action-Crear, .action-Activar, .action-NuevoUsuario { color: var(--success); }
.action-Editar, .action-EditarUsuario { color: var(--accent); }
.action-Eliminar, .action-EliminarUsuario { color: var(--danger); }
.action-Desactivar { color: var(--warning); }
.action-ResetPass  { color: var(--purple); }
.action-color { font-weight: 600; font-size: 12px; }

/* ── Client chip ── */
.cli-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--purple-bg); color: var(--purple);
  border: 1px solid var(--purple-bd); border-radius: 20px;
  padding: 5px 12px; font-size: 12px; font-weight: 500;
}
.cli-chip-remove {
  background: none; border: none; color: var(--danger);
  cursor: pointer; padding: 0; font-size: 15px; line-height: 1;
  display: flex; align-items: center;
}
.cli-chips-empty { color: var(--text-muted); font-size: 12px; line-height: 36px; }

/* ── Equipo picker (modal proyecto) ── */
.pry-equipo-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  min-height: 36px; padding: 6px 8px;
  background: var(--surface-2); border: 1px solid var(--border-1); border-radius: 8px;
  margin-bottom: 8px;
}
.pry-equipo-add { display: flex; gap: 8px; align-items: stretch; }
.pry-equipo-select { flex: 1; min-width: 0; }

/* ── Client access section ── */
.client-access-section {
  margin-top: 16px; background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 10px; padding: 14px;
}
.client-access-label {
  font-size: 11px; font-weight: 700; letter-spacing: .6px;
  color: var(--text-muted); text-transform: uppercase; margin-bottom: 10px;
}
.client-select {
  flex: 1; background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 8px; color: var(--text-strong); padding: 8px 12px; font-size: 13px;
}

/* ── Password input with toggle ── */
.password-wrap { position: relative; display: block; }
.password-wrap input { padding-right: 40px; width: 100%; box-sizing: border-box; }
.password-toggle {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 16px; padding: 4px 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px; transition: color .15s, background .15s;
}
.password-toggle:hover { color: var(--text-default); background: rgba(147,197,253,.08); }
.password-toggle .mi { font-size: 18px; line-height: 1; }

/* (§pto6) El recuadro "Pendientes de facturar" de Ventas se retiró: la
   facturación pendiente vive ahora en el módulo Facturación. CSS eliminado. */

/* ── Fiscal details (pending invoice modal) ── */
.fiscal-details { background: var(--surface-raised); border: 1px solid var(--border-3); border-radius: 8px; padding: 10px 14px; margin: 8px 0 12px; font-size: 13px; }
.fiscal-details summary { cursor: pointer; font-size: 12px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; }
.fiscal-details[open] summary { margin-bottom: 8px; }
.fiscal-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 16px; }
.fiscal-item { display: flex; flex-direction: column; gap: 1px; }
.fiscal-lbl { font-size: 10px; color: var(--text-muted); text-transform: uppercase; }
.fiscal-val { font-size: 13px; color: var(--text-default); user-select: all; }

/* ── Factura badge indicator ── */
.badge-fac { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 4px; background: var(--purple-bg); color: var(--purple); font-size: 10px; font-weight: 800; margin-left: 4px; vertical-align: middle; }

/* ── Detail view (read-only modal) ── */
.detail-view .val { color: var(--text-strong); font-size: 14px; padding: 6px 0; }
.detail-view .hito-row-view { display: grid; grid-template-columns: 1fr auto auto auto; gap: 12px; padding: 6px 10px; background: var(--surface-2); border-radius: 6px; margin-bottom: 4px; font-size: 13px; align-items: center; }
.view-val { color: var(--text-strong); font-size: 14px; padding: 8px 0 2px; display: block; word-break: break-word; }

/* ── Required / Optional field indicators ── */
.fg label .req { color: var(--danger); margin-left: 2px; font-size: 12px; }
.fg label .opc { color: var(--text-muted); font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 10px; margin-left: 4px; }

/* ── Roles info box ── */
.roles-info {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 8px; padding: 12px; margin: 10px 0;
  font-size: 12px; color: var(--text-muted);
}

/* ── IVA summary grid ── */
.iva-summary {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 8px; padding: 12px 16px; margin-bottom: 12px;
}
.iva-summary-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 16px; font-size: 13px; }
.iva-summary-border { border-top: 1px solid var(--border-1); padding-top: 4px; }

/* ── Price warning ── */
.price-warning {
  margin-top: 6px; padding: 8px 10px;
  background: var(--surface-3); border: 1px solid var(--border-strong);
  border-radius: 6px; font-size: 12px; color: var(--accent);
}

/* ── Periodos pendientes (Cobranza) ── */
.periodos-panel { margin: 8px 0 4px; padding: 10px 12px; background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 8px; max-height: 38vh; overflow-y: auto; }
.periodos-title { font-size: 13px; font-weight: 600; color: var(--text-strong); margin-bottom: 8px; }
.periodos-acuerdo { margin-bottom: 10px; }
.periodos-acuerdo:last-child { margin-bottom: 0; }
.periodos-acuerdo-title { font-size: 12px; color: var(--text-subtle); margin-bottom: 6px; }
.periodos-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.periodo-chip {
  padding: 5px 10px; border-radius: 6px; font-size: 12px; cursor: pointer;
  background: var(--surface-raised); border: 1px solid var(--border-strong); color: var(--text-default);
  transition: all .15s;
}
.periodo-chip:hover { background: var(--surface-raised); border-color: var(--border-strong); color: var(--text-strong); }
.periodo-chip.selected { background: var(--accent); border-color: var(--accent); color: #fff; }
.periodo-chip.vencido { border-color: var(--danger-bd); color: var(--danger); }
.periodo-chip.vencido:hover { background: var(--danger-bg); border-color: var(--danger); }
.periodo-chip.vencido.selected { background: var(--danger-bg); border-color: var(--danger); color: var(--text-default); }
.periodo-chip.parcial { border-color: var(--warning); color: var(--warning); }
.periodo-chip.parcial:hover { background: var(--warning-bg); border-color: var(--warning); }
.periodo-chip.parcial.selected { background: var(--warning-bg); border-color: var(--warning); color: var(--warning); }
.periodo-chip.cubierto { background: var(--surface-3); border-color: var(--border-strong); color: var(--text-soft); cursor: default; opacity: .6; }
.periodo-chip.condonado { background: var(--purple-bg); border-color: var(--purple-bd); color: var(--purple); cursor: default; opacity: .7; }
.periodos-sugerencia { font-size: 12px; color: var(--warning); padding: 4px 0 8px; border-bottom: 1px solid var(--border-strong); margin-bottom: 8px; }
.pago-resumen-box { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; padding: 8px 12px; background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 8px; font-size: 13px; color: var(--text-strong); }
/* Resumen de cuadre SIEMPRE visible mientras seleccionas periodos (antes scrolleaba
   fuera de vista — reportado por el tester). Sticky al tope del scroll del modal,
   solo cuando tiene contenido. */
#pago-resumen:not(:empty) { position: sticky; top: 0; z-index: 4; background: var(--surface-1); padding: 6px 0; }
.periodos-nota { color: var(--warning); margin: 2px 0 6px; }
.periodos-hint { margin: 4px 0 8px; line-height: 1.45; }

.saldo-favor-banner { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 8px; font-size: 13px; color: var(--accent); }
.saldo-favor-banner .mi { font-size: 18px; }

/* ── Anulado status ── */
.badge-Anulado { background: var(--surface-3); color: var(--text-soft); text-decoration: line-through; }

/* ── Milestone / Hitos editor ── */
/* ── Exhibiciones del acuerdo (§195): panel con barra de reparto, cabecera de
      columnas, renglones en grid y pie con el avance del reparto. La cabecera y el
      renglón COMPARTEN plantilla de grid (con y sin la columna de %): si cambias
      una, cambia la otra o se desalinean. ── */
.hitos-box { background: var(--surface-2); border: 1px solid var(--border-1); border-radius: 10px; padding: 10px; }
.hitos-controls { display: flex; gap: 16px; align-items: flex-end; flex-wrap: wrap; padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--border-1); }
.hitos-ctrl { display: flex; flex-direction: column; gap: 4px; }
.hitos-ctrl label { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-dimmed); font-weight: 700; display: flex; align-items: center; gap: 2px; }
.hitos-controls .hito-money { width: 150px; }
.hitos-controls select { width: auto; min-width: 150px; }
.hitos-box .hitos-controls input, .hitos-box .hitos-controls select { font-size: 13px; padding: 7px 10px; background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 7px; color: var(--text-strong); }
.hitos-vacio { font-size: 12px; color: var(--text-dimmed); text-align: center; padding: 10px 6px; }
.hitos-table { display: flex; flex-direction: column; gap: 4px; }
.hito-head, .hito-row { display: grid; grid-template-columns: minmax(110px, 2.2fr) minmax(90px, 1.1fr) 150px 30px; gap: 8px; align-items: center; }
.hitos-table.con-pct .hito-head, .hitos-table.con-pct .hito-row { grid-template-columns: minmax(110px, 2.2fr) 82px minmax(90px, 1.1fr) 150px 30px; }
.hito-head { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-dimmed); font-weight: 700; padding: 0 2px 2px; }
.hito-row input { font-size: 13px; padding: 7px 10px; background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 7px; color: var(--text-strong); width: 100%; }
.hito-row input:focus, .hitos-box .hitos-controls input:focus, .hitos-controls select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); outline: none; }
/* El monto derivado del % NO se apaga: es el número que el usuario vino a ver. Se
   marca "calculado" con el borde punteado, no escondiéndolo. */
.hito-row input[readonly] { border-style: dashed; cursor: default; }
/* Campo de dinero/porcentaje: el símbolo es un adorno del contenedor (un input no
   admite ::before) y la cifra va a la derecha, como en cualquier estado de cuenta. */
.hito-money { position: relative; display: block; }
.hito-money-sym { position: absolute; top: 50%; transform: translateY(-50%); left: 10px; font-size: 12px; color: var(--text-dimmed); pointer-events: none; }
.hito-money-sym.suf { left: auto; right: 10px; }
.hito-money input { text-align: right; padding-left: 22px; }
.hito-pct-wrap input { padding-left: 10px; padding-right: 22px; }
/* Quitar: gris hasta que lo apuntas (§85 — una fila con 3 botones rojos grita). */
.hito-del {
  background: none; border: 1px solid transparent; border-radius: 7px; cursor: pointer;
  color: var(--text-dimmed); font-size: 13px; line-height: 1; padding: 7px 6px; transition: .15s;
}
.hito-del:hover, .hito-del:focus-visible { background: var(--danger-bg); border-color: var(--danger-bd); color: var(--danger); }
.hito-total {
  display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--text-muted); padding: 8px 2px 2px; margin-top: 4px;
  border-top: 1px solid var(--border-1);
}
.hito-total strong { color: var(--text-strong); }
.hito-total.is-ok     .hito-total-estado { color: var(--success); }
.hito-total.is-falta  .hito-total-estado { color: var(--warning); }
.hito-total.is-exceso .hito-total-estado { color: var(--danger); }
.hitos-add { margin-top: 10px; }
/* §199 (auditoría): las filas de Ventas/Acuerdos medían ~150px porque el folio (mono,
   columna angosta) y las fechas se partían en dos líneas y debajo va la tira de
   acciones. Un folio, una fecha o un importe no se parten: la tabla desplaza
   horizontalmente dentro de su `.table-wrap` en vez de apretar las columnas. */
td.td-title, td.mono, td.nowrap, .nowrap { white-space: nowrap; }
/* La tira de acciones tampoco se parte: como `.row-actions` es flex con `wrap`, en una
   columna angosta (folio de 167px) caía en 4 renglones y la fila seguía midiendo ~120px.
   Con `nowrap` la columna del título se ensancha lo que mida la tira (~250px) y la tabla
   desplaza dentro de `.table-wrap`, que es justo la regla de arriba. */
td.td-title .row-actions { flex-wrap: nowrap; white-space: nowrap; }
/* Desglose de la venta ligada bajo su combo en el modal de acuerdo (§195). */
.venta-desglose:not(:empty) { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; font-size: 12px; color: var(--text-muted); margin-top: 6px; }

/* ── Vigencia label ── */
.vig-siempre   { color: var(--success); font-size: 11px; }
.vig-rango     { font-size: 11px; color: var(--text-muted); }
.vig-historico { font-size: 10px; color: var(--text-muted); }

/* ── Category swatch ── */
.cat-swatch { display: inline-block; width: 20px; height: 20px; border-radius: 50%; vertical-align: middle; }
.cat-badge  { padding: 3px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; }
.cat-indent { padding-left: 28px; }
.cat-arrow  { color: var(--text-muted); margin-right: 4px; }
.cat-parent-hint { font-size: 10px; color: var(--text-muted); margin-left: 6px; }

/* ── Delete confirm dialog ── */
.delete-title { color: var(--danger); }
.delete-desc  { color: var(--text-muted); font-size: 13px; margin: -6px 0 16px; }
.input-danger {
  background: var(--surface-2); border: 1px solid var(--danger-bd); border-radius: 8px;
  padding: 10px 14px; color: var(--text-strong); font-size: 13px; outline: none;
  width: 100%; font-family: inherit;
}

/* ── Tab switcher (nuevo/contacto) ── */
.tab-switcher {
  display: flex; gap: 0; border: 1px solid var(--border-1);
  border-radius: 10px; overflow: hidden; margin-bottom: 16px;
}
.tab-switcher-btn {
  flex: 1; padding: 10px; border: none;
  font-weight: 600; font-size: 13px; cursor: pointer;
}
.tab-switcher-btn.active   { background: var(--accent-2); color: #fff; font-weight: 700; }
.tab-switcher-btn.inactive { background: var(--surface-2); color: var(--text-muted); }

/* ── Log filter select ── */
.log-filter {
  background: var(--surface-2); border: 1px solid var(--border-2);
  color: var(--text-strong); padding: 6px 10px; border-radius: 7px; font-size: 12px;
}

/* ── Filter buttons ── */
.filter-btn { transition: .15s; }
.filter-btn.active { background: var(--accent-2); color: #fff; border-color: var(--accent-2); }

/* ── Contacto aviso ── */
.contacto-aviso {
  background: var(--warning-bg); border: 1px solid var(--warning-bd);
  border-radius: 8px; padding: 10px 14px;
  font-size: 12px; color: var(--warning); margin-top: 8px;
}

/* ── Details fiscal ── */
.details-fiscal {
  margin-top: 12px; border: 1px solid var(--border-1);
  border-radius: 8px; padding: 10px 14px;
}
.details-fiscal summary {
  cursor: pointer; font-size: 12px; color: var(--text-muted);
  font-weight: 600; letter-spacing: .5px;
}

/* ── Table icon image (small) ── */
.icon-preview-img { width: 32px; height: 32px; object-fit: contain; border-radius: 6px; }

/* ── Color picker ── */
.color-picker-wrap { display: flex; gap: 8px; align-items: center; }
.color-picker-input { width: 48px; height: 38px; border: none; background: none; cursor: pointer; padding: 0; }

/* ════════════════════════════════════════════════════════════
   GRADIENT BACKGROUNDS (dashboard hero icons)
   ════════════════════════════════════════════════════════════ */
.bg-gradient-blue   { background: linear-gradient(135deg, var(--accent-2), var(--accent)); }
.bg-gradient-green  { background: linear-gradient(135deg, var(--success), var(--success)); }
.bg-gradient-purple { background: linear-gradient(135deg, var(--purple), var(--purple)); }
.bg-gradient-amber  { background: linear-gradient(135deg, var(--warning), var(--warning)); }
.bg-gradient-teal   { background: linear-gradient(135deg, var(--info), var(--info)); }

/* ── Dashboard chip colors ── */
.dash-chip-success { color: var(--success); font-weight: 700; font-size: 13px; }
.dash-chip-info    { color: var(--accent); font-weight: 700; font-size: 13px; }
.dash-chip-warning { color: var(--warning); font-weight: 700; font-size: 13px; }

/* ── Dashboard alert border variants ── */
.dash-alert-danger  { border-left: 3px solid var(--danger); }
.dash-alert-warning { border-left: 3px solid var(--warning); }
.dash-alert-info    { border-left: 3px solid var(--accent); }
.dash-alert-success { border-left: 3px solid var(--success); }

/* ════════════════════════════════════════════════════════════
   PORTAL (cliente.html)
   ════════════════════════════════════════════════════════════ */
.balance-card { flex: 1; min-width: 180px; border-radius: 12px; padding: 16px 20px; }
.balance-card-blue { background: var(--surface-1); border: 1px solid var(--border-strong); }
.balance-card-red  { background: var(--danger-bg); border: 1px solid var(--danger-bd); }
.balance-card-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .6px; margin-bottom: 6px;
}
.balance-card-value { font-size: clamp(20px, 1.4vw + 16px, 26px); font-weight: 800; }
.balance-card-hint  { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

.portal-acuerdo-card { border: 1px solid var(--border-1); border-radius: 10px; padding: 14px 16px; margin-bottom: 12px; background: var(--surface-3); }
.portal-acuerdo-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; flex-wrap: wrap; gap: 8px; }
.portal-periodos-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.portal-periodos-grid .periodo-chip { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 14px; min-width: 90px; cursor: default; }
.portal-periodos-grid .periodo-label { font-size: 12px; font-weight: 600; }
.portal-periodos-grid .periodo-monto { font-size: 13px; font-weight: 700; }
.portal-periodos-grid .periodo-badge { font-size: 9px; text-transform: uppercase; letter-spacing: 0.5px; padding: 1px 6px; border-radius: 4px; }
.portal-periodos-grid .periodo-chip.vencido .periodo-badge { background: var(--danger-bg); color: var(--danger); }
.portal-periodos-grid .periodo-chip.pendiente { border-color: var(--border-strong); color: var(--text-default); }
.portal-periodos-grid .periodo-badge.parcial { background: var(--warning-bg); color: var(--warning); }
.portal-periodos-grid .periodo-chip.cubierto { border-color: var(--success-bd); color: var(--success); opacity: .75; }
.portal-periodos-grid .periodo-chip.cubierto .periodo-monto { text-decoration: line-through; opacity: .7; }
.portal-periodos-grid .periodo-chip.cubierto .periodo-badge { background: var(--success-bg); color: var(--success); }
.portal-periodos-grid .periodo-chip.parcial { border-color: var(--warning); color: var(--warning); }
.portal-periodos-grid .periodo-chip.condonado { border-color: var(--purple-bd); color: var(--purple); opacity: .75; }
.portal-periodos-grid .periodo-chip.condonado .periodo-monto { text-decoration: line-through; opacity: .7; }
.portal-periodos-grid .periodo-chip.condonado .periodo-badge { background: var(--purple-bg); color: var(--purple); }

.portal-footer {
  text-align: center; padding: 18px 24px; font-size: 11px;
  color: var(--text-muted); border-top: 1px solid var(--border-1);
  background: var(--bg-topbar); position: fixed; bottom: 0;
  left: 0; right: 0; z-index: 10;
}
.portal-footer-spacer { height: 44px; }
.portal-notes { font-size: 13px; color: var(--text-muted); line-height: 1.7; margin-top: 4px; }

/* ── XML/PDF download links ── */
.link-xml { color: var(--accent); }
.link-pdf { color: var(--warning); }

/* ════════════════════════════════════════════════════════════
   TOPBAR SEARCH (admin.html)
   ════════════════════════════════════════════════════════════ */
.topbar-search {
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  color: var(--text-strong); padding: 7px 14px; font-size: 13px;
  width: 220px; outline: none;
}
.topbar-search:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); }
.topbar-search-results {
  position: absolute; top: calc(100% + 6px); right: 0;
  width: 380px; background: var(--surface-1); border: 1px solid var(--border-1);
  border-radius: 10px; box-shadow: 0 8px 32px rgba(var(--shadow-rgb),.4);
  z-index: 2000; max-height: 400px; overflow-y: auto;
}
.gs-result-item {
  padding: 10px 16px; cursor: pointer; display: flex;
  gap: 10px; align-items: center; border-bottom: 1px solid var(--border-strong);
}
.gs-result-item:hover { background: var(--surface-3); }
.gs-result-icon  { font-size: 18px; }
.gs-result-label { font-size: 13px; font-weight: 600; color: var(--text-strong); }
.gs-result-sub   { font-size: 11px; color: var(--text-muted); }
.gs-searching    { padding: 12px 16px; color: var(--text-muted); font-size: 12px; }

/* ── Alert badge ── */
.alert-badge {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--danger-bg); border: 1px solid var(--danger-bd);
  border-radius: 20px; padding: 5px 12px;
  font-size: 12px; font-weight: 700; color: var(--danger);
}

/* ── Sidebar footer ── */
.sidebar-footer { margin-top: auto; padding: 8px 12px; border-top: 1px solid var(--border-1); }
.sidebar-copyright { padding: 6px 4px; font-size: 10px; color: var(--text-muted); text-align: center; }
/* §364: lista de archivos del servidor en Herramientas → Diagnóstico (antes en el pie del sidebar). */
.version-panel { padding: 6px 8px; background: var(--surface-2); border-radius: 6px; margin-top: 4px; border: 1px solid var(--border-1); }
.ver-row { display: flex; justify-content: space-between; padding: 4px 0; font-size: 13px; gap: 12px; }
.ver-file { color: var(--text-muted); font-weight: 600; }
.ver-ts { color: var(--accent); font-family: monospace; }
.sidebar-section-title {
  margin: 16px 12px 6px; font-size: 10px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 1px; font-weight: 700;
}

/* ── Config: switch toggle label ── */
.switch-label { display: flex; align-items: center; gap: 16px; cursor: pointer; user-select: none; }
.switch-wrap  { position: relative; width: 44px; height: 24px; flex-shrink: 0; }
.switch-hidden{ opacity: 0; width: 0; height: 0; position: absolute; }
.switch-title { font-size: 13px; font-weight: 700; color: var(--text-muted); }
.switch-desc  { font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* ── Config: module card ── */
/* ── Roles management ── */
.role-row {
  display: flex; align-items: center; gap: 8px;
}
.role-input {
  flex: 1; padding: 8px 12px; background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 8px; color: var(--text-strong); font-size: 13px; outline: none;
}
.role-input:focus { border-color: var(--accent); }

/* ── Policies editor (§11.9) ── */
.policy-entity {
  border: 1px solid var(--border-1); border-radius: 8px; padding: 10px 12px;
  background: var(--surface-2);
}
.policy-entity > summary {
  cursor: pointer; font-size: 13px; color: var(--text-default); list-style: none;
  display: flex; align-items: center; gap: 8px;
}
.policy-entity > summary::-webkit-details-marker { display: none; }
.policy-entity > summary::before {
  content: '▸'; color: var(--text-muted); transition: transform .15s;
}
.policy-entity[open] > summary::before { transform: rotate(90deg); }
textarea.policy-dsl {
  width: 100%; min-height: 34px; padding: 6px 10px;
  background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 6px;
  color: var(--text-strong); font-family: ui-monospace, monospace; font-size: 12px;
  outline: none; resize: vertical;
}
textarea.policy-dsl:focus { border-color: var(--accent); }
textarea.policy-dsl.has-error { border-color: var(--danger); }
.policy-err:empty { display: none; }
.policy-err { margin-top: 4px; }

/* Sección colapsable "Reglas de acceso por fila — avanzado": esconde el
   editor de policies DSL bajo lenguaje llano (decisión del dueño 2026-06-21). */
.policy-advanced {
  margin-top: 14px; border: 1px solid var(--border-1); border-radius: 8px;
  background: var(--surface-2);
}
.policy-advanced > summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text-default);
  list-style: none; display: flex; align-items: center; gap: 8px; padding: 12px 14px;
}
.policy-advanced > summary::-webkit-details-marker { display: none; }
.policy-advanced > summary::before { content: '▸'; color: var(--text-muted); transition: transform .15s; }
.policy-advanced[open] > summary::before { transform: rotate(90deg); }
.policy-advanced[open] > summary { border-bottom: 1px solid var(--border-1); }
.policy-advanced-body { padding: 14px; }
.policy-syntax > summary { cursor: pointer; list-style: none; }
.policy-syntax > summary::-webkit-details-marker { display: none; }
.policy-syntax code { font-size: 11px; }

.tag-input-wrap {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  padding: 6px 10px; background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 8px; min-height: 40px; cursor: text;
}
.tag-input-wrap:focus-within { border-color: var(--accent); }
.tag-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: 20px;
  padding: 2px 10px 2px 12px; font-size: 12px; color: var(--text-default);
}
.tag-chip button {
  background: none; border: none; color: var(--text-muted); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 0; margin-left: 2px;
}
.tag-chip button:hover { color: var(--danger); }
.tag-input-field {
  flex: 1; min-width: 160px; background: none; border: none;
  color: var(--text-strong); font-size: 13px; outline: none; padding: 2px 4px;
}


/* ── Login page ── */
.login-wrap {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 24px; width: 100%;
}
.login-logo {
  display: flex; align-items: center; gap: 10px;
  font-size: 24px; font-weight: 800; color: var(--text-strong); letter-spacing: -1px;
}
.login-logo .mi { font-size: 32px; color: var(--accent); }
.login-logo span { color: var(--accent); }
.login-box {
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 16px;
  padding: 40px; width: 380px; display: flex; flex-direction: column;
  gap: 16px; box-shadow: 0 4px 24px rgba(var(--shadow-rgb),.3);
}
.login-box h2 { font-size: 20px; font-weight: 800; color: var(--text-strong); text-align: center; }
.login-box p  { font-size: 13px; color: var(--text-muted); text-align: center; margin-top: -6px; }
.login-err {
  color: var(--danger); font-size: 12px; text-align: center;
  background: var(--danger-bg); border: 1px solid var(--danger-bd); border-radius: 8px; padding: 10px;
}
.login-remember { display: flex; align-items: center; gap: 10px; margin-top: -4px; }
.login-remember input { width: 16px; height: 16px; cursor: pointer; accent-color: var(--accent); flex-shrink: 0; }
.login-remember label { font-size: 13px; color: var(--text-muted); cursor: pointer; font-weight: 500; margin: 0; }
.login-btn { width: 100%; justify-content: center; padding: 12px; }
.login-footer { font-size: 12px; color: var(--text-muted); text-align: center; }

/* ── CSF Mode Selector ── */
.csf-mode-selector {
  display: flex; gap: 0; border: 2px solid var(--border-2);
  border-radius: 10px; margin-bottom: 16px;
}
.csf-mode-selector .csf-mode-btn:first-child { border-radius: 8px 0 0 8px; }
.csf-mode-selector .csf-mode-btn:last-child  { border-radius: 0 8px 8px 0; }
.csf-mode-btn {
  flex: 1 1 0%; display: flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 12px 8px; border: none; outline: none;
  appearance: none; -webkit-appearance: none;
  font-weight: 600; font-size: 13px; cursor: pointer;
  background: var(--surface-2); color: var(--text-subtle); transition: .15s;
  text-align: center; line-height: 1.3; font-family: inherit;
}
.csf-mode-btn.active { background: var(--accent-2); color: #fff; font-weight: 700; }
.csf-mode-btn:hover:not(.active) { background: var(--surface-raised); color: var(--text-strong); }

.csf-upload-area {
  display: flex; align-items: center; gap: 10px;
  padding: 14px; background: var(--surface-1); border: 2px dashed var(--border-strong);
  border-radius: 10px; cursor: pointer; transition: .15s;
  margin-bottom: 14px;
}
.csf-upload-area:hover { border-color: var(--accent); background: var(--surface-3); }
.csf-upload-icon { font-size: 24px; }
.csf-upload-text { font-size: 13px; color: var(--accent); font-weight: 600; }
.csf-upload-hint { font-size: 11px; color: var(--text-muted); }
.csf-parsed-ok {
  padding: 10px 14px; background: var(--success-bg); border: 1px solid var(--success-bd);
  border-radius: 8px; font-size: 12px; color: var(--success); margin-bottom: 14px;
}

/* ════════════════════════════════════════════════════════════
   EMPRESA SELECTOR (topbar)
   ════════════════════════════════════════════════════════════ */
.empresa-selector-wrap { display: flex; align-items: center; }
.topbar-empresa-select {
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 8px;
  color: var(--text-strong); padding: 6px 12px; font-size: 13px;
  outline: none; cursor: pointer; min-width: 160px;
}
.topbar-empresa-select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(var(--accent-rgb),.15); }
/* Vista de grupo (§186 → §192): barrita al INICIO del contenido, sólo en las
   secciones de Tesorería / Finanzas. Antes era un chip fijo junto al selector del
   topbar — se veía mal, y un `display` en su clase le ganaba al atributo `hidden`
   (se veía siempre). El topbar ya no se toca. */
.vista-grupo-bar {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 12px; padding: 7px 12px; border-radius: 8px; font-size: 12.5px;
  background: var(--info-bg); border: 1px solid var(--info-bd); color: var(--text-default);
}
.vista-grupo-bar .mi { color: var(--info); font-size: 16px; flex-shrink: 0; }
.vista-grupo-bar b { color: var(--info); }

/* ── Filtro de empresa VISIBLE (§empresa-visible) ──────────────────────────
   El selector filtra TODO el portal pero se leía como un desplegable decorativo:
   en modo Operación no hay opción "Todas" (§F8), así que no existe un estado sin
   filtro contra el cual notar que faltan datos. Estas 3 piezas lo hacen evidente:
   (1) el prefijo "Empresa:" delante del selector — dice que es un filtro, no un
       adorno; (2) la nota "N de M ocultos" junto al título de cada tabla; (3) el
       estado vacío explícito con el salto a la empresa donde sí están.
   Todo por tokens (nunca hex) para que funcione en tema claro y oscuro. */
.empresa-selector-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-dimmed); margin-right: 6px; white-space: nowrap;
}

@media (max-width: 720px) {
  .empresa-selector-label { display: none; }  /* el espacio del topbar es escaso en móvil */
}

/* ════════════════════════════════════════════════════════════
   CHECKBOX GROUP (admin modal — empresa assignment)
   ════════════════════════════════════════════════════════════ */
.checkbox-group {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 180px; overflow-y: auto;
  padding: 8px 10px; background: var(--surface-2);
  border: 1px solid var(--border-2); border-radius: 8px;
}
.checkbox-label {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-default); cursor: pointer;
  padding: 4px 6px; border-radius: 6px;
}
.checkbox-label:hover { background: var(--surface-3); }
.checkbox-label input[type="checkbox"] {
  accent-color: var(--accent); width: 16px; height: 16px; cursor: pointer;
}

/* ════════════════════════════════════════════════════════════
   PORTAL — Topbar Logo
   ════════════════════════════════════════════════════════════ */
/* En el flujo y centrado en el espacio libre (antes absolute al 50%: no reservaba lugar y entre 769 y ~1100 px quedaba encima de Soporte/Facturación). */
.topbar-logo { display: flex; align-items: center; margin: 0 auto; padding: 0 12px; min-width: 0; }
.topbar-logo:empty { display: none; }
.topbar-logo-img { max-height: 36px; max-width: 160px; object-fit: contain; border-radius: 6px; }
.topbar-logo-fallback {
  width: 36px; height: 36px; border-radius: 6px;
  background: linear-gradient(135deg, var(--border-1), var(--surface-raised));
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: var(--accent); letter-spacing: .5px;
}

/* ════════════════════════════════════════════════════════════
   PORTAL — Welcome & Action Cards (Inicio)
   ════════════════════════════════════════════════════════════ */
.portal-welcome { margin-bottom: 24px; }
.portal-welcome h2 { font-size: clamp(18px, 1.4vw + 14px, 22px); font-weight: 800; color: var(--text-strong); margin-bottom: 4px; }
.portal-welcome-summary { font-size: 13px; color: var(--text-muted); }
.pi-highlight { color: var(--accent); font-weight: 600; }
.pi-warning { color: var(--warning); font-weight: 600; }
.pi-muted { color: var(--text-muted); }

.portal-action-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px; margin-bottom: 24px;
}
.pac {
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 14px;
  padding: 20px 16px; text-align: center; cursor: pointer;
  transition: .2s; display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.pac:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: 0 8px 24px rgba(var(--shadow-rgb),.3); }
.pac-icon {
  width: 52px; height: 52px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 28px;
}
.pac-icon .mi { font-size: 28px; }
.pac-blue   { background: var(--surface-raised); color: var(--accent); border: 1px solid var(--border-strong); }
.pac-green  { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.pac-teal   { background: var(--info-bg); color: var(--success); border: 1px solid var(--info-bd); }
.pac-orange { background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-bd); }
.pac-purple { background: var(--purple-bg); color: var(--purple); border: 1px solid var(--purple-bd); }
.pac-title { font-size: 13px; font-weight: 700; color: var(--text-strong); }
.pac-value { font-size: 15px; font-weight: 800; color: var(--text-default); }
.pac-link { font-size: 11px; color: var(--text-muted); font-weight: 600; }

/* Bloque "portal bottom row + .ps-* + .pa-*" eliminado: zombie code per
   CLAUDE.md §49 (reemplazado por .dash-metrics-card / .dash-alerts-card
   en la migración del portal cliente al lenguaje del dashboard v2). */

/* ════════════════════════════════════════════════════════════
   PORTAL — Notification Center
   ════════════════════════════════════════════════════════════ */
.notif-wrap { position: relative; }
.notif-bell, .topbar-iconbtn {
  background: none; border: 1px solid var(--border-strong); border-radius: 8px;
  color: var(--accent); font-size: 13px; font-family: inherit;
  padding: 7px 10px; cursor: pointer; position: relative;
  display: flex; align-items: center; transition: .2s;
}
.notif-bell:hover, .topbar-iconbtn:hover { background: var(--surface-raised); border-color: var(--border-strong); color: var(--accent); }
.notif-bell:focus-visible, .topbar-iconbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.notif-bell .mi, .topbar-iconbtn .mi { font-size: 20px; }
.notif-badge {
  position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px;
  background: var(--notif-bg); color: #fff; font-size: 10px; font-weight: 700;
  border-radius: 9px; display: flex; align-items: center; justify-content: center;
  padding: 0 4px; line-height: 1; border: 2px solid var(--bg-page);
}
.notif-dropdown {
  display: none; position: absolute; top: calc(100% + 8px); right: 0;
  width: 360px; max-height: 440px; overflow-y: auto;
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(var(--shadow-rgb),.5); z-index: 120;
}
.notif-dropdown.open { display: block; }
.notif-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px 10px; border-bottom: 1px solid var(--border-1);
  font-size: 14px; color: var(--text-strong);
}
.notif-list { padding: 6px; }
/* §pto7 — Secciones del centro de notificaciones (Sistema / Recordatorios / Alertas). */
.notif-group + .notif-group { margin-top: 6px; border-top: 1px solid var(--border-1); padding-top: 4px; }
.notif-group-label {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px 4px; font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--text-dimmed);
}
.notif-group-label .mi { font-size: 14px; }
.notif-group-label .notif-group-action { margin-left: auto; }
.notif-cfg-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border: none; border-radius: 6px;
  background: transparent; color: var(--text-dimmed); cursor: pointer;
}
.notif-cfg-btn:hover { background: var(--border-3); color: var(--text-strong); }
.notif-empty-sec { padding: 6px 10px 10px; font-size: 12px; color: var(--text-dimmed); }
/* §pto7 Fase A — chip de severidad de alertas (deriva de cls danger/warning). */
.alert-sev {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  vertical-align: middle; line-height: 1.4;
}
.alert-sev-critica { background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger-bd); }
.alert-sev-media   { background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-bd); }
/* §pto7 fase 2 — Modal de configuración de alertas. */
.alert-cfg-list { display: flex; flex-direction: column; gap: 4px; }
.alert-cfg-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--border-1); border-radius: 8px; cursor: pointer;
}
.alert-cfg-row:hover { background: var(--surface-2); }
.alert-cfg-row input { margin-top: 3px; flex: 0 0 auto; }
.alert-cfg-icon { color: var(--text-dimmed); font-size: 20px; flex: 0 0 auto; }
.alert-cfg-label { display: block; font-size: 14px; font-weight: 600; color: var(--text-strong); }
.alert-cfg-desc { display: block; font-size: 12px; color: var(--text-dimmed); margin-top: 2px; }
/* §pto7 fase 2 — Recordatorios personales dentro del centro de notificaciones. */
.rec-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; padding: 2px 8px 8px; }
.rec-add-btn { margin: 0; flex: 1 1 auto; justify-content: center; }
.rec-email-toggle { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-dimmed); cursor: pointer; white-space: nowrap; }
.rec-email-toggle input { margin: 0; }
.rec-email-toggle .mi { font-size: 14px; }
.rec-item {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 10px; border-radius: 8px;
  cursor: pointer; /* la fila abre el recordatorio para editar — ver recordatorios.js _recEditar */
}
.rec-item:hover { background: var(--surface-raised); }
.rec-item + .rec-item { border-top: 1px solid var(--border-1); border-radius: 0; }
.rec-item.rec-due { background: var(--warning-bg); }
.rec-title { font-size: 13px; font-weight: 600; color: var(--text-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rec-when { font-size: 11px; color: var(--text-dimmed); display: flex; align-items: center; gap: 4px; }
.rec-item.rec-due .rec-when { color: var(--warning); font-weight: 600; }
.rec-item .btn-icon {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: none; border-radius: 6px;
  background: transparent; color: var(--text-dimmed); cursor: pointer;
}
.rec-item .btn-icon:hover { background: var(--border-3); color: var(--text-strong); }
.rec-item .rec-del:hover { background: var(--danger-bg); color: var(--danger); }
.notif-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; border-radius: 8px; cursor: pointer;
  transition: background .15s; font-size: 12px; margin-bottom: 2px;
}
.notif-item:hover { background: var(--surface-raised); }
.notif-item .mi { font-size: 18px; margin-top: 1px; }
.notif-title { font-weight: 700; color: var(--text-strong); font-size: 12px; }
.notif-desc { color: var(--text-muted); font-size: 11px; margin-top: 2px; }
.notif-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  flex-shrink: 0; margin-top: 5px;
}
.notif-read { opacity: .5; }
.notif-read:hover { opacity: .75; }
.notif-empty {
  text-align: center; padding: 28px 16px; color: var(--text-muted);
  font-size: 13px; line-height: 1.8;
}
.notif-danger .mi { color: var(--danger); }
.notif-warning .mi { color: var(--warning); }
.notif-info .mi { color: var(--accent); }
.notif-success .mi { color: var(--success); }

/* ════════════════════════════════════════════════════════════
   USER MENU (avatar dropdown) — patrón Linear/Notion/Vercel 2026
   Absorbe "Hola X" + densidad + soporte + refresh + cerrar sesión
   para liberar el topbar. Coexiste con notif-bell (un solo dropdown
   abierto a la vez, manejado por toggleUserMenu/toggleNotifCenter).
   ════════════════════════════════════════════════════════════ */
.user-menu-wrap { position: relative; }
.user-menu-trigger {
  background: none; border: 1px solid var(--border-strong); border-radius: 8px;
  color: var(--text-default); font-family: inherit; font-size: 13px;
  padding: 4px 8px 4px 4px; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  transition: .15s;
}
.user-menu-trigger:hover { background: var(--surface-raised); border-color: var(--border-strong); }
.user-menu-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.user-avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent));
  color: #fff; font-weight: 700; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  text-transform: uppercase;
}
.user-avatar.lg { width: 40px; height: 40px; font-size: 16px; }
.user-name-inline { color: var(--text-default); font-weight: 500; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu-chev { color: var(--text-muted); font-size: 16px; transition: transform .15s; }
.user-menu-trigger[aria-expanded="true"] .user-menu-chev { transform: rotate(180deg); }

.user-menu-dropdown {
  display: none; position: absolute; top: calc(100% + 8px); right: 0;
  width: 260px;
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(var(--shadow-rgb),.5); z-index: 120;
  padding: 6px;
}
.user-menu-dropdown.open { display: block; }
.user-menu-header {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px 12px; border-bottom: 1px solid var(--border-1);
  margin-bottom: 6px;
}
.user-menu-id { min-width: 0; flex: 1; }
.user-menu-name { color: var(--text-strong); font-weight: 600; font-size: 14px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu-role { color: var(--text-muted); font-size: 11px; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu-section { padding: 4px 0; }
.user-menu-label {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted); padding: 4px 12px 4px;
}
.user-menu-item {
  width: 100%; background: none; border: none; color: var(--text-default);
  font-family: inherit; font-size: 13px; text-align: left; cursor: pointer;
  padding: 8px 12px; border-radius: 6px;
  display: flex; align-items: center; gap: 10px;
  transition: background .12s;
}
.user-menu-item:hover { background: rgba(var(--accent-rgb),.08); color: var(--text-strong); }
.user-menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.user-menu-item .mi { color: var(--text-muted); font-size: 18px; flex-shrink: 0; }
.user-menu-item:hover .mi { color: var(--accent); }
.user-menu-item.danger:hover { background: rgba(255,71,87,.12); color: var(--danger); }
.user-menu-item.danger:hover .mi { color: var(--danger); }
.user-menu-divider { height: 1px; background: var(--border-1); margin: 6px 0; }

/* ════════════════════════════════════════════════════════════
   PORTAL — Soporte
   ════════════════════════════════════════════════════════════ */
/* Soporte step wizard */
.soporte-steps {
  display: flex; align-items: center; gap: 0; margin-bottom: 24px;
  max-width: 700px;
}
.soporte-step {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; color: var(--text-muted);
  padding: 8px 0;
}
.soporte-step.active { color: var(--accent); }
.soporte-step.done { color: var(--success); }
.soporte-step-num {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface-1); border: 2px solid var(--border-1);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; flex-shrink: 0;
}
.soporte-step.active .soporte-step-num { background: var(--surface-3); border-color: var(--accent); color: var(--accent); }
.soporte-step.done .soporte-step-num { background: var(--success-bg); border-color: var(--success); color: var(--success); }
.soporte-step-divider {
  flex: 1; height: 2px; background: var(--border-1); margin: 0 16px;
}
.soporte-step-divider.done { background: var(--success); }

.support-form-card {
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 14px;
  padding: 24px; max-width: 700px;
}
.support-form-card h3 { font-size: 16px; font-weight: 700; color: var(--text-strong); margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
.support-form-actions { display: flex; justify-content: space-between; margin-top: 16px; }

/* Soporte method cards (paso 2) */
.soporte-methods {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
.soporte-method {
  background: var(--bg-topbar); border: 2px solid var(--border-1); border-radius: 14px;
  padding: 28px 20px; text-align: center; cursor: pointer;
  transition: .2s;
}
.soporte-method:hover { border-color: var(--accent); background: var(--surface-3); transform: translateY(-2px); }
.soporte-method.disabled { opacity: .45; cursor: not-allowed; }
.soporte-method.disabled:hover { border-color: var(--border-1); background: var(--bg-topbar); transform: none; }
.soporte-method-icon { margin-bottom: 12px; color: var(--accent); }
.soporte-method h4 { font-size: 15px; font-weight: 700; color: var(--text-strong); margin-bottom: 6px; }
.soporte-method .btn-sm { font-size: 12px; padding: 6px 14px; }

.soporte-checklist { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; }
.soporte-check {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 12px; background: var(--bg-topbar); border: 1px solid var(--border-1);
  border-radius: 6px; cursor: pointer; transition: border-color .15s, background .15s;
}
.soporte-check:hover { border-color: var(--border-strong); background: var(--surface-3); }
.soporte-check input[type=checkbox] { margin-top: 2px; cursor: pointer; flex-shrink: 0; }
.soporte-check span { color: var(--text-default); font-size: 14px; line-height: 1.4; }

.tkt-check-list { list-style: none; padding: 0; margin: 4px 0 0; display: flex; flex-direction: column; gap: 4px; }
.tkt-check-list li { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.tkt-check-list li .mi { font-size: 18px; }

/* ════════════════════════════════════════════════════════════
   ROLE BADGE (Ejecutivo)
   ════════════════════════════════════════════════════════════ */
.role-Ejecutivo { background: var(--purple-bg); color: var(--purple); border-color: var(--purple-bd); }

/* ════════════════════════════════════════════════════════════
   SPINNER (for save buttons)
   ════════════════════════════════════════════════════════════ */
.spinner-sm {
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid rgba(255,255,255,.3); border-top-color: #fff;
  border-radius: 50%; animation: spin .6s linear infinite;
  vertical-align: middle; margin-right: 4px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ════════════════════════════════════════════════════════════
   BULK SELECT (checkbox column in tables)
   ════════════════════════════════════════════════════════════ */
.bulk-bar {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface-raised); border: 1px solid var(--border-1); border-radius: 8px;
  padding: 8px 14px; margin-bottom: 10px;
}
.bulk-bar .bulk-count { font-weight: 600; color: var(--accent); }
.chk-col { width: 32px; text-align: center; }
.chk-col input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; accent-color: var(--accent); }

/* ── Edición masiva (cuadrícula full-screen, bulk_edit.js) ── */
body.bulkedit-open { overflow: hidden; }
.bulkedit-overlay { position: fixed; inset: 0; z-index: 1500; background: var(--bg-page); display: flex; flex-direction: column; }
.bulkedit-shell { display: flex; flex-direction: column; height: 100%; width: 100%; }
.bulkedit-head { display: flex; align-items: center; gap: 14px; padding: 12px 20px; border-bottom: 1px solid var(--border-1); background: var(--surface-1); }
.bulkedit-head .btn .mi { font-size: 16px; }
.bulkedit-title { font-size: 16px; font-weight: 800; color: var(--text-strong); }
.bulkedit-dirty-badge { font-size: 11px; font-weight: 600; color: var(--warning); background: var(--warning-bg); border: 1px solid var(--warning-bd); border-radius: 999px; padding: 2px 9px; white-space: nowrap; }
.bulkedit-progress { color: var(--text-default); font-size: 13px; font-variant-numeric: tabular-nums; }
.bulkedit-dirty-count { color: var(--warning); font-size: 13px; margin-left: auto; }
.bulkedit-grid-wrap { flex: 1; overflow: auto; }
.bulkedit-grid { border-collapse: separate; border-spacing: 0; width: max-content; }
.bulkedit-grid th, .bulkedit-grid td { border-bottom: 1px solid var(--border-3); border-right: 1px solid var(--border-3); text-align: left; vertical-align: middle; }
.bulkedit-grid th { padding: 6px 6px 6px 12px; }
.bulkedit-grid thead th { position: sticky; top: 0; z-index: 2; background: var(--surface-1); color: var(--text-default); font-size: 12px; font-weight: 700; }
/* Encabezado plano (§178): etiqueta + ⓘ opcional a la izquierda, ⋮ a la derecha.
   Sin fila de controles — "Aplicar a todas" vive en el menú ⋮ y en el toast. */
.bulkedit-th { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 150px; }
.bulkedit-th-label { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.bulkedit-th-label .req { color: var(--danger); }
.bulkedit-th-info { font-size: 15px; color: var(--text-dimmed); cursor: help; }
.bulkedit-th-menu-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--text-muted); cursor: pointer; padding: 0; flex: none; }
.bulkedit-th-menu-btn .mi { font-size: 18px; }
.bulkedit-th-menu-btn:hover, .bulkedit-th-menu-btn.open { background: var(--surface-raised); color: var(--text-strong); border-color: var(--border-2); }
.bulkedit-th-menu-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (max-width: 768px) { .bulkedit-th-menu-btn { width: 40px; height: 40px; } } /* blanco táctil ≥40px (checklist P-legibilidad) */
.bulkedit-name-h, .bulkedit-name { position: sticky; left: 0; background: var(--surface-3); color: var(--text-default); font-weight: 600; max-width: 280px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bulkedit-name { z-index: 1; padding: 0 12px; }
.bulkedit-name-inner { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulkedit-grid thead .bulkedit-name-h { z-index: 3; }
/* Celdas planas, estilo hoja de cálculo (§178): el <td> no tiene padding; la
   celda `.bulkedit-cell` ocupa todo, 40px de alto, borde transparente que solo
   aparece al enfocar (accent) o al editar (accent + fondo tenue). */
.bulkedit-td { padding: 0; height: 40px; }
.bulkedit-cell { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 6px; height: 40px; min-width: 160px; padding: 0 8px 0 12px; border: 1px solid transparent; color: var(--text-strong); font-size: 14px; background: transparent; }
.bulkedit-cell:hover { background: var(--surface-2); }
/* Enfocada = anillo NEUTRO; editada = anillo accent + tinte. Distintos a propósito
   (el público 40+ no distingue un 6% de tinte): "en qué celda estoy" ≠ "qué se va
   a guardar". La regla de editada va después → gana aunque la celda tenga foco. */
.bulkedit-cell:focus-within { border-color: var(--border-strong); box-shadow: inset 0 0 0 1px var(--border-strong); background: var(--surface-1); }
.bulkedit-cell.bulkedit-cell-edited { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: rgba(var(--accent-rgb), .06); }
.bulkedit-cell-display { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; pointer-events: none; }
.bulkedit-cell-display .badge { font-size: 11.5px; }
.bulkedit-cell-chev { font-size: 16px; color: var(--text-dimmed); flex: none; pointer-events: none; }
.bulkedit-cell-empty { color: var(--text-dimmed); }
.bulkedit-cell-offcat { color: var(--text-muted); font-style: italic; }
/* El <select> nativo va ENCIMA, transparente: recibe click/teclado y abre su
   desplegable nativo; lo que se ve es `.bulkedit-cell-display` de abajo. */
.bulkedit-cell-select select.bulkedit-input { position: absolute; inset: 0; width: 100%; height: 100%; min-width: 0; opacity: 0; cursor: pointer; border: 0; padding: 0; margin: 0; background: transparent; color: var(--text-strong); font-size: 14px; }
.bulkedit-cell-select select.bulkedit-input:focus { outline: none; }
/* Texto/número: input plano, sin caja propia (la caja es la celda). */
.bulkedit-cell-txt input.bulkedit-input { width: 100%; height: 100%; min-width: 0; background: transparent; border: 0; padding: 0; color: var(--text-strong); font-size: 14px; }
.bulkedit-cell-txt input.bulkedit-input:focus { outline: none; }
.bulkedit-td-number .bulkedit-cell-txt input.bulkedit-input { text-align: right; font-variant-numeric: tabular-nums; }
/* Checkbox "Disponible para todo el grupo" (§173) — centrado en su celda. */
.bulkedit-cell-chk { justify-content: center; padding: 0; }
input[type="checkbox"].bulkedit-input { width: 18px; min-width: 0; height: 18px; padding: 0; margin: 0; display: block; cursor: pointer; accent-color: var(--accent); }
input[type="checkbox"].bulkedit-input:disabled { cursor: not-allowed; opacity: .4; }
.bulkedit-row-failed td { background: rgba(220,70,70,.12); }
.bulkedit-row-ok td { background: rgba(60,200,120,.06); }
/* Popovers: selector de columnas ("Columnas") y menú ⋮ de columna (§178). */
.bulkedit-cols-pop, .bulkedit-colmenu { position: fixed; background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 8px; box-shadow: 0 12px 32px rgba(var(--shadow-rgb),.5); z-index: 1600; padding: 6px; min-width: 210px; }
.bulkedit-cols-hd, .bulkedit-colmenu-hd { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); padding: 4px 10px 6px; }
.bulkedit-cols-search { display: block; width: calc(100% - 8px); margin: 0 4px 6px; padding: 7px 9px; font-size: 13px; background: var(--surface-2); border: 1px solid var(--border-1); border-radius: 6px; color: var(--text-strong); }
.bulkedit-cols-search:focus { outline: none; border-color: var(--accent); }
.bulkedit-cols-row { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 6px; cursor: pointer; font-size: 14px; color: var(--text-default); }
.bulkedit-cols-row:hover { background: var(--surface-raised); }
/* `row.hidden` (buscador del picker): la regla de autor `display:flex` de arriba
   le gana al `[hidden]{display:none}` de la hoja UA — sin esto el filtro no
   ocultaba ninguna fila. */
.bulkedit-cols-row[hidden] { display: none; }
.bulkedit-cols-row input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.bulkedit-colmenu { width: 260px; }
.bulkedit-colmenu-pick { margin: 0 4px; }
.bulkedit-fill-input { display: block; width: 100%; box-sizing: border-box; background: var(--surface-2); border: 1px solid var(--border-1); color: var(--text-strong); border-radius: 6px; padding: 8px 9px; font-size: 14px; }
.bulkedit-fill-input:focus { outline: none; border-color: var(--accent); }
.bulkedit-colmenu-apply { display: block; width: calc(100% - 8px); margin: 8px 4px 4px; }
.bulkedit-colmenu-sep { border: 0; border-top: 1px solid var(--border-1); margin: 4px 2px; }
.bulkedit-colmenu-row { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; border: 0; border-radius: 6px; background: transparent; color: var(--text-default); font-size: 14px; cursor: pointer; text-align: left; }
.bulkedit-colmenu-row:hover { background: var(--surface-raised); }
.bulkedit-colmenu-row .mi { font-size: 17px; color: var(--text-muted); }

/* Campo de empresa fijo (heredada de la empresa activa, modal de cliente) */
.emp-fixed-box { padding: 9px 11px; background: var(--surface-raised); border: 1px solid var(--border-1); border-radius: 8px; color: var(--text-strong); font-weight: 600; }
.emp-fixed-box .text-dimmed { font-weight: 400; }

/* Selector de contribuyente fiscal (rediseño UX fiscal Fase 2). El recorrido
   de 5 pasos que vivía aquí (.fiscal-recorrido/.fiscal-step*) se retiró en
   1.10.0 (sidebar aplanado, estilo SatView) — clases eliminadas (code-review:
   quedaban muertas, sin ningún productor en fiscal.js). */
/* Sub-pestañas (2º nivel), hoy usadas por Conciliación de Cuentas: subrayado
   ligero, para que no compitan con la nav primaria del sidebar. */
.fiscal-subtabs { display: flex; gap: 2px; flex-wrap: wrap; border-bottom: 1px solid var(--border-1); margin-bottom: 14px; }
.fiscal-subtab { background: transparent; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: 8px 14px; cursor: pointer; color: var(--text-muted); font-size: 13px; font-weight: 600; transition: color .15s, border-color .15s; }
.fiscal-subtab:hover { color: var(--text-default); }
.fiscal-subtab.active { color: var(--accent); border-bottom-color: var(--accent); }
/* Renovación (feedback del dueño: "se ve mal distribuido") — la causa real
   era el link "Traer datos" duplicando el botón que Tablero/Libro fiscal ya
   muestran (ver _fiscalCtbBar, fiscal.js), no el CSS en sí — pero de paso se
   agrupa identidad+switch en `.fiscal-ctb-main` (mismo peso, un solo bloque)
   y el link (cuando SÍ aplica) se empuja al extremo con margin-left:auto en
   vez de competir por espacio con `justify-content:space-between` a 3. */
.fiscal-ctb-bar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 12px; }
.fiscal-ctb-main { display: flex; align-items: center; gap: 16px; flex: 1; min-width: 0; flex-wrap: wrap; }
.fiscal-ctb-who { display: flex; align-items: center; gap: 12px; }
.fiscal-ctb-who > .mi { font-size: 30px; color: var(--accent); }
.fiscal-ctb-tipo { background: var(--surface-raised); color: var(--text-default); font-weight: 600; vertical-align: middle; margin-left: 6px; }
.fiscal-ctb-rfc { margin-left: 6px; }
.fiscal-ctb-div { width: 1px; align-self: stretch; background: var(--border-1); flex: 0 0 auto; }
.fiscal-ctb-traer { margin-left: auto; }
.fiscal-ctb-switch { display: flex; flex-direction: column; gap: 3px; }
.fiscal-ctb-switch select:not(.ss-native) { width: auto; min-width: 200px; }
/* A 400 px había scroll horizontal en las 6 secciones de Contabilidad: la regla le ponía width:100% también
   al <select> ORIGINAL que el buscador esconde (.ss-native: 1px, absoluto) → medía 395 px fuera de la tarjeta.
   Mismo patrón que .periodo-wrap: :not(.ss-native). Más min-width:0 para que el flex no se estire. */
@media (max-width: 640px) { .fiscal-ctb-div { display: none; } .fiscal-ctb-main, .fiscal-ctb-who { min-width: 0; } .fiscal-ctb-switch { flex: 1 1 100%; min-width: 0; } .fiscal-ctb-switch select:not(.ss-native), .fiscal-ctb-switch .ss-trigger { min-width: 0; width: 100%; max-width: 100%; } .fiscal-ctb-traer { margin-left: 0; } }
.fiscal-portal-cliente { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; border-left: 3px solid var(--border-strong); }
.fiscal-next { display: flex; align-items: center; justify-content: space-between; gap: 14px; cursor: pointer; margin-top: 14px; transition: border-color .15s, transform .1s; }
.fiscal-next:hover { border-color: var(--accent); transform: translateY(-1px); }
.fiscal-next > .mi { font-size: 26px; color: var(--accent); }
.fiscal-kpi-group { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--text-muted); margin: 14px 0 7px; }
.fiscal-kpi-group:first-child { margin-top: 2px; }
.fiscal-kpi-group > .mi-sm { color: var(--accent); }
.fiscal-kpi-heroes { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.fiscal-kpi-hero { display: flex; align-items: center; gap: 14px; }
.fiscal-kpi-icon { width: 46px; height: 46px; border-radius: 12px; background: var(--surface-raised); display: flex; align-items: center; justify-content: center; flex: 0 0 46px; }
.fiscal-kpi-icon .mi { font-size: 26px; }
.fiscal-kpi-val { font-size: 1.7rem; font-weight: 800; line-height: 1.12; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.viewmode-directivo .fiscal-kpi-val { font-size: 2.1rem; }

/* CFDI Upload Zone */
.cfdi-upload-zone { border: 2px dashed rgba(var(--accent-rgb),.35); border-radius: 10px; padding: 20px; margin-bottom: 16px; text-align: center; transition: border-color .2s; }
.cfdi-upload-zone:hover { border-color: rgba(var(--accent-rgb),.6); }
.cfdi-upload-inner p { margin: 4px 0; }
.cfdi-icon { font-size: 32px; display: block; margin-bottom: 4px; }

/* Activity Timeline */
.timeline { padding: 12px 0 4px 18px; border-left: 2px solid rgba(var(--accent-rgb),.2); margin-left: 8px; }
.timeline-item { position: relative; padding: 0 0 18px 18px; }
.timeline-item:last-child { padding-bottom: 4px; }
.timeline-dot { position: absolute; left: -24px; top: 4px; width: 10px; height: 10px; border-radius: 50%; background: var(--accent); border: 2px solid var(--bg-page); }
.timeline-content { min-height: 20px; }
.timeline-date { margin-bottom: 2px; }
.timeline-text { color: var(--text-default); font-size: .87rem; line-height: 1.4; }

/* ── Services Card Grid ── */
.cards-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; padding: 16px; }
.service-card {
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px;
  padding: 20px; position: relative; overflow: hidden;
  transition: border-color .2s, box-shadow .2s; cursor: default;
}
.service-card:hover { border-color: var(--border-strong); box-shadow: 0 4px 16px rgba(var(--shadow-rgb),.3); }
.service-card::before {
  content:''; position:absolute; top:0; left:0; right:0; height:3px;
  background:linear-gradient(90deg,var(--accent-2),var(--accent)); opacity:0; transition:opacity .2s;
}
.service-card:hover::before { opacity:1; }
.service-card .sc-header { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.service-card .sc-icon { font-size: 28px; flex-shrink: 0; }
.service-card .sc-icon img { width: 32px; height: 32px; border-radius: 6px; object-fit: cover; }
.service-card .sc-title { font-size: 15px; font-weight: 700; color: var(--text-strong); line-height: 1.25; }
.service-card .sc-cat { margin-bottom: 8px; }
.service-card .sc-desc { font-size: 12px; color: var(--text-muted); line-height: 1.4; margin-bottom: 12px; min-height: 34px; }
.service-card .sc-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.service-card .sc-price { font-size: 14px; font-weight: 700; color: var(--accent); }
.service-card .sc-actions { display: flex; gap: 4px; }
.btn-view-toggle { background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 8px; padding: 5px 10px; cursor: pointer; font-size: 16px; color: var(--text-default); transition: background .2s, border-color .2s; }
.btn-view-toggle:hover { background: var(--surface-raised); border-color: var(--border-strong); }
.btn-view-toggle.active { background: var(--accent); border-color: var(--accent); }

/* ════════════════════════════════════════════════════════════
   TICKET THREAD — Conversation in tickets
   ════════════════════════════════════════════════════════════ */
.ticket-thread {
  max-height: 300px; overflow-y: auto;
  border: 1px solid var(--border-3); border-radius: 8px;
  padding: 12px; margin-bottom: 8px;
}
.thread-msg {
  padding: 8px 12px; border-radius: 6px;
  background: rgba(30,58,95,0.3); margin-bottom: 8px;
}
.thread-msg:last-child { margin-bottom: 0; }
.thread-msg-header {
  display: flex; justify-content: space-between; margin-bottom: 4px;
}
.thread-msg-body { font-size: 0.875rem; line-height: 1.5; }

/* ════════════════════════════════════════════════════════════
   AGING REPORT — Cobranza estado de cuenta
   ════════════════════════════════════════════════════════════ */
.aging-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px; margin-bottom: 16px;
}
.aging-card {
  background: rgba(30,58,95,0.4); border-radius: 8px;
  padding: 12px; text-align: center;
}
.aging-card .lbl { font-size: 0.75rem; color: var(--text-subtle); margin-bottom: 4px; }
.aging-card .val { font-size: 1.25rem; font-weight: 600; }
.aging-0-30 .val { color: var(--success); }
.aging-31-60 .val { color: var(--warning); }
.aging-61-90 .val { color: var(--warning); }
.aging-90plus .val { color: var(--danger); }

/* ════════════════════════════════════════════════════════════
   PERIOD CHIPS — Cobranza period selection in modals
   ════════════════════════════════════════════════════════════ */
.period-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.period-chip {
  padding: 4px 10px; border-radius: 14px; font-size: 0.8rem;
  cursor: pointer; border: 1px solid var(--border-3);
  background: rgba(30,58,95,0.3); transition: all 0.2s;
}
.period-chip:hover { border-color: var(--accent-bright); }
.period-chip.selected { background: var(--accent); border-color: var(--accent-bright); color: #fff; }
.period-chip.covered { opacity: 0.4; text-decoration: line-through; cursor: default; }

/* ════════════════════════════════════════════════════════════
   VIEW TOGGLE BUTTON
   ════════════════════════════════════════════════════════════ */
.view-toggle {
  display: inline-flex; border: 1px solid var(--border-3);
  border-radius: 6px; overflow: hidden;
}
.view-toggle button {
  padding: 4px 10px; background: transparent; border: none;
  color: var(--text-subtle); cursor: pointer; font-size: 0.85rem;
}
.view-toggle button.active { background: rgba(var(--accent-bright-rgb),0.2); color: var(--accent-bright); }

/* ── DISMISS DROPDOWN ── */
.dismiss-dropdown { position: relative; display: inline-block; }
.dismiss-trigger { opacity: 0.4; transition: opacity 0.15s; }
@media (hover: hover) {
  .dismiss-trigger:hover { opacity: 1; }
  tr:hover .dismiss-trigger { opacity: 0.7; }
}
@media (hover: none) { .dismiss-trigger { opacity: 0.7; } }
.dismiss-menu {
  display: none; position: absolute; right: 0; top: 100%; z-index: 50;
  background: var(--surface-raised); border: 1px solid var(--border-3); border-radius: 6px;
  box-shadow: 0 8px 24px rgba(var(--shadow-rgb),0.4); min-width: 170px; padding: 4px 0;
}
.dismiss-dropdown:hover .dismiss-menu,
.dismiss-dropdown:focus-within .dismiss-menu { display: block; }
.dismiss-option {
  padding: 8px 14px; color: var(--text-default); font-size: 0.8rem; cursor: pointer;
  white-space: nowrap; transition: background 0.1s;
}
.dismiss-option:hover { background: rgba(var(--accent-bright-rgb),0.15); color: #fff; }

/* ── Addons (§13) ───────────────────────────────────────── */
.mkt-toolbar { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; margin-bottom: 1rem; }
.mkt-search { flex: 1; min-width: 240px; }
.mkt-grid-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; margin-bottom: 24px; }
.mkt-group-head { color: var(--text-soft); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; margin: 18px 0 10px; }
.mkt-card { background: var(--surface-3); border: 1px solid var(--border-3); border-left: 3px solid var(--border-strong); border-radius: 8px; padding: 14px; cursor: pointer; transition: transform 0.1s, border-color 0.15s; display: flex; flex-direction: column; gap: 10px; }
.mkt-card:hover { transform: translateY(-1px); border-color: var(--accent-bright); }
.mkt-card-head { display: flex; align-items: flex-start; gap: 10px; }
.mkt-icon { font-size: 32px !important; }
.mkt-icon-lg { font-size: 48px !important; }
.mkt-card-title { font-weight: 700; color: var(--text-strong); font-size: 14px; }
.mkt-card-head > .flex-1 { min-width: 0; } /* sin esto, un contenido ancho empuja el switch fuera de la tarjeta */
.mkt-card-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
.mkt-card-action { margin-top: 8px; }
.mkt-card-desc { color: var(--text-soft); font-size: 12px; line-height: 1.4; min-height: 32px; }
.mkt-card-deps { display: flex; align-items: center; gap: 6px; color: var(--text-soft); font-size: 11px; }
.mkt-card-deps .mi { font-size: 14px !important; }
.mkt-toggle { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; }
.mkt-toggle input { opacity: 0; width: 0; height: 0; }
.mkt-slider { position: absolute; cursor: pointer; inset: 0; background: var(--border-strong); border-radius: 22px; transition: 0.2s; }
.mkt-slider::before { content: ""; position: absolute; height: 16px; width: 16px; left: 3px; bottom: 3px; background: var(--text-default); border-radius: 50%; transition: 0.2s; }
.mkt-toggle input:checked + .mkt-slider { background: var(--success); }
.mkt-toggle input:checked + .mkt-slider::before { transform: translateX(18px); background: #fff; }
.mkt-toggle input:disabled + .mkt-slider { opacity: 0.4; cursor: not-allowed; }
.mkt-drawer { position: fixed; top: 0; right: 0; width: 480px; max-width: 95vw; height: 100vh; height: 100dvh; background: var(--bg-page); border-left: 1px solid var(--border-3); box-shadow: -8px 0 24px rgba(var(--shadow-rgb),0.5); z-index: 950; overflow-y: auto; transition: transform 0.2s; }
.mkt-drawer.hidden { transform: translateX(100%); pointer-events: none; }
.mkt-drawer-head { display: flex; align-items: center; gap: 12px; padding: 20px; border-bottom: 1px solid var(--border-3); position: sticky; top: 0; background: var(--bg-page); z-index: 2; }
.mkt-drawer-title { font-size: 20px; font-weight: 800; color: var(--text-strong); }
.mkt-drawer-body { padding: 20px; color: var(--text-default); font-size: 13px; }
.mkt-drawer-body h4 { margin: 18px 0 8px; color: var(--accent-bright); font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
.mkt-caps-list { list-style: none; padding: 0; margin: 0; }
.mkt-caps-list li { padding: 4px 0; font-size: 12px; }
.mkt-caps-list code { background: var(--surface-raised); padding: 2px 6px; border-radius: 3px; font-size: 11px; color: var(--warning-bright); }
.mkt-confirm-list { margin: 8px 0 12px 16px; color: var(--text-default); }
.mkt-progress { padding: 10px 0; max-height: 300px; overflow-y: auto; }
.mkt-progress-step { padding: 4px 0; font-family: ui-monospace, monospace; font-size: 12px; color: var(--text-soft); }
.mkt-progress-step.wait { color: var(--warning-bright); }
.mkt-progress-step.err { color: var(--danger); }

/* ── Importador (§12) — flow de 4 pasos ──────────────────────────── */
.imp-view-tabs { display: flex; gap: 8px; margin-bottom: 14px; }

/* Progress indicator */
.imp-progress { display: flex; align-items: center; gap: 6px; margin: 1rem 0 1.5rem; flex-wrap: wrap; }
.imp-step { display: flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 18px; font-size: 12px; color: var(--text-soft); background: var(--surface-3); border: 1px solid var(--border-3); }
.imp-step.active { color: #fff; background: var(--accent); border-color: var(--accent-bright); font-weight: 700; }
.imp-step.done { color: var(--success); border-color: #3ddd7e40; cursor: pointer; }
.imp-step.done:hover { background: var(--success-bg); }
.imp-step-num { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--border-3); font-size: 10px; font-weight: 700; }
.imp-step.active .imp-step-num { background: #fff; color: var(--text-muted); }
.imp-step.done .imp-step-num { background: var(--success); color: var(--bg-page); }
.imp-step.done .imp-step-num .mi { font-size: 14px !important; }
.imp-step-label { font-weight: 500; }
.imp-step-sep { color: var(--border-3); font-size: 18px; }

/* Body wrapper */
.imp-body { background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 8px; padding: 20px; }

/* Step head (título + búsqueda) */
.imp-step-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 8px 0 16px; flex-wrap: wrap; }
.imp-step-head h3 { margin: 0; color: var(--text-strong); font-size: 18px; font-weight: 700; }
.imp-step-head p { margin: 4px 0 0; }
.imp-search-wrap { flex: 1; min-width: 260px; max-width: 380px; }
.imp-search { width: 100%; }

/* Context head (fuente → destino) */
.imp-context-head { display: flex; align-items: center; gap: 16px; padding: 12px 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; margin-bottom: 14px; }
.imp-context-head > .mi { font-size: 28px !important; color: var(--accent-bright); }
.imp-context-source, .imp-context-target { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.imp-context-source .mi, .imp-context-target .mi { font-size: 24px !important; color: var(--accent-bright); }
.imp-context-arrow { color: var(--accent-bright); font-size: 20px !important; flex-shrink: 0; }

/* Preset bar + incremental */
.imp-preset-bar { display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: var(--surface-raised); border: 1px solid var(--border-3); border-radius: 8px; margin-bottom: 12px; }
.imp-preset-bar .mi { color: var(--accent-bright); }
.imp-preset-bar select { flex: 1; min-width: 200px; background: var(--surface-0); border: 1px solid var(--border-3); color: var(--text-strong); padding: 6px 10px; border-radius: 6px; font-size: 12px; }
.imp-incr-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }

/* Paso 1: destination grid */
.imp-dest-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; margin-bottom: 16px; }
.imp-dest-card { display: flex; align-items: flex-start; gap: 12px; padding: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; cursor: pointer; transition: transform 0.1s, border-color 0.15s, background 0.15s; text-align: left; color: inherit; font: inherit; }
.imp-dest-card:hover { border-color: var(--accent-bright); background: var(--surface-raised); transform: translateY(-1px); }
.imp-dest-card.selected { border-color: var(--accent-bright); background: var(--surface-raised); box-shadow: 0 0 0 2px rgba(var(--accent-bright-rgb), 0.25); }
.imp-dest-card.status-missing { opacity: 0.85; }
.imp-dest-icon { font-size: 28px !important; color: var(--accent-bright); flex-shrink: 0; }
.imp-dest-body { flex: 1; min-width: 0; }
.imp-dest-title { font-weight: 700; color: var(--text-strong); font-size: 14px; margin-bottom: 2px; }
.imp-dest-desc { color: var(--text-soft); font-size: 12px; margin-bottom: 6px; line-height: 1.35; }
.imp-dest-list code { font-size: 10px; color: var(--warning-bright); background: var(--surface-raised); padding: 1px 5px; border-radius: 3px; }
.imp-dest-status { flex-shrink: 0; }

/* Provision banner (schema embebido) */
.imp-provision-banner { display: flex; align-items: center; gap: 14px; padding: 16px; background: linear-gradient(135deg, var(--surface-raised), var(--accent)); border: 1px solid var(--accent-bright); border-radius: 8px; margin: 14px 0; }
.imp-provision-banner > .mi { font-size: 32px !important; color: var(--accent-bright); flex-shrink: 0; }
.imp-provision-banner > div { flex: 1; }
.imp-provision-banner code { color: var(--warning-bright); background: var(--surface-0); padding: 2px 6px; border-radius: 3px; font-size: 11px; }
/* Variante ADVERTENCIA (paso Confirmar: faltan columnas de auditoría). El degradado
   azul a --accent del base se ve "raro" en claro y deja texto/botón con poco
   contraste sobre azul; aquí va fondo ámbar plano + texto oscuro legible. */
.imp-provision-banner.is-warn { background: var(--warning-bg); border-color: var(--warning-bd); }
.imp-provision-banner.is-warn > .mi { color: var(--warning); }
.imp-provision-banner.is-warn code { color: var(--warning-bright); background: var(--surface-1); }

/* Paso 2: source tabs + SP list */
.imp-source-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.imp-source-tab { display: flex; align-items: center; gap: 12px; padding: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; cursor: pointer; text-align: left; color: inherit; font: inherit; transition: border-color 0.15s, background 0.15s; }
.imp-source-tab:hover { border-color: var(--accent-bright); background: var(--surface-raised); }
.imp-source-tab.active { border-color: var(--accent-bright); background: var(--surface-raised); box-shadow: 0 0 0 2px rgba(var(--accent-bright-rgb), 0.25); }
.imp-source-tab > .mi { font-size: 28px !important; color: var(--accent-bright); flex-shrink: 0; }
.imp-source-tab-title { font-weight: 700; color: var(--text-strong); font-size: 14px; margin-bottom: 2px; }
.imp-source-tab-desc { color: var(--text-soft); font-size: 12px; line-height: 1.35; }

.imp-sp-list { max-height: 320px; overflow-y: auto; overscroll-behavior: contain; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; padding: 6px; margin-top: 10px; }
.imp-sp-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: transparent; border: none; border-radius: 6px; width: 100%; cursor: pointer; text-align: left; color: inherit; font: inherit; transition: background 0.1s; }
.imp-sp-item:hover { background: var(--surface-raised); }
.imp-sp-item.selected { background: var(--surface-raised); color: var(--accent-bright); }
.imp-sp-item.selected .mi { color: var(--accent-bright); }
.imp-sp-item-body { flex: 1; min-width: 0; }
.imp-sp-item-title { font-weight: 500; color: var(--text-strong); font-size: 13px; }
.imp-sp-item-meta { color: var(--text-muted); font-size: 11px; font-family: ui-monospace, monospace; }

/* Source preview (sample table) */
.imp-source-preview { margin-top: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; padding: 12px; }
.imp-source-preview-head { font-size: 12px; color: var(--text-soft); margin-bottom: 8px; }
.imp-preview-table-wrap { overflow-x: auto; max-width: 100%; }
.imp-preview-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 0 8px; }
.imp-preview-head .btn { padding: 4px 10px; font-size: 12px; }
.imp-preview-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.imp-preview-table th { text-align: left; padding: 6px 10px; background: var(--surface-raised); color: var(--text-soft); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; white-space: nowrap; }
.imp-preview-table td { padding: 6px 10px; border-top: 1px solid var(--border-3); color: var(--text-default); white-space: nowrap; max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.imp-preview-table tr.row-error td { background: var(--purple-bg); color: var(--danger); }

/* Cotizaciones: vista previa en vivo del modal (§13.5.3, cotizaciones.js renderCotizacion) */
.cot-preview-doc { background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; padding: 14px; }
.cot-preview-head { margin-bottom: 10px; }
.cot-preview-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.cot-preview-table th { text-align: left; padding: 6px 8px; background: var(--surface-raised); color: var(--text-soft); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; }
.cot-preview-table td { padding: 6px 8px; border-top: 1px solid var(--border-3); color: var(--text-default); }
.cot-preview-total { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border-3); }
.cot-preview-terminos { margin-top: 8px; color: var(--text-dimmed); }

/* CSV drop */
.imp-csv-drop { border: 2px dashed var(--border-strong); border-radius: 8px; padding: 28px 16px; text-align: center; background: var(--surface-0); transition: border-color 0.15s, background 0.15s; }
.imp-csv-drop.over { border-color: var(--accent-bright); background: var(--surface-raised); }
.imp-csv-drop.has-file { border-style: solid; border-color: var(--accent-bright); background: var(--surface-raised); }
.imp-csv-icon { font-size: 40px !important; color: var(--accent-bright); display: block; margin: 0 auto 8px; }
.imp-csv-link { color: var(--accent-bright); text-decoration: underline; cursor: pointer; }

/* Paso 3: mapping toolbar + table */
.imp-map-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px 8px 0 0; margin-top: 14px; flex-wrap: wrap; }
.imp-map-stats { display: flex; gap: 14px; flex-wrap: wrap; }
.imp-map-stat { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-default); }
.imp-map-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.imp-map-filter { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-default); cursor: pointer; padding: 4px 8px; border-radius: 6px; }
.imp-map-filter:hover { background: var(--surface-raised); }
.imp-map-filter input { margin: 0; }

.imp-map-table-wrap { background: var(--surface-0); border: 1px solid var(--border-3); border-top: none; border-radius: 0 0 8px 8px; overflow-x: auto; }
.imp-map-table { width: 100%; border-collapse: collapse; }
.imp-map-table th, .imp-map-table td { padding: 10px 12px; border-bottom: 1px solid var(--border-3); text-align: left; font-size: 13px; }
.imp-map-table tr:last-child td { border-bottom: none; }
.imp-map-table th { color: var(--text-soft); font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; background: var(--surface-3); font-weight: 600; }
.imp-map-table tr.row-excluded { opacity: 0.5; }
.imp-map-table tr.row-mapped .col-arrow { color: var(--success); }
.imp-map-table tr.row-lookup .col-arrow { color: var(--info); }
.imp-map-table tr.row-cascade .col-arrow { color: var(--purple); }
.imp-intent-row { margin-top: 6px; }
.imp-intent { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 500; line-height: 1.4; }
.imp-intent .mi { font-size: 13px !important; }
.imp-intent-link { background: var(--surface-raised); color: var(--info); border: 1px solid var(--border-3); }
.imp-intent-cascade { background: var(--purple-bg); color: var(--text-default); border: 1px solid var(--purple-bd); }
.imp-intent-cat-padre { background: var(--surface-3); color: var(--purple); border: 1px solid var(--border-strong); }
.imp-map-table tr.row-cat-padre .col-arrow { color: var(--purple); }
.imp-map-table .col-inc { width: 44px; text-align: center; }
.imp-map-table .col-src { width: 26%; }
.imp-map-table .col-arrow { width: 30px; text-align: center; color: var(--accent-bright); }
.imp-map-table .col-dst { width: 26%; }
.imp-map-table .col-sample { width: 22%; }
.imp-map-table .col-vm { width: 110px; text-align: right; }
.imp-map-table select { width: 100%; background: var(--surface-raised); border: 1px solid var(--border-3); color: var(--text-strong); padding: 6px 10px; border-radius: 6px; font-size: 13px; }
.imp-map-table select:disabled { opacity: 0.5; cursor: not-allowed; }
.imp-map-table code { color: var(--warning-bright); background: var(--surface-raised); padding: 2px 6px; border-radius: 3px; font-size: 11px; }
.imp-checkbox { display: inline-flex; cursor: pointer; padding: 4px; }
.imp-checkbox input { margin: 0; cursor: pointer; accent-color: var(--accent-bright); width: 16px; height: 16px; }

/* Test run block */
.imp-test-run { margin-top: 14px; background: var(--surface-0); border: 1px solid var(--accent-bright); border-radius: 8px; overflow: hidden; }
.imp-test-run-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; background: var(--surface-raised); border-bottom: 1px solid var(--border-3); font-size: 13px; color: var(--text-strong); }
.imp-test-run-head .mi { color: var(--accent-bright); }
.imp-test-table { margin: 0; }

/* Advanced disclosure */
/* Bloque de filtro de filas origen (paso 3 del importador) */
.imp-filter-panel { margin-top: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; }
.imp-filter-panel > summary { padding: 12px 14px; cursor: pointer; color: var(--text-default); font-size: 13px; display: flex; align-items: center; gap: 10px; user-select: none; list-style: none; flex-wrap: wrap; }
.imp-filter-panel > summary::-webkit-details-marker { display: none; }
.imp-filter-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.imp-filter-toggle input { cursor: pointer; }
.imp-filter-stats-pill { margin-left: auto; padding: 3px 9px; border-radius: 999px; background: var(--surface-raised); border: 1px solid var(--border-3); font-size: 11px; color: var(--text-soft); }
.imp-filter-body { padding: 8px 14px 12px; display: flex; flex-direction: column; gap: 10px; border-top: 1px solid var(--border-3); }

.imp-filter-rule-card { background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 8px; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.imp-filter-rule-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.imp-filter-field { background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px; color: var(--text-strong); padding: 7px 10px; font-size: 13px; min-width: 180px; flex: 0 0 auto; }
.imp-filter-field:focus { border-color: var(--accent-bright); outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-bright-rgb),.12); }
.imp-mode-chips { display: flex; gap: 6px; flex-wrap: wrap; flex: 1; }
.imp-modechip { background: transparent; border: 1px solid var(--border-strong); color: var(--text-soft); border-radius: 999px; font-size: 11px; padding: 4px 10px; cursor: pointer; transition: all .12s ease; font-family: inherit; }
.imp-modechip:hover { color: var(--text-strong); border-color: var(--accent-bright); }
.imp-modechip.on { background: var(--accent-bright); border-color: var(--accent-bright); color: #fff; }

.imp-filter-rule-body { padding-left: 0; }
.imp-filter-hint { font-size: 12px; line-height: 1.5; color: var(--text-soft); padding-top: 4px; }
.imp-filter-hint code { background: var(--surface-raised); padding: 1px 5px; border-radius: 3px; color: var(--text-default); font-size: 11px; }

/* Categorical: chips de valores únicos del sample */
.imp-chips-row { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0; }
.imp-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 10px; font-size: 12px; line-height: 1;
  background: var(--surface-0); border: 1px solid var(--border-strong); color: var(--text-default);
  border-radius: 999px; cursor: pointer; user-select: none;
  transition: all .12s ease; font-family: inherit;
}
.imp-chip:hover { border-color: var(--accent-bright); color: var(--text-strong); }
.imp-chip.on { background: var(--accent-bright); border-color: var(--accent-bright); color: #fff; font-weight: 500; }
.imp-chip-x { background: transparent; border: none; color: inherit; opacity: .65; padding: 0 0 0 4px; cursor: pointer; font-size: 14px; line-height: 1; }
.imp-chip-x:hover { opacity: 1; }
.imp-chip-add { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-soft); }
.imp-chip-add:hover { border-color: var(--accent-bright); color: var(--accent-bright); border-style: solid; }

/* Range editor (date / number) */
.imp-range-row { display: flex; gap: 12px; flex-wrap: wrap; padding: 4px 0; }
.imp-range-row label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--text-soft); text-transform: uppercase; letter-spacing: .4px; font-weight: 600; }
.imp-range-row input { background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px; color: var(--text-strong); padding: 7px 10px; font-size: 13px; font-family: inherit; min-width: 160px; }
.imp-range-row input:focus { border-color: var(--accent-bright); outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-bright-rgb),.12); }

/* Text editor */
.imp-text-row input.imp-filter-value {
  background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px;
  color: var(--text-strong); padding: 7px 10px; font-size: 13px; font-family: inherit;
  width: 100%; max-width: 380px;
}
.imp-text-row input.imp-filter-value:focus { border-color: var(--accent-bright); outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-bright-rgb),.12); }

/* Stat pill de "descartadas por filtro" en paso 4 */
.imp-confirm-stat.stat-filtered .imp-confirm-num { color: var(--text-default); }
.imp-confirm-stat.stat-filtered { border-color: var(--border-strong); }

.imp-advanced { margin-top: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; }
.imp-advanced summary { padding: 12px 14px; cursor: pointer; color: var(--text-default); font-size: 13px; display: flex; align-items: center; gap: 8px; user-select: none; list-style: none; }
.imp-advanced summary::-webkit-details-marker { display: none; }
.imp-advanced summary::before { content: '▸'; color: var(--accent-bright); transition: transform 0.15s; }
.imp-advanced[open] summary::before { transform: rotate(90deg); }
.imp-advanced-body { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 14px; }

/* Keys chips */
.imp-keys-grid { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.imp-key-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 18px; background: var(--surface-3); border: 1px solid var(--border-3); font-size: 12px; cursor: pointer; color: var(--text-default); }
.imp-key-chip.on { background: var(--surface-raised); border-color: var(--accent-bright); color: var(--accent-bright); }
.imp-key-chip input { margin: 0; accent-color: var(--accent-bright); }

/* Paso 4: confirm stats */
.imp-confirm-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin: 14px 0; }
.imp-confirm-stat { padding: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; text-align: center; }
.imp-confirm-num { font-size: 28px; font-weight: 800; color: var(--text-strong); line-height: 1; margin-bottom: 4px; }
.imp-confirm-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--text-soft); }
.imp-confirm-stat.stat-insert { border-color: #3ddd7e40; }
.imp-confirm-stat.stat-insert .imp-confirm-num { color: var(--success); }
.imp-confirm-stat.stat-update { border-color: rgba(var(--accent-bright-rgb),.25); }
.imp-confirm-stat.stat-update .imp-confirm-num { color: var(--accent-bright); }
.imp-confirm-stat.stat-skip { border-color: var(--border-3); }
.imp-confirm-stat.stat-error { border-color: #ff6b6b40; }
.imp-confirm-stat.stat-error .imp-confirm-num { color: var(--danger); }
.imp-confirm-stat.stat-total { background: var(--surface-raised); }

.imp-notice { display: flex; align-items: center; gap: 8px; padding: 10px 14px; background: var(--surface-raised); border: 1px solid var(--border-3); border-radius: 6px; font-size: 12px; color: var(--text-soft); margin: 10px 0; }
.imp-notice .mi { color: var(--accent-bright); }

/* Strip global de operaciones async en vuelo. Sticky al tope del scroller
   .content para que se vea aunque el usuario haga scroll en una sección
   larga. Estilo prominente con fade-out gradient al fondo (suaviza el
   corte visual cuando contenido scrollea por debajo) y pulso sutil de
   shadow azul para llamar atención sin ser molesto. */
.app-busy-strip {
  position: sticky; top: 0; z-index: 10;
  display: flex; flex-direction: column; gap: 8px;
  margin: 0 0 18px;
  padding: 4px 0 12px;
  background: linear-gradient(180deg, var(--bg-page) 0%, var(--bg-page) 70%, transparent 100%);
}
.app-busy-strip:empty,
.app-busy-strip.hidden { display: none; }
.app-busy-item {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px;
  background: var(--surface-raised);
  border: 1px solid var(--border-3);
  border-left: 4px solid var(--accent);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-strong);
  box-shadow: 0 2px 12px rgba(var(--accent-rgb), .15);
  animation: appBusyPulse 2.4s ease-in-out infinite;
}
.app-busy-item > .mi {
  color: var(--accent); flex-shrink: 0; font-size: 22px !important;
}
.app-busy-item .spinner-sm {
  width: 18px; height: 18px;
  border-width: 2.5px;
  border-color: var(--border-3); border-top-color: var(--accent);
  flex-shrink: 0; margin-right: 0;
}
.app-busy-item.app-busy-error {
  background: var(--purple-bg);
  border-color: var(--danger);
  border-left-color: var(--danger);
  color: var(--text-default);
  box-shadow: 0 2px 12px rgba(255, 107, 107, .2);
  animation: none;
}
@keyframes appBusyPulse {
  0%, 100% { box-shadow: 0 2px 12px rgba(var(--accent-rgb), .15); }
  50%      { box-shadow: 0 2px 18px rgba(var(--accent-rgb), .35); }
}
.app-busy-item.app-busy-error > .mi { color: var(--danger); }
.app-busy-item.app-busy-error > div { flex: 1; min-width: 0; }
.app-busy-item button {
  color: var(--text-default); padding: 4px 8px;
  background: rgba(255, 107, 107, .1);
  border-radius: 6px;
}
.app-busy-item button:hover { background: rgba(255, 107, 107, .2); }

/* Estado .app-pending — para elementos cuya interacción depende de un
   fetch en vuelo. No los oculta ni bloquea por completo (eso sería muy
   agresivo y confuso), sólo los atenúa con cursor:wait para señalar
   que el resultado de hacer click va a estar incompleto hasta que
   la operación termine. El módulo de origen aplica/quita esta clase
   al gusto.

   Quien quiera bloqueo total puede usar [aria-disabled="true"] +
   pointer-events:none, pero ése es un opt-in explícito por componente. */
.app-pending {
  opacity: .55; cursor: wait;
  transition: opacity .2s;
}
.app-pending * { cursor: wait !important; }

/* La strip de operaciones async ahora vive a nivel global — ver
   .app-busy-strip arriba en este archivo. Las clases .imp-busy-* fueron
   removidas en favor de las globales .app-busy-*. */
.imp-notice.imp-notice-warn { background: var(--warning-bg); border-color: var(--warning-bd); color: var(--warning); }
.imp-notice.imp-notice-warn .mi { color: var(--warning); }

/* Banner de cascada en step 3: visualmente más prominente que un .imp-notice
   porque aporta info de capacidad (no de status), y necesita destacar para
   que los usuarios noten que pueden mapear campos hijos. */
.imp-cascade-hint {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 16px; margin: 12px 0;
  background: linear-gradient(180deg, var(--surface-raised) 0%, var(--surface-3) 100%);
  border: 1px solid var(--border-strong); border-left: 3px solid var(--accent);
  border-radius: 8px;
}
.imp-cascade-hint > .mi { color: var(--accent); font-size: 24px !important; flex-shrink: 0; margin-top: 2px; }
.imp-cascade-hint-title { font-weight: 700; color: var(--text-strong); font-size: 13px; margin-bottom: 4px; }
.imp-cascade-hint-body { color: var(--text-subtle); font-size: 12px; line-height: 1.5; }
.imp-cascade-hint-body strong { color: var(--text-default); }
.imp-cascade-hint-note { display: flex; align-items: flex-start; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border-2); font-size: 12px; color: var(--text-subtle); }
.imp-cascade-hint-note .mi { font-size: 15px !important; color: var(--warning); flex-shrink: 0; }
.imp-cascade-hint-note b { color: var(--text-default); }

/* Banner de prerrequisitos (paso Fuente) — qué importar antes para que los FKs resuelvan */
.imp-prereq-banner { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; background: var(--info-bg); border: 1px solid var(--info-bd); border-radius: 8px; margin-bottom: 14px; }
.imp-prereq-banner > .mi { color: var(--info); font-size: 24px !important; flex-shrink: 0; margin-top: 1px; }
.imp-prereq-main { flex: 1; min-width: 0; }
.imp-prereq-title { font-size: 13px; color: var(--text-strong); margin-bottom: 8px; }
.imp-prereq-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.imp-prereq-chip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 999px; font-size: 12px; color: var(--text-default); font-weight: 600; }
.imp-prereq-chip > .mi { font-size: 15px !important; color: var(--text-muted); }
.imp-prereq-badge { display: inline-flex; align-items: center; gap: 2px; font-size: 11px; color: var(--text-muted); }
.imp-prereq-badge .mi { font-size: 13px !important; }
.imp-prereq-chip.imp-prereq-ok { border-color: var(--success-bd); }
.imp-prereq-chip.imp-prereq-ok .imp-prereq-badge { color: var(--success); }
.imp-prereq-chip.imp-prereq-warn { border-color: var(--warning-bd); background: var(--warning-bg); }
.imp-prereq-chip.imp-prereq-warn .imp-prereq-badge { color: var(--warning); }
.imp-prereq-note { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 12px; color: var(--text-subtle); }
.imp-prereq-note .mi { font-size: 15px !important; color: var(--info); }
/* Prereqs OPCIONALES: separador + chips atenuados (no bloquean, solo recomiendan) */
.imp-prereq-opt-title { font-size: 12px; color: var(--text-subtle); margin: 10px 0 6px; font-weight: 600; }
.imp-prereq-chip-opt { background: transparent; border-style: dashed; border-color: var(--border-2); color: var(--text-subtle); font-weight: 500; }
.imp-prereq-chip-opt > .mi { color: var(--text-dimmed); }

/* Panel "orden recomendado" (paso Destino) — tiers topológicos del grafo FK */
.imp-order-panel { background: var(--surface-raised); border: 1px solid var(--border-2); border-radius: 8px; margin-bottom: 14px; }
.imp-order-panel > summary { cursor: pointer; padding: 10px 14px; font-size: 13px; font-weight: 600; color: var(--text-default); display: flex; align-items: center; gap: 8px; list-style: none; }
.imp-order-panel > summary::-webkit-details-marker { display: none; }
.imp-order-panel > summary > .mi { color: var(--accent); }
.imp-order-sub { font-weight: 400; font-size: 11px; color: var(--text-muted); }
.imp-order-body { padding: 0 14px 12px; }
.imp-order-intro { font-size: 12px; color: var(--text-muted); margin: 0 0 10px; }
.imp-order-tier { display: flex; align-items: flex-start; gap: 10px; padding: 4px 0; }
.imp-order-tier-n { flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%; background: var(--accent); color: #fff; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.imp-order-tier-ents { display: flex; flex-wrap: wrap; gap: 6px; }
.imp-order-ent { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; background: var(--surface-1); border: 1px solid var(--border-2); border-radius: 999px; font-size: 12px; color: var(--text-default); }
.imp-order-ent > .mi { font-size: 14px !important; color: var(--text-muted); }
.imp-order-ent.cur { border-color: var(--accent); color: var(--accent); font-weight: 700; }
.imp-order-opt-tag { margin-left: 5px; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--text-muted); background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 4px; padding: 0 4px; }
.imp-error-details { margin: 14px 0; background: var(--purple-bg); border: 1px solid #ff6b6b40; border-radius: 8px; overflow: hidden; }
.imp-error-details summary { padding: 10px 14px; cursor: pointer; color: var(--danger); font-size: 13px; }

.imp-confirm-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.imp-confirm-actions-right { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-lg { padding: 10px 20px; font-size: 14px; font-weight: 700; }

/* Progress bar en ejecución */
.imp-progress-bar-wrap { margin: 14px 0; }
.imp-progress-label { font-size: 13px; color: var(--text-default); margin-bottom: 6px; }
.imp-bar { width: 100%; height: 10px; background: var(--surface-raised); border-radius: 6px; overflow: hidden; }
.imp-bar-fill { height: 100%; background: linear-gradient(90deg, var(--accent-bright), var(--success)); transition: width 0.2s; }
.imp-log { max-height: 200px; overflow: auto; margin-top: 12px; padding: 10px; background: var(--surface-0); border-radius: 6px; font-family: ui-monospace, monospace; font-size: 11px; }

/* Nav buttons */
.imp-nav-btns { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--border-3); }

/* Legacy preview JSON (sigue usándose en results) */
.imp-preview-json { background: var(--bg-page); border: 1px solid var(--border-3); border-radius: 4px; padding: 10px; font-size: 11px; max-height: 280px; overflow: auto; color: var(--text-default); }

/* Value mapping */
.imp-vm-row td { padding: 0 !important; background: var(--surface-0); }
.imp-vm-panel { padding: 12px 16px; border-top: 2px solid var(--border-strong); }
.imp-vm-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; gap: 10px; flex-wrap: wrap; }
.imp-vm-entries { display: flex; flex-direction: column; gap: 6px; max-height: 280px; overflow: auto; }
.imp-vm-entry { display: grid; grid-template-columns: 1fr 24px 1fr auto; gap: 8px; align-items: center; }
.imp-vm-entry input { background: var(--surface-3); border: 1px solid var(--border-strong); color: var(--text-default); border-radius: 4px; padding: 6px 8px; font-family: ui-monospace, monospace; font-size: 12px; }

/* Historial */
.imp-history { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.imp-history-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 14px; background: var(--surface-0); border: 1px solid var(--border-strong); border-radius: 8px; }
.imp-history-main { flex: 1; min-width: 0; }
.imp-history-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.imp-history-pager { display: flex; justify-content: center; align-items: center; gap: 12px; padding: 10px 0 4px; }

/* Badges usados por audit status */
.badge-ok   { background: var(--success-bg); border: 1px solid var(--success); color: var(--success); }
.badge-warn { background: var(--warning-bg); border: 1px solid var(--warning-bright); color: var(--warning-bright); }
.badge-err  { background: var(--purple-bg); border: 1px solid var(--danger); color: var(--danger); }

/* Badges del historial del importador */
.badge-completo            { background: var(--success-bg); border: 1px solid var(--success); color: var(--success); }
.badge-parcial             { background: var(--warning-bg); border: 1px solid var(--warning-bright); color: var(--warning-bright); }
.badge-fallido             { background: var(--purple-bg); border: 1px solid var(--danger); color: var(--danger); }
.badge-en_curso            { background: var(--surface-raised); border: 1px solid var(--accent-bright); color: var(--accent-bright); }
.badge-revertido           { background: var(--surface-raised); border: 1px solid var(--text-muted); color: var(--text-soft); }
.badge-revertido-parcial   { background: var(--warning-bg); border: 1px solid var(--warning-bright); color: var(--warning-bright); }

/* ────────────────────────────────────────────────────────────
   v2.0 — UI PRIMITIVES (greenfield)
   Drawer (slide-over), Command Palette, Kanban, Timeline,
   Sidebar agrupado, Cmdk trigger en topbar, Module group.
   ──────────────────────────────────────────────────────────── */

/* ── Sidebar agrupado y colapsable (§80, Fase 2) ── */
/* El header es <button> para a11y (Enter/Space, focus visible). Tipografía
   idéntica al diseño previo (uppercase + 10px) para no romper la estética.
   Chevron rota 180° cuando el grupo está expandido. */
.sidebar-group {
  display: block;
}
/* Categorías = divisores informativos (NO colapsables). Un solo nivel de
   disclosure vive en el submenú de cada item (estilo macOS Ajustes/Notion).
   Más chicas, sin chevron ni número — solo separan bloques. */
.sidebar-group-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: inherit;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--accent);
  padding: 14px 18px 6px;
  font-weight: 800;
  user-select: none;
}
.sidebar-group-items { overflow: visible; }

/* Pin de favoritos en sidebar (§80 Fase 6). El botón ⭐ aparece on-hover
   en la esquina derecha del nav-item; siempre visible para items que ya
   son favoritos (estilo Notion/Slack). En modo iconos colapsado (§51)
   y modo Dirección (§46) el botón se oculta — ahí el espacio es premium. */
.nav-item { position: relative; }
.nav-item-star {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s, color .15s;
  color: var(--text-muted);
  display: flex; align-items: center; justify-content: center;
}
.nav-item-star .mi { font-size: 16px !important; }
.nav-item:hover .nav-item-star { opacity: .55; }
.nav-item:hover .nav-item-star:hover { opacity: 1; color: var(--warning); }
.nav-item-star.active {
  opacity: 1;
  color: var(--warning);
}
.nav-item-star.active:hover { color: var(--text-muted); }
/* En modo iconos colapsado el botón ⭐ se oculta — no hay espacio horizontal */
body.sidebar-collapsed .nav-item-star { display: none; }
/* En modo iconos colapsado: ocultar la sección "★ Favoritos" entera.
   Los items ya aparecen como iconos en sus grupos originales — verlos
   también en Favoritos sería duplicación visible. */
body.sidebar-collapsed .sidebar-group-favs { display: none; }
/* En modo Dirección la sección Favoritos también se oculta — solo el
   item Dashboard es relevante en ese modo. */
body.viewmode-directivo .sidebar-group-favs { display: none; }

/* ── Submenú expandible de nav-item (3er nivel) ───────────────────────
   Click en el chevron (NO hover — P1/§85) despliega las acciones/tabs de
   la sección: ej. Clientes → Todos / Contactos / + Nuevo cliente. El de la
   sección ACTIVA se abre solo (setActive agrega .subnav-open). El "+ Nuevo"
   va en acento azul para que SE NOTE (la queja original: "no se ve"). */
.nav-item-wrap { display: block; }
.nav-subnav-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 6px;
  cursor: pointer; color: var(--text-default); opacity: 1;
  background: var(--surface-raised);
  transition: opacity .15s, color .15s, background .15s; z-index: 2;
}
.nav-subnav-toggle:hover { opacity: 1; color: var(--accent); background: var(--surface-3); }
/* Cuando un item tiene chevron de submenú, la ⭐ (que vive en el mismo
   right:8px y en hover interceptaba el click del chevron) se corre a la
   izquierda para que AMBOS controles sean clickeables. §7pts-9 R-UX. */
.nav-item-wrap.has-subnav > .nav-item .nav-item-star { right: 38px; }
.nav-subnav-toggle .mi { font-size: 18px !important; transition: transform .15s; }
.nav-item-wrap.subnav-open > .nav-item .nav-subnav-toggle .mi { transform: rotate(180deg); }
.nav-subnav-toggle:focus-visible {
  outline: 2px solid rgba(var(--accent-rgb),.5); outline-offset: 1px; border-radius: 4px;
}
/* La estrella de favorito se recorre a la izquierda del chevron en items
   con submenú, para que no se encimen (ambas son absolute, right). */
.nav-item-wrap.has-subnav .nav-item-star { right: 32px; }

.nav-subitems {
  display: none; flex-direction: column; gap: 1px;
  margin: 1px 0 5px 26px; padding-left: 5px;
  border-left: 1px solid var(--border-1);
}
.nav-item-wrap.subnav-open > .nav-subitems { display: flex; }
.nav-subitem {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 12px 7px 12px; border-radius: 7px;
  font-size: 13px; font-weight: 500; color: var(--text-muted);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: .12s;
}
.nav-subitem .mi { font-size: 17px; color: var(--text-soft); transition: .12s; }
.nav-subitem:hover { background: var(--surface-1); color: var(--accent); }
.nav-subitem:hover .mi { color: var(--accent); }
.nav-subitem:focus-visible { outline: 2px solid rgba(var(--accent-rgb),.4); outline-offset: 1px; }
/* "+ Nuevo X": acento azul para que destaque (resuelve la queja) */
.nav-subitem-action { color: var(--accent); font-weight: 600; }
.nav-subitem-action .mi { color: var(--accent); }
.nav-subitem-action:hover { background: var(--surface-raised); }
/* Sub-item activo (la pestaña en la que estás) — mismo acento que nav-item.active */
.nav-subitem.active { background: var(--surface-3); color: var(--accent); font-weight: 600; }
.nav-subitem.active .mi { color: var(--accent); }

/* Modo iconos (Ctrl+B §51) y modo Dirección (§46): sin 3er nivel.
   En iconos no hay ancho; en Dirección la nav es minimal a propósito. */
body.sidebar-collapsed .nav-subitems,
body.sidebar-collapsed .nav-subnav-toggle,
body.viewmode-directivo .nav-subitems,
body.viewmode-directivo .nav-subnav-toggle { display: none !important; }
/* Cursor pointer + keyboard focus visible para el ⭐ (span role=button) */
.nav-item-star { cursor: pointer; }
.nav-item-star:focus-visible {
  outline: 2px solid rgba(251,191,36,.5);
  outline-offset: 1px;
  opacity: 1 !important;
}

/* Banner "Probando como X" (§80 Fase 6). Sticky en el tope sobre todo —
   incluido el topbar — para que el Superadmin no olvide que está en
   modo impersonate. Color ámbar para distinguirlo de toasts/errores. */
.impersonate-banner {
  position: sticky;
  top: 0;
  z-index: 1000;
  background: linear-gradient(90deg, #f59e0b 0%, #fbbf24 100%);
  color: #1a1408;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  box-shadow: 0 2px 8px rgba(var(--shadow-rgb),.3);
}
.impersonate-banner .mi { color: #1a1408 !important; }
.impersonate-banner strong {
  background: rgba(26,20,8,.15);
  padding: 1px 8px;
  border-radius: 4px;
}
.impersonate-banner .btn {
  background: rgba(26,20,8,.15) !important;
  color: #1a1408 !important;
  border: 1px solid rgba(26,20,8,.3) !important;
}
.impersonate-banner .btn:hover {
  background: rgba(26,20,8,.3) !important;
}
.nav-item .mi {
  font-size: 18px;
  color: var(--text-muted);
  flex-shrink: 0;
}
.nav-item.active .mi, .nav-item:hover .mi { color: var(--text-default); }
.nav-item {
  display: flex !important;
  align-items: center;
  gap: 10px;
}
/* §216: la única forma de ocultar una entrada del menú (el display:flex de arriba es !important). */
.nav-item.nav-oculto, .bottom-tab.nav-oculto, .topbar-soporte-btn.nav-oculto { display: none !important; }

/* ── Cmdk trigger (topbar pill) ── */
.cmdk-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-0);
  border: 1px solid var(--border-3);
  color: var(--text-muted);
  padding: 7px 12px 7px 10px;
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  min-width: 280px;
  transition: border-color 0.15s, color 0.15s;
}
.cmdk-trigger:hover { border-color: var(--accent-bright); color: var(--text-default); }
.cmdk-trigger:hover .mi { color: var(--accent-bright); }
.cmdk-trigger .cmdk-trigger-text { flex: 1; text-align: left; }

/* D4: búsqueda inline en el topbar (input visible + dropdown de resultados,
   sin modal). Reusa los estilos de .cmdk-item para los resultados. */
.topsearch-wrap { position: relative; display: flex; align-items: center; gap: 8px; background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 8px; padding: 0 10px; }
.topsearch-wrap:focus-within { border-color: var(--accent-bright); }
.topsearch-icon { color: var(--text-muted); font-size: 20px !important; flex-shrink: 0; }
.topsearch-input { background: transparent; border: none; outline: none; color: var(--text-default); font-size: 14px; padding: 9px 0; width: 260px; max-width: 34vw; }
.topsearch-input::placeholder { color: var(--text-muted); }
.topsearch-results { position: absolute; top: calc(100% + 6px); left: 0; min-width: 380px; max-width: 92vw; background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 10px; box-shadow: 0 12px 32px rgba(var(--shadow-rgb),.45); max-height: 60vh; overflow-y: auto; z-index: 1200; padding: 6px 0; display: none; }
.topsearch-results.open { display: block; }
body.viewmode-directivo .topsearch-wrap { display: none; }
@media (max-width: 768px) { .topsearch-input { width: 130px; } .topsearch-results { min-width: 260px; } }
.cmdk-kbd, .cmdk-footer kbd {
  font-family: ui-monospace, monospace;
  font-size: 11px;
  background: var(--surface-raised);
  border: 1px solid var(--border-3);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 1px 6px;
  color: var(--text-soft);
}

/* ── Command Palette (Cmd+K) ── */
.cmdk-scrim {
  position: fixed; inset: 0; background: rgba(2, 8, 16, 0.65);
  backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none; transition: opacity 0.16s;
  z-index: 9000;
}
.cmdk-scrim.open { opacity: 1; pointer-events: auto; }
.cmdk {
  position: fixed; top: 12vh; left: 50%; transform: translateX(-50%) translateY(-12px);
  width: min(640px, 92vw);
  background: var(--surface-3);
  border: 1px solid var(--border-3);
  border-radius: 12px;
  box-shadow: 0 24px 60px rgba(var(--shadow-rgb),0.6);
  opacity: 0; pointer-events: none; transition: opacity 0.16s, transform 0.16s;
  z-index: 9001;
  overflow: hidden;
  display: flex; flex-direction: column;
  max-height: 70vh;
}
.cmdk.open { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
.cmdk-input-wrap {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-3);
}
.cmdk-input-wrap .mi { color: var(--text-muted); font-size: 22px; }
.cmdk-input-wrap input {
  flex: 1; background: transparent; border: none; outline: none;
  color: var(--text-strong); font-size: 15px; padding: 0;
}
.cmdk-results { flex: 1; overflow-y: auto; padding: 6px 0; min-height: 60px; }
.cmdk-group-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--text-muted); padding: 8px 18px 4px; font-weight: 700;
}
.cmdk-item {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 18px; cursor: pointer;
  transition: background 0.08s;
}
.cmdk-item:hover, .cmdk-item.active { background: var(--surface-raised); }
.cmdk-item .mi { color: var(--text-muted); font-size: 18px; }
.cmdk-item.active .mi { color: var(--accent-bright); }
.cmdk-item-main { flex: 1; min-width: 0; }
.cmdk-item-label { color: var(--text-default); font-size: 14px; }
.cmdk-item-sub { color: var(--text-muted); font-size: 11px; margin-top: 1px; }
.cmdk-item-hint { color: var(--text-muted); font-size: 11px; }
.cmdk-empty { padding: 36px 18px; text-align: center; color: var(--text-muted); font-size: 13px; }
.cmdk-footer {
  display: flex; gap: 16px; padding: 8px 18px;
  border-top: 1px solid var(--border-3); font-size: 11px; color: var(--text-muted);
  background: var(--surface-0);
}

/* ── Drawer (slide-over) ── */
.drawer-scrim {
  position: fixed; inset: 0; background: rgba(2, 8, 16, 0.5);
  opacity: 0; pointer-events: none; transition: opacity 0.18s;
  z-index: 8000;
}
.drawer-scrim.open { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(560px, 96vw);
  background: var(--bg-page);
  border-left: 1px solid var(--border-3);
  box-shadow: -16px 0 40px rgba(var(--shadow-rgb),0.5);
  transform: translateX(100%);
  transition: transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);
  z-index: 8001;
  display: flex; flex-direction: column;
}
.drawer.open { transform: translateX(0); }
.drawer.drawer-wide { width: min(820px, 96vw); }
.drawer-header {
  padding: 18px 22px;
  border-bottom: 1px solid var(--border-3);
  display: flex; align-items: center; gap: 12px;
  flex-shrink: 0;
}
.drawer-title { font-size: 17px; font-weight: 600; color: var(--text-strong); flex: 1; min-width: 0; }
.drawer-subtitle { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.drawer-close {
  background: none; border: none; color: var(--text-muted); cursor: pointer;
  padding: 6px; border-radius: 6px;
  transition: background 0.12s, color 0.12s;
}
.drawer-close:hover { background: var(--surface-raised); color: var(--text-default); }
.drawer-body { flex: 1; overflow-y: auto; padding: 20px 22px; }
.drawer-footer {
  padding: 14px 22px;
  border-top: 1px solid var(--border-3);
  display: flex; justify-content: flex-end; gap: 10px;
  background: var(--surface-0);
  flex-shrink: 0;
}
.drawer-footer:empty { display: none; }
.drawer-tabs {
  display: flex; gap: 4px;
  padding: 0 22px;
  border-bottom: 1px solid var(--border-3);
  flex-shrink: 0;
}
.drawer-tab {
  padding: 10px 14px;
  background: none; border: none;
  color: var(--text-muted); font-size: 13px; cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.12s, border-color 0.12s;
}
.drawer-tab:hover { color: var(--text-default); }
.drawer-tab.active { color: var(--accent-bright); border-bottom-color: var(--accent-bright); }

/* ── Ayuda (core/asistente.js) — chat determinístico, sin LLM, §94 ──
   Deliberadamente SEPARADO de .cmdk (decisión del dueño: público 40+,
   "bajarle dos rayitas a la innovación" — nada de fusionarlo con el command
   palette). Sin scrim: no bloquea el resto de la página, igual que un
   widget de soporte convencional (Intercom/Zendesk/WhatsApp Business) — el
   patrón más reconocible de "hacer una pregunta" para este público. */
/* 🔴 Fix (code-review): ambos vivían por encima de `.overlay` (100) — un
   z-index heredado sin pensar en el resto del mapa de apilamiento del Portal
   (ver comentario de `.overlay-apilada` arriba: 100/1500/8000/9000/9500/9600).
   Con 300/7000 el widget de Ayuda tapaba visualmente parte de cualquier modal
   abierto (incl. `.modal-wide`) sin que nada lo cerrara al abrirse uno. Ahora
   quedan JUSTO debajo de `.overlay` (100) — un modal siempre los cubre por
   completo (el propio `.overlay` intercepta los clics), igual que un widget
   de soporte convencional (Intercom/Zendesk) cede el paso a un diálogo modal. */
/* Lado derecho (pedido explícito, antes vivía a la izquierda). `bottom: 24px`
   (al ras, como cualquier FAB tipo Intercom/WhatsApp) — pedido explícito del
   dueño 2026-08-18, REVIERTE el `88px` de `1.2.5`: ese valor dejaba libre el
   carril de `.toast` para que ningún toast quedara pegado/encima del botón, a
   costa de que el botón se viera "muy arriba" en reposo (el problema
   reportado). En vez de aceptar el roce, `.toast` se movió a bottom-LEFT
   (mismo día) — ambos quedan en esquinas OPUESTAS, así que el roce que este
   comentario aceptaba antes ya no puede pasar (no fue una garantía frágil de
   z-index/timing, fue separarlos de plano). `.ayuda-panel` mantiene el mismo
   espacio (66px) sobre el botón. */
.ayuda-btn {
  position: fixed; right: 24px; bottom: 24px; z-index: 90;
  display: flex; align-items: center; gap: 8px;
  background: var(--accent); color: #fff; border: none; border-radius: 999px;
  padding: 12px 18px; font-size: 14px; font-weight: 700; cursor: pointer;
  box-shadow: 0 8px 24px rgba(var(--shadow-rgb),.35);
  transition: transform .12s, box-shadow .12s;
}
.ayuda-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(var(--shadow-rgb),.4); }
/* §576: Ayuda sigue esperando tu respuesta (una propuesta sin contestar) y el panel está cerrado. */
.ayuda-btn.ayuda-btn-aviso::after { content: ''; position: absolute; top: -2px; right: -2px; width: 14px; height: 14px; border-radius: 50%; background: var(--warning); border: 2px solid var(--surface-1); }
.ayuda-btn .mi { font-size: 20px; }
.ayuda-panel {
  position: fixed; right: 24px; bottom: 90px; z-index: 95;
  /* `100vh - 140px`: espejo de `1.2.5` en reversa — el bottom bajó de 154→90
     (-64), el reservado baja lo mismo, para mantener el mismo margen libre
     arriba en viewports bajos. */
  width: min(380px, calc(100vw - 48px)); height: min(560px, calc(100vh - 140px));
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(var(--shadow-rgb),.5);
  display: flex; flex-direction: column; overflow: hidden;
  opacity: 0; pointer-events: none; transform: translateY(12px);
  transition: opacity .16s, transform .16s;
}
.ayuda-panel.open { opacity: 1; pointer-events: auto; transform: translateY(0); }
.ayuda-panel-head {
  display: flex; align-items: center; gap: 10px; padding: 14px 16px;
  border-bottom: 1px solid var(--border-1); flex-shrink: 0;
}
.ayuda-panel-title { font-size: 15px; font-weight: 700; color: var(--text-strong); }
.ayuda-panel-close {
  background: none; border: none; color: var(--text-muted); cursor: pointer;
  padding: 6px; border-radius: 6px; transition: background .12s, color .12s;
}
.ayuda-panel-close:hover { background: var(--surface-2); color: var(--text-default); }
/* §526: «Empezar de nuevo» con texto (antes un icono suelto que casi nadie veía). */
.ayuda-panel-nueva {
  display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px solid var(--border-2); color: var(--text-muted);
  cursor: pointer; padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; min-height: 32px; transition: background .12s, color .12s;
}
.ayuda-panel-nueva:hover { background: var(--surface-2); color: var(--text-default); }
/* §526: corte de conversación — lo anterior se queda arriba, en gris. */
.ayuda-anterior { opacity: .55; }
.ayuda-corte { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dimmed); margin: 6px 0; }
.ayuda-corte::before, .ayuda-corte::after { content: ''; flex: 1; border-top: 1px solid var(--border-2); }
.ayuda-panel-body { flex: 1; overflow-y: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }
.ayuda-msg { max-width: 88%; font-size: 14px; line-height: 1.45; }
.ayuda-msg-user {
  align-self: flex-end; background: var(--accent); color: #fff;
  padding: 9px 13px; border-radius: 12px 12px 2px 12px;
}
.ayuda-msg-bot {
  align-self: flex-start; background: var(--surface-2); color: var(--text-strong);
  padding: 9px 13px; border-radius: 12px 12px 12px 2px;
}
.ayuda-msg-bot p { margin: 0 0 8px; }
.ayuda-msg-bot p:last-child { margin-bottom: 0; }
/* §460: pasos numerados de una respuesta del catálogo "cómo usar el portal" (el panel es angosto). */
.ayuda-msg-bot ol.ayuda-pasos { margin: 0 0 8px; padding-left: 20px; }
.ayuda-msg-bot ol.ayuda-pasos li { margin: 0 0 4px; }
.ayuda-msg-cargando { display: flex; align-items: center; gap: 6px; color: var(--text-muted); }
.ayuda-link {
  background: none; border: none; padding: 0; margin-left: 4px;
  color: var(--accent-bright); font-size: 13px; font-weight: 600;
  cursor: pointer; font-family: inherit; text-decoration: underline;
}
.ayuda-link:hover { color: var(--accent); }
/* §368 (reglas del canal Ayuda): bajo la respuesta sólo las acciones de lo pedido, en orden (cliente,
   acción). Sin línea de origen ni notas: el aviso genérico vive fijo bajo el cuadro de texto. */
.ayuda-acciones { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; }
.ayuda-acciones .ayuda-link { margin-left: 0; }
.ayuda-chips { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.ayuda-chip {
  text-align: left; background: var(--surface-1); border: 1px solid var(--border-1);
  color: var(--text-default); border-radius: 8px; padding: 8px 10px; font-size: 13px;
  cursor: pointer; font-family: inherit;
}
.ayuda-chip:hover { border-color: var(--accent-bright); color: var(--accent-bright); }
/* §572: botón de una propuesta vencida (15 min): apagado, sin afordancia */
.ayuda-chip:disabled, .ayuda-chip.ayuda-chip-vencido { opacity: .55; cursor: default; border-color: var(--border-1); color: var(--text-dimmed); }
/* Chip no clickeable: mismo aspecto, sin afordancia — se usa cuando el
   registro se encontró pero su ficha no se puede abrir todavía (el addon
   dueño no cargó). Mejor mostrarlo apagado que ofrecer un botón muerto. */
.ayuda-chip-plano {
  text-align: left; background: var(--surface-1); border: 1px dashed var(--border-1);
  color: var(--text-muted); border-radius: 8px; padding: 8px 10px; font-size: 13px;
}
/* Título de grupo en "ver todo lo que puedo responder" (`1.6.0`). */
.ayuda-grupo-tit {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-dimmed); margin: 12px 0 2px;
}
/* Feedback 👍/👎 por respuesta (`1.6.0`). Discreto: no debe competir con la
   respuesta ni con el CTA, pero sí ser alcanzable en móvil. */
.ayuda-fb { display: flex; align-items: center; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.ayuda-fb-lbl { font-size: 11px; color: var(--text-dimmed); }
/* §397: tras un 👎, un cuadro opcional para contar qué esperaba la persona (sin opciones). */
.ayuda-fb-coment { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.ayuda-fb-txt { width: 100%; font-size: 14px; padding: 6px 8px; border: 1px solid var(--border-strong); border-radius: 8px; background: var(--surface-1); color: var(--text-default); resize: vertical; }
.ayuda-fb-btn {
  background: none; border: 1px solid var(--border-1); border-radius: 6px;
  cursor: pointer; font-size: 13px; line-height: 1; padding: 4px 8px;
  min-height: 28px; transition: border-color .12s, background .12s;
}
.ayuda-fb-btn:hover { border-color: var(--accent-bright); background: var(--surface-2); }
/* §399: el tema de la conversación ("Hablando de: …") arriba del cuadro, con su ✕ para empezar de cero. */
.ayuda-tema { display: flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 12px; color: var(--text-dimmed); border-top: 1px solid var(--border-strong); }
.ayuda-tema[hidden] { display: none; }
.ayuda-tema b { color: var(--text-default); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ayuda-tema-x { margin-left: auto; border: 0; background: transparent; color: var(--accent); cursor: pointer; font-size: 12px; font-weight: 600; min-height: 32px; padding: 0 8px; border-radius: 6px; white-space: nowrap; }
.ayuda-tema-x:hover { color: var(--text-default); background: var(--surface-2, transparent); }
.ayuda-panel-foot {
  display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--border-1);
  flex-shrink: 0; background: var(--surface-0);
}
.ayuda-panel-foot input {
  flex: 1; background: var(--surface-2); border: 1px solid var(--border-1); border-radius: 8px;
  padding: 10px 12px; font-size: 14px; color: var(--text-strong); min-height: var(--touch-target);
}
.ayuda-panel-foot input:focus { outline: none; border-color: var(--accent-bright); }
.ayuda-panel-aviso { flex-shrink: 0; padding: 0 12px 10px; font-size: 12px; color: var(--text-dimmed); text-align: center; background: var(--surface-0); }
@media (max-width: 768px) {
  .ayuda-panel {
    left: 0; right: 0; bottom: 0; top: 0;
    width: 100vw; height: 100vh; height: 100dvh;
    border-radius: 0;
  }
  .ayuda-panel-foot input { font-size: 16px; } /* anti-zoom iOS */
  .ayuda-panel-aviso { padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
}

/* ── Kanban (pipeline de oportunidades) ── */
.kanban-board {
  display: flex; gap: 14px;
  overflow-x: auto;
  padding-bottom: 14px;
  min-height: calc(100vh - 220px);
  min-height: calc(100dvh - 220px);
}
.kanban-col {
  flex: 0 0 280px;
  background: var(--surface-0);
  border: 1px solid var(--border-3);
  border-radius: 10px;
  display: flex; flex-direction: column;
  max-height: 100%;
}
.kanban-col-header {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-3);
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.kanban-col-title { font-size: 13px; font-weight: 600; color: var(--text-default); flex: 1; }
.kanban-col-count {
  font-size: 11px; color: var(--text-muted);
  background: var(--surface-raised); padding: 2px 8px; border-radius: 10px;
}
.kanban-col-total { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.kanban-col-body {
  flex: 1; overflow-y: auto; padding: 8px;
  display: flex; flex-direction: column; gap: 8px;
  min-height: 80px;
}
.kanban-col-body.drag-over { background: var(--surface-raised); outline: 2px dashed var(--accent-bright); outline-offset: -8px; }
.kanban-card {
  background: var(--surface-3);
  border: 1px solid var(--border-3);
  border-left: 3px solid var(--accent-bright);
  border-radius: 6px;
  padding: 10px 12px;
  cursor: grab;
  transition: border-color 0.12s, transform 0.12s, box-shadow 0.12s;
}
.kanban-card:hover { border-color: var(--accent-bright); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(var(--shadow-rgb),0.3); }
.kanban-card.dragging { opacity: 0.4; cursor: grabbing; }
.kanban-card-title { font-size: 13px; color: var(--text-strong); font-weight: 500; line-height: 1.3; }
.kanban-card-cliente { font-size: 11px; color: var(--text-soft); margin-top: 4px; display: flex; align-items: center; gap: 4px; }
.kanban-card-meta {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 8px; font-size: 11px;
}
.kanban-card-monto { color: var(--success); font-weight: 600; font-family: ui-monospace, monospace; }
.kanban-card-prob { color: var(--text-muted); }
.kanban-card-fecha { color: var(--text-muted); font-size: 10px; margin-top: 4px; }
.kanban-card-prio-alta { border-left-color: var(--danger); }
.kanban-card-prio-baja { border-left-color: var(--text-muted); }
.kanban-card-rotting { margin-top: 4px; }
/* Deal-rotting badge (Quick win #3): pill ámbar para señalar
   oportunidades/tickets sin movimiento por más tiempo del esperado.
   Patrón Pipedrive activity-based selling. */
.badge.badge-rotting {
  background: rgba(255,170,68,.14);
  color: var(--warning);
  border: 1px solid rgba(255,170,68,.32);
  font-size: 10px; font-weight: 600;
  padding: 2px 7px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 3px;
  vertical-align: middle;
}
.badge.badge-rotting .mi { font-size: 12px; }
/* Hover-reveal de "next action" en card de Kanban (Quick win #5):
   propietario + última actividad. Visible solo en hover (devices con
   hover capability) o siempre en touch (sin hover). */
.kanban-card-hover {
  display: flex; flex-wrap: wrap; gap: 4px 10px;
  margin-top: 0; padding-top: 0;
  max-height: 0; overflow: hidden; opacity: 0;
  border-top: 1px dashed transparent;
  transition: max-height .18s ease, opacity .15s ease, margin-top .18s ease, padding-top .18s ease, border-top-color .18s ease;
}
.kanban-card-hover .kanban-card-meta-row {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; color: var(--text-soft);
}
.kanban-card-hover .kanban-card-meta-row .mi { font-size: 13px; color: var(--text-muted); }
.kanban-card:hover .kanban-card-hover {
  max-height: 50px; opacity: 1;
  margin-top: 6px; padding-top: 6px;
  border-top-color: var(--border-1);
}
/* En touch devices (sin hover real) siempre visible para no quedarse oculto */
@media (hover: none) {
  .kanban-card-hover {
    max-height: 50px; opacity: 1;
    margin-top: 6px; padding-top: 6px;
    border-top-color: var(--border-1);
  }
}
.kanban-add-btn {
  background: none; border: 1px dashed var(--border-3);
  color: var(--text-muted); padding: 8px;
  border-radius: 6px; cursor: pointer; font-size: 12px;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.kanban-add-btn:hover { border-color: var(--accent-bright); color: var(--accent-bright); background: var(--surface-3); }

/* ── Timeline (actividades polimórficas) ── */
.timeline {
  position: relative;
  padding-left: 28px;
}
.timeline::before {
  content: ''; position: absolute;
  left: 11px; top: 6px; bottom: 6px;
  width: 2px; background: var(--border-3);
}
.timeline-item {
  position: relative;
  padding-bottom: 18px;
}
.timeline-item:last-child { padding-bottom: 0; }
.timeline-dot {
  position: absolute;
  left: -22px; top: 4px;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--surface-3);
  border: 2px solid var(--border-3);
  display: flex; align-items: center; justify-content: center;
}
.timeline-dot .mi { font-size: 14px; color: var(--text-muted); }
.timeline-item.tipo-llamada .timeline-dot { border-color: var(--accent-bright); }
.timeline-item.tipo-llamada .timeline-dot .mi { color: var(--accent-bright); }
.timeline-item.tipo-email .timeline-dot { border-color: var(--purple); }
.timeline-item.tipo-email .timeline-dot .mi { color: var(--purple); }
.timeline-item.tipo-reunion .timeline-dot { border-color: var(--warning-bright); }
.timeline-item.tipo-reunion .timeline-dot .mi { color: var(--warning-bright); }
.timeline-item.tipo-tarea .timeline-dot { border-color: var(--success); }
.timeline-item.tipo-tarea .timeline-dot .mi { color: var(--success); }
.timeline-item.tipo-nota .timeline-dot { border-color: var(--text-default); }
.timeline-item.tipo-nota .timeline-dot .mi { color: var(--text-default); }
.timeline-card {
  background: var(--surface-3);
  border: 1px solid var(--border-3);
  border-radius: 8px;
  padding: 12px 14px;
}
.timeline-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px;
}
.timeline-asunto { font-size: 13px; font-weight: 600; color: var(--text-strong); }
.timeline-fecha { font-size: 11px; color: var(--text-muted); flex-shrink: 0; }
.timeline-meta { font-size: 11px; color: var(--text-soft); margin-top: 4px; display: flex; gap: 10px; flex-wrap: wrap; }
.timeline-cuerpo { font-size: 13px; color: var(--text-default); margin-top: 8px; line-height: 1.5; white-space: pre-wrap; }
.timeline-empty {
  text-align: center; padding: 40px 16px;
  color: var(--text-muted); font-size: 13px;
  border: 1px dashed var(--border-3);
  border-radius: 8px;
}

/* ── Pipeline header / quick actions ── */
.pipeline-header {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.pipeline-stat {
  display: flex; flex-direction: column;
  padding: 8px 14px;
  background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px;
  min-width: 110px;
}
.pipeline-stat-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--text-muted); }
.pipeline-stat-value { font-size: 17px; color: var(--text-strong); font-weight: 600; font-family: ui-monospace, monospace; margin-top: 2px; }
.pipeline-stat-value.success { color: var(--success); }
.pipeline-stat-value.warn { color: var(--warning-bright); }
.pipeline-spacer { flex: 1; }

/* ── Toolbar / SegmentedControl ── */
.segctrl {
  display: inline-flex;
  background: var(--surface-0); border: 1px solid var(--border-3);
  border-radius: 8px; padding: 3px;
}
.segctrl button {
  background: none; border: none; color: var(--text-soft);
  padding: 5px 12px; font-size: 12px;
  border-radius: 5px; cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.segctrl button.active { background: var(--border-3); color: #fff; }

/* ── Hide legacy global search results dropdown (replaced by cmdk) ── */
.topbar-search, .topbar-search-results { display: none !important; }

/* ── Drawer detail rows (opportunidades / clientes / etc) ── */
.opp-detail { display: flex; flex-direction: column; gap: 2px; }
.opp-detail-row {
  display: grid; grid-template-columns: 22px 130px 1fr;
  gap: 10px; align-items: center;
  padding: 8px 4px;
  border-bottom: 1px solid #1e3a5f30;
}
.opp-detail-row:last-of-type { border-bottom: none; }
.opp-detail-row .mi { color: var(--text-muted); font-size: 16px; }
.opp-detail-label { color: var(--text-soft); font-size: 12px; text-transform: uppercase; letter-spacing: 0.4px; }
.opp-detail-value { color: var(--text-default); font-size: 13px; }
.opp-detail-desc { padding: 14px 4px 4px; }
.opp-detail-desc-body {
  margin-top: 6px; padding: 10px 12px;
  background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px;
  color: var(--text-default); font-size: 13px; line-height: 1.5;
  white-space: pre-wrap;
}

/* ── BOTTOM TAB BAR (portal cliente, mobile) ───────────────────── */
/* Patrón Slack/Airbnb: 5 destinos primarios en la zona del pulgar.
   Hidden por default; CSS lo activa solo en mobile. */
.bottom-tabs {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0;
  background: var(--bg-topbar); border-top: 1px solid var(--border-1);
  z-index: 80;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-shadow: 0 -4px 12px rgba(var(--shadow-rgb),.25);
}
.bottom-tab {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  gap: 2px; padding: 8px 4px 6px;
  /* var(--text-muted) sobre var(--bg-topbar) = ~5.2:1 (WCAG AA pass para texto <18px). El
     gris anterior daba ~4.0:1 — fallaba AA (se unificó a var(--text-muted)). */
  cursor: pointer; color: var(--text-muted); text-decoration: none;
  font-size: 11px; font-weight: 600;
  transition: color .12s; min-height: 52px;
  -webkit-tap-highlight-color: transparent;
  /* Reset de estilos de <button> para que se vea igual que un <a> */
  background: transparent; border: 0; appearance: none; -webkit-appearance: none;
  font-family: inherit; outline: none;
}
.bottom-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }
.bottom-tab .mi { font-size: 22px; transition: color .12s, transform .12s; }
.bottom-tab.active { color: var(--accent); }
.bottom-tab.active .mi {
  color: var(--accent);
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}
.bottom-tab-label { white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* ── RESPONSIVE / MOBILE ── */
.nav-toggle {
  display: none;
  background: transparent; border: none; color: var(--text-default);
  padding: 6px 10px; cursor: pointer; font-size: 22px;
  margin-right: 8px; border-radius: 8px;
}
.nav-toggle:hover { background: var(--surface-raised); }
.nav-toggle .mi { font-size: 24px; }
.sidebar-backdrop { display: none; }

/* Tablet (≤1024px): narrow the sidebar a touch and let content breathe */
@media (max-width: 1024px) {
  .sidebar { width: 220px; padding: 14px 10px; }
  .content { padding: 24px 22px; --sh-pad-top: 24px; }
  .topbar { padding: 0 18px; }
  .cmdk-trigger { min-width: 220px; }
  .topbar-search { width: 180px; }
  .dash-bottom-row { grid-template-columns: 1fr; }
  /* Importador wizard: stack source/destino panels and toolbars */
  .imp-source-tabs { grid-template-columns: 1fr; }
  /* Catálogos sidebar layout collapses earlier */
  .cat-layout { grid-template-columns: 1fr; }
}

/* ── Sidebar colapsable en desktop (Quick win #1) ────────────────────
   En mobile el .nav-toggle abre/cierra el drawer (body.nav-open).
   En desktop (>768px) colapsa el sidebar a 60px mostrando solo iconos
   (body.sidebar-collapsed). Persiste en localStorage.portal_sidebar_collapsed
   y se hidrata pre-paint para evitar flash. */
@media (min-width: 769px) {
  .nav-toggle { display: inline-flex; align-items: center; }

  body.sidebar-collapsed .sidebar {
    width: 60px;
    padding: 16px 6px;
    overflow: visible;
  }
  body.sidebar-collapsed .sidebar-group-label { display: none; }
  /* Modo iconos override (§80 Fase 2): los grupos colapsables son ortogonales
     al modo iconos. Aquí desactivamos el max-height:0 para que los nav-items
     se vean como iconos aunque el grupo "lógicamente" esté colapsado. */
  body.sidebar-collapsed .sidebar-group-items { max-height: none !important; transition: none !important; }
  body.sidebar-collapsed .sidebar-footer { padding: 8px 4px; border-top: none; }
  body.sidebar-collapsed .sidebar-copyright { display: none; }

  body.sidebar-collapsed .nav-item {
    justify-content: center;
    padding: 10px 0;
    position: relative;
  }
  body.sidebar-collapsed .nav-item > span:not(.mi) { display: none; }
  body.sidebar-collapsed .nav-item .mi { font-size: 22px; }

  /* Floating label en hover (reemplaza al label oculto). Más legible que
     el title="" nativo y consistente con el design system. */
  body.sidebar-collapsed .nav-item[data-label]:hover::after {
    content: attr(data-label);
    position: absolute;
    left: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    background: var(--surface-1);
    color: var(--text-strong);
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    border: 1px solid var(--border-1);
    box-shadow: 0 4px 12px rgba(var(--shadow-rgb),.4);
    pointer-events: none;
    z-index: 100;
    animation: navTooltipIn .12s ease-out;
  }
  @keyframes navTooltipIn {
    from { opacity: 0; transform: translate(-4px, -50%); }
    to   { opacity: 1; transform: translate(0, -50%); }
  }

  /* En modo Dirección el sidebar ya está minimal — no colapsamos más */
  body.viewmode-directivo.sidebar-collapsed .sidebar { width: 240px; padding: 16px 12px; }
  body.viewmode-directivo.sidebar-collapsed .nav-item { justify-content: flex-start; padding: 9px 14px; }
  body.viewmode-directivo.sidebar-collapsed .nav-item > span:not(.mi) { display: inline; }
}

/* Mobile (≤768px): full mobile layout */
@media (max-width: 768px) {
  /* Anti-zoom on focus (iOS): inputs ≥16px font-size to disable auto-zoom */
  .fg input, .fg select, .fg textarea,
  .login-box input, .setup-box input,
  .qe-input, .topbar-search, .cmdk-input-wrap input,
  .imp-filter-field, .imp-range-row input, .imp-text-row input.imp-filter-value,
  .role-input, .client-select, .periodo-select, .periodo-input,
  textarea.policy-dsl, .tag-input-field, .topbar-empresa-select,
  .icon-picker-search, .ss-search input { font-size: 16px; }

  /* ── Topbar: collapse to essentials ── */
  .nav-toggle { display: inline-flex; align-items: center; }
  .topbar { padding: 0 10px; gap: 8px; }
  .topbar h1 { font-size: 15px; gap: 4px; }
  .topbar h1 span:not(.mi) { display: none; }   /* "Dheko" / "Portal" word */
  .topbar .right { gap: 4px; flex-wrap: nowrap; }
  /* ⌘K trigger isn't useful on phones (no keyboard shortcut). Hide. */
  .cmdk-trigger { display: none; }
  /* ViewMode toggle is a desktop reporting affordance. Hide on phones. */
  .topbar .viewmode-switch { display: none; }
  .topbar-logo { display: none; }
  .topbar-empresa-select { min-width: 0; max-width: 130px; padding: 6px 8px; }
  .empresa-selector-wrap { min-width: 0; }
  /* User-menu trigger: solo avatar + chevron en mobile (sin nombre inline) */
  .user-name-inline { display: none; }
  /* §199 (auditoría 2026-09-16): en 400px el bloque derecho del topbar medía 506px
     con `nowrap` → toda la página hacía scroll horizontal (622px) aunque #content
     cabía. El topbar deja de ser una fila de alto fijo: el bloque derecho ocupa el
     ancho que sobra junto al botón del menú y acomoda sus controles en dos renglones
     (buscador + empresa / iconos + usuario). OJO: el `flex-wrap` va en `.right`, NO en
     `.topbar` — ahí mandaba todo el bloque debajo del botón del menú y salían tres
     renglones (137px) con el botón solo en el primero. */
  .topbar { height: auto; min-height: 56px; padding: 6px 10px; }
  .topbar .right { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; justify-content: flex-end; gap: 4px 8px; }
  /* El buscador cede ancho (110-180px) para caber junto al selector de empresa en el
     primer renglón; con los 130px fijos de abajo sumaban 318px en 315 disponibles y
     caía a tres renglones. Medido en 400px: topbar de 93px, dos renglones. */
  .topbar .right .topsearch-wrap { flex: 1 1 110px; min-width: 110px; }
  .topbar .right .topsearch-wrap .topsearch-input { width: 100%; min-width: 0; }
}
/* §217 (smoke 400px): con selector de empresa el bloque derecho mide ~220px y caía a TRES
   renglones (137px): buscador solo / empresa + 2 iconos / campana + usuario. En teléfono
   el buscador cede hasta 90px y va con la campana y el usuario en el primer renglón; el
   selector de empresa ocupa el segundo completo; tema y soporte se quitan del topbar
   (siguen en el menú del usuario / la sección). Medido: dos renglones. */
@media (max-width: 480px) {
  .topbar .right .topsearch-wrap { flex: 1 1 90px; min-width: 90px; }
  .topbar .right .empresa-selector-wrap { flex: 1 1 100%; order: 9; }
  .topbar .right .empresa-selector-wrap .topbar-empresa-select { max-width: none; width: 100%; }
  .topbar .right #themeToggleBtn, .topbar .right #userMenuSoporte { display: none; }
  .user-menu-trigger { padding: 4px; min-height: 40px; }
  .user-menu-dropdown { width: 240px; }
  /* Company-switcher button: hide username row, narrow it */
  .cs-btn { min-width: 0; padding: 6px 8px; gap: 6px; min-height: 40px; }
  /* Notif bell: touch target 40px */
  .notif-bell, .topbar-iconbtn { padding: 8px 10px; min-height: 40px; }
  .cs-username { display: none; }
  .cs-name { max-width: 90px; font-size: 12px; }
  .cs-avatar { width: 28px; height: 28px; font-size: 11px; }

  /* Notification dropdown — pin to viewport edges on mobile */
  .notif-dropdown {
    position: fixed; top: 70px; left: 8px; right: 8px; width: auto;
    max-height: calc(100vh - 80px);
  }
  /* Company switcher dropdown — same approach */
  .cs-dropdown {
    position: fixed; top: 70px; left: 8px; right: 8px; width: auto;
    min-width: 0; max-height: calc(100vh - 80px); overflow-y: auto;
  }
  /* Topbar search results dropdown */
  .topbar-search-results {
    position: fixed; top: 70px; left: 8px; right: 8px; width: auto;
  }

  /* ── Sidebar: slide-in drawer ── */
  .sidebar {
    position: fixed; top: 62px; left: 0; bottom: 0; z-index: 90;
    width: 280px; max-width: 88vw; transform: translateX(-100%);
    transition: transform .22s ease;
    overflow-y: auto;
    /* Account for iOS bottom safe area / browser chrome */
    padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }
  body.nav-open .sidebar { transform: translateX(0); box-shadow: 6px 0 20px rgba(var(--shadow-rgb),.5); }
  .sidebar-backdrop {
    display: block; position: fixed; inset: 62px 0 0 0; z-index: 85;
    background: rgba(0,10,20,.55); opacity: 0; pointer-events: none;
    transition: opacity .22s ease;
  }
  body.nav-open .sidebar-backdrop { opacity: 1; pointer-events: auto; }
  /* Sidebar items: bigger tap targets */
  .nav-item { padding: 12px 14px; font-size: 14px; }

  /* ── Content & general layout ── */
  .content { padding: 16px 12px; --sh-pad-top: 16px; }
  .layout { height: calc(100vh - 62px); height: calc(100dvh - 62px); overflow: hidden; }

  /* Modals: bottom-sheet feel */
  .overlay { align-items: flex-end; }
  .modal {
    padding: 18px; width: 100vw; max-width: 100vw;
    gap: 14px; max-height: 92dvh; border-radius: 16px 16px 0 0;
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    padding-top: 22px;
    animation: slideUpSheet .22s ease;
    touch-action: pan-y;
  }
  /* Handle bar visual (drag affordance estilo iOS/Material 3) */
  .modal::before {
    content: ''; position: absolute; top: 8px; left: 50%;
    transform: translateX(-50%);
    width: 36px; height: 4px; border-radius: 2px;
    background: var(--border-strong); pointer-events: none;
  }
  /* Si el usuario está arrastrando hacia abajo, seguimos el dedo */
  .modal.dragging { transition: none; }
  .modal.dismissing { animation: slideDownSheet .22s ease forwards; }
  @keyframes slideDownSheet { to { opacity: 0; transform: translateY(60px); } }
  @keyframes slideUpSheet { from { opacity:0; transform: translateY(40px); } to { opacity:1; transform: translateY(0); } }
  .modal h3 { font-size: 16px; }
  /* Stack buttons full-width on mobile. Keep them in flow (no sticky) —
     the modal already has overflow-y:auto so users can scroll to them.
     En flujo estático no hay fuga por detrás, así que anulamos el sangrado
     (margin/padding negativos) del footer de escritorio. */
  .modal-btns { flex-direction: column-reverse; align-items: stretch; gap: 8px; position: static; margin: 0; padding: 14px 0 0; border-radius: 0; }
  .modal-btns .btn { width: 100%; justify-content: center; min-height: 40px; }

  /* Forms: single column */
  .form-grid { grid-template-columns: 1fr; gap: 12px; }
  .form-grid .full { grid-column: 1; }
  .det-row { grid-template-columns: 1fr 1fr; gap: 6px; }
  .fiscal-grid { grid-template-columns: 1fr; }
  .iva-summary-row { grid-template-columns: 1fr auto; }

  /* Page title stacks with actions */
  .page-title { font-size: 18px; flex-wrap: wrap; gap: 8px; }
  .page-title .title-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }

  /* ── Tables: keep horizontal scroll, soften padding & add affordance ── */
  .table-head { padding: 12px 14px; gap: 8px; }
  .table-head h3 { font-size: 13px; }
  .card-table-head { padding: 12px 14px; gap: 8px; }
  th, td { padding: 9px 10px; }
  th { font-size: 10px; }
  td { font-size: 12px; }
  /* Smoother momentum scroll on iOS */
  .table-wrap { -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }

  /* Sticky first column en mobile (641-768px). Mantiene visible el
     identificador (folio/nombre/fecha) durante el scroll horizontal.
     IMPORTANTE: si la tabla tiene .chk-col (bulk-select) como primera
     columna, hacer sticky el checkbox vacío sería inútil — el folio
     queda en columna 2. Por eso usamos :not(:has(.chk-col)).
     En tablas con chk-col aplicamos sticky a la SEGUNDA columna. */
  .table-wrap table:not(:has(th.chk-col, td.chk-col)) th:first-child,
  .table-wrap table:has(th.chk-col, td.chk-col) th:nth-child(2) {
    position: sticky; left: 0; z-index: 3;
    background: var(--surface-2);
    box-shadow: 1px 0 0 var(--border-1), 4px 0 8px -4px rgba(var(--shadow-rgb),.4);
  }
  .table-wrap table:not(:has(th.chk-col, td.chk-col)) td:first-child,
  .table-wrap table:has(th.chk-col, td.chk-col) td:nth-child(2) {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface-1);
    box-shadow: 1px 0 0 var(--border-2), 4px 0 8px -4px rgba(var(--shadow-rgb),.3);
  }
  .table-wrap table:not(:has(th.chk-col, td.chk-col)) tr.clickable:hover td:first-child,
  .table-wrap table:has(th.chk-col, td.chk-col) tr.clickable:hover td:nth-child(2) { background: var(--surface-3); }
  /* Compact action column on touch */
  .td-actions { gap: 4px; flex-wrap: wrap; }
  .td-actions .btn-sm { padding: 8px 10px; min-height: 40px; }
  .smart-filters { padding: 8px 12px; gap: 6px; }

  /* Buttons & touch targets */
  .btn { padding: 10px 16px; font-size: 13px; min-height: 40px; }
  .btn-sm { padding: 8px 12px; font-size: 12px; min-height: 40px; }
  .search-input { font-size: 14px; padding: 9px 14px 9px 36px; }
  .select-compact { font-size: 14px; padding: 9px 14px; }
  /* Cierra los huecos < 44px de la auditoría móvil. Botones siguen el piso de
     40px de arriba; inputs/selects usan --touch-target (44px, declarado en
     :root y antes SIN uso). El chevron de edit-pill NO se fuerza a 44px: es un
     acelerador inline (§54) y agrandarlo distorsionaría las columnas de
     estatus — el camino requerido (Editar) ya vive en el menú Acciones. */
  .btn-xs { padding: 8px 10px; min-height: 40px; font-size: 12px; }
  .paginator .pg-nav .btn { min-height: 40px; min-width: 40px; padding: 8px 10px; }
  .chk-col input[type="checkbox"] { width: 24px; height: 24px; }
  /* Excluir checkbox/radio: son descendientes de .fg (chips de rol/empresa en
     el modal de Colaborador) y min-height:44px ganaría sobre su height:18px,
     deformándolos. Sólo inputs de texto/selects/textarea suben a 44px. */
  .fg input:not([type="checkbox"]):not([type="radio"]), .fg select, .fg textarea, .ss-trigger { min-height: var(--touch-target); }
  /* Buscador de select: filas y caja más grandes al tacto. */
  .ss-opt { min-height: var(--touch-target); }
  .ss-list { max-height: min(50vh, 320px); }

  /* Dashboard — solo properties que NO cubren clamp()/container queries.
     dash-hero-cards / .cards / .dash-metrics-grid: ya manejados por
     @container app-content (max-width: 460px) → 1col, ≤720px → 2col.
     dash-hero-val / dash-metric-val: clamp() ya regresa min-floor en
     viewports angostos. No duplicamos. */
  .dash-welcome { padding: 20px 18px; gap: 12px; }
  .dash-welcome > div:last-child { flex-shrink: 1; }
  .dash-hero-cards { gap: 10px; }
  .dash-hero-card { padding: 16px 12px; gap: 8px; }
  .dash-hero-icon { width: 42px; height: 42px; }
  .dash-hero-icon .mi { font-size: 22px; }
  .dash-hero-label { font-size: 10px; }
  .dash-metrics-card, .dash-alerts-card { padding: 16px; }
  .dash-metrics-grid { gap: 10px; }
  .dash-metric { padding: 14px 12px; }
  .dash-chart-bars { height: 140px; gap: 6px; }

  /* Detail header */
  .detail-header { padding: 18px 16px; gap: 14px; }
  .detail-avatar { width: 48px; height: 48px; font-size: 18px; }
  .detail-info .detail-name { font-size: 17px; }
  .detail-header-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }

  /* Tabs: scrollable horizontally */
  .tabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .tabs::-webkit-scrollbar { height: 0; }
  .tab { white-space: nowrap; padding: 9px 14px; font-size: 12px; }

  /* Periodo selector: stack */
  .periodo-wrap { flex-direction: column; align-items: stretch; gap: 8px; }
  /* `:not(.ss-native)`: el <select> nativo que esconde el enhancer (1px, absoluto) también es hijo
     directo — el 100% lo estiraba a todo el ancho y desbordaba 9px en 400px (smoke §202, cobranza). */
  .periodo-wrap > *:not(.ss-native) { width: 100%; }
  /* `.ss-native` es el <select> ORIGINAL que el enhancer esconde (1px, absoluto): el
     100% de aquí lo volvía a estirar y en 400px se salía 9px del documento (smoke §202).
     El control visible es el enhanceado; el nativo se queda escondido. */
  .periodo-select:not(.ss-native), .periodo-input { width: 100%; }

  /* Bulk bar */
  .bulk-bar { flex-wrap: wrap; gap: 8px; }

  /* Toast: full-width on mobile */
  .toast { left: 12px; right: 12px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }

  /* Drawer (slide-over): goes full screen */
  .drawer { width: 100% !important; }
  .drawer.drawer-wide { width: 100% !important; }
  .qe-drawer { width: 100%; max-width: 100%; }
  .mkt-drawer { width: 100%; max-width: 100%; }
  .cat-drawer { width: 100%; max-width: 100%; }
  .drawer-header, .drawer-body, .drawer-footer { padding-left: 16px; padding-right: 16px; }

  /* Command palette */
  .cmdk { top: 6vh; width: 96vw; max-height: 80vh; }

  /* Login / Setup */
  .login-box { width: 100%; padding: 24px; box-sizing: border-box; }
  .login-wrap { padding: 16px; box-sizing: border-box; }
  .setup-wrap { padding: 0; }
  .setup-box { padding: 1.25rem !important; }

  /* ── Bottom tab bar visible en mobile (portal cliente) ── */
  .bottom-tabs { display: flex; }
  /* Si hay bottom-tabs, ocultamos el hamburguesa del portal — la nav
     primaria ya está en pantalla. El sidebar drawer queda como
     respaldo si el módulo crece (futuras opciones secundarias).
     :has() es el primary; .has-bottom-tabs es fallback para Firefox<121
     (toggle aplicado por JS detectBottomTabs() en app.js). */
  body:has(.bottom-tabs) .nav-toggle,
  body.has-bottom-tabs .nav-toggle { display: none; }
  /* Reservamos espacio bajo el contenido para que la barra no tape
     la última fila de la tabla / botón "Guardar". */
  body:has(.bottom-tabs) .content,
  body.has-bottom-tabs .content { padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
  body:has(.bottom-tabs) .portal-footer,
  body:has(.bottom-tabs) .portal-footer-spacer,
  body.has-bottom-tabs .portal-footer,
  body.has-bottom-tabs .portal-footer-spacer { display: none; }
  /* El pill de loading sube para no chocar con la tab bar */
  body:has(.bottom-tabs) .loading-pill,
  body.has-bottom-tabs .loading-pill {
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
  }
  /* §658 Los avisos y el botón de Ayuda arriba de la barra (antes la tapaban o quedaban debajo). */
  body:has(.bottom-tabs) .toast,
  body.has-bottom-tabs .toast { bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
  body:has(.bottom-tabs) .ayuda-btn,
  body.has-bottom-tabs .ayuda-btn { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); right: 16px; }

  /* Portal action cards (inicio): 2 cols */
  .portal-action-cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .pac { padding: 16px 10px; }

  /* Portal footer respects safe area */
  .portal-footer {
    font-size: 10px; padding: 12px 16px;
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }
  .portal-footer-spacer { height: calc(40px + env(safe-area-inset-bottom, 0px)); }

  /* CSF mode selector: stack vertically */
  .csf-mode-selector { flex-direction: column; }
  .csf-mode-selector .csf-mode-btn:first-child { border-radius: 8px 8px 0 0; }
  .csf-mode-selector .csf-mode-btn:last-child  { border-radius: 0 0 8px 8px; }

  /* Exhibiciones: sin cabecera (no cabe) y el concepto a todo lo ancho; el resto
     comparte renglón para no volver la lista una torre de 4 campos por fila. */
  .hito-head { display: none; }
  .hito-row, .hitos-table.con-pct .hito-row { grid-template-columns: 1fr 1fr auto; }
  .hito-row .hito-label { grid-column: 1 / -1; }
  .hitos-controls { gap: 10px; }
  .hitos-controls .hito-money, .hitos-controls select { width: 100%; min-width: 0; }
  .hitos-ctrl { flex: 1 0 100%; }

  /* Importador */
  .imp-progress { gap: 4px; }
  .imp-step { padding: 5px 8px; font-size: 11px; }
  .imp-step-label { font-size: 11px; }
  .imp-step-sep { display: none; }
  .imp-body { padding: 14px; }
  .imp-step-head { gap: 8px; }
  .imp-search-wrap { min-width: 0; max-width: 100%; width: 100%; flex-basis: 100%; }   /* §658: sin la base, `flex:1` lo dejaba junto al título y se salía de la pantalla */
  .imp-context-head { flex-wrap: wrap; gap: 8px; padding: 10px; }
  .imp-context-arrow { display: none; }
  .imp-confirm-stats { grid-template-columns: repeat(2, 1fr); }
  .imp-dest-grid { grid-template-columns: 1fr; }
  .imp-source-tabs { grid-template-columns: 1fr; }
  .imp-map-toolbar { flex-direction: column; align-items: stretch; }
  .imp-history-row { flex-direction: column; align-items: stretch; gap: 8px; }
  .imp-history-actions { align-items: stretch; flex-direction: row; }
  .imp-confirm-actions { flex-direction: column-reverse; align-items: stretch; }
  .imp-confirm-actions-right { flex-direction: column-reverse; }

  /* Addons */
  .mkt-grid-row { grid-template-columns: 1fr; }
  .mkt-toolbar { gap: .5rem; }
  .mkt-search { min-width: 0; }

  /* Soporte methods */
  .soporte-methods { grid-template-columns: 1fr; }
  .soporte-step-divider { margin: 0 8px; }
  .soporte-steps { max-width: 100%; }
  .support-form-card { padding: 16px; }
  .support-form-actions { flex-direction: column-reverse; gap: 8px; }
  .support-form-actions .btn { width: 100%; justify-content: center; }

  /* Kanban: keep horizontal scroll but slimmer columns */
  .kanban-col { flex: 0 0 240px; }
  .kanban-board { gap: 10px; min-height: calc(100vh - 200px); min-height: calc(100dvh - 200px); }

  /* Pipeline header */
  .pipeline-header { gap: 8px; }
  .pipeline-stat { min-width: 0; flex: 1 1 130px; padding: 8px 10px; }

  /* Service / hero card grids */
  .cards-grid { grid-template-columns: 1fr; gap: 12px; padding: 12px 0; }
  .aging-cards { grid-template-columns: repeat(2, 1fr); }

  /* Dash welcome — periodo selector stacks under title */
  .periodo-wrap { margin-bottom: 14px; }

  /* Aviso/banner styles fit narrow */
  #preview-banner { font-size: .75rem; padding: 6px 10px; gap: 6px; flex-wrap: wrap; text-align: center; }

  /* Smart filters wrap, smaller */
  .smart-filter { font-size: 11px; padding: 5px 9px; }

  /* Filter buttons in lists */
  .filter-btn { font-size: 11px; padding: 5px 9px; }
}

/* Ultra-compact (≤480px) */
@media (max-width: 480px) {
  .topbar h1 { font-size: 14px; }
  .topbar h1 span.mi-xl { font-size: 22px; }
  .topbar .right strong { display: none; }
  .content { padding: 14px 10px; --sh-pad-top: 14px; }
  .modal { padding: 16px; padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
  .dash-hero-cards { grid-template-columns: 1fr; }
  .dash-metrics-grid { grid-template-columns: 1fr; }
  .portal-action-cards { grid-template-columns: 1fr; }
  .imp-confirm-stats { grid-template-columns: 1fr; }
  .login-box h2 { font-size: 18px; }
  .aging-cards { grid-template-columns: 1fr; }
  /* Notification button: tighter */
  .notif-bell, .topbar-iconbtn { padding: 6px 8px; }
  .notif-dropdown .notif-header { padding: 12px 14px 8px; font-size: 13px; }
  .notif-item { padding: 9px 10px; }
  /* Login: smaller logo */
  .login-logo { font-size: 20px; }
  .login-logo .mi { font-size: 26px; }
}

/* Print: keep it minimal — flatten layout for paper */
@media print {
  .topbar, .sidebar, .sidebar-backdrop, .nav-toggle,
  .notif-wrap, .cs-wrap, .cmdk-trigger, .viewmode-switch,
  .empresa-selector-wrap, .user-menu-wrap,
  .qe-row-overlay, .td-actions, .bulk-bar, .modal-btns,
  .table-footer, .smart-filters, .portal-footer { display: none !important; }
  body, .content { background: #fff !important; color: #000 !important; }
  .layout { display: block; height: auto; overflow: visible; }
  .content { padding: 0; overflow: visible; --sh-pad-top: 0px; }
  .table-wrap, .card, .info-card, .modal { box-shadow: none; border-color: #ccc; background: #fff; color: #000; }
  th, td { color: #000; border-color: #ccc; }
}

/* ── Catálogos admin UI (§5) ──────────────────────────────────── */
.cat-page { position: relative; }
.cat-layout { display: grid; grid-template-columns: 260px 1fr; gap: 16px; margin-top: 12px; }
@media (max-width: 900px) { .cat-layout { grid-template-columns: 1fr; } }

/* Sidebar */
.cat-sidebar { background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 8px; display: flex; flex-direction: column; max-height: 70vh; }
.cat-sidebar-head { padding: 10px; border-bottom: 1px solid var(--border-3); }
.cat-sidebar-list { flex: 1; overflow-y: auto; padding: 4px; }
.cat-sidebar-foot { padding: 8px; border-top: 1px solid var(--border-3); }
.cat-slug-item { display: flex; align-items: center; gap: 8px; width: 100%; padding: 10px 12px; background: transparent; border: none; border-radius: 6px; cursor: pointer; color: inherit; font: inherit; text-align: left; transition: background 0.1s; }
.cat-slug-item:hover { background: var(--surface-raised); }
.cat-slug-item.active { background: var(--surface-raised); color: var(--accent-bright); }
.cat-slug-item.active .mi { color: var(--accent-bright); }
.cat-slug-body { flex: 1; min-width: 0; }
.cat-slug-name { font-weight: 500; font-size: 13px; font-family: ui-monospace, monospace; }
.cat-slug-count { font-size: 11px; color: var(--text-muted); }

/* Main */
.cat-main { background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 8px; padding: 16px; min-height: 400px; }
.cat-main-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.cat-main-title h3 { margin: 0 0 6px; color: var(--text-strong); font-size: 18px; }
.cat-main-title h3 code { background: var(--surface-raised); padding: 2px 8px; border-radius: 4px; color: var(--warning-bright); font-size: 15px; }
.cat-bindings { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.cat-binding-chip { background: var(--surface-raised); border: 1px solid var(--border-3); border-radius: 4px; padding: 2px 8px; font-size: 11px; }
.cat-binding-chip code { color: var(--accent-bright); font-size: 10px; }
.cat-main-actions { display: flex; gap: 6px; align-items: center; }
.cat-inactive-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-soft); cursor: pointer; padding: 4px 8px; border-radius: 6px; }
.cat-inactive-toggle:hover { background: var(--surface-raised); }
.cat-inactive-toggle input { margin: 0; accent-color: var(--accent-bright); }

/* Empty states */
.cat-empty, .cat-empty-state { padding: 3rem 1rem; text-align: center; color: var(--text-soft); }
.cat-empty .mi-lg, .cat-empty-state .mi-lg { font-size: 48px !important; color: var(--accent-bright); margin-bottom: 8px; display: block; }
.cat-empty h3, .cat-empty-state h3 { margin: 0 0 8px; color: var(--text-strong); }

/* Tree */
.cat-tree { background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px; padding: 4px; min-height: 100px; }
.cat-row { border-radius: 4px; transition: background 0.1s; }
.cat-row.dragging { opacity: 0.5; }
.cat-row.drag-over > .cat-row-inner { background: var(--surface-raised); box-shadow: inset 0 0 0 2px var(--accent-bright); }
.cat-row.selected > .cat-row-inner { background: var(--surface-raised); }
.cat-row.inactive > .cat-row-inner { opacity: 0.55; }
.cat-row-inner { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 4px; min-height: 36px; }
.cat-row-inner:hover { background: var(--surface-raised); }
.cat-children { margin-left: 0; }

.cat-cb input { margin: 0; accent-color: var(--accent-bright); cursor: pointer; }
/* Drag handle: oculto hasta hover (mouse) o focus (teclado), visible
   siempre en touch. */
.cat-drag-handle { color: var(--text-muted); cursor: grab; transition: opacity 0.1s; }
@media (hover: hover) {
  .cat-drag-handle { opacity: .5; }
  .cat-row-inner:hover .cat-drag-handle,
  .cat-row-inner:focus-within .cat-drag-handle { opacity: 1; }
}
.cat-drag-handle:active { cursor: grabbing; }
.cat-expand { background: transparent; border: none; color: var(--text-soft); cursor: pointer; padding: 2px; display: inline-flex; align-items: center; justify-content: center; border-radius: 4px; }
.cat-expand:hover { background: var(--surface-raised); color: var(--text-strong); }
.cat-expand.hidden { visibility: hidden; }
.cat-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; border: 1px solid rgba(255,255,255,0.1); }
.cat-label { flex: 1; color: var(--text-strong); font-size: 13px; cursor: text; padding: 2px 4px; border-radius: 3px; }
.cat-label:hover { background: var(--surface-raised); }
.cat-inline-input { flex: 1; background: var(--surface-raised); border: 1px solid var(--accent-bright); color: var(--text-strong); padding: 4px 8px; border-radius: 4px; font-size: 13px; }
.cat-desc { color: var(--text-muted); cursor: help; }
.cat-usage { display: inline-flex; align-items: center; gap: 4px; color: var(--text-muted); font-size: 11px; cursor: pointer; padding: 2px 6px; border-radius: 4px; }
.cat-usage:hover { background: var(--surface-raised); color: var(--accent-bright); }
.cat-usage-n { font-weight: 600; }

/* Acciones de fila: ocultas hasta hover/focus, visibles siempre en touch. */
.cat-row-actions { display: flex; gap: 2px; transition: opacity 0.1s; }
@media (hover: hover) {
  .cat-row-actions { opacity: .55; }
  .cat-row-inner:hover .cat-row-actions,
  .cat-row-inner:focus-within .cat-row-actions { opacity: 1; }
}
.btn-xs { padding: 2px 6px; font-size: 11px; }
.btn-xs .mi { font-size: 14px !important; }

/* Kebab menu */
.cat-menu { position: fixed; background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 6px; box-shadow: 0 4px 16px rgba(var(--shadow-rgb),0.4); z-index: 1000; min-width: 180px; padding: 4px 0; }
.cat-menu button { display: flex; align-items: center; gap: 8px; width: 100%; background: transparent; border: none; color: var(--text-strong); padding: 8px 12px; text-align: left; cursor: pointer; font-size: 13px; }
.cat-menu button:hover { background: var(--surface-raised); }
.cat-menu button.danger { color: var(--danger); }

/* ── Menú de acciones de fila "Acciones ▾" (D1) ── */
.ra-wrap { display: inline-block; }
.ra-trigger { gap: 4px; }
.ra-trigger .ra-chev { font-size: 16px !important; transition: transform .12s ease; }
.ra-trigger[aria-expanded="true"] .ra-chev { transform: rotate(180deg); }
.row-menu { position: fixed; background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 8px; box-shadow: 0 6px 20px rgba(var(--shadow-rgb),0.45); z-index: 1100; min-width: 180px; padding: 4px 0; }
.row-menu .ra-item { display: flex; align-items: center; gap: 10px; width: 100%; background: transparent; border: none; color: var(--text-strong); padding: 10px 14px; text-align: left; cursor: pointer; font-size: 14px; font-family: inherit; }
.row-menu .ra-item:hover, .row-menu .ra-item:focus-visible { background: var(--surface-raised); outline: none; }
.row-menu .ra-item.danger { color: var(--danger); }
.row-menu .ra-item .mi { font-size: 18px; color: var(--text-muted); }
.row-menu .ra-item.danger .mi { color: var(--danger); }

/* D19: coach-marks de onboarding (globos guiados la 1ª vez). */
.coach-overlay { position: fixed; inset: 0; z-index: 3000; background: rgba(3,10,20,.72); }
.coach-ring { position: fixed; border: 2px solid var(--accent); border-radius: 10px; box-shadow: 0 0 0 4px rgba(var(--accent-rgb),.25); pointer-events: none; transition: all .25s ease; }
.coach-bubble { position: fixed; background: var(--surface-1); border: 1px solid var(--border-strong); border-radius: 12px; padding: 16px 18px; width: 320px; max-width: 92vw; box-shadow: 0 16px 40px rgba(var(--shadow-rgb),.55); }
.coach-bubble h4 { font-size: 15px; font-weight: 700; color: var(--text-strong); margin-bottom: 6px; display: flex; align-items: center; gap: 8px; }
.coach-bubble h4 .mi { color: var(--accent); }
.coach-bubble p { font-size: 13px; color: var(--text-subtle); line-height: 1.5; }
.coach-bubble-actions { display: flex; justify-content: space-between; align-items: center; margin-top: 14px; }
.coach-bubble-step { font-size: 12px; color: var(--text-muted); }

/* §86: Asistente de primer arranque (onboarding). Vista centrada, una sola
   tarjeta, lenguaje llano — el primer contacto de un dueño no técnico. */
.onb-wrap { display: flex; align-items: flex-start; justify-content: center; padding: 48px 16px 64px; min-height: 60vh; }
.onb-card { width: 100%; max-width: 560px; background: var(--surface-1); border: 1px solid var(--border-strong); border-radius: 16px; padding: 40px 36px 28px; box-shadow: 0 18px 48px rgba(var(--shadow-rgb),.45); text-align: center; }
.onb-hero-icon { width: 76px; height: 76px; margin: 0 auto 18px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, var(--accent), var(--accent)); box-shadow: 0 6px 20px rgba(44,90,160,.35); }
.onb-hero-icon .mi { font-size: 40px; color: var(--text-strong); }
.onb-hero-icon.onb-ok { background: linear-gradient(135deg, var(--success), var(--success)); box-shadow: 0 6px 20px rgba(46,163,106,.35); }
.onb-hero-icon.onb-ok .mi { color: var(--text-strong); }
.onb-title { font-size: 26px; font-weight: 700; color: var(--text-strong); margin: 0 0 8px; line-height: 1.25; }
.onb-lead { font-size: 16px; color: var(--text-default); line-height: 1.6; margin: 0 auto 18px; max-width: 460px; }
.onb-note { display: flex; gap: 10px; text-align: left; background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: 10px; padding: 12px 14px; font-size: 14px; color: var(--text-default); line-height: 1.55; margin: 0 0 20px; }
.onb-note .mi { color: var(--accent); font-size: 20px; flex: 0 0 auto; }
.onb-note b { color: var(--text-strong); }
.onb-preview { display: flex; gap: 10px; align-items: center; text-align: left; background: var(--warning-bg); border: 1px solid var(--warning); border-radius: 10px; padding: 10px 14px; font-size: 13.5px; color: var(--warning); line-height: 1.5; margin: 0 0 18px; }
.onb-preview .mi { color: var(--warning); font-size: 19px; flex: 0 0 auto; }
.onb-preview b { color: var(--text-strong); }
.onb-list { list-style: none; text-align: left; margin: 0 0 18px; padding: 14px 16px; background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 10px; max-height: 230px; overflow: auto; }
.onb-list li { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-default); padding: 4px 0; }
.onb-list li .mi { font-size: 18px; color: var(--text-subtle); }
.onb-error { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; text-align: left; background: var(--danger-bg); border: 1px solid var(--danger); border-radius: 10px; padding: 12px 14px; font-size: 14px; color: var(--text-default); line-height: 1.5; margin: 0 0 16px; }
.onb-error .mi { color: var(--danger); font-size: 20px; }
.onb-error a { color: var(--text-strong); text-decoration: underline; margin-left: auto; white-space: nowrap; }
.onb-steps-dots { display: flex; gap: 8px; justify-content: center; margin: 18px 0; }
.onb-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); transition: background .2s, transform .2s; }
.onb-dot.is-on { background: var(--accent); transform: scale(1.25); }
.onb-actions { display: flex; gap: 12px; justify-content: center; align-items: center; flex-wrap: wrap; }
.btn.btn-lg { font-size: 16px; padding: 12px 24px; border-radius: 10px; }
.btn.btn-lg .mi { font-size: 20px; vertical-align: middle; }
.onb-skip { display: block; margin: 16px auto 0; background: none; border: none; color: var(--text-muted); font-size: 13px; cursor: pointer; text-decoration: underline; }
.onb-skip:hover { color: var(--text-default); }
.onb-busy-hint { font-size: 13px; color: var(--text-muted); margin-top: 14px; }
.onb-spin { display: inline-block; animation: onb-spin 1s linear infinite; vertical-align: middle; }
@keyframes onb-spin { to { transform: rotate(360deg); } }
.onb-nextgrid { display: grid; grid-template-columns: 1fr; gap: 10px; text-align: left; margin: 8px 0 4px; }
.onb-next { display: grid; grid-template-columns: 28px 1fr; grid-template-rows: auto auto; column-gap: 12px; align-items: center; background: var(--surface-raised); border: 1px solid var(--border-strong); border-radius: 10px; padding: 14px 16px; cursor: pointer; transition: border-color .15s, transform .15s, background .15s; }
.onb-next:hover { border-color: var(--border-strong); background: var(--surface-raised); transform: translateY(-1px); }
.onb-next .mi { grid-row: 1 / span 2; font-size: 24px; color: var(--accent); }
.onb-next-t { font-size: 15px; font-weight: 600; color: var(--text-strong); }
.onb-next-d { font-size: 13px; color: var(--text-default); line-height: 1.45; }
@media (max-width: 600px) { .onb-card { padding: 28px 20px 22px; } .onb-title { font-size: 22px; } .onb-lead { font-size: 15px; } }

/* Add root */
.cat-add-root { display: flex; align-items: center; gap: 12px; margin-top: 10px; padding: 8px 4px; flex-wrap: wrap; }

/* Color palette */
.cat-color-palette { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.cat-color-swatch { width: 28px; height: 28px; border-radius: 6px; border: 2px solid transparent; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-raised); color: var(--text-muted); }
.cat-color-swatch:hover { transform: scale(1.1); }
.cat-color-swatch.selected { border-color: #fff; box-shadow: 0 0 0 2px var(--accent-bright); }

/* Bulk bar */
.cat-bulk-bar { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: var(--surface-raised); border: 1px solid var(--accent-bright); border-radius: 10px; padding: 10px 16px; display: flex; gap: 16px; align-items: center; box-shadow: 0 8px 24px rgba(var(--shadow-rgb),0.5); z-index: 900; }
.cat-bulk-actions { display: flex; gap: 6px; }

/* Undo toast */
.cat-undo-toast { position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%); background: var(--surface-3); border: 1px solid var(--success); border-radius: 8px; padding: 10px 16px; display: none; z-index: 950; box-shadow: 0 8px 24px rgba(var(--shadow-rgb),0.5); }
.cat-undo-toast.visible { display: block; }
.cat-undo-inner { display: flex; gap: 12px; align-items: center; color: var(--text-strong); font-size: 13px; }

/* Usage drawer */
.cat-drawer-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 940; }
.cat-drawer { position: fixed; top: 0; right: 0; width: 480px; max-width: 95vw; height: 100vh; height: 100dvh; background: var(--bg-page); border-left: 1px solid var(--border-3); box-shadow: -8px 0 24px rgba(var(--shadow-rgb),0.5); z-index: 950; overflow-y: auto; display: flex; flex-direction: column; }
.cat-drawer-head { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--border-3); }
.cat-drawer-title { font-size: 16px; font-weight: 700; color: var(--text-strong); }
.cat-drawer-body { flex: 1; overflow-y: auto; padding: 12px 0; }
.cat-usage-group { margin-bottom: 14px; }
.cat-usage-group-head { padding: 8px 20px; color: var(--text-soft); font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; background: var(--surface-0); }
.cat-usage-record { display: flex; align-items: flex-start; gap: 8px; padding: 10px 20px; border-bottom: 1px solid var(--border-strong); font-size: 13px; }
.cat-usage-record .mi { color: var(--accent-bright); margin-top: 2px; }

/* Form helpers dentro de modales */
.cat-form .fg { margin-bottom: 12px; }
.cat-parent-display { display: inline-flex; align-items: center; gap: 6px; color: var(--text-soft); font-size: 13px; padding: 6px 10px; background: var(--surface-0); border-radius: 6px; border: 1px solid var(--border-3); }

/* ── Catalog-aware select (§5 fase 3) ─────────────────────────── */
.cat-select { font-family: inherit; }
.cat-select option[data-create="1"] { color: var(--accent-bright) !important; font-style: italic; }
.cat-select option[value=""] { color: var(--text-muted); }

/* Popover inline-create */
.cat-select-popover { background: var(--surface-3); border: 1px solid var(--accent-bright); border-radius: 8px; box-shadow: 0 8px 24px rgba(var(--shadow-rgb),0.5); padding: 0; max-width: 360px; z-index: 1050; animation: catPopoverIn 0.12s ease-out; }
@keyframes catPopoverIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
.cat-select-popover-head { display: flex; align-items: center; gap: 6px; padding: 10px 12px; border-bottom: 1px solid var(--border-3); color: var(--text-strong); font-size: 13px; background: var(--surface-0); border-radius: 8px 8px 0 0; }
.cat-select-popover-head .mi { color: var(--accent-bright); }
.cat-select-popover-head code { background: var(--surface-raised); padding: 1px 6px; border-radius: 3px; color: var(--warning-bright); font-size: 10px; }
.cat-select-popover-body { padding: 12px; }
.cat-select-popover-body .fg { margin-bottom: 10px; }
.cat-select-popover-body .fg label { display: block; font-size: 11px; color: var(--text-soft); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.4px; font-weight: 600; }
.cat-select-popover-body input, .cat-select-popover-body select { width: 100%; background: var(--surface-0); border: 1px solid var(--border-3); color: var(--text-strong); padding: 6px 10px; border-radius: 6px; font-size: 13px; }
.cat-select-popover-body input:focus, .cat-select-popover-body select:focus { border-color: var(--accent-bright); outline: none; }
.cat-select-popover-actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border-3); }

/* Importador Fase 5: value map catalog-bound + unknown catalog panel */
.imp-vm-panel.cat-bound { border-left: 3px solid var(--success); }
.imp-vm-panel.cat-bound .imp-vm-head .badge-ok { font-size: 10px; margin-left: 8px; }
.imp-vm-entry select.imp-vm-tgt { min-width: 140px; }

.imp-unknown-panel { margin: 14px 0; background: var(--warning-bg); border: 1px solid var(--warning-bright); border-radius: 8px; }
.imp-unknown-panel > summary { padding: 12px 16px; cursor: pointer; display: flex; align-items: center; gap: 8px; color: var(--warning-bright); font-size: 13px; }
.imp-unknown-body { padding: 0 16px 14px; }
.imp-unknown-group { margin-bottom: 14px; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px; overflow: hidden; }
.imp-unknown-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--surface-3); border-bottom: 1px solid var(--border-3); font-size: 13px; }
.imp-unknown-head code { color: var(--warning-bright); background: var(--surface-raised); padding: 1px 6px; border-radius: 3px; font-size: 11px; }
.imp-unknown-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.imp-unknown-table th { text-align: left; padding: 6px 12px; background: var(--surface-0); color: var(--text-soft); font-weight: 600; font-size: 11px; text-transform: uppercase; }
.imp-unknown-table td { padding: 8px 12px; border-top: 1px solid var(--border-strong); color: var(--text-default); }
.imp-unknown-table td:last-child { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.imp-unknown-map { background: var(--surface-0); border: 1px solid var(--border-3); color: var(--text-strong); padding: 4px 8px; border-radius: 4px; font-size: 12px; min-width: 180px; }
.imp-unknown-bulk { margin-top: 10px; text-align: right; }

.text-warn { color: var(--warning-bright) !important; }

/* Mini paleta de color del popover */
.cat-pop-palette { display: flex; gap: 4px; flex-wrap: wrap; }
.cat-pop-swatch { width: 24px; height: 24px; border-radius: 5px; border: 2px solid transparent; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-raised); color: var(--text-muted); padding: 0; }
.cat-pop-swatch:hover { transform: scale(1.1); }
.cat-pop-swatch.selected { border-color: #fff; box-shadow: 0 0 0 2px var(--accent-bright); }

/* ── Quick Edit (drawer + row actions) ───────────────────────────── */

/* Backdrop translúcido */
.qe-backdrop {
  position: fixed; inset: 0; z-index: 1500;
  background: rgba(7, 14, 26, 0.55);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  animation: qe-fade-in .15s ease-out;
}
.qe-backdrop.hidden { display: none; }

/* Drawer lateral derecho */
.qe-drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: 420px; max-width: 92vw; z-index: 1600;
  background: var(--surface-3); border-left: 1px solid var(--border-3);
  box-shadow: -8px 0 24px rgba(var(--shadow-rgb), 0.45);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .22s cubic-bezier(.2, .8, .2, 1);
}
.qe-drawer.open { transform: translateX(0); }
/* Sombra fantasma en el borde DERECHO de la página: los drawers anclados a la
   derecha llevan box-shadow hacia la IZQUIERDA (-Xpx 0 …), que se dibuja FUERA
   del elemento. Cuando el drawer está cerrado (translateX(100%), fuera de pantalla
   a la derecha) esa sombra se derrama de vuelta ~30-50px sobre el viewport y se ve
   como una franja oscura pegada al borde derecho — en CUALQUIER pantalla, porque
   el quick-edit drawer existe siempre en el DOM. Fix: sombra SOLO cuando abierto. */
.qe-drawer:not(.open),
.drawer:not(.open),
.mkt-drawer.hidden { box-shadow: none; }

.qe-drawer-head {
  padding: 14px 16px; border-bottom: 1px solid var(--border-3);
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: linear-gradient(180deg, var(--surface-raised) 0%, var(--surface-3) 100%);
}
.qe-drawer-title { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1; }
.qe-drawer-icon {
  width: 32px; height: 32px; border-radius: 8px;
  background: rgba(var(--accent-bright-rgb), 0.15); color: var(--accent-bright);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; flex-shrink: 0;
}
.qe-drawer-entity { font-size: 11px; color: var(--text-soft); text-transform: uppercase; letter-spacing: .5px; font-weight: 600; }
.qe-drawer-subtitle { font-size: 14px; color: var(--text-strong); font-weight: 500; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qe-drawer-close {
  background: transparent; border: none; color: var(--text-soft); cursor: pointer;
  padding: 6px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center;
}
.qe-drawer-close:hover { background: var(--surface-raised); color: var(--text-strong); }

.qe-drawer-body { flex: 1; overflow-y: auto; padding: 16px; }
.qe-loading { display: flex; justify-content: center; padding: 40px 0; }
.qe-error { padding: 16px; background: rgba(239, 68, 68, 0.1); border: 1px solid rgba(239, 68, 68, 0.3); border-radius: 6px; color: var(--danger); font-size: 13px; }

.qe-form { display: flex; flex-direction: column; gap: 14px; }
.qe-field { display: flex; flex-direction: column; gap: 5px; }
.qe-label { font-size: 11px; color: var(--text-soft); text-transform: uppercase; letter-spacing: .4px; font-weight: 600; }
.qe-input {
  width: 100%; background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 6px;
  color: var(--text-strong); padding: 8px 11px; font-size: 13px; font-family: inherit;
  transition: border-color .12s ease;
}
.qe-input:focus { border-color: var(--accent-bright); outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-bright-rgb), 0.12); }

/* ── Campo CALCULADO en el drawer (§campo-derivado) ────────────────────────
   Se muestra con su valor (es contexto útil) pero sin input: ofrecer uno crea
   dos escritores del mismo dato — el drawer lo PATCHea y el siguiente guardado
   del modal lo recalcula y lo pisa. Lectura, no edición, y con el motivo a la
   vista para que no parezca un campo roto. */
.qe-input-readonly {
  background: var(--surface-1); color: var(--text-dimmed);
  border-style: dashed; cursor: default; user-select: text;
  display: flex; align-items: center;
}
.qe-field-derived .qe-label { color: var(--text-dimmed); }
.qe-hint {
  display: flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--text-dimmed);
}
.qe-hint .mi { font-size: 14px; }
.qe-textarea { resize: vertical; min-height: 60px; }

.qe-drawer-foot {
  padding: 12px 16px; border-top: 1px solid var(--border-3);
  background: var(--surface-3);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap;
}
.qe-drawer-hint { flex: 1; min-width: 0; }
.qe-drawer-actions { display: flex; gap: 8px; }

/* Row hover overlay (botones flotantes).
   Posicionado ARRIBA-DERECHA del row, ligeramente alzado, para no cubrir
   la columna td-actions existente (Ver/Editar/Eliminar). El JS coloca
   `top` en `rect.top - 4` y `left` en `rect.right - 8`; estos transforms
   mueven el overlay a su posición visual final. */
/* #5: las filas de tablas editables (QuickEdit) son clicables → abren la edición
   rápida. El cursor lo anuncia (las celdas de nombre/acciones tienen su propio cursor). */
table[data-qe] tbody tr { cursor: pointer; }
.qe-row-overlay {
  position: absolute; z-index: 50;
  display: flex; gap: 4px; padding: 4px;
  background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 8px;
  box-shadow: 0 4px 14px rgba(var(--shadow-rgb), 0.45);
  transform: translate(-100%, -100%);
  pointer-events: auto; user-select: none;
  animation: qe-fade-in .12s ease-out;
}
.qe-row-overlay.hidden { display: none; }
.qe-row-btn {
  background: transparent; border: none; cursor: pointer;
  padding: 8px; border-radius: 5px; color: var(--text-soft);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s ease, color .12s ease;
  min-width: 40px; min-height: 40px;
}
.qe-row-btn:hover { background: var(--surface-raised); color: var(--accent-bright); }
.qe-row-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.qe-row-btn .mi { font-size: 18px; }

/* Resaltar filas con quick edit habilitado */
table[data-qe] tr[data-id]:hover { background: var(--surface-raised); }

@keyframes qe-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Mobile: drawer ocupa toda la pantalla */
@media (max-width: 640px) {
  .qe-drawer { width: 100%; }
}

/* ────────────────────────────────────────────────────────────────────
   Modo de vista (Backoffice / Directivo) — segmented control + lens UI
   ──────────────────────────────────────────────────────────────────── */

/* Segmented control en topbar */
.viewmode-switch {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface-0); border: 1px solid var(--border-3); border-radius: 999px;
  align-items: stretch;
}
.viewmode-switch.hidden { display: none; }
.viewmode-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; font-size: 12px; font-weight: 500;
  background: transparent; border: none; color: var(--text-soft); cursor: pointer;
  border-radius: 999px; transition: all .14s ease; font-family: inherit;
  white-space: nowrap;
}
.viewmode-pill:hover { color: var(--text-strong); }
.viewmode-pill.on {
  background: var(--accent-bright); color: #fff;
  box-shadow: 0 1px 3px rgba(var(--accent-bright-rgb), 0.4);
}
.viewmode-pill.on:hover { color: #fff; }
.viewmode-pill .mi { font-size: 16px; }

/* ── Modo Directivo: lens read-only + densidad ejecutiva ─────────── */

/* Sidebar de Dirección: lo CONSTRUYE renderSidebar() (Tablero + Áreas), no se
   esconde con CSS. Las reglas viejas de display:none (que dejaban solo Dashboard
   y un sidebar casi vacío que "se veía fatal") se eliminaron — feedback del
   dueño 2026-06-16. */

/* Ocultar todo lo de edición/creación en cualquier vista */
body.viewmode-directivo .btn-edit,
body.viewmode-directivo .btn-del,
body.viewmode-directivo .btn-duplicate,
body.viewmode-directivo .btn-csv,
body.viewmode-directivo .td-actions,
body.viewmode-directivo .row-actions,
body.viewmode-directivo .qe-row-overlay,
body.viewmode-directivo .bulk-bar,
body.viewmode-directivo .modal-btns .btn-primary,
body.viewmode-directivo .drawer-foot .btn-primary {
  display: none !important;
}

/* "+ Nuevo X" buttons: estos siguen el patrón class="btn btn-primary"
   con onclick que abre modales de creación. Demasiado genérico para
   ocultar por clase — los ocultamos por su ubicación en page-title. */
body.viewmode-directivo .page-title .btn-primary { display: none !important; }

/* Quitar checkboxes de bulk en headers de tabla */
body.viewmode-directivo table th input[type="checkbox"],
body.viewmode-directivo table td input[type="checkbox"] {
  display: none !important;
}

/* Hover de filas: en Backoffice indica "click para editar"; en Directivo
   sólo es navegación, suaviza el hover. */
body.viewmode-directivo table[data-qe] tr[data-id]:hover {
  background: rgba(var(--accent-bright-rgb), 0.06);
  cursor: default;
}

/* Density ejecutiva: más respiro en el dashboard. Apunta a las clases
   reales del dashboard (dash-hero-card, dash-metric, dash-alert-item)
   en vez de nombres genéricos que no existían (.card, .hero-card). */
body.viewmode-directivo .content { padding: 32px 40px; max-width: 1400px; margin: 0 auto; --sh-pad-top: 32px; }
body.viewmode-directivo .page-title { font-size: 1.85rem; margin-bottom: 1.5rem; }

/* Hero cards (Clientes Activos, MRR, Facturado, etc.) */
body.viewmode-directivo .dash-hero-cards { gap: 18px; margin-bottom: 24px; }
body.viewmode-directivo .dash-hero-card { padding: 26px 28px; }
body.viewmode-directivo .dash-hero-val { font-size: 2.4rem; font-weight: 700; }
body.viewmode-directivo .dash-hero-label { font-size: 12px; letter-spacing: .4px; text-transform: uppercase; font-weight: 600; }
body.viewmode-directivo .dash-hero-sub { font-size: 13px; margin-top: 6px; }

/* Metrics secundarias (margen operativo, total clientes, etc.) */
body.viewmode-directivo .dash-metric { padding: 22px 26px; }
body.viewmode-directivo .dash-metric-val { font-size: 2.1rem; font-weight: 700; }
body.viewmode-directivo .dash-metric-label { font-size: 12px; letter-spacing: .4px; text-transform: uppercase; font-weight: 600; }

/* Alertas accionables — más prominentes para decision-first */
body.viewmode-directivo .dash-alert-item { padding: 14px 16px; }
body.viewmode-directivo .dash-alert-title { font-size: 14px; font-weight: 600; }
body.viewmode-directivo .dash-alert-desc { font-size: 12px; }

/* Section titles ("Resumen del negocio", "Pendientes") */
body.viewmode-directivo .dash-section-title { font-size: 14px; font-weight: 700; margin-bottom: 14px; }

/* Welcome block más relajado */
body.viewmode-directivo .dash-welcome { padding: 20px 24px; }
body.viewmode-directivo .dash-welcome-title { font-size: 1.5rem; }

/* Decision-first ordering (tendencia 2026): dentro de la fila inferior
   del dashboard, las alertas accionables suben arriba de las métricas.
   Y la fila se apila vertical en vez de side-by-side, para que la
   alerta tenga ancho completo y sea legible. La estructura DOM real:
       .dash-bottom-row (flex side-by-side)
         .dash-metrics-card
         .dash-alerts-card  ← lo subimos con order: -1   */
body.viewmode-directivo .dash-bottom-row { flex-direction: column; gap: 18px; }
body.viewmode-directivo .dash-bottom-row .dash-alerts-card { order: -1; }

/* Tablas read-only se ven más como reportes que como editables */
body.viewmode-directivo .table-wrap { background: transparent; border: none; }
body.viewmode-directivo .table-head h3 { font-size: 1rem; font-weight: 600; }

/* Filas clickables van con cursor pointer en backoffice; en directivo
   también, pero sin la indicación de "editar" */
body.viewmode-directivo .clickable[onclick] { cursor: pointer; }

/* Topbar: el toggle es el ancla, no quitamos otras cosas (notif sigue,
   empresa selector sigue — info útil para el director). Sí escondemos:
   - "Hola, admin": innecesario, no es presentación ejecutiva.
   - cmdk-trigger: el palette permitía bypassear el sidebar minimal (ir a
     cualquier sección o invocar acciones "Crear"). En lens read-only no
     tiene sentido. cmdkOpen() también valida la clase para bloquear ⌘K. */
body.viewmode-directivo .user-name-inline { display: none; }
body.viewmode-directivo .cmdk-trigger { display: none; }

/* En modal de detalle: ocultar SÓLO los botones de acción primaria
   (Editar, Guardar). El ghost (Cerrar/Cancelar) se queda para tener una
   forma explícita de cerrar, además del X y Esc. */
body.viewmode-directivo .modal-btns .btn-primary,
body.viewmode-directivo .qe-drawer-foot .qe-drawer-actions { display: none !important; }

/* ════════════════════════════════════════════════════════════
   PREFERS-REDUCED-MOTION — neutraliza animaciones largas
   Reduce a casi-cero los keyframes que mueven distancia o opacidad
   en transiciones largas. No quita transiciones cortas (<0.15s) —
   esas son percibidas como "feedback inmediato", no animación.
   ════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
  /* Las transiciones cortas se quedan; las largas (>200ms) se cortan */
  .modal, .drawer, .qe-drawer, .mkt-drawer, .cat-drawer,
  .cmdk, .cmdk-scrim, .drawer-scrim, .qe-backdrop,
  .sidebar, .sidebar-backdrop, .notif-dropdown, .cs-dropdown,
  .toast, .loading-pill, .skeleton {
    transition-duration: 0.01ms !important;
    animation: none !important;
  }
  /* Skeleton: sin shimmer pero mantiene el tinte */
  .skeleton { background: var(--surface-raised) !important; }
}

/* ════════════════════════════════════════════════════════════
   CARD-VIEW DE TABLAS (≤640px) — UX Movement / NN/g 2026
   Cada <tr> de una tabla en .table-wrap se transforma en una
   tarjeta vertical: <thead> oculto, cada <td> en línea con su
   label (data-label inyectado por _autoLabelTables en app.js).
   Aplica solo a teléfonos en portrait — en tablet/desktop la
   tabla mantiene su layout normal (con scroll horizontal y
   sticky first column).
   ════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* Cancelamos el chrome de la tabla — cada fila es su propia tarjeta */
  .table-wrap {
    background: transparent; border: 0; box-shadow: none;
    overflow: visible; border-radius: 0;
  }
  .table-wrap .table-head {
    background: transparent; padding: 0 4px 12px;
    border-bottom: 0;
  }
  .table-wrap table,
  .table-wrap thead,
  .table-wrap tbody,
  .table-wrap tr,
  .table-wrap td { display: block; width: auto; }

  /* <thead> visualmente oculto pero accesible para lectores */
  .table-wrap thead {
    position: absolute; left: -9999px;
    width: 1px; height: 1px; overflow: hidden;
    clip: rect(0,0,0,0); white-space: nowrap;
  }

  /* Cancelamos sticky-first (en card view no aplica) */
  .table-wrap table th:first-child,
  .table-wrap table td:first-child {
    position: static; box-shadow: none; background: transparent;
  }

  /* Cada fila = una tarjeta */
  .table-wrap tbody tr {
    background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px;
    padding: 12px 14px; margin-bottom: 10px;
    box-shadow: 0 1px 4px rgba(var(--shadow-rgb),.18);
  }
  .table-wrap tbody tr:hover td { background: transparent; }
  .table-wrap tbody tr.clickable { cursor: pointer; }

  /* Cada celda = una línea label : valor */
  .table-wrap tbody td {
    padding: 6px 0; border: 0;
    display: flex; align-items: flex-start; gap: 12px;
    font-size: 13px; color: var(--text-strong); min-height: auto;
  }
  .table-wrap tbody td::before {
    content: attr(data-label);
    flex-shrink: 0; width: 90px;
    font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
    color: var(--text-muted); font-weight: 700; padding-top: 2px;
  }
  /* Si no hay label útil, no reservamos columna izquierda */
  .table-wrap tbody td:not([data-label])::before,
  .table-wrap tbody td[data-label=""]::before { display: none; }

  /* Primer celda más prominente (suele ser nombre/folio) */
  .table-wrap tbody tr > td:first-child { font-weight: 600; font-size: 14px; padding-bottom: 10px; }
  .table-wrap tbody tr > td:first-child::before {
    width: 90px; padding-top: 4px;
  }

  /* §206: la celda-título trae la tira de acciones estilo WordPress (§190/§201). En
     la tarjeta el título va en su renglón y la tira DEBAJO, envolviendo — no al lado
     del rótulo ni en un solo renglón de 370px (la regla de escritorio la pone nowrap). */
  .table-wrap tbody td.td-title { flex-wrap: wrap; }
  .table-wrap tbody td.td-title .row-actions { flex: 1 1 100%; flex-wrap: wrap; white-space: normal; margin-top: 4px; }

  /* Acciones: full-width, separador superior */
  .table-wrap tbody td.td-actions {
    border-top: 1px solid var(--border-1);
    margin-top: 8px; padding-top: 10px;
    justify-content: flex-end; gap: 6px; flex-wrap: wrap;
  }
  .table-wrap tbody td.td-actions::before { display: none; }

  /* Checkbox column (bulk select): arriba a la derecha */
  .table-wrap tbody td.chk-col {
    position: absolute; top: 12px; right: 14px;
    padding: 0; min-height: 0;
  }
  .table-wrap tbody td.chk-col::before { display: none; }
  .table-wrap tbody tr { position: relative; }

  /* Logos / avatares dentro de tablas: alinear con valor */
  .table-wrap tbody td .tbl-cell-logo { gap: 8px; }

  /* Filas vacías ("Sin resultados") siguen full-width sin cards */
  .table-wrap tbody tr:has(.empty-row),
  .table-wrap tbody tr td.empty-row { display: block; }
  .table-wrap tbody tr:has(.empty-row) {
    background: transparent; border: 1px dashed var(--border-1);
  }
  .table-wrap tbody td.empty-row { text-align: center; padding: 28px 16px; }
}

/* ════════════════════════════════════════════════════════════
   PULL-TO-REFRESH (mobile) — indicador flotante
   ════════════════════════════════════════════════════════════ */
.ptr-indicator {
  position: fixed; top: 62px; left: 50%;
  transform: translate(-50%, -40px) rotate(0);
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--surface-1); border: 1px solid var(--border-1);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); font-size: 18px;
  z-index: 95; opacity: 0; pointer-events: none;
  box-shadow: 0 4px 14px rgba(var(--shadow-rgb),.4);
}
.ptr-indicator .mi { font-size: 20px; transition: transform .15s ease; }
.ptr-indicator.ready { background: var(--surface-3); border-color: var(--accent); }
.ptr-indicator.ready .mi { color: var(--success); }
.ptr-indicator.refreshing { background: var(--surface-3); border-color: var(--accent); }
.ptr-indicator .spinner { margin: 0; border-color: var(--border-1); border-top-color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .ptr-indicator { transition: none !important; }
}

/* ════════════════════════════════════════════════════════════════
   DASHBOARD v2 — sparklines, deltas, insights, aging buckets,
   empty states. Greenfield 2026 (Linear/Attio/HubSpot patrones).
   ════════════════════════════════════════════════════════════════ */

/* Hero head: contiene el icon + (delta opcional) en la cabecera de la
   hero card. Permite que el delta vs periodo previo viva al lado del
   icon sin alterar el layout vertical clásico de label/val/sub. */
.dash-hero-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; margin-bottom: 4px;
}
.dash-hero-head .dash-hero-icon { margin-bottom: 0; }

/* Sparkline SVG — full-width al pie de la hero card. Bloquea pointer
   events para no robar el click del card (que es onclick a showSection). */
.dash-spark {
  display: block; width: 100%; height: 22px; margin-top: 6px;
  pointer-events: none;
}

/* Delta vs periodo anterior — pill compacta arriba a la derecha. */
.dash-delta {
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px;
  white-space: nowrap; line-height: 1; letter-spacing: .2px;
  display: inline-flex; align-items: center; gap: 3px;
}
.dash-delta-up    { background: rgba(46,213,115,.14);  color: var(--success); }
.dash-delta-down  { background: rgba(255,107,107,.14); color: var(--danger); }
.dash-delta-flat  { background: rgba(122,141,160,.12); color: var(--text-muted); }
.dash-delta-new   { background: rgba(var(--accent-rgb),.14); color: var(--accent); }
/* Magnitud absoluta junto al delta % (opt-in vía showAbs=true). */
.dash-delta-abs   { font-weight: 600; opacity: .85; letter-spacing: 0; }

/* Trend label — pill que clasifica la sparkline en una de 4 etiquetas
   (Sube/Baja/Estancado/Inestable). Se renderiza junto al sparkline para
   que el usuario no tenga que "leer" la curva. Patrón Pipedrive 2026
   (deal-rotting extendido a métricas). Inspirado en infografía
   "5 preguntas que un dashboard profesional responde". */
.dash-trend {
  font-size: 10.5px; font-weight: 700; padding: 2px 7px 2px 5px;
  border-radius: 999px; white-space: nowrap; line-height: 1;
  letter-spacing: .2px; display: inline-flex; align-items: center;
  gap: 3px; margin-top: 4px;
}
.dash-trend .mi { font-size: 13px; }
.dash-trend-good     { background: rgba(46,213,115,.14);  color: var(--success); }
.dash-trend-bad      { background: rgba(255,107,107,.14); color: var(--danger); }
.dash-trend-flat     { background: rgba(122,141,160,.12); color: var(--text-muted); }
.dash-trend-volatile { background: rgba(245,158,11,.14);  color: var(--warning); }

/* En modo Dirección los micro-señales se ocultan junto con .dash-spark
   y .dash-delta — el ejecutivo lee números grandes, no etiquetas. */
body.viewmode-directivo .dash-trend { display: none; }

/* Hero card en estado vacío — onboarding inline (NN/g 2026).
   Ícono atenuado y CTA principal para que el primer paint del
   dashboard ya muestre la ruta a hidratar el bloque. */
.dash-hero-empty .dash-hero-icon-empty {
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-3)) !important;
  color: var(--text-muted);
}
.dash-hero-empty-msg {
  font-size: 12px; color: var(--text-muted); line-height: 1.4; margin-top: 2px;
  flex: 1; display: flex; align-items: center;
}

/* Empty state global — cuando el tenant no tiene datos. Centro de
   pantalla, ícono grande, dos CTAs (crear / importar). Reemplaza
   completamente al dashboard cuando cli/ctr/vta están vacíos. */
.dash-empty-global {
  background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface-1) 100%);
  border: 1px solid var(--border-1); border-radius: 16px;
  padding: 56px 32px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.dash-empty-icon {
  width: 72px; height: 72px; border-radius: 18px;
  background: linear-gradient(180deg, var(--border-1), var(--surface-1));
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 6px;
}
.dash-empty-icon .mi { font-size: 36px; color: var(--accent); }
.dash-empty-title { font-size: 22px; font-weight: 800; color: var(--text-strong); }
.dash-empty-desc { font-size: 14px; color: var(--text-muted); max-width: 460px; line-height: 1.5; }
.dash-empty-ctas { display: flex; gap: 10px; margin-top: 8px; flex-wrap: wrap; justify-content: center; }

/* Daily summary card (Quick win #2) — frase narrativa con 1-3 hechos
   del día arriba del dashboard. Patrón Stripe/Folk: lo primero que el
   usuario lee al abrir el portal es "qué pasó", no decoración.
   El borde-izquierdo cambia de color según el peor caso entre los hechos. */
.dash-summary {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--surface-1); border: 1px solid var(--border-1); border-left-width: 3px;
  border-radius: 10px; padding: 12px 16px;
  margin-bottom: 16px;
  font-size: 13px; line-height: 1.55;
}
.dash-summary-urgent  { border-left-color: var(--danger); }
.dash-summary-neg     { border-left-color: var(--warning); }
.dash-summary-pos     { border-left-color: var(--success); }
.dash-summary-neutral { border-left-color: var(--accent); }
.dash-summary-icon { color: var(--text-muted); margin-top: 1px; }
.dash-summary-urgent .dash-summary-icon { color: var(--danger); }
.dash-summary-neg    .dash-summary-icon { color: var(--warning); }
.dash-summary-pos    .dash-summary-icon { color: var(--success); }
.dash-summary-text { flex: 1; color: var(--text-default); }
.dash-summary-greet { color: var(--text-strong); font-weight: 600; margin-right: 6px; }
.dash-summary-fact { color: var(--text-default); }
.dash-summary-fact.dash-summary-urgent { color: var(--danger); }
.dash-summary-fact.dash-summary-neg    { color: var(--warning); }
.dash-summary-fact.dash-summary-pos    { color: var(--success); }
.dash-summary-sep { color: var(--text-muted); margin: 0 8px; }
/* En modo Dirección la card se hace más prominente (números grandes). */
body.viewmode-directivo .dash-summary {
  padding: 18px 22px; font-size: 15px; margin-bottom: 24px;
}

/* Insights panel — top 3 actionable insights arriba de heroes/metrics.
   Cada card es clickeable a la sección relevante. Borde coloreado por
   severidad (danger/warning/info/success), inspirado en Folk/Attio. */
.dash-insights-panel {
  background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px;
  padding: 16px 18px; margin-bottom: 20px;
}
.dash-insights-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.dash-insight {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 14px; background: var(--surface-1);
  border: 1px solid var(--border-1); border-radius: 10px;
  transition: background .15s ease, border-color .15s ease;
}
.dash-insight.clickable { cursor: pointer; }
.dash-insight.clickable:hover { background: var(--surface-raised); border-color: var(--border-strong); }
.dash-insight-title { font-size: 13px; font-weight: 700; color: var(--text-strong); line-height: 1.3; }
.dash-insight-desc  { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; line-height: 1.4; }
.dash-insight-danger  { border-left: 3px solid var(--danger); }
.dash-insight-warning { border-left: 3px solid var(--warning); }
.dash-insight-info    { border-left: 3px solid var(--accent); }
.dash-insight-success { border-left: 3px solid var(--success); }

/* AR Aging buckets — stacked horizontal bar + leyenda inline.
   Inspirado en QuickBooks/Xero. La barra es full-width, segmentos
   proporcionales, hover muestra tooltip con monto+%. */
.dash-aging-bar {
  display: flex; width: 100%; height: 22px;
  background: var(--surface-1); border: 1px solid var(--border-1);
  border-radius: 6px; overflow: hidden; margin-top: 12px;
}
.dash-aging-seg {
  height: 100%; transition: opacity .15s ease;
  border-right: 1px solid rgba(0,0,0,.25);
}
.dash-aging-seg:last-child { border-right: none; }
.dash-aging-seg:hover { opacity: .85; }
.dash-aging-legend {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px 14px; margin-top: 12px;
}
.dash-aging-leg-item {
  display: flex; align-items: center; gap: 6px; font-size: 11.5px;
}
.dash-aging-leg-dot {
  width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0;
}
.dash-aging-leg-label { color: var(--text-muted); flex: 1; }
.dash-aging-leg-value { color: var(--text-strong); font-weight: 700; }
.dash-aging-leg-pct   { color: var(--text-muted); font-size: 10.5px; }

/* Modo Directivo: lens UI ejecutivo. Sparklines y deltas son ruido
   en vista decision-first — el director quiere el número y el insight,
   no la serie temporal. Insights SÍ se quedan (son la decisión). */
body.viewmode-directivo .dash-spark,
body.viewmode-directivo .dash-metric-spark { display: none; }
body.viewmode-directivo .dash-hero-head .dash-delta,
body.viewmode-directivo .dash-metric-label .dash-delta { display: none; }
/* Los insights se hacen más prominentes y suben antes que heroes */
body.viewmode-directivo .dash-insights-panel { padding: 20px 22px; margin-bottom: 28px; }
body.viewmode-directivo .dash-insight-title { font-size: 14.5px; }
body.viewmode-directivo .dash-insight-desc { font-size: 12.5px; }

/* Responsive — apilar empty CTAs en mobile */
@media (max-width: 640px) {
  .dash-empty-global { padding: 36px 18px; }
  .dash-empty-title { font-size: 18px; }
  .dash-empty-ctas { flex-direction: column; width: 100%; }
  .dash-empty-ctas .btn { width: 100%; justify-content: center; }
  .dash-aging-legend { grid-template-columns: 1fr 1fr; }
}

/* Overflow handling para hero card values: nombres largos del ejecutivo
   (.dash-hero-name) usan line-clamp; números grandes ($1,234,567) usan
   tabular-nums + nowrap + ellipsis para no romper layout. Bug fix audit. */
.dash-hero-name {
  font-size: 1.05rem !important;
  line-height: 1.3 !important;
  word-break: break-word;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 100%;
}
.dash-hero-num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
/* Sparkline: limitar al ancho del card en viewports muy chicos (320px). */
.dash-spark { max-width: 100%; height: auto; }

/* role=button affordance: focus outline visible en hero cards y métricas
   clickeables (anteriormente sólo onclick sin tabindex; bug fix audit). */
.dash-hero-card[role="button"]:focus-visible,
.dash-metric[role="button"]:focus-visible,
.dash-insight[role="button"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── Cash plan 13 semanas — tabla densa con saldo running. Scroll
   horizontal en mobile para preservar legibilidad. */
.dash-13w-table-wrap {
  margin-top: 12px;
  overflow-x: auto;
  border: 1px solid var(--border-1);
  border-radius: 8px;
}
.dash-13w-table {
  width: 100%; border-collapse: collapse;
  font-size: 12px;
}
.dash-13w-table th, .dash-13w-table td {
  padding: 8px 12px;
  text-align: left;
  border-bottom: 1px solid var(--border-strong);
}
.dash-13w-table th {
  background: var(--surface-1); color: var(--text-muted);
  font-weight: 700; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .4px;
  position: sticky; top: 0;
}
.dash-13w-table tbody tr:hover { background: var(--surface-raised); }
.dash-13w-table tbody tr:last-child td { border-bottom: none; }
.dash-13w-table .text-right { text-align: right; }
@media (max-width: 640px) {
  .dash-13w-table { font-size: 11px; }
  .dash-13w-table th, .dash-13w-table td { padding: 6px 8px; }
}

/* ─────────────────────────────────────────────────────────────────────────────
 * Addon proyectos — Reportes gallery (tab Reportes → grid de project cards)
 * Cada proyecto activo tiene su reporte vivo siempre accesible. Click en card
 * → detail view live. En modo Directivo se ve polished (Code Wiki style);
 * en modo Operación va más denso.
 * ─────────────────────────────────────────────────────────────────────────── */
.rpt-gallery-intro { margin: 8px 0 20px; max-width: 720px; }

/* Hero ejecutivo de Reportes (modo Directivo). Patrón "agency monthly review":
   eyebrow pequeño con periodo + 6 stats grandes en grid. Sin sparklines,
   sin micro-decoración — scan rápido. */
.rpt-dirhero {
  margin: 16px 0 32px; padding: 28px 30px;
  background: linear-gradient(135deg, var(--surface-3) 0%, var(--surface-0) 100%);
  border: 1px solid var(--border-1);
  border-radius: 14px;
}
.rpt-dirhero-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: .25em;
  color: var(--success); margin-bottom: 22px;
}
.rpt-dirhero-stats {
  display: grid; grid-template-columns: repeat(6, 1fr);
  gap: 28px; align-items: end;
}
.rpt-dirhero-stat { text-align: left; }
.rpt-dirhero-n {
  font-size: 2.6rem; font-weight: 700; color: var(--success);
  line-height: 1; margin-bottom: 6px;
}
.rpt-dirhero-l {
  font-size: 10.5px; font-weight: 600; letter-spacing: .12em;
  color: var(--text-dimmed); text-transform: uppercase;
}
.rpt-dirhero-risk {
  margin-top: 18px; padding: 8px 12px;
  background: rgba(248,113,113,.08); border: 1px solid rgba(248,113,113,.2);
  border-radius: 8px; color: var(--danger); font-size: 12.5px;
  display: inline-flex; align-items: center; gap: 6px;
}
@media (max-width: 1100px) {
  .rpt-dirhero-stats { grid-template-columns: repeat(3, 1fr); gap: 20px; }
  .rpt-dirhero-n { font-size: 2.1rem; }
}
@media (max-width: 600px) {
  .rpt-dirhero-stats { grid-template-columns: repeat(2, 1fr); }
}

/* Título de sección con número grande (patrón "01 · Proyectos"). Sólo en
   modo Directivo, para el "Proyectos" header debajo del hero. */
.rpt-section-title {
  display: flex; align-items: baseline; gap: 14px;
  font-size: 2rem; font-weight: 600; color: var(--text-strong);
  margin: 16px 0 22px;
}
.rpt-section-num {
  color: var(--success); font-size: 12px; font-weight: 700;
  letter-spacing: .15em;
}

/* Buscador de la galería de reportes. Vive justo arriba del grid. */
.rpt-search {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; margin-bottom: 18px;
  background: var(--surface-1); border: 1px solid var(--border-1);
  border-radius: 10px; max-width: 480px;
}
.rpt-search .mi { color: var(--text-dimmed); }
.rpt-search input {
  flex: 1; background: transparent; border: none; outline: none;
  color: var(--text-strong); font-size: 14px; padding: 4px 0;
}
.rpt-search input::placeholder { color: var(--text-dimmed); }
.rpt-search #rptSearchCount { white-space: nowrap; }

.rpt-gallery-empty {
  text-align: center; padding: 64px 24px; color: var(--text-subtle);
  border: 1px dashed var(--border-1); border-radius: 12px;
  background: var(--surface-1);
}
.rpt-gallery-empty h3 { color: var(--text-strong); margin: 16px 0 4px; }
.rpt-gallery {
  display: grid; gap: 14px; margin-top: 8px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.rpt-card {
  background: var(--surface-1);
  border: 1px solid var(--border-1); border-radius: 10px;
  padding: 18px; cursor: pointer; transition: all .15s ease;
  display: flex; flex-direction: column; gap: 10px;
  outline: none;
}
.rpt-card:hover, .rpt-card:focus-visible {
  border-color: var(--accent); background: var(--surface-3);
}
.rpt-card-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 10px;
}
.rpt-card-title { font-weight: 600; color: var(--text-strong); font-size: 1.05rem; }
.rpt-card-tag {
  font-size: .72rem; padding: 3px 8px; border-radius: 999px;
  white-space: nowrap; font-weight: 600;
}
.rpt-card-sub {
  display: flex; gap: 8px; align-items: center; font-size: .85rem;
  color: var(--text-subtle); flex-wrap: wrap;
}
.rpt-card-cliente { color: var(--text-default); }
.rpt-card-lider { color: var(--text-default); }
.rpt-card-risk { color: var(--danger); font-size: 1rem; }
.rpt-card-tag-repo {
  color: var(--text-dimmed); font-size: .8rem;
  display: inline-flex; align-items: center;
}
.rpt-card-progress {
  height: 4px; background: var(--surface-2); border-radius: 2px;
  overflow: hidden; margin-top: 4px;
}
.rpt-card-progress-fill {
  height: 100%; transition: width .3s ease;
}
.rpt-card-cta {
  margin-top: 8px; display: flex; align-items: center; gap: 6px;
  color: var(--accent); font-size: .85rem; font-weight: 500;
  border-top: 1px solid var(--border-1); padding-top: 12px;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * Vista mamadora del reporte (cliente + Directivo).
 * Hero cover + nav sticky con anchors + animación fade-up. Vive DENTRO del
 * shell del portal — no es un full-screen takeover. Tokens del portal con
 * énfasis visual (gradientes sutiles, glow del accent en hero).
 * ─────────────────────────────────────────────────────────────────────────── */

.rpt-mm {
  border: 1px solid var(--border-1); border-radius: 12px;
  background: var(--surface-1); overflow: hidden;
  position: relative;
}

/* Nav sticky con anchors */
.rpt-mm-nav {
  position: sticky; top: 0; z-index: 20;
  background: rgba(var(--bg-page-rgb),.94); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border-1);
  padding: 10px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.rpt-mm-nav-l { display: flex; align-items: center; gap: 10px; min-width: 0; }
.rpt-mm-nav-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  flex-shrink: 0;
}
.rpt-mm-nav-brand {
  font-size: 13px; font-weight: 600; color: var(--text-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rpt-mm-nav-live {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 600; color: var(--success);
  background: rgba(61,221,126,.10); border: 1px solid rgba(61,221,126,.25);
}
.rpt-mm-nav-links { display: flex; gap: 2px; overflow-x: auto; }
.rpt-mm-nav-links a {
  padding: 5px 11px; border-radius: 6px;
  font-size: 12px; color: var(--text-dimmed); text-decoration: none;
  white-space: nowrap; transition: color .12s, background .12s;
}
.rpt-mm-nav-links a:hover { color: var(--text-strong); background: var(--surface-2); }
.rpt-mm-nav-links a.active { color: var(--text-strong); background: var(--surface-3); }

/* Hero — el único "WOW" del reporte. Título grande pero con Inter heavy
 * (no serif italic): se nota la presencia sin sentirse documento. Glow
 * sutil de acento atrás del título. */
.rpt-mm-hero {
  padding: 64px 32px 48px;
  text-align: center;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 80% 50% at 50% -5%, rgba(var(--accent-rgb),.14), transparent 65%),
    radial-gradient(ellipse 40% 40% at 70% 60%, rgba(var(--accent-rgb),.06), transparent 60%);
}
.rpt-mm-tag {
  font-size: 11px; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--accent);
  margin-bottom: 18px;
}
.rpt-mm-title {
  font-family: inherit;
  font-size: clamp(2.2rem, 5.5vw, 3.8rem);
  line-height: 1.05; font-weight: 700;
  letter-spacing: -.025em;
  color: var(--text-strong);
  margin-bottom: 14px;
}
.rpt-mm-meta { color: var(--text-subtle); font-size: 14px; margin-bottom: 14px; }
.rpt-mm-badges { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-bottom: 28px; }

/* Stats en el hero — números grandes con tilt sutil del accent */
.rpt-mm-stats { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.rpt-mm-stat {
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: 10px; padding: 14px 22px; min-width: 110px;
}
.rpt-mm-stat-n {
  font-size: 1.85rem; font-weight: 700; line-height: 1;
  color: var(--text-strong); letter-spacing: -.01em;
}
.rpt-mm-stat-l {
  font-size: 10px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-dimmed); margin-top: 6px;
}

/* Content body — ancho ajustado y secciones que aparecen al scroll */
.rpt-mm-content { padding: 40px 32px 32px; max-width: 920px; margin: 0 auto; }
.rpt-mm-block {
  /* Visible por default — la animación de entrada es progressive enhancement.
     Si el IntersectionObserver no corre (print, browser viejo, reduced-motion)
     o se atrasa, el contenido NO se queda invisible. JS añade rpt-mm-prefade
     antes de observar para activar la animación cuando aplica. */
  opacity: 1; transform: none;
  transition: opacity .55s ease-out, transform .55s ease-out;
  margin-bottom: 42px;
}
.rpt-mm-block.rpt-mm-prefade { opacity: 0; transform: translateY(20px); }
.rpt-mm-block.rpt-mm-visible  { opacity: 1; transform: none; }
.rpt-mm-block:last-child { margin-bottom: 0; }

.rpt-mm-h {
  font-size: 11px; font-weight: 700; letter-spacing: .15em;
  text-transform: uppercase; color: var(--text-dimmed);
  margin-bottom: 14px;
  display: flex; align-items: center; gap: 12px;
}
.rpt-mm-h::after { content: ''; flex: 1; height: 1px; background: var(--border-1); }

.rpt-mm-summary {
  font-size: 1rem; line-height: 1.7; color: var(--text-default);
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-left: 3px solid var(--accent);
  border-radius: 0 10px 10px 0; padding: 16px 20px;
}

.rpt-mm-readme {
  /* Reusa typography de .rpt-changelog (declaradas más arriba). Sin reglas
   * extra — el contenedor .rpt-changelog en el render ya estiliza todo. */
}

.rpt-mm-rm { margin-top: 4px; }

.rpt-mm-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 10px;
}
.rpt-mm-metric {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 10px; padding: 18px; text-align: center;
}
.rpt-mm-metric-v {
  font-size: 1.7rem; font-weight: 700; line-height: 1;
  color: var(--text-strong); letter-spacing: -.01em; margin-bottom: 6px;
}
.rpt-mm-metric-l {
  font-size: 10px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-dimmed);
}

.rpt-mm-text {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 10px; padding: 16px 20px;
  font-size: 14px; line-height: 1.7; color: var(--text-default);
}

.rpt-mm-empty {
  text-align: center; padding: 48px 24px;
  border: 1px dashed var(--border-2); border-radius: 12px;
  background: var(--surface-2);
}
.rpt-mm-empty h3 { color: var(--text-strong); margin: 14px 0 6px; font-size: 1.05rem; }
.rpt-mm-empty p { color: var(--text-subtle); max-width: 480px; margin: 0 auto; line-height: 1.65; font-size: 14px; }

@media (max-width: 720px) {
  .rpt-mm-nav { padding: 8px 16px; }
  .rpt-mm-nav-links { display: none; }
  .rpt-mm-hero { padding: 48px 18px 36px; }
  .rpt-mm-content { padding: 32px 18px; }
  .rpt-mm-stat { padding: 12px 16px; min-width: 90px; }
  .rpt-mm-stat-n { font-size: 1.5rem; }
}

/* ─────────────────────────────────────────────────────────────────────────────
 * Modo Dirección — overrides específicos para la vista de reporte.
 * Mismo design system del portal, pero con tipografía y espaciado subidos
 * de tono para que el ejecutivo escanee menos texto y vea más números/
 * decisiones. NO redibujamos la estructura — sólo respiramos más y damos
 * presencia visual. Reutiliza el patrón de §46 (dash-hero-val 2.4rem,
 * padding generoso, decisión-first).
 * ─────────────────────────────────────────────────────────────────────── */

/* Detail-header del reporte: avatar 1.5x, título XL, glow sutil de acento
 * detrás del bloque para distinguir visualmente de Operación. */
body.viewmode-directivo .rpt-gallery + * .detail-header,
body.viewmode-directivo .content > .detail-header {
  padding: 28px 32px;
  position: relative;
  background:
    radial-gradient(ellipse 60% 100% at 20% 50%, rgba(var(--accent-rgb),.08), transparent 60%),
    var(--surface-1);
}
body.viewmode-directivo .detail-avatar {
  width: 72px; height: 72px; font-size: 1.6rem;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #fff;
}
body.viewmode-directivo .detail-name { font-size: 2rem; letter-spacing: -.02em; line-height: 1.1; }
body.viewmode-directivo .detail-meta { font-size: 14px; }

/* Stats / cards anidados en métricas: números grandes tipo dashboard. */
body.viewmode-directivo .cards { gap: 14px; }
body.viewmode-directivo .cards .card { padding: 20px 24px; }
body.viewmode-directivo .cards .card .lbl { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; font-weight: 600; color: var(--text-dimmed); }
body.viewmode-directivo .cards .card .val { font-size: 2rem; font-weight: 700; letter-spacing: -.01em; margin-top: 6px; }

/* Info-cards con más presencia: padding, headings más sólidos, separación. */
body.viewmode-directivo .info-card { padding: 26px 28px; margin-bottom: 18px; }
body.viewmode-directivo .info-card h3 {
  font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em;
  margin-bottom: 16px; padding-bottom: 12px;
  border-bottom: 1px solid var(--border-1);
  color: var(--text-strong);
}

/* Roadmap rows con más aire — el ejecutivo no quiere apretar la vista. */
body.viewmode-directivo .rpt-rm-list { gap: 10px; }
body.viewmode-directivo .rpt-rm-item { padding: 14px 18px; }
body.viewmode-directivo .rpt-rm-period { padding: 5px 12px; font-size: 12px; }
body.viewmode-directivo .rpt-rm-prio { padding: 5px 12px; font-size: 11px; }
body.viewmode-directivo .rpt-rm-desc { font-size: 15px; }

/* Page-title del reporte: más grande, más cómodo de escanear. */
body.viewmode-directivo .page-title:has(.mi[data-icon="summarize"]),
body.viewmode-directivo .content > .page-title,
body.viewmode-directivo .content > .section-header > .page-title { font-size: 1.5rem; padding-bottom: 8px; }

/* CHANGELOG en Directivo: leading más cómodo, h2 con acento más fuerte. */
body.viewmode-directivo .rpt-changelog { font-size: 15px; line-height: 1.8; }
body.viewmode-directivo .rpt-changelog h1 { font-size: 1.5rem; }
body.viewmode-directivo .rpt-changelog h2 { font-size: 1.25rem; }

/* Gallery Directivo: cards más grandes con un sutil acento decorativo
 * arriba — el primer hint visual de "estos son tus proyectos clave". */
body.viewmode-directivo .rpt-gallery {
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 20px;
}
body.viewmode-directivo .rpt-card {
  position: relative;
  padding: 26px; min-height: 200px;
  border-color: var(--border-2);
  overflow: hidden;
}
body.viewmode-directivo .rpt-card::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--accent), transparent);
  opacity: .5;
}
body.viewmode-directivo .rpt-card-title { font-size: 1.3rem; letter-spacing: -.01em; }
body.viewmode-directivo .rpt-card-cta { font-size: .95rem; }

/* Badge "En vivo" en el nav del detail */
.rpt-live-badge {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: 12px; padding: 2px 10px; border-radius: 999px;
  font-size: .72rem; font-weight: 600; color: var(--success);
  background: rgba(61,221,126,.10); border: 1px solid rgba(61,221,126,.25);
}
.rpt-live-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--success);
  animation: rpt-pulse 2s ease-in-out infinite;
}
@keyframes rpt-pulse {
  0%, 100% { opacity: .6; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.15); }
}

/* ─────────────────────────────────────────────────────────────────────────────
 * Addon proyectos — modal: rows interactivos para Roadmap / Métricas / Token
 * ─────────────────────────────────────────────────────────────────────────── */
/* CHANGELOG colapsable por versión. Cada `<details>` agrupa una entry
 * (## heading). La más reciente va `open` por default; las demás se
 * pueden expandir on demand. Chevron rota al abrir. */
.rpt-changelog-sections { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.rpt-cl-version {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 8px; overflow: hidden;
}
.rpt-cl-version > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  font-weight: 600; color: var(--text-strong);
  user-select: none;
  transition: background .12s;
}
.rpt-cl-version > summary::-webkit-details-marker { display: none; }
.rpt-cl-version > summary:hover { background: var(--surface-3); }
.rpt-cl-chev { color: var(--text-dimmed); transition: transform .18s; }
.rpt-cl-version[open] > summary > .rpt-cl-chev { transform: rotate(90deg); }
.rpt-cl-vtitle { flex: 1; font-size: 14px; }
.rpt-cl-body { padding: 4px 14px 14px; }
.rpt-cl-body > :first-child { margin-top: 0; }

.pry-repo-option:hover { background: var(--surface-3) !important; }
.pry-repo-option:last-child { border-bottom: none !important; }
.pry-repo-option:focus-visible { background: var(--surface-3) !important; outline: 2px solid var(--accent); outline-offset: -2px; }
/* Markdown editor (reusable) — toolbar minimal + textarea + preview toggle.
 * Sin frameworks; usa marked.js para el preview, ya cargado en admin.php
 * y cliente.php. Render: _mdEditorHtml(id, value, opts). */
.md-editor {
  background: var(--surface-2); border: 1px solid var(--border-1);
  border-radius: 8px; overflow: hidden;
}
.md-toolbar {
  display: flex; gap: 2px; align-items: center;
  padding: 6px 8px; background: var(--surface-1);
  border-bottom: 1px solid var(--border-1);
}
.md-tb-btn {
  background: none; border: 1px solid transparent;
  color: var(--text-default); padding: 4px 9px;
  border-radius: 5px; cursor: pointer; font-family: inherit;
  font-size: 13px; line-height: 1;
  display: inline-flex; align-items: center; gap: 4px;
  transition: background .12s, border-color .12s, color .12s;
}
.md-tb-btn:hover { background: var(--surface-3); border-color: var(--border-2); color: var(--text-strong); }
.md-tb-btn:active { transform: translateY(1px); }
.md-tb-btn[data-state="preview"] {
  background: rgba(var(--accent-rgb),.10); border-color: rgba(var(--accent-rgb),.30);
  color: var(--accent);
}
.md-tb-sep {
  width: 1px; height: 18px; background: var(--border-1);
  margin: 0 6px;
}
.md-tb-help {
  margin-left: auto; color: var(--text-dimmed);
  text-decoration: none; font-size: 12px;
  width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-1);
  transition: color .12s, border-color .12s;
}
.md-tb-help:hover { color: var(--accent); border-color: var(--accent); }
.md-textarea {
  width: 100%; min-height: 120px; padding: 12px 14px;
  border: none; outline: none; resize: vertical;
  background: var(--surface-2); color: var(--text-default);
  font-family: 'DM Mono', ui-monospace, monospace; font-size: 13px;
  line-height: 1.6;
}
.md-textarea:focus { background: var(--bg-page); }
.md-preview {
  padding: 14px 16px; min-height: 120px;
  background: var(--surface-2);
}
.md-preview > :first-child { margin-top: 0; }

.pry-row-list { display: flex; flex-direction: column; gap: 6px; }
.pry-row { display: flex; gap: 6px; align-items: center; }
.pry-row input[type="text"],
.pry-row select { padding: 6px 8px; font-size: .9rem; }
.pry-row-empty {
  padding: 12px; border: 1px dashed rgba(255,255,255,.1);
  border-radius: 6px; text-align: center;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * Addon proyectos: sub-nav del portal cliente + render del reporte premium
 * (prototipo /ref). Prefijo .rpt-* para no chocar con globales.
 * El reporte vive embebido en el shell del portal (sidebar + topbar visibles);
 * sólo @media print oculta el shell para producir un PDF limpio.
 * ─────────────────────────────────────────────────────────────────────────── */

.portal-subnav {
  display: flex; gap: 4px; flex-wrap: wrap;
  margin: 0 0 16px;
  padding: 6px;
  background: var(--surface-3);
  border: 1px solid var(--border-3);
  border-radius: 10px;
}
.portal-subnav button {
  flex: 1; min-width: 110px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 14px;
  background: transparent; border: none; border-radius: 7px;
  color: var(--text-subtle); font-family: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; transition: all .18s;
}
.portal-subnav button:hover { color: var(--text-default); background: rgba(255,255,255,.04); }
.portal-subnav button.active { color: #fff; background: rgba(124,106,247,.18); }
.portal-subnav .mi { font-size: 16px; }

/* Lista de reportes (cards) ─────────────────────────────────────────────── */
.rep-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.rep-list-card {
  background: linear-gradient(135deg, var(--surface-3) 0%, var(--surface-3) 100%);
  border: 1px solid var(--border-3);
  border-radius: 14px;
  padding: 20px;
  cursor: pointer;
  transition: transform .18s, border-color .18s, box-shadow .18s;
}
.rep-list-card:hover, .rep-list-card:focus {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 8px 24px rgba(124,106,247,.15);
  outline: none;
}
.rep-list-card-header { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.rep-list-card-title { font-size: 1.05rem; font-weight: 600; color: var(--text-default); line-height: 1.3; }
.rep-list-card-version { font-size: 11px; color: var(--purple); background: rgba(177,151,252,.1); padding: 2px 8px; border-radius: 12px; }
.rep-list-card-meta { display: flex; gap: 12px; font-size: 12px; color: var(--text-subtle); margin-bottom: 10px; }
.rep-list-card-meta .mi { font-size: 14px; vertical-align: -2px; }
.rep-list-card-preview { font-size: 13px; color: var(--text-default); line-height: 1.55; margin-bottom: 12px; min-height: 36px; }
.rep-list-card-cta { font-size: 12px; font-weight: 600; color: var(--purple); }

/* Reporte usa primitives del portal — .page-title, .detail-header,
 * .cards, .info-card. Sólo conservamos clases custom para lo que NO
 * cubre el design system base: roadmap rows (chip de periodo + prio),
 * y el .rpt-changelog para que el markdown del CHANGELOG.md se vea
 * bien tipográficamente.
 *
 * El reporte no es un "documento embebido" con su propio wrapper /
 * sticky-nav / hero / footer — es una sección más, igual que el
 * detalle de cliente o empresa. Eso lo hace sentir parte del sistema.
 *
 * CHANGELOG — typography del portal. h1/h2 sin italic, body normal Inter,
 * inline-code en pill azul (acento del portal), pre en panel surface-2. */
.rpt-changelog { font-size: 14px; line-height: 1.75; color: var(--text-default); margin-top: 16px; }
.rpt-changelog h1, .rpt-changelog h2, .rpt-changelog h4 {
  font-family: inherit; color: var(--text-strong);
  margin: 1.75rem 0 .65rem; line-height: 1.3; font-weight: 700;
  letter-spacing: -.01em;
}
.rpt-changelog h1 { font-size: 1.35rem; padding-bottom: .6rem; border-bottom: 1px solid var(--border-1); }
.rpt-changelog h2 { font-size: 1.15rem; color: var(--accent); }
.rpt-changelog h3 {
  font-size: .78rem; font-family: inherit; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-dimmed);
  margin: 1.6rem 0 .55rem;
}
.rpt-changelog h4 { font-size: 1rem; color: var(--text-strong); }
.rpt-changelog p { margin: .65rem 0; }
.rpt-changelog ul, .rpt-changelog ol { padding-left: 1.5rem; margin: .55rem 0; }
.rpt-changelog li { margin: .35rem 0; }
.rpt-changelog li::marker { color: var(--accent); }
.rpt-changelog strong { color: var(--text-strong); font-weight: 600; }
.rpt-changelog em { color: var(--text-strong); font-style: italic; }
.rpt-changelog code {
  font-family: monospace; font-size: .85em; color: var(--accent);
  background: rgba(var(--accent-rgb),.10); padding: .12rem .4rem; border-radius: 4px;
}
.rpt-changelog pre {
  background: var(--surface-2); border: 1px solid var(--border-1); border-radius: 8px;
  padding: 1rem 1.2rem; overflow-x: auto; margin: 1rem 0;
}
.rpt-changelog pre code { background: none; color: var(--text-default); font-size: .85rem; padding: 0; }
.rpt-changelog hr { border: none; border-top: 1px solid var(--border-1); margin: 1.5rem 0; }
.rpt-changelog blockquote {
  border-left: 3px solid var(--accent); padding: .4rem 0 .4rem 1.25rem;
  margin: 1rem 0; color: var(--text-subtle); font-style: italic;
}
.rpt-changelog a { color: var(--accent); text-decoration: none; border-bottom: 1px dashed rgba(var(--accent-rgb),.40); }
.rpt-changelog a:hover { border-bottom-style: solid; }
.rpt-changelog table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: .9rem; }
.rpt-changelog th { background: var(--surface-2); color: var(--text-strong); font-weight: 600; padding: .55rem .95rem; text-align: left; border: 1px solid var(--border-1); }
.rpt-changelog td { padding: .5rem .95rem; border: 1px solid var(--border-1); color: var(--text-default); }
.rpt-changelog img { max-width: 100%; height: auto; border-radius: 8px; }

/* ─────────────────────────────────────────────────────────────────────────────
 * README rendering — tipografía generosa estilo Claude.ai/Notion.
 * Mismo voice tipográfico del portal (Inter, --accent), pero con más aire
 * vertical, headings más pesados, code blocks con toolbar copy, callouts
 * para GitHub-flavored alerts ([!NOTE], [!WARNING], etc.).
 * ─────────────────────────────────────────────────────────────────────── */
.rpt-readme {
  font-size: 15px;
  line-height: 1.75;
  color: var(--text-default);
  margin-top: 8px;
}
.rpt-readme > :first-child { margin-top: 0; }
.rpt-readme > :last-child { margin-bottom: 0; }

.rpt-readme h1, .rpt-readme h2, .rpt-readme h3, .rpt-readme h4, .rpt-readme h5, .rpt-readme h6 {
  font-family: inherit; color: var(--text-strong);
  letter-spacing: -.015em;
  line-height: 1.25;
  font-weight: 700;
  scroll-margin-top: 60px; /* sticky nav offset */
}
.rpt-readme h1 {
  font-size: 1.85rem;
  margin: 2.25rem 0 1.1rem;
  padding-bottom: .55rem;
  border-bottom: 1px solid var(--border-1);
  letter-spacing: -.02em;
}
.rpt-readme h1:first-child { margin-top: 0; }
.rpt-readme h2 {
  font-size: 1.4rem;
  margin: 2rem 0 .9rem;
  padding-bottom: .35rem;
  border-bottom: 1px solid var(--border-1);
}
.rpt-readme h3 {
  font-size: 1.15rem;
  margin: 1.6rem 0 .65rem;
  color: var(--text-strong);
}
.rpt-readme h4 { font-size: 1rem; margin: 1.3rem 0 .5rem; }
.rpt-readme h5 { font-size: .9rem; margin: 1.1rem 0 .4rem; color: var(--text-subtle); text-transform: uppercase; letter-spacing: .08em; }
.rpt-readme h6 { font-size: .85rem; margin: 1rem 0 .4rem; color: var(--text-dimmed); text-transform: uppercase; letter-spacing: .08em; font-weight: 600; }

.rpt-readme p { margin: .85rem 0; }

.rpt-readme ul, .rpt-readme ol { padding-left: 1.5rem; margin: .75rem 0; }
.rpt-readme li { margin: .35rem 0; }
.rpt-readme li > p { margin: .3rem 0; }
.rpt-readme li::marker { color: var(--accent); }
.rpt-readme ul ul, .rpt-readme ol ol, .rpt-readme ul ol, .rpt-readme ol ul { margin: .3rem 0; }

/* Task lists (GitHub style) */
.rpt-readme li input[type="checkbox"] {
  margin-right: 6px;
  accent-color: var(--accent);
  transform: translateY(1px);
}

.rpt-readme strong { color: var(--text-strong); font-weight: 600; }
.rpt-readme em { color: var(--text-default); font-style: italic; }

.rpt-readme a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid rgba(var(--accent-rgb),.30);
  transition: border-color .15s, color .15s;
}
.rpt-readme a:hover { border-bottom-color: var(--accent); color: var(--accent-2); }

.rpt-readme hr {
  border: none;
  border-top: 1px solid var(--border-1);
  margin: 2.2rem 0;
}

/* Inline code pill */
.rpt-readme :not(pre) > code {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: .87em;
  color: var(--accent);
  background: rgba(var(--accent-rgb),.10);
  padding: .12em .42em;
  border-radius: 5px;
  border: 1px solid rgba(var(--accent-rgb),.18);
}

/* Code blocks con toolbar */
.rpt-readme pre, .rpt-readme-codeblock {
  background: var(--bg-page);
  border: 1px solid var(--border-1);
  border-radius: 10px;
  margin: 1.1rem 0;
  overflow: hidden;
  position: relative;
}
.rpt-readme-codetools {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 10px 6px 14px;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border-1);
  min-height: 32px;
}
.rpt-readme-codelang {
  font-family: 'DM Mono', monospace; font-size: 11px;
  color: var(--text-dimmed);
  text-transform: lowercase;
  letter-spacing: .04em;
}
.rpt-readme-copy {
  background: none; border: 1px solid var(--border-2);
  color: var(--text-subtle); cursor: pointer;
  padding: 3px 9px; border-radius: 6px;
  font: inherit; font-size: 11px;
  display: inline-flex; align-items: center; gap: 4px;
  transition: all .15s;
}
.rpt-readme-copy:hover { color: var(--accent); border-color: var(--accent); }
.rpt-readme-copy-ok { color: var(--success) !important; border-color: var(--success) !important; }
.rpt-readme pre code {
  display: block;
  padding: 14px 16px;
  background: none;
  border: none;
  border-radius: 0;
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 13px;
  line-height: 1.65;
  color: var(--text-default);
  overflow-x: auto;
}

/* Blockquote */
.rpt-readme blockquote {
  margin: 1.2rem 0;
  padding: .6rem 1.2rem;
  border-left: 3px solid var(--accent);
  background: rgba(var(--accent-rgb),.04);
  color: var(--text-subtle);
  font-style: italic;
  border-radius: 0 8px 8px 0;
}
.rpt-readme blockquote > :first-child { margin-top: 0; }
.rpt-readme blockquote > :last-child { margin-bottom: 0; }

/* GitHub-flavored alerts (NOTE/TIP/IMPORTANT/WARNING/CAUTION) */
.rpt-readme-alert {
  margin: 1.3rem 0;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid var(--border-1);
  border-left-width: 3px;
  background: var(--surface-2);
}
.rpt-readme-alert-head {
  display: flex; align-items: center; gap: 6px;
  font-weight: 600; font-size: 13px;
  text-transform: uppercase; letter-spacing: .06em;
  margin-bottom: 8px;
}
.rpt-readme-alert-body { color: var(--text-default); line-height: 1.65; }
.rpt-readme-alert-body > :first-child { margin-top: 0; }
.rpt-readme-alert-body > :last-child { margin-bottom: 0; }

.rpt-readme-alert-note      { border-left-color: var(--info); }
.rpt-readme-alert-note      .rpt-readme-alert-head { color: var(--info); }
.rpt-readme-alert-tip       { border-left-color: var(--success); }
.rpt-readme-alert-tip       .rpt-readme-alert-head { color: var(--success); }
.rpt-readme-alert-important { border-left-color: var(--purple); }
.rpt-readme-alert-important .rpt-readme-alert-head { color: var(--purple); }
.rpt-readme-alert-warning   { border-left-color: var(--warning); }
.rpt-readme-alert-warning   .rpt-readme-alert-head { color: var(--warning); }
.rpt-readme-alert-caution   { border-left-color: var(--danger); }
.rpt-readme-alert-caution   .rpt-readme-alert-head { color: var(--danger); }

/* Tablas — wrap horizontal scroll en mobile */
.rpt-readme-table-wrap {
  overflow-x: auto;
  margin: 1.2rem 0;
  border: 1px solid var(--border-1);
  border-radius: 8px;
}
.rpt-readme table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  /* Sin min-width hardcoded — el wrap .rpt-readme-table-wrap maneja overflow-x
   * cuando el contenido natural excede el ancho del card. Forzar 480px
   * generaba scroll horizontal innecesario en tablas pequeñas. */
}
.rpt-readme th {
  text-align: left; padding: 10px 14px;
  background: var(--surface-2);
  color: var(--text-strong); font-weight: 600;
  border-bottom: 1px solid var(--border-1);
  white-space: nowrap;
}
.rpt-readme td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-1);
  color: var(--text-default);
}
.rpt-readme tr:last-child td { border-bottom: none; }
.rpt-readme tr:nth-child(even) td { background: rgba(255,255,255,.012); }

/* Imágenes — bordeadas, no maxwidth full para no romper densidad lectora */
.rpt-readme img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  border: 1px solid var(--border-1);
  margin: .8rem 0;
  background: var(--surface-2);
}

/* Roadmap rows — único custom layout, no cubierto por .info-grid. Cada
 * row es un slim panel con chip de periodo, chip de prioridad y
 * descripción. Vive dentro de un .info-card del portal. */
.rpt-rm-list { display: grid; gap: 8px; margin-top: 4px; }
.rpt-rm-item { display: flex; gap: 14px; align-items: flex-start; background: var(--surface-2); border: 1px solid var(--border-1); border-radius: 8px; padding: 10px 14px; }
.rpt-rm-period { font-family: monospace; font-size: 11px; color: var(--accent); background: rgba(var(--accent-rgb),.10); border: 1px solid rgba(var(--accent-rgb),.20); padding: 3px 9px; border-radius: 6px; white-space: nowrap; flex-shrink: 0; }
.rpt-rm-prio { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; padding: 3px 9px; border-radius: 6px; white-space: nowrap; flex-shrink: 0; font-family: monospace; }
.rpt-prio-P0 { background: rgba(255,107,107,.10); color: var(--danger); border: 1px solid rgba(255,107,107,.25); }
.rpt-prio-P1 { background: rgba(255,170,68,.08); color: var(--warning); border: 1px solid rgba(255,170,68,.25); }
.rpt-prio-P2 { background: rgba(var(--accent-rgb),.08); color: var(--accent); border: 1px solid rgba(var(--accent-rgb),.20); }
.rpt-rm-desc { font-size: 14px; color: var(--text-default); line-height: 1.5; }

/* Print del reporte — usa cualquier .rpt-changelog visible en pantalla
 * como señal de "esto es un reporte". El @media print global del portal
 * en line 3160 ya oculta sidebar/topbar/bottom-tabs cuando aplica. Las
 * reglas abajo sólo ajustan colores e info-card para tinta. */
@media print {
  body:has(.rpt-changelog) { background: #fff; color: #000; }
  body:has(.rpt-changelog) .info-card,
  body:has(.rpt-changelog) .rpt-rm-item { background: var(--surface-raised); border-color: #ccc; }
  body:has(.rpt-changelog) .info-card h3,
  body:has(.rpt-changelog) .detail-name { color: #000; }
  body:has(.rpt-changelog) .rpt-changelog,
  body:has(.rpt-changelog) .rpt-changelog * { color: #000 !important; -webkit-text-fill-color: #000 !important; background: none !important; }
}

/* "Conoce tu X" — panel con título y grid de tiles. Patrón visual del
 * dashBlock activos-inventario: header con icono + título, grid auto-fit
 * con tiles que muestran categoría + número grande + icono semántico
 * (esquina inferior derecha). Es un componente reusable: cualquier
 * dashBlock que quiera presentar contadores categóricos puede usarlo. */
.dash-conoce-panel {
  background: var(--surface-1);
  border: 1px solid var(--border-3);
  border-radius: 12px;
  padding: 18px 20px 22px;
  margin-top: 12px;
}
.dash-conoce-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 600; color: var(--text-default);
  margin-bottom: 14px;
}
.dash-conoce-head .mi { color: var(--text-soft); }
.dash-conoce-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
.dash-conoce-tile {
  position: relative;
  background: linear-gradient(135deg, var(--surface-raised) 0%, var(--surface-3) 100%);
  border: 1px solid var(--border-3);
  border-radius: 10px;
  padding: 14px 16px 12px;
  cursor: pointer;
  transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
  min-height: 96px;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
.dash-conoce-tile:hover,
.dash-conoce-tile:focus-visible {
  transform: translateY(-1px);
  border-color: var(--accent);
  box-shadow: 0 4px 14px rgba(99,102,241,.18);
  outline: none;
}
.dash-conoce-tile-label {
  font-size: 11px; font-weight: 600;
  color: var(--text-default); text-transform: uppercase; letter-spacing: .04em;
}
.dash-conoce-tile-val {
  font-size: 32px; font-weight: 700; color: var(--text-strong);
  line-height: 1.1; margin: 4px 0 0;
}
.dash-conoce-tile-icon {
  position: absolute; right: 10px; bottom: 6px;
  opacity: .25; pointer-events: none;
}
.dash-conoce-tile-icon .mi {
  font-size: 38px; color: var(--text-soft);
}
/* Touch (sin hover real): tap feedback */
.dash-conoce-tile:active { transform: scale(.98); }
/* Modo Dirección: tiles más grandes, menos densidad */
body.viewmode-directivo .dash-conoce-tile { min-height: 110px; padding: 18px 20px 14px; }
body.viewmode-directivo .dash-conoce-tile-val { font-size: 38px; }
body.viewmode-directivo .dash-conoce-tile-icon .mi { font-size: 44px; }

/* ============================================================
   Organigrama (tema "organigrama" del dashboard)
   Vista de árbol jerárquico de Portal_Colaboradores por JefeDirectoId.
   Patrón clásico: cards con conectores CSS via border + ::before/::after.
   ============================================================ */
.org-wrap { padding: 18px 20px; }
.org-header {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; margin-bottom: 14px; flex-wrap: wrap;
}
.org-header h3 { margin: 0; display: inline-flex; align-items: center; gap: 8px; }
.org-controls { display: flex; gap: 6px; flex-wrap: wrap; }

/* Canvas: scroll horizontal cuando el árbol es ancho. */
.org-canvas {
  overflow-x: auto; overflow-y: visible;
  padding: 8px 4px 16px; background: var(--surface-3); border-radius: 6px;
  border: 1px solid var(--border-3);
}

.org-tree, .org-children {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.org-tree { padding: 8px 12px; }

/* Cada nivel se indenta y dibuja una guía vertical a la izquierda. */
.org-children {
  padding-left: 32px; position: relative; margin-top: 4px;
}
/* Línea vertical guía: sutil para que el conector horizontal sea el
   elemento visual dominante. Antes era var(--border-1) (igual al borde de las
   cards) y los users confundían qué nodo cuelga de qué padre en árboles
   con 3+ niveles. */
.org-children::before {
  content: ''; position: absolute; left: 10px; top: 0; bottom: 10px;
  width: 1px; background: var(--border-1); border-radius: 1px;
}

.org-node { position: relative; }
/* Conector horizontal del nodo a su padre — color accent (azul) para
   resaltar contra la vertical sutil. Cap redondeado al final del lado
   del card para que se vea como "entra" al nodo. Patrón Linear. */
.org-children > .org-node::before {
  content: ''; position: absolute; left: -22px; top: 22px;
  width: 20px; height: 2px;
  background: var(--accent); border-radius: 1px 2px 2px 1px;
}
/* Pequeño dot circular en el inicio del conector (donde nace de la
   vertical), refuerza el "T-junction" visualmente. */
.org-children > .org-node::after {
  content: ''; position: absolute; left: -24px; top: 19px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); pointer-events: none;
}

.org-card {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface-raised); border: 1px solid var(--border-1); border-radius: 8px;
  padding: 8px 12px; cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
  min-width: 240px; max-width: 380px;
}
/* Card del usuario actual: resaltada para ubicarse rápido en árboles grandes.
   Border accent + glow sutil. Patrón "you-are-here" de mapas org. */
.org-card.org-card-me {
  border-color: var(--border-strong);
  box-shadow: 0 0 0 1px var(--accent), 0 0 12px rgba(44,90,160,.25);
}
.org-me-pill {
  display: inline-block;
  background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  padding: 1px 7px; border-radius: 10px;
  margin-left: 6px; letter-spacing: .5px;
  vertical-align: middle;
}
.org-card:hover {
  background: var(--surface-raised); border-color: var(--border-strong);
  transform: translateY(-1px);
}
.org-card.org-card-warn {
  background: var(--danger-bg); border-color: var(--warning-bd);
  cursor: default;
}

.org-avatar {
  flex-shrink: 0;
  width: 32px; height: 32px; border-radius: 50%;
  background: linear-gradient(135deg, var(--purple), var(--purple));
  color: #fff; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
  letter-spacing: .02em;
}

.org-card-body { flex: 1; min-width: 0; }
.org-name {
  font-weight: 600; color: var(--text-strong); font-size: 13.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.org-sub {
  font-size: 11.5px; color: var(--text-default); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.org-toggle {
  flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--border-1); color: var(--text-default);
  border: none; border-radius: 12px;
  padding: 3px 8px; cursor: pointer;
  font-size: 11px; font-weight: 600;
  transition: background .15s;
}
.org-toggle:hover { background: var(--accent); }
.org-toggle-count { font-size: 11px; }

/* Estado colapsado: ocultar hijos. */
.org-node.org-collapsed > .org-children { display: none; }

/* Huérfanos */
.org-huerfanos {
  margin-top: 16px; padding: 12px 14px;
  background: var(--danger-bg); border-left: 3px solid var(--warning);
  border-radius: 6px;
}
.org-huerfanos h4 { margin: 0 0 4px; font-size: 14px; color: var(--warning); }
.org-huerfanos p { margin: 0 0 8px; }
.org-flat-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.org-flat-list li {
  padding: 5px 9px; background: var(--surface-raised); border-radius: 4px;
  font-size: 13px; transition: background .15s;
}
.org-flat-list li:hover { background: var(--surface-raised); }

/* Modo Dirección: cards más grandes y limpias, menos densidad. */
body.viewmode-directivo .org-card { padding: 11px 15px; min-width: 280px; }
body.viewmode-directivo .org-avatar { width: 38px; height: 38px; font-size: 13px; }
body.viewmode-directivo .org-name { font-size: 15px; }
body.viewmode-directivo .org-sub { font-size: 12.5px; }
body.viewmode-directivo .org-toggle { opacity: .65; } /* el toggle es operacional */

/* Mobile: reducir indentación y permitir que las cards se contraigan. */
@media (max-width: 700px) {
  .org-children { padding-left: 22px; }
  .org-children > .org-node::before { left: -16px; width: 14px; }
  .org-children > .org-node::after  { left: -19px; }
  .org-children::before { left: 6px; }
  .org-card { min-width: 180px; max-width: none; }
}

/* ============================================================
   Organigrama — selector de representación + modos alternativos
   (compacto=base de arriba · clasico · horizontal · tarjetas) + densidad.
   compacto/clasico/horizontal comparten el markup (.org-tree/.org-node/
   .org-children); la clase .org-mode-* del <ul> raíz cambia SOLO el layout.
   ============================================================ */

/* Selector segmentado (estilo "Ver como"). */
.org-seg { display: inline-flex; background: var(--surface-3); border: 1px solid var(--border-3); border-radius: 8px; padding: 2px; gap: 2px; }
.org-seg button { background: none; border: none; color: var(--text-default); padding: 5px 9px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; transition: background .15s, color .15s; }
.org-seg button:hover { background: var(--surface-raised); color: var(--text-strong); }
.org-seg button.on { background: var(--accent); color: #fff; }

/* ── Modo CLÁSICO (organigrama top-down) ──
   Técnica CSS-only estándar: hijos en fila horizontal debajo del padre, unidos
   por conectores dibujados con bordes en ::before/::after. Se re-escriben (mayor
   especificidad) los conectores indentados del modo compacto. */
.org-tree.org-mode-clasico { flex-direction: row; align-items: flex-start; justify-content: flex-start; gap: 24px; padding: 8px 16px 4px; width: max-content; min-width: 100%; }
/* flex-shrink:0 es CLAVE: sin él, con muchas raíces en fila el flex comprime los
   nodos y aplasta las tarjetas (se veía solo el toggle). El canvas hace scroll-x. */
.org-mode-clasico .org-node { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
.org-mode-clasico .org-card { flex-shrink: 0; }
.org-mode-clasico .org-children {
  flex-direction: row; align-items: flex-start; justify-content: center;
  padding: 22px 0 0; margin: 0; gap: 0; position: relative;
}
/* línea que BAJA del padre hacia el bus horizontal de sus hijos (repurpone la
   guía vertical del compacto) */
.org-mode-clasico .org-children::before {
  content: ''; position: absolute; top: 0; left: 50%; bottom: auto;
  width: 0; height: 22px; border-left: 2px solid var(--accent); background: none; border-radius: 0;
}
/* bus horizontal: cada hijo aporta media línea superior + su bajada central */
.org-mode-clasico .org-children > .org-node { padding: 22px 12px 0; }
.org-mode-clasico .org-children > .org-node::before,
.org-mode-clasico .org-children > .org-node::after {
  content: ''; position: absolute; top: 0; right: 50%; left: auto;
  width: 50%; height: 22px; border-top: 2px solid var(--accent);
  background: none; border-radius: 0;
}
.org-mode-clasico .org-children > .org-node::after { right: auto; left: 50%; border-left: 2px solid var(--accent); }
/* hijo único: sin bus, solo la bajada del padre (::before del ul) lo conecta */
.org-mode-clasico .org-children > .org-node:only-child::before,
.org-mode-clasico .org-children > .org-node:only-child::after { display: none; }
/* extremos: no dibujar bus más allá del primer/último hijo; el último conserva
   su bajada vía border-right */
.org-mode-clasico .org-children > .org-node:first-child::before,
.org-mode-clasico .org-children > .org-node:last-child::after { border: 0 none; }
.org-mode-clasico .org-children > .org-node:last-child::before { border-right: 2px solid var(--accent); }

/* ── Modo HORIZONTAL (izquierda → derecha) ──
   El nodo se vuelve fila [card | hijos-en-columna]; el card queda centrado
   verticalmente contra su bloque de hijos. */
.org-mode-horizontal .org-node { display: flex; flex-direction: row; align-items: center; }
.org-mode-horizontal .org-children {
  flex-direction: column; justify-content: center; gap: 8px;
  padding-left: 34px; padding-top: 0; margin-top: 0; position: relative;
}
/* guía vertical entre hermanos (reposicionada del compacto) */
.org-mode-horizontal .org-children::before {
  content: ''; position: absolute; left: 16px; top: 20px; bottom: 20px;
  width: 2px; height: auto; background: var(--border-1); border-radius: 1px;
}
/* elbow horizontal de cada hijo hacia la guía */
.org-mode-horizontal .org-children > .org-node::before {
  content: ''; position: absolute; left: -18px; top: 50%; right: auto;
  width: 18px; height: 2px; background: var(--accent); border: 0; border-radius: 1px;
}
.org-mode-horizontal .org-children > .org-node::after { display: none; }

/* ── Modo TARJETAS (mosaico plano / "iconos grandes") ── */
.org-tarjetas { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; padding: 10px 12px; }
.org-tarjeta {
  position: relative; display: flex; align-items: center; gap: 10px;
  background: var(--surface-raised); border: 1px solid var(--border-1); border-radius: 8px;
  padding: 10px 12px; cursor: pointer; transition: background .15s, border-color .15s, transform .1s;
}
.org-tarjeta:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.org-tarjeta-team {
  position: absolute; top: 8px; right: 8px;
  display: inline-flex; align-items: center; gap: 3px;
  background: var(--border-1); color: var(--text-default);
  border-radius: 10px; font-size: 11px; font-weight: 600; padding: 1px 7px;
}

/* ── Densidad compacta (modificador; aplica a cualquier representación) ── */
.org-dense .org-card { min-width: 170px; padding: 5px 9px; gap: 7px; }
.org-dense .org-avatar { width: 24px; height: 24px; font-size: 9px; }
.org-dense .org-name { font-size: 12px; }
.org-dense .org-sub { font-size: 10.5px; }
.org-dense .org-tarjetas { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.org-dense .org-tarjeta { padding: 7px 9px; gap: 7px; }

/* ═══════════════════════════════════════════════════════════════════════
   Campos personalizados (§77) — panel de gestión + render en modales
   ═════════════════════════════════════════════════════════════════════ */

/* Banner informativo arriba del panel (Zoho: showIf no aplica en imports) */
.cc-banner {
  display: flex; gap: 10px; align-items: flex-start;
  background: var(--surface-raised); border: 1px solid var(--border-3);
  border-left: 3px solid var(--accent-bright);
  border-radius: 6px; padding: 10px 14px;
  margin: 16px 0; font-size: 13px; color: var(--text-default);
}
.cc-banner .mi { color: var(--accent-bright); margin-top: 2px; }
.cc-banner b { color: var(--text-strong); }

/* Tabs horizontales para seleccionar la lista destino */
.cc-list-tabs {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 14px 0 10px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border-3);
}
.cc-list-tab {
  background: var(--surface-3); color: var(--text-default);
  border: 1px solid var(--border-strong); border-radius: 18px;
  padding: 5px 12px; font-size: 12.5px; font-weight: 500;
  cursor: pointer; transition: all .15s;
  display: inline-flex; align-items: center; gap: 6px;
}
.cc-list-tab:hover { background: var(--surface-raised); color: var(--text-default); }
.cc-list-tab.active {
  background: var(--accent); color: #fff;
  border-color: var(--border-strong);
}
.cc-count {
  background: rgba(255,255,255,.12); color: inherit;
  border-radius: 10px; padding: 1px 7px;
  font-size: 11px; font-weight: 600; min-width: 18px; text-align: center;
}
.cc-list-tab.active .cc-count { background: rgba(255,255,255,.22); }

/* Contador "X de N campos" */
.cc-counter {
  font-size: 12px; color: var(--text-default);
  margin: 8px 0 14px;
}
.cc-counter.warn { color: var(--warning); font-weight: 500; }

/* Empty state del panel */
.cc-empty { padding: 40px 24px; text-align: center; }
.cc-empty .mi { font-size: 48px; color: var(--text-muted); }
.cc-empty h3 { margin: 12px 0 6px; }
.cc-empty p { color: var(--text-default); margin: 0 0 18px; }

/* Tabla de campos custom */
.cc-internal {
  background: var(--surface-1); color: var(--text-default);
  padding: 1px 6px; border-radius: 3px;
  font-size: 11.5px; font-family: 'Fira Code', monospace;
}
tr.cc-inactive { opacity: .55; }
tr.cc-inactive td { background: var(--surface-1); }

/* Grid de showIf en el modal de crear/editar */
.cc-showif-grid {
  margin-top: 8px;
  background: var(--surface-3); border-radius: 6px;
  padding: 12px;
}

/* ── Render de campos custom en modales de entidades (Clientes, Tickets, etc.) */
.cust-fields-block {
  margin-top: 14px;
  border-top: 1px dashed var(--border-3);
  padding-top: 12px;
}
.cust-fields-block > summary {
  cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--text-default);
  padding: 4px 0;
  list-style: none;
}
.cust-fields-block > summary::-webkit-details-marker { display: none; }
.cust-fields-block > summary::before {
  content: '▸';
  display: inline-block;
  transition: transform .15s;
  color: var(--text-muted); font-size: 10px;
}
.cust-fields-block[open] > summary::before { transform: rotate(90deg); }
.cust-fields-block > summary .mi { color: var(--text-default); }

.cust-fg { /* hereda de .fg, sólo para gancho de selector */ }

.cust-bool {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 0; font-size: 13px;
}
.cust-bool input[type="checkbox"] { width: auto; }

/* ── Editor de roles (§80 Fase 5): módulos visibles + preview ── */
.role-edit-section {
  margin-top: 12px;
  padding: 10px 12px;
  background: var(--surface-3);
  border: 1px solid var(--border-1);
  border-radius: 6px;
}
/* §7pts-9 R-UX — el chevron era un ▸ de 10px muted (invisible): el dueño
   "expandió el preview y no había cómo colapsarlo / no salió icono". Ahora es un
   control claro: barra clickeable con hover + chevron de acento a la DERECHA que
   gira ▸→▾ al abrir. Solo aplica a los <summary> (los <label> no colapsables no
   heredan el ::before). */
.role-edit-section > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 4px 6px; margin: -2px -4px 0; border-radius: 6px;
  transition: background .15s;
}
.role-edit-section > summary:hover { background: var(--surface-raised); }
.role-edit-section > summary::-webkit-details-marker { display: none; }
.role-edit-section > summary::after {
  content: '▸';               /* Unicode (sin dependencia de fuente de iconos) */
  font-size: 15px; line-height: 1; font-weight: 700; color: var(--accent);
  margin-left: auto; flex: 0 0 auto;
  transition: transform .15s;
}
.role-edit-section[open] > summary::after { transform: rotate(90deg); }  /* ▸ → ▾ */
.role-section-title {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--text-default);
  margin-bottom: 4px;
}

.role-addons-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 6px;
}
.role-addons-group {
  background: var(--bg-page);
  border: 1px solid var(--border-1);
  border-radius: 4px;
  padding: 8px 10px;
}
.role-addons-group-title {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  font-weight: 700;
  margin-bottom: 6px;
}
.role-addon-row {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 0;
  font-size: 13px;
  cursor: pointer;
  color: var(--text-default);
}
.role-addon-row:hover { color: var(--text-strong); }
.role-addon-row input[type="checkbox"] { width: auto; cursor: pointer; }
.role-addon-row .mi { font-size: 16px; color: var(--text-muted); }
.role-addons-orphans { padding: 6px 0; }
.role-addons-orphans code {
  background: var(--border-1);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 11px;
}

.role-preview-card {
  background: var(--bg-page);
  border: 1px solid var(--border-1);
  border-radius: 4px;
  padding: 10px 12px;
  margin-top: 6px;
}
.role-preview-summary {
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border-1);
}
.role-preview-summary strong { color: var(--text-default); }
.role-preview-summary > span { margin-right: 6px; }
.role-preview-section { margin-top: 10px; }
.role-preview-section-title {
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  font-weight: 700;
  margin-bottom: 4px;
}
.role-preview-group { margin-bottom: 6px; }
.role-preview-group-title {
  font-size: 11px;
  color: var(--text-default);
  font-weight: 600;
  margin-bottom: 2px;
}
.role-preview-items {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.role-preview-item, .role-preview-theme {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--border-1);
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  color: var(--text-default);
}
.role-preview-themes { display: flex; flex-wrap: wrap; gap: 4px; }
.role-preview-item .mi, .role-preview-theme .mi { font-size: 13px !important; }
.role-preview-warning {
  background: var(--warning-bg);
  border: 1px solid var(--warning-bd);
  padding: 6px 8px;
  border-radius: 4px;
  margin-top: 8px !important;
  display: inline-flex; align-items: center; gap: 6px;
}

/* ── Frappe Gantt — mapeado a los TOKENS de tema del Portal ────────────────
   Frappe define las vars --g-* en :root. Las re-mapeamos a los tokens del
   design system (NO hex fijo) con scope al contenedor que la librería crea
   dentro de #pry-gantt-mount → el Gantt sigue el tema claro/oscuro
   automáticamente. (Antes eran navy hardcodeado: se quedaba oscuro en claro.) */
.gantt-container {
  --g-header-background: var(--surface-2);
  --g-row-color: var(--surface-1);
  --g-row-border-color: var(--border-1);
  --g-border-color: var(--border-1);
  --g-tick-color: var(--border-2);
  --g-tick-color-thick: var(--border-1);
  --g-text-dark: var(--text-default);
  --g-text-light: var(--text-strong);
  --g-text-muted: var(--text-muted);
  --g-bar-color: var(--accent);
  --g-bar-border: var(--accent);
  --g-progress-color: var(--accent-bright);
  --g-handle-color: var(--text-default);
  --g-arrow-color: var(--text-muted);
  --g-actions-background: var(--surface-raised);
  --g-today-highlight: var(--warning);
  --g-weekend-highlight-color: var(--surface-2);
  --g-weekend-label-color: var(--border-1);
  --g-expected-progress: var(--accent);
  --g-popup-actions: var(--surface-2);
  border: 1px solid var(--border-3);
  background: var(--bg-page);
  margin-top: 4px;
}
/* Color de barra por Estatus (custom_class de la tarea Frappe). Colores que COINCIDEN con
   la leyenda y se ven bien en tema claro: "en proceso" en azul de acento (no un slate de
   texto), bloqueada/completada en semáforo, y "no iniciada"/"cancelada" en slate neutro
   (cancelada además atenuada). Etiqueta blanca legible sobre todos. */
.gantt .bar-wrapper.gantt-est-no-iniciada .bar { fill: var(--text-soft); }
.gantt .bar-wrapper.gantt-est-en-proceso  .bar { fill: var(--accent); }
.gantt .bar-wrapper.gantt-est-bloqueada   .bar { fill: var(--danger); }
.gantt .bar-wrapper.gantt-est-completada  .bar { fill: var(--success); }
.gantt .bar-wrapper.gantt-est-cancelada   .bar { fill: var(--text-soft); }
.gantt .bar-wrapper.gantt-est-cancelada { opacity: .5; }
/* Progreso: overlay claro semitransparente sobre el color de la barra. */
.gantt .bar-progress { fill: #ffffff; fill-opacity: .38; }
/* Retraso: contorno rojo en barras vencidas (clase gantt-late). */
.gantt .bar-wrapper.gantt-late .bar { stroke: var(--danger); stroke-width: 2; }
/* Etiqueta DENTRO de la barra: blanca, legible sobre los colores de barra
   (estatus saturado / slate medio) en ambos temas. La que se desborda
   (.big) usa --text-default sobre el fondo de fila. */
.gantt .bar-label { fill: #ffffff; font-weight: 500; }
.gantt .bar-label.big { fill: var(--text-default); }
/* Cuadrito de leyenda debajo del Gantt. */
.gantt-legend { display: inline-block; width: 11px; height: 11px; border-radius: 2px; vertical-align: -1px; margin-right: 4px; }

/* ── Kanban swimlanes por Actividad (Tareas, §87 Fase 3) ──────────────────── */
.kanban-swimlane { margin-bottom: 14px; }
.kanban-swimlane-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--text-default);
  padding: 6px 4px 6px 8px; margin-bottom: 2px;
  border-left: 3px solid var(--border-strong);
  cursor: pointer; list-style: none; user-select: none;
}
.kanban-swimlane-head::-webkit-details-marker { display: none; }
/* display:flex suprime el triángulo nativo de disclosure de <summary> sin
   avisar que es colapsable (bug real, §code-review) — mismo patrón chevron
   que .policy-advanced/.imp-advanced (::before + rotate en [open]). */
.kanban-swimlane-head::before { content: '▸'; color: var(--text-muted); transition: transform .15s; flex-shrink: 0; }
.kanban-swimlane[open] > .kanban-swimlane-head::before { transform: rotate(90deg); }
/* .kanban-swimlane es ahora un <details> (colapsable, §pto-swim); su
   .kanban-board hijo hereda min-height: calc(100vh - 220px) de la regla de
   arriba (pensada para UN tablero de nivel superior) — sin esto, cada
   swimlane reservaba casi un viewport completo sin importar cuántas tareas
   tuviera. */
.kanban-swimlane .kanban-board { min-height: auto; }
.kanban-swimlane-count {
  font-size: 11px; font-weight: 600; color: var(--text-muted);
  background: var(--surface-raised); border-radius: 10px; padding: 1px 8px;
}

/* ── Reporte: rollup de avances por actividad (§87 Fase 4) ────────────────── */
.rpt-av-list { display: flex; flex-direction: column; gap: 11px; margin-top: 8px; }
.rpt-av-row { display: flex; flex-direction: column; gap: 3px; }
.rpt-av-name { font-size: 14px; color: var(--text-default); font-weight: 500; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rpt-av-bar { height: 7px; background: var(--border-3); border-radius: 4px; overflow: hidden; }
.rpt-av-fill { height: 100%; border-radius: 4px; }
.rpt-av-meta { font-size: 12px; color: var(--text-muted); }

/* ── Demo sin tenant (docs/DEMO_PLAN.md §7.11): banner permanente + login por rol ── */
#demo-banner { position: fixed; left: 12px; bottom: 12px; z-index: 1200; display: flex; align-items: center; gap: 10px; max-width: calc(100vw - 150px); flex-wrap: wrap; padding: 6px 8px 6px 14px; border-radius: 999px; background: var(--surface-raised); border: 1px solid var(--border-strong); color: var(--text-default); font-size: 13px; box-shadow: 0 4px 16px rgba(var(--shadow-rgb), .25); }
#demo-banner .mi { color: var(--accent); }
#demo-banner a.btn { text-decoration: none; }
#demo-banner a.btn .mi { color: inherit; }
@media (max-width: 600px) { #demo-banner { border-radius: 12px; left: 8px; bottom: 8px; max-width: calc(100vw - 150px); font-size: 12px; } }
/* §658: con la barra de abajo del teléfono (≤480 px), la franja de la demo va arriba de ella (la tapaba y no se podía tocar). */
@media (max-width: 480px) { body:has(.bottom-tabs) #demo-banner, body.has-bottom-tabs #demo-banner { bottom: calc(64px + env(safe-area-inset-bottom, 0px)); } }
/* Con un formulario abierto en el teléfono, la franja tapaba sus botones (Crear/Guardar): se esconde hasta que se cierre. */
@media (max-width: 600px) { body:has(#overlay.open) #demo-banner { display: none; } }
#demo-login { display: flex; flex-direction: column; gap: 10px; }
#demo-login .login-btn { width: 100%; }
#demo-banner .demo-ver-como { display: inline-flex; align-items: center; gap: 6px; margin: 0 2px 0 6px; font-size: 12px; color: var(--text-dimmed); }
#demo-banner .demo-ver-como select { font-size: 12px; padding: 2px 6px; min-height: 28px; max-width: 220px; }
/* El botón "Ayuda" vive abajo a la derecha: el banner le deja ~150px y suelta la nota antes de chocar. */
@media (max-width: 1180px) { #demo-banner .demo-banner-nota { display: none; } }
@media (max-width: 760px) { #demo-banner .demo-ver-como > span { display: none; } }
#demo-panel { position: fixed; left: 12px; bottom: 62px; z-index: 1201; width: min(360px, calc(100vw - 24px)); max-height: 70vh; overflow-y: auto; padding: 14px 16px; border-radius: 12px; background: var(--surface-raised); border: 1px solid var(--border-strong); color: var(--text-default); box-shadow: 0 8px 28px rgba(var(--shadow-rgb), .3); }
#demo-panel h4 { margin: 10px 0 6px; font-size: 13px; color: var(--text-strong); }
#demo-panel h4:first-child { margin-top: 0; }
#demo-panel .demo-panel-item { display: flex; width: 100%; justify-content: flex-start; gap: 8px; margin: 4px 0; text-align: left; }
#demo-panel .fg { margin-bottom: 8px; }
#demo-tour { position: fixed; right: 16px; bottom: 84px; z-index: 1202; width: min(360px, calc(100vw - 32px)); padding: 14px 16px; border-radius: 12px; background: var(--surface-raised); border: 1px solid var(--accent); color: var(--text-default); box-shadow: 0 8px 28px rgba(var(--shadow-rgb), .35); }
#demo-tour h4 { margin: 4px 0 6px; font-size: 15px; color: var(--text-strong); }
#demo-tour p { margin: 0 0 10px; font-size: 14px; line-height: 1.45; }
#demo-tour .demo-tour-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
#demo-tour .demo-tour-btns { display: flex; justify-content: space-between; gap: 8px; margin-top: 10px; }
/* Demo: correo que se habría enviado (§7.5). Arriba a la derecha, bajo la barra superior: no tapa el recorrido ni "Ayuda". */
#demo-correos { position: fixed; top: 72px; right: 16px; z-index: 1203; width: min(360px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 8px; }
#demo-correos .demo-correo { padding: 10px 14px; border-radius: 12px; background: var(--surface-raised); border: 1px solid var(--border-strong); border-left: 3px solid var(--accent); color: var(--text-default); box-shadow: 0 8px 28px rgba(var(--shadow-rgb), .3); }
#demo-correos .demo-correo-head { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
#demo-correos .demo-correo-head .btn { margin-left: auto; }
#demo-correos .demo-correo-head .mi { color: var(--accent); }
#demo-correos p { margin: 6px 0; line-height: 1.45; }
#demo-correos .demo-correo-linea { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#demo-correos summary { cursor: pointer; color: var(--accent); margin-top: 4px; }

/* ── Tablero de Dirección por preguntas (plan de Dirección §4.1, §288) ─────────────────────────
   Sólo tokens: se ve igual en tema claro y oscuro. A 400px todo cae a una columna (§4.2 regla 8). */
.dir-tablero { display: flex; flex-direction: column; gap: 18px; margin-bottom: 28px; }
.dir-ventana { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: 13px; color: var(--text-dimmed); }
.dir-aviso { padding: 2px 8px; border-radius: 999px; background: var(--warning-bg); border: 1px solid var(--warning-bd); color: var(--warning); font-size: 12px; }
.dir-bloque { background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 12px; padding: 16px 18px; min-width: 0; }
.dir-h2 { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 16px; font-weight: 700; color: var(--text-strong); }
.dir-cuenta { font-size: 12px; font-weight: 700; padding: 1px 8px; border-radius: 999px; background: var(--surface-2); color: var(--text-subtle); }
.dir-dec-lista { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.dir-dec { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: 8px; border: 1px solid var(--border-1); background: var(--surface-2); }
.dir-dec[onclick] { cursor: pointer; }
.dir-dec .mi { flex-shrink: 0; margin-top: 1px; }
.dir-dec-danger { border-color: var(--danger-bd); } .dir-dec-danger .mi { color: var(--danger); }
.dir-dec-warning { border-color: var(--warning-bd); } .dir-dec-warning .mi { color: var(--warning); }
.dir-dec-info .mi { color: var(--info); }
.dir-dec-txt { min-width: 0; }
.dir-dec-tit { font-size: 14px; font-weight: 600; color: var(--text-strong); }
.dir-dec-p { font-size: 11px; font-weight: 700; padding: 0 6px; border-radius: 4px; background: var(--surface-1); color: var(--text-dimmed); margin-left: 4px; }
.dir-dec-desc { font-size: 13px; color: var(--text-subtle); margin-top: 2px; }
.dir-preguntas { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 18px; }
.dir-pregunta { border-top-width: 3px; }
.dir-borde-bien { border-top-color: var(--success); }
.dir-borde-cuidado { border-top-color: var(--warning); }
.dir-borde-atencion { border-top-color: var(--danger); }
.dir-preg-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.dir-pid { font-size: 11px; font-weight: 800; color: var(--text-dimmed); padding: 1px 6px; border: 1px solid var(--border-1); border-radius: 4px; }
.dir-preg-cuerpo { display: flex; flex-direction: column; gap: 12px; }
.dir-secundarios { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; padding-top: 12px; border-top: 1px solid var(--border-1); }
.dir-ind { min-width: 0; }
.dir-ind-etq { font-size: 12px; font-weight: 600; color: var(--text-dimmed); }
.dir-ind-fila { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px; margin-top: 2px; }
.dir-ind-val { font-size: 20px; font-weight: 700; color: var(--text-strong); overflow-wrap: anywhere; }
.dir-ind-principal .dir-ind-val { font-size: 30px; }
.dir-ind-comp, .dir-ind-sub { font-size: 13px; color: var(--text-subtle); margin-top: 2px; overflow-wrap: anywhere; }
.dir-ind-sub { color: var(--text-dimmed); }
.dir-spark { display: block; margin-top: 6px; max-width: 100%; }
.dir-estado { font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.dir-estado-bien { color: var(--success); background: var(--success-bg); border: 1px solid var(--success-bd); }
.dir-estado-cuidado { color: var(--warning); background: var(--warning-bg); border: 1px solid var(--warning-bd); }
.dir-estado-atencion { color: var(--danger); background: var(--danger-bg); border: 1px solid var(--danger-bd); }
.dir-areas { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--border-1); font-size: 13px; color: var(--text-dimmed); }
.dir-area { display: inline-flex; align-items: center; cursor: pointer; color: var(--accent); font-weight: 600; min-height: 32px; }
@media (max-width: 480px) {
  .dir-preguntas { grid-template-columns: 1fr; }
  .dir-bloque { padding: 14px; }
  .dir-ind-principal .dir-ind-val { font-size: 26px; }
}
.dir-dec-mas > summary { cursor: pointer; color: var(--accent); font-weight: 600; font-size: 13px; min-height: 32px; display: flex; align-items: center; }
.dir-dec-mas > .dir-dec-lista { margin-top: 4px; }
/* §290: nivel de confirmación y trazabilidad en los indicadores de Dirección */
.dir-nivel { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 4px; white-space: nowrap; border: 1px solid var(--border-1); color: var(--text-dimmed); cursor: help; }
.dir-nivel-cruzado { color: var(--info); border-color: var(--info-bd); background: var(--info-bg); }
.dir-nivel-validado { color: var(--success); border-color: var(--success-bd); background: var(--success-bg); }
.dir-origen { display: inline-flex; align-items: center; min-height: 32px; margin-top: 4px; padding: 0; background: none; border: 0; color: var(--accent); font-size: 12px; font-weight: 600; cursor: pointer; }
.dir-origen:hover { text-decoration: underline; }

/* ══ Tablero de Dirección en gráficas (§295, core/dashboard_vistas.js) ══════════════════════════ */
.vz-tablero { display: flex; flex-direction: column; gap: 18px; margin-bottom: 28px; }
.vz-barra { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.vz-barra-der { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }
.vz-ventana { font-size: 13px; color: var(--text-dimmed); }
.vz-selector { display: inline-flex; padding: 4px; border-radius: 12px; background: var(--surface-2); border: 1px solid var(--border-1); }
.vz-sel { min-height: 40px; padding: 0 16px; border-radius: 9px; border: 0; background: transparent; color: var(--text-subtle); font: inherit; font-size: 15px; font-weight: 600; display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.vz-sel.on { background: var(--surface-1); color: var(--text-strong); font-weight: 700; box-shadow: 0 1px 3px rgba(var(--shadow-rgb), .18); }
.vz-sel:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vz-decidir { min-height: 44px; background: var(--danger); color: #fff; border: 0; font-weight: 700; display: inline-flex; align-items: center; gap: 8px; }
.vz-franja { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.vz-kpi { background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 14px; padding: 14px 16px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.vz-kpi-t { font-size: 13px; font-weight: 600; color: var(--text-dimmed); }
.vz-kpi-fila { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; }
.vz-kpi-v { font-size: 26px; font-weight: 700; color: var(--text-strong); letter-spacing: -.5px; line-height: 1.1; }
.vz-mini-bar { width: 110px; }
.vz-temas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; align-items: start; }
.vz-mosaico { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; align-items: start; }
.vz-panel, .vz-tile { background: var(--surface-1); border: 1px solid var(--border-1); border-radius: 16px; padding: 18px 20px; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.vz-hero { gap: 12px; }
.vz-panel-cab { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.vz-panel-cab h2 { margin: 0; font-size: 18px; font-weight: 700; color: var(--text-strong); }
.vz-tile .vz-panel-cab h2 { font-size: 16px; }
.vz-panel-cab h2 a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 2px; min-height: 32px; cursor: pointer; }
.vz-panel-cab h2 a:hover { color: var(--accent); }
.vz-pieza { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.vz-pieza + .vz-pieza { border-top: 1px solid var(--border-1); padding-top: 14px; }
.vz-tit { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.vz-tit h3 { margin: 0; font-size: 14px; font-weight: 600; color: var(--text-subtle); display: inline-flex; align-items: center; gap: 2px; }
.vz-tit > span, .vz-tit > b { margin-left: auto; }
.vz-total { font-size: 15px; color: var(--text-strong); }
.vz-estado { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 700; }
.vz-punto { width: 10px; height: 10px; border-radius: 50%; background: currentColor; }
.vz-estado-bien { color: var(--success); } .vz-estado-cuidado { color: var(--warning); } .vz-estado-atencion { color: var(--danger); }
.vz-chip { font-size: 13px; font-weight: 700; padding: 2px 9px; border-radius: 999px; white-space: nowrap; border: 1px solid var(--border-1); color: var(--text-subtle); background: var(--surface-2); }
.vz-chip-bien { color: var(--success); background: var(--success-bg); border-color: var(--success-bd); }
.vz-chip-cuidado { color: var(--warning); background: var(--warning-bg); border-color: var(--warning-bd); }
.vz-chip-atencion { color: var(--danger); background: var(--danger-bg); border-color: var(--danger-bd); }
.vz-origen { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 8px; border: 0; background: none; color: var(--text-dimmed); cursor: pointer; }
.vz-origen:hover, .vz-origen:focus-visible { color: var(--accent); background: var(--surface-2); }
.vz-pie { font-size: 12px; color: var(--text-dimmed); }
.vz-cifra { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 24px; font-weight: 700; color: var(--text-strong); }
.vz-leyenda { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 13px; color: var(--text-subtle); }
.vz-leyenda span { display: inline-flex; align-items: center; gap: 6px; }
.vz-leyenda i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.vz-leyenda i.vz-i-linea { height: 3px; }
.vz-leyenda b { color: var(--text-strong); }
.vz-neg { color: var(--danger); }
/* SVG */
.vz-svg { max-width: 100%; height: auto; display: block; overflow: visible; font-family: inherit; }  /* nunca crece sobre su tamaño de diseño: sólo se encoge */
.vz-spark { flex-shrink: 0; }
.vz-grid { stroke: var(--chart-grid); stroke-width: 1; }
.vz-cero { stroke: var(--danger); stroke-width: 1.5; stroke-dasharray: 4 3; }
.vz-colchon { stroke: var(--chart-warn); stroke-width: 1.5; stroke-dasharray: 6 4; }
.vz-colchon-t { font-size: 11px; font-weight: 600; fill: var(--warning); }
.vz-eje { font-size: 11px; fill: var(--text-dimmed); }
.vz-nota { font-size: 12px; font-weight: 700; fill: var(--text-strong); }
.vz-nota-s { font-size: 11px; fill: var(--text-subtle); }
.vz-hoy { stroke: var(--text-strong); stroke-width: 1.5; stroke-dasharray: 4 3; }
.vz-hoy-t { font-size: 12px; font-weight: 700; fill: var(--text-strong); }
.vz-futuro { fill: var(--surface-2); opacity: .75; }
.vz-in { fill: var(--chart-in); } .vz-in-soft { fill: var(--chart-in-soft); }
.vz-out { fill: var(--chart-out); } .vz-out-soft { fill: var(--chart-out-soft); }
.vz-in-proy { fill: var(--chart-in-soft); stroke: var(--chart-in); stroke-width: 1.2; stroke-dasharray: 3 2; }
.vz-out-proy { fill: var(--chart-out-soft); stroke: var(--chart-out); stroke-width: 1.2; stroke-dasharray: 3 2; }
.vz-good { fill: var(--chart-good); } .vz-good-soft { fill: var(--chart-good-soft); }
.vz-warn { fill: var(--chart-warn); } .vz-warn-soft { fill: var(--chart-warn-soft); }
.vz-danger { fill: var(--chart-danger); } .vz-danger-soft { fill: var(--chart-danger-soft); }
.vz-neutro { fill: var(--chart-neutro); }
.vz-linea, .vz-linea-in { fill: none; stroke: var(--chart-in); stroke-width: 2.8; stroke-linejoin: round; stroke-linecap: round; }
.vz-linea-good { fill: none; stroke: var(--chart-good); stroke-width: 2.5; stroke-linejoin: round; }
.vz-linea-danger { fill: none; stroke: var(--chart-danger); stroke-width: 2.5; stroke-linejoin: round; }
.vz-area-good { fill: var(--chart-good-soft); opacity: .7; } .vz-area-in { fill: var(--chart-in-soft); opacity: .7; }
.vz-punto-in { fill: var(--chart-in); stroke: var(--surface-1); stroke-width: 2; }
.vz-punto-good { fill: var(--chart-good); stroke: var(--surface-1); stroke-width: 2; }
.vz-punto-danger { fill: var(--chart-danger); stroke: var(--surface-1); stroke-width: 2; }
.vz-punto-hueco { fill: var(--surface-1); stroke: var(--chart-in); stroke-width: 2; }
.vz-dona-fondo { fill: none; stroke: var(--surface-2); }
.vz-dona-good { fill: none; stroke: var(--chart-good); } .vz-dona-danger { fill: none; stroke: var(--chart-danger); }
.vz-dona-out { fill: none; stroke: var(--chart-out); } .vz-dona-fondo, .vz-dona-fondo { stroke: var(--surface-2); }
.vz-dona-t { font-size: 22px; font-weight: 700; fill: var(--text-strong); }
/* Barras HTML */
.vz-apilada { display: flex; border-radius: 6px; overflow: hidden; background: var(--surface-2); }
.vz-seg { display: block; height: 100%; }
.vz-bg-in { background: var(--chart-in); } .vz-bg-in-soft { background: var(--chart-in-soft); }
.vz-bg-in-2 { background: var(--chart-in-2); } .vz-bg-in-3 { background: var(--chart-in-3); } .vz-bg-in-4 { background: var(--chart-in-4); } .vz-bg-in-5 { background: var(--chart-in-5); }
.vz-bg-in-proy { background: var(--chart-in-soft); outline: 1px dashed var(--chart-in); }
.vz-bg-out { background: var(--chart-out); } .vz-bg-out-soft { background: var(--chart-out-soft); }
.vz-bg-good { background: var(--chart-good); } .vz-bg-good-soft { background: var(--chart-good-soft); }
.vz-bg-warn { background: var(--chart-warn); } .vz-bg-warn-soft { background: var(--chart-warn-soft); }
.vz-bg-danger { background: var(--chart-danger); } .vz-bg-danger-soft { background: var(--chart-danger-soft); }
.vz-bg-neutro { background: var(--chart-neutro); }
.vz-hbarras, .vz-embudo { display: flex; flex-direction: column; gap: 8px; }
.vz-hfila { display: grid; grid-template-columns: minmax(90px, 150px) minmax(0, 1fr) 62px; align-items: center; gap: 10px; font-size: 13px; }
.vz-hfila b { color: var(--text-strong); text-align: right; }
.vz-hnom { color: var(--text-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vz-htrack { position: relative; height: 14px; background: var(--surface-2); border-radius: 7px; }
.vz-hbar { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 7px; }
.vz-href { position: absolute; top: -4px; bottom: -4px; border-left: 2px dashed var(--text-strong); }
.vz-bala { position: relative; height: 22px; background: var(--surface-2); border-radius: 6px; }
.vz-bala span { position: absolute; left: 0; top: 4px; bottom: 4px; border-radius: 4px; }
.vz-bala i { position: absolute; right: 0; top: -3px; bottom: -3px; border-left: 3px solid var(--text-strong); }
.vz-bala-pie { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; color: var(--text-subtle); }
.vz-bala-pie b { color: var(--text-strong); }
.vz-gantt { display: flex; flex-direction: column; gap: 10px; }
.vz-gmeses { position: relative; height: 14px; margin-left: 170px; font-size: 11px; color: var(--text-dimmed); }
.vz-gmeses span { position: absolute; }
.vz-gfila { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 10px; align-items: center; font-size: 13px; }
.vz-gtrack { position: relative; height: 16px; background: linear-gradient(var(--chart-grid), var(--chart-grid)) center / 100% 2px no-repeat; }
.vz-gbar { position: absolute; left: 0; top: 3px; height: 10px; border-radius: 5px; }
.vz-gpunto { position: absolute; top: 1px; width: 14px; height: 14px; margin-left: -7px; border-radius: 50%; border: 2px solid var(--surface-1); }
.vz-tickets { display: flex; gap: 8px; flex-wrap: wrap; }
.vz-ticket { width: 28px; height: 28px; border-radius: 8px; background: var(--chart-in-soft); border: 2px solid var(--chart-in); }
.vz-ticket-urg { background: var(--chart-danger); border-color: var(--chart-danger); }
.vz-dona-fila { display: flex; align-items: center; gap: 14px; }
.vz-mini { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--text-subtle); }
.vz-mini b { color: var(--text-strong); }
.vz-personas { display: flex; flex-wrap: wrap; gap: 2px; color: var(--chart-in); align-items: center; }
.vz-personas .mi { font-size: 28px; }
.vz-totales { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.vz-totales div { background: var(--surface-2); border-radius: 10px; padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.vz-totales span { font-size: 12px; color: var(--text-dimmed); }
.vz-totales b { font-size: 20px; color: var(--text-strong); }
@media (max-width: 1100px) { .vz-mosaico { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) { .vz-temas { grid-template-columns: minmax(0, 1fr); } .vz-franja { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px) {
  .vz-mosaico { grid-template-columns: minmax(0, 1fr); }
  .vz-selector { width: 100%; } .vz-sel { flex: 1; justify-content: center; }
  .vz-barra-der { margin-left: 0; width: 100%; } .vz-decidir { flex: 1; justify-content: center; }
  .vz-ventana { width: 100%; }
  .vz-totales { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vz-panel, .vz-tile { padding: 16px; }
  .vz-gmeses { margin-left: 120px; } .vz-gfila { grid-template-columns: 110px minmax(0, 1fr); }
  .vz-hfila { grid-template-columns: minmax(80px, 110px) minmax(0, 1fr) 54px; }
  .vz-kpi .vz-spark { display: none; }
  .vz-kpi-v { font-size: 22px; white-space: nowrap; }
  .vz-embudo .vz-hfila { grid-template-columns: minmax(80px, 100px) minmax(0, 1fr) 70px; }
}

/* ══ Áreas de Dirección en gráficas + llamadas a explorar (§297, core/dashboard_areas.js) ══ */
.vz-ctas { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border-1); }
.vz-cta { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px; border-radius: 10px; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--text-strong); font-size: 14px; font-weight: 600; text-decoration: none; }
.vz-cta:hover, .vz-cta:focus-visible { border-color: var(--accent); color: var(--accent); }
.vz-cta .vz-estado { font-size: 0; gap: 0; } .vz-cta .vz-punto { width: 8px; height: 8px; }
.vz-explora { display: flex; flex-direction: column; gap: 12px; }
.vz-explora .vz-panel-cab h2 { font-size: 18px; margin: 0; color: var(--text-strong); }
.vz-explora-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.vz-area { display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; border-radius: 14px; background: var(--surface-1); border: 1px solid var(--border-1); color: inherit; text-decoration: none; min-width: 0; }
.vz-area:hover, .vz-area:focus-visible { border-color: var(--accent); box-shadow: 0 2px 8px rgba(var(--shadow-rgb), .12); }
.vz-area-cab { display: flex; align-items: center; gap: 8px; font-size: 15px; color: var(--text-strong); }
.vz-area-cab .vz-estado { margin-left: auto; font-size: 12px; }
.vz-area-fila { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; }
.vz-area-fila > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.vz-area-v { font-size: 22px; font-weight: 700; color: var(--text-strong); }
.vz-area-ir { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 700; color: var(--accent); }
.vz-area-pag .vz-barra { gap: 12px; }
.vz-volver { display: inline-flex; align-items: center; gap: 4px; min-height: 40px; padding: 0 12px; border-radius: 10px; border: 1px solid var(--border-1); background: var(--surface-1); color: var(--text-strong); font-size: 14px; font-weight: 600; text-decoration: none; }
.vz-volver:hover { border-color: var(--accent); color: var(--accent); }
.vz-area-titulo { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 24px; font-weight: 700; color: var(--text-strong); }
.vz-area-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; align-items: start; }
.vz-area-grid .vz-ancho { grid-column: 1 / -1; }
.vz-kpi-atencion { border-color: var(--danger-bd); } .vz-kpi-atencion .vz-kpi-v { color: var(--danger); }
.vz-kpi-cuidado { border-color: var(--warning-bd); } .vz-kpi-cuidado .vz-kpi-v { color: var(--warning); }
.vz-eje-cero { stroke: var(--text-dimmed); stroke-width: 1.2; }
.vz-lista { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--text-subtle); }
.vz-lista b { color: var(--text-strong); margin-right: 6px; }
.vz-meses { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; }
.vz-mes { text-align: center; padding: 8px 0; border-radius: 8px; font-size: 13px; font-weight: 600; background: var(--surface-2); color: var(--text-dimmed); border: 1px dashed var(--border-2); }
.vz-mes.on { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-bd); }
.vz-seguir h2 { margin: 0 0 8px; font-size: 16px; font-weight: 700; color: var(--text-strong); }
.vz-seguir .vz-ctas { border-top: 0; padding-top: 0; }
.vz-legado { margin: 8px 0 28px; border: 1px solid var(--border-1); border-radius: 14px; background: var(--surface-1); }
.vz-legado > summary { cursor: pointer; padding: 14px 18px; font-size: 15px; font-weight: 600; color: var(--text-subtle); display: flex; align-items: center; gap: 8px; min-height: 44px; }
.vz-legado[open] > summary { border-bottom: 1px solid var(--border-1); }
.vz-legado > *:not(summary) { margin: 16px 18px; }
@media (max-width: 1100px) { .vz-explora-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .vz-area-grid { grid-template-columns: minmax(0, 1fr); } .vz-explora-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px) { .vz-explora-grid { grid-template-columns: minmax(0, 1fr); } .vz-area-titulo { font-size: 20px; width: 100%; } .vz-cta { flex: 1 1 auto; } }

/* ── §301 Estructura de datos: visor compartido (popup de Estructura del Portal + estructura.php) ── */
.schema-mod { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; white-space: nowrap;
  background: var(--info-bg); color: var(--info); border: 1px solid var(--info-bd); }
.schema-mod-nucleo { background: var(--surface-2); color: var(--text-soft); border-color: var(--border-2); }
.ev { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 16px; min-height: 0; }
.ev-nav { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.ev-nav .search-input { width: 100%; }
.ev-nav-lista { overflow-y: auto; min-height: 0; border: 1px solid var(--border-1); border-radius: 10px; background: var(--surface-1); padding: 6px; }
.ev-grupo + .ev-grupo { margin-top: 6px; }
.ev-grupo-t { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); padding: 8px 8px 4px; }
.ev-item { display: flex; justify-content: space-between; align-items: center; gap: 8px; width: 100%; text-align: left; padding: 7px 10px; min-height: 36px;
  border: 0; border-radius: 8px; background: transparent; color: var(--text-default); font: inherit; font-size: 14px; cursor: pointer; }
.ev-item:hover { background: var(--surface-2); }
.ev-item.activo { background: rgba(var(--accent-rgb), .14); color: var(--accent); font-weight: 600; }
.ev-item-n { font-size: 12px; color: var(--text-dimmed); font-variant-numeric: tabular-nums; }
.ev-main { min-width: 0; overflow-y: auto; outline: none; }
.ev-det-cab { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; align-items: flex-start; }
.ev-titulo { font-size: 22px; margin: 0 0 6px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--text-strong); word-break: break-all; }
.ev-meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ev-mod { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; background: var(--info-bg); color: var(--info); border: 1px solid var(--info-bd); }
.ev-mod-nucleo { background: var(--surface-2); color: var(--text-soft); border-color: var(--border-2); }
.ev-mod-ext { background: transparent; color: var(--text-muted); border-style: dashed; border-color: var(--border-2); }
.ev-desc { margin: 8px 0 0; color: var(--text-soft); font-size: 14px; max-width: 70ch; }
.ev-cifras { display: flex; gap: 10px; }
.ev-cifras > div { display: flex; flex-direction: column; align-items: center; min-width: 76px; padding: 8px 10px; border-radius: 10px; background: var(--surface-1); border: 1px solid var(--border-1); }
.ev-cifras b { font-size: 20px; color: var(--text-strong); font-variant-numeric: tabular-nums; }
.ev-cifras span { font-size: 12px; color: var(--text-muted); }
.ev-cifras .ev-cifra-falta b { color: var(--warning); }
.ev-sec { margin-top: 18px; }
.ev-sec h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); margin: 0 0 8px; }
.ev-sec-cab { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.ev-sec-cab h3 { margin: 0; }
.ev-diag-cab { display: flex; justify-content: space-between; font-size: 12px; color: var(--text-muted); padding: 0 4px 4px; }
.ev-diag-wrap { border: 1px solid var(--border-1); border-radius: 10px; background: var(--surface-1); padding: 8px; overflow-x: auto; }
.ev-diag { display: block; max-width: 100%; height: auto; margin: 0 auto; }
.ev-diag .ev-arista { fill: none; stroke: var(--border-strong); stroke-width: 1.5; }
.ev-diag .ev-flecha { fill: var(--border-strong); }
.ev-diag .ev-n rect { fill: var(--surface-0); stroke: var(--border-2); stroke-width: 1; }
.ev-diag .ev-n text { fill: var(--text-default); font-size: 12px; }
.ev-diag .ev-n .ev-n-t { font-weight: 600; font-size: 12.5px; }
.ev-diag .ev-n .ev-n-s { fill: var(--text-muted); font-size: 11px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.ev-diag .ev-n[data-ev-ir] { cursor: pointer; }
.ev-diag .ev-n[data-ev-ir]:hover rect, .ev-diag .ev-n[data-ev-ir]:focus rect { stroke: var(--accent); stroke-width: 2; }
.ev-diag .ev-n-fuera rect { stroke-dasharray: 4 3; }
.ev-diag .ev-n-fuera text { fill: var(--text-dimmed); }
.ev-diag .ev-n-mas rect { fill: transparent; stroke-dasharray: 4 3; }
.ev-diag .ev-n-mas text { fill: var(--text-muted); }
.ev-diag .ev-n-centro rect { fill: rgba(var(--accent-rgb), .14); stroke: var(--accent); stroke-width: 2; }
.ev-diag .ev-n-centro text { fill: var(--accent); font-weight: 700; font-size: 14px; }
.ev-todas { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.ev-todas-movil { display: none; }
.ev-vacio { padding: 14px; border: 1px dashed var(--border-2); border-radius: 10px; color: var(--text-muted); font-size: 14px; }
.ev-tabla-wrap { overflow-x: auto; }
.ev-tabla td { vertical-align: top; font-size: 14px; }
.ev-col { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 600; color: var(--text-strong); word-break: break-all; }
.ev-raw { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; color: var(--text-muted); }
.ev-tenue { color: var(--text-dimmed); font-size: 12px; }
.ev-tipo { display: inline-block; padding: 1px 8px; border-radius: 6px; font-size: 12px; font-weight: 600; border: 1px solid var(--border-2); background: var(--surface-2); color: var(--text-default); }
.ev-tipo-number { background: var(--success-bg); color: var(--success); border-color: var(--success-bd); }
.ev-tipo-dateTime { background: var(--purple-bg); color: var(--purple); border-color: var(--purple-bd); }
.ev-tipo-boolean { background: var(--warning-bg); color: var(--warning); border-color: var(--warning-bd); }
.ev-extra { min-width: 200px; }
.ev-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px; font: inherit; font-size: 12px; line-height: 1.6;
  border: 1px solid var(--border-2); background: var(--surface-1); color: var(--text-soft); margin: 2px 0; }
.ev-chip .mi { font-size: 14px; }
button.ev-chip-rel { cursor: pointer; color: var(--accent); border-color: rgba(var(--accent-rgb), .45); background: rgba(var(--accent-rgb), .08); }
button.ev-chip-rel:hover { background: rgba(var(--accent-rgb), .16); }
button.ev-chip-rel:disabled { cursor: default; color: var(--text-muted); border-style: dashed; background: transparent; }
.ev-chip-cat { cursor: pointer; list-style: none; }
.ev-chip-cat::-webkit-details-marker { display: none; }
.ev-chip-sens { color: var(--danger); border-color: var(--danger-bd); background: var(--danger-bg); }
.ev-cat { display: inline-block; }
.ev-cat[open] { display: block; }
.ev-vals { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 2px; }
.ev-vals span { font-size: 12px; padding: 1px 7px; border-radius: 6px; background: var(--surface-2); color: var(--text-default); }
.ev-de { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.ev-falta { display: inline-block; margin-top: 2px; font-size: 12px; color: var(--warning); }
.ev-nota { font-size: 12px; color: var(--text-dimmed); margin-top: 10px; }
.ev-link { border: 0; background: none; padding: 0; font: inherit; color: var(--accent); cursor: pointer; text-decoration: underline; }
/* En el modal de Estructura del Portal: panel de altura fija, cada lado con su scroll. */
.ev-en-modal .ev { height: min(70vh, 720px); }
/* Página pública estructura.php */
.ev-pagina { background: var(--bg-page); color: var(--text-default); min-height: 100vh; }
.ev-top { position: sticky; top: 0; z-index: 5; display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 20px; background: var(--bg-topbar); border-bottom: 1px solid var(--border-1); }
.ev-top-marca { display: flex; align-items: center; gap: 8px; font-size: 16px; color: var(--text-strong); }
.ev-top-der { display: flex; align-items: center; gap: 12px; }
.ev-app { padding: 18px 20px 28px; max-width: 1400px; margin: 0 auto; }
.ev-app > .ev-intro { margin-bottom: 14px; display: flex; flex-direction: column; gap: 4px; }
.ev-pagina #ev-vista .ev { height: calc(100vh - 170px); min-height: 480px; }
.ev-login { max-width: 460px; margin: 8vh auto 0; padding: 24px; }
.ev-login h1 { font-size: 20px; display: flex; align-items: center; gap: 8px; margin: 0 0 10px; }
.ev-login .fg { margin: 14px 0; }
.ev-err { color: var(--danger); background: var(--danger-bg); border: 1px solid var(--danger-bd); border-radius: 8px; padding: 8px 10px; font-size: 14px; margin-bottom: 12px; }
@media (max-width: 760px) {
  .ev { grid-template-columns: 1fr; }
  .ev-nav-lista { max-height: 220px; }
  .ev-en-modal .ev, .ev-pagina #ev-vista .ev { height: auto; }
  .ev-main { overflow: visible; }
  .ev-app { padding: 14px 16px 24px; }
  .ev-diag-wrap, .ev-diag-cab { display: none; }
  .ev-todas-movil { display: flex; }
}

/* §343 Reportes: el bloque al que lleva una página del menú se resalta un momento al llegar. */
.rep-foco { outline: 3px solid var(--accent); outline-offset: 2px; transition: outline-color .6s; }

/* §343 Demo: tablero externo simulado (Athena) dentro de Reportes. Sólo lo pinta demo.js. */
.ath-aviso { display: flex; align-items: center; gap: 6px; margin: 14px 0 8px; font-size: 13px; color: var(--text-muted); }
.ath-marco { border: 1px solid var(--border-strong); border-radius: 12px; overflow: hidden; background: var(--surface-1); }
.ath-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 16px; background: var(--surface-3); border-bottom: 1px solid var(--border-1); color: var(--text-strong); font-size: 14px; }
.ath-top span { color: var(--text-muted); font-size: 13px; }
.ath-cuerpo { display: flex; min-height: 420px; }
.ath-nav { flex: 0 0 190px; padding: 10px 0; border-right: 1px solid var(--border-1); background: var(--surface-2); display: flex; flex-direction: column; }
.ath-nav-t { padding: 4px 16px 8px; font-weight: 600; color: var(--text-strong); font-size: 15px; }
.ath-pag { padding: 7px 16px; font-size: 14px; color: var(--text-dimmed); border-left: 3px solid transparent; }
a.ath-pag { color: var(--text-default); cursor: pointer; text-decoration: none; }
a.ath-pag:hover { background: var(--surface-3); }
.ath-pag.act { border-left-color: var(--accent); background: var(--surface-3); color: var(--text-strong); font-weight: 600; }
.ath-lienzo { flex: 1; min-width: 0; padding: 16px 20px; }
.ath-titulo { margin: 0 0 12px; font-size: 20px; color: var(--text-strong); }
.ath-h { margin: 18px 0 8px; font-size: 14px; color: var(--text-strong); }
.ath-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
.ath-tile { padding: 12px 14px; border: 1px solid var(--border-1); border-radius: 10px; background: var(--surface-raised); }
.ath-tile-lbl { font-size: 12px; color: var(--text-muted); }
.ath-tile-val { font-size: 22px; font-weight: 700; color: var(--text-strong); margin-top: 2px; }
.ath-tile-sub { font-size: 12px; color: var(--text-dimmed); margin-top: 2px; }
.ath-barras { display: flex; flex-direction: column; gap: 6px; }
.ath-barra { display: grid; grid-template-columns: minmax(120px, 210px) 1fr auto; align-items: center; gap: 10px; font-size: 14px; }
.ath-barra-lbl { color: var(--text-default); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ath-barra-track { height: 14px; background: var(--surface-3); border-radius: 4px; overflow: hidden; }
.ath-barra-fill { display: block; height: 100%; background: var(--accent); opacity: .55; border-radius: 0 4px 4px 0; }
.ath-barra.sel .ath-barra-fill { opacity: 1; }
.ath-barra.sel .ath-barra-lbl { font-weight: 700; color: var(--text-strong); }
.ath-barra.neg .ath-barra-fill { background: var(--danger); }
.ath-barra-val { font-variant-numeric: tabular-nums; color: var(--text-strong); min-width: 90px; text-align: right; }
.ath-tabla { width: 100%; margin-top: 14px; border-collapse: collapse; font-size: 14px; }
.ath-tabla th, .ath-tabla td { padding: 6px 8px; border-bottom: 1px solid var(--border-1); text-align: left; }
.ath-tabla th { color: var(--text-muted); font-weight: 600; font-size: 12px; }
.ath-tabla .num { text-align: right; font-variant-numeric: tabular-nums; }
.ath-vacio { padding: 30px 0; color: var(--text-muted); }
@media (max-width: 760px) {
  .ath-cuerpo { flex-direction: column; }
  .ath-nav { flex: none; flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--border-1); }
  .ath-nav-t { width: 100%; }
  .ath-pag { border-left: 0; border-bottom: 3px solid transparent; }
  .ath-pag.act { border-bottom-color: var(--accent); }
  .ath-barra { grid-template-columns: 1fr auto; }
  .ath-barra-track { grid-column: 1 / -1; grid-row: 2; }
  .ath-tabla { display: block; overflow-x: auto; }
}

/* §345 Modo embebido (`?embed=1`, admin.php): dentro del marco de Athena sólo se ve la pantalla. */
html.embed .topbar, html.embed .sidebar, html.embed .sidebar-backdrop, html.embed #demo-banner,
html.embed #viewmode-banner, html.embed #impersonate-banner, html.embed #ayuda-btn, html.embed .ayuda-btn { display: none !important; }
html.embed .layout { height: 100vh; height: 100dvh; }
html.embed .content { margin-left: 0; max-width: none; }
