/* ==========================================================================
   base.css — Tema luivo-aero · CAPA 1 (base Tabler-plana).
   Bloque :root de tokens.md + reset + estructura de todos los componentes.
   Ningún componente usa un hex suelto: todo sale de var(--…) de :root.
   La capa Aero (aero.css) se aplica ENCIMA y sube --radius a 14px.
   ========================================================================== */

:root{
  --primary:#006ED0; --primary-dk:#0058AB;
  /* Deriva del acento: al cambiar --primary (tema), este tinte lo sigue. */
  --primary-lt:color-mix(in srgb, var(--primary) 8%, transparent);
  --secondary:#64748B; --success:#2fb344; --warning:#f59f00; --danger:#d63939; --info:#17a2b8;
  --blue:#066fd1; --green:#2fb344; --yellow:#f59f00; --orange:#f76707; --red:#d63939; --purple:#ae3ec9; --cyan:#17a2b8;
  --green-lt:rgba(47,179,68,0.09); --red-lt:rgba(214,57,57,0.09); --yellow-lt:rgba(245,159,0,0.10); --purple-lt:rgba(174,62,201,0.09); --cyan-lt:rgba(6,182,212,0.10); --gray-lt:rgba(100,116,139,0.12);
  --sidebar-bg:#1a2332; --sidebar-text:#7b8fa3; --sidebar-width:252px; --sidebar-collapsed:64px;
  --body-bg:#f5f7fb; --surface:#FFFFFF; --border:#e6e7eb; --border-translucent:rgba(4,32,69,0.08);
  --text-primary:#1e2633; --text-secondary:#626d7d; --text-muted:#7e8896;
  --radius:3px; --shadow-card:0 0 0 1px var(--border-translucent), rgba(30,38,51,0.04) 0 2px 4px 0;
  --font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;

  /* Derivados usados por la estructura (no hex sueltos en las reglas). */
  --blanco:#ffffff;                 /* texto/superficie sobre color de marca */
  --sidebar-text-activo:#ffffff;
  --sidebar-hover:rgba(255,255,255,0.06);
  --topbar-h:58px;
  /* Gloss del botón primario en Aero (web.md 2.4). #1a86e6 está sancionado ahí;
     su compañero oscuro para el hover se tokeniza aquí para no dejar hex sueltos. */
  --primary-gloss:#1a86e6; --primary-gloss-dk:#1479d6;
}

*{ box-sizing:border-box; -webkit-user-drag:none; }
html,body{ height:100%; }
body{
  margin:0;
  background:var(--body-bg);
  color:var(--text-primary);
  font-family:var(--font-family);
  font-size:0.9rem;
  -webkit-font-smoothing:antialiased;
}
a{ color:var(--primary); text-decoration:none; }
a:hover{ text-decoration:underline; }

/* Foco consistente en TODO input/select (tokens.md · sección Foco). */
.form-control:focus, .form-select:focus, .custom-select-btn:focus,
.custom-select.show .custom-select-btn {
  border-color: var(--primary) !important;
  box-shadow: 0 0 0 0.15rem rgba(var(--primary-rgb), 0.2) !important;
}

/* Inputs con icono integrado */
.input-con-icono { position: relative; }
.input-con-icono > i.bi { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); font-size: 0.85rem; z-index: 4; pointer-events: none; color: var(--text-muted); }
.input-con-icono > .form-control,
.input-con-icono .custom-select-btn { padding-left: 32px; }

.form-control, .form-select{
  border-radius:var(--radius);
  border-color:var(--border);
  color:var(--text-primary);
  font-size:0.875rem;
}
.xml-file-pick{
  display:flex; align-items:center; gap:.75rem;
}
.btn-xml-file{
  display:inline-flex; align-items:center; gap:.4rem;
  background:#0d9488; color:#fff; border:none;
  padding:.45rem .9rem; border-radius:var(--radius);
  font-size:.85rem; font-weight:600; cursor:pointer;
  transition:background .2s; white-space:nowrap;
}
.btn-xml-file:hover{ background:#0f766e; }
.btn-xml-file i{ font-size:1rem; }
.xml-file-name{
  font-size:.82rem; color:var(--text-secondary);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* Foco visible en controles personalizados (los nativos ya lo traen arriba).
   Sobre el sidebar de vidrio oscuro se usa un anillo claro para que contraste. */
.btn-icono:focus-visible,
.segmentado button:focus-visible,
.toggle-pass:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; }
.menu-item:focus-visible{ outline:2px solid var(--blanco); outline-offset:-2px; }

.form-label{ font-size:0.8rem; font-weight:600; color:var(--text-secondary); margin-bottom:0.3rem; }
.form-text{ color:var(--text-muted); font-size:0.72rem; }

/* ── Botones ─────────────────────────────────────────────────────────────── */
.btn{ border-radius:var(--radius); font-size:0.85rem; font-weight:600; }
.btn-primary{ background:var(--primary); border-color:var(--primary); }
.btn-primary:hover, .btn-primary:focus{ background:var(--primary-dk); border-color:var(--primary-dk); }
.btn-danger{ background:var(--danger); border-color:var(--danger); }
.btn-light{ background:var(--surface); border-color:var(--border); color:var(--text-secondary); }
.btn-light:hover{ background:var(--body-bg); border-color:var(--border); color:var(--text-primary); }
.btn-icono{
  display:inline-flex; align-items:center; justify-content:center;
  width:28px; height:28px; font-size:0.85rem; padding:0; border-radius:var(--radius);
  border:1px solid var(--border); background:var(--surface); color:var(--text-secondary);
  cursor:pointer; transition:all .12s;
}
.btn-icono:hover{ color:var(--primary); border-color:var(--primary); background:var(--primary-lt); }
.btn-icono:active{ transform:scale(0.9); }
/* Botones de acción con color propio para distinguirse entre sí:
   editar=azul · permisos=púrpura · activar=verde · peligro/desactivar=rojo. */
.btn-icono.editar{ color:var(--primary); background:var(--primary-lt); border-color:transparent; }
.btn-icono.editar:hover{ color:var(--blanco); background:var(--primary); }
.btn-icono.permisos{ color:var(--purple); background:var(--purple-lt); border-color:transparent; }
.btn-icono.permisos:hover{ color:var(--blanco); background:var(--purple); }
.btn-icono.activar{ color:var(--success); background:var(--green-lt); border-color:transparent; }
.btn-icono.activar:hover{ color:var(--blanco); background:var(--success); }
.btn-icono.peligro{ color:var(--danger); background:var(--red-lt); border-color:transparent; }
.btn-icono.peligro:hover{ color:var(--blanco); background:var(--danger); border-color:transparent; }

/* ── Tab buttons (pestañas de módulo) ────────────────────────────────────── */
.tab-btn:not(.btn-primary){
  background:var(--surface); color:var(--text-secondary);
  border:1px solid var(--border);
  box-shadow:0 1px 2px rgba(0,0,0,.06);
}
.tab-btn:not(.btn-primary):hover{
  background:var(--primary-lt); color:var(--primary);
  border-color:var(--primary);
}

/* ── Marca / login ───────────────────────────────────────────────────────── */
.login-pantalla{
  min-height:100vh; display:flex; align-items:center; justify-content:center; padding:1.5rem;
}
.login-card{
  width:100%; max-width:400px;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow-card); padding:2rem 1.75rem;
}
.login-marca{ text-align:center; margin-bottom:1.5rem; }
.login-logo{
  width:60px; height:60px; border-radius:16px; margin:0 auto 0.85rem;
  display:flex; align-items:center; justify-content:center;
  background:var(--primary); color:var(--blanco); font-size:1.7rem;
}
.login-titulo{ font-size:1.2rem; font-weight:700; letter-spacing:-0.02em; margin:0; }
.login-sub{ font-size:0.8rem; font-weight:500; color:var(--text-muted); margin-top:0.15rem; }
.login-campo{ position:relative; margin-bottom:0.9rem; }
.login-campo > .bi{
  position:absolute; left:0.75rem; top:50%; transform:translateY(-50%);
  color:var(--text-muted); pointer-events:none;
}
.login-campo .form-control{ padding-left:2.25rem; height:46px; }
.login-campo .toggle-pass{
  position:absolute; right:0.6rem; top:50%; transform:translateY(-50%);
  background:none; border:none; color:var(--text-muted); cursor:pointer; padding:4px;
}
.login-btn{ width:100%; height:46px; font-weight:700; letter-spacing:0.5px; margin-top:0.35rem; }
.login-error{
  display:none; align-items:center; gap:0.5rem;
  background:var(--red-lt); color:var(--danger);
  border-radius:var(--radius); padding:0.6rem 0.75rem; font-size:0.82rem; margin-bottom:0.9rem;
}
.login-error.visible{ display:flex; }
.login-aviso{
  display:none; align-items:center; gap:0.5rem;
  background:var(--yellow-lt); color:var(--warning);
  border-radius:var(--radius); padding:0.6rem 0.75rem; font-size:0.82rem; margin-bottom:0.9rem;
}
.login-aviso.visible{ display:flex; }

/* ── Layout: FRAME FIJO (100vh, sin scroll de página) ──────────────────────
   Estructura de referencia (panel-diseno/admin.html): el shell es fijo a la
   altura de la ventana; el header y el footer viven en .app-main y NO scrollean.
   El sidebar AUTO-OCULTA: es un rail de iconos que se expande al pasar el mouse
   (montándose ENCIMA del contenido). El botón hamburguesa lo FIJA abierto
   (.sider-fijo) — y ahí el header/footer/contenido corren con él. */
.app-shell{ height:100vh; overflow:hidden; }

.sidebar{
  position:fixed; top:0; left:0; bottom:0; z-index:1040;
  width:var(--sidebar-collapsed);           /* rail de iconos por defecto */
  background:var(--sidebar-bg); color:var(--sidebar-text);
  display:flex; flex-direction:column; overflow:hidden;
  transition:width .22s cubic-bezier(.25,1,.5,1);
}
.sidebar:hover, .app-shell.sider-fijo .sidebar{ width:var(--sidebar-width); }

/* Marca: logo centrado en el rail. Al expandir, se apila y crece. */
.sidebar-marca{
  min-height:var(--topbar-h); height:var(--topbar-h); flex:0 0 auto;
  display:flex; align-items:center; flex-direction:row; gap:0.4rem;
  background:rgba(0,0,0,0.15); color:var(--blanco); white-space:nowrap; overflow:hidden;
  transition:all .22s cubic-bezier(.25,1,.5,1);
}
.sidebar:hover .sidebar-marca, .app-shell.sider-fijo .sidebar-marca{
  flex-direction:column; justify-content:center;
  height:130px; gap:0.5rem;
}
.marca-logo{
  width:var(--sidebar-collapsed); min-width:var(--sidebar-collapsed);
  display:flex; align-items:center; justify-content:center;
}
.img-logo{
  width:24px; height:24px; object-fit:contain;
  transition:all .22s cubic-bezier(.25,1,.5,1);
}
.sidebar:hover .img-logo, .app-shell.sider-fijo .img-logo{
  width:64px; height:64px;
}
.marca-txt{ font-weight:700; letter-spacing:-0.01em; opacity:0; transition:opacity .18s; line-height:1; }
.sidebar:hover .marca-txt, .app-shell.sider-fijo .marca-txt{ opacity:1; }

/* Menú por categorías (acordeón). */
.sidebarMenu{ flex:1 1 auto; overflow-y:auto; overflow-x:hidden; padding:0.5rem 0; }
.menu-cat{ margin:0; }

/* Cabecera de categoría: oculta en el rail; visible al expandir. Clic →
   despliega/pliega su submenú (efecto acordeón). */
.menu-cat-head{
  width:100%; border:none; background:none; cursor:pointer;
  display:flex; align-items:center; height:40px;
  color:rgba(255,255,255,.42); font-size:0.68rem; font-weight:700;
  letter-spacing:0.07em; text-transform:uppercase; white-space:nowrap;
}
.menu-cat-head:hover{ color:rgba(255,255,255,.75); }
.menu-cat-chevron{
  margin:0 0.8rem 0 auto; font-size:0.8rem; transition:transform .22s ease, opacity .18s; opacity:0;
}
.sidebar:hover .menu-cat-chevron, .app-shell.sider-fijo .menu-cat-chevron{ opacity:0.7; }
.menu-cat.abierto > .menu-cat-head .menu-cat-chevron{ transform:rotate(180deg); }

/* Submenú. Oculto por defecto (0fr). Se expande sólo si está abierto Y el sidebar está activo. */
.menu-sub{ display: grid; grid-template-rows: 0fr; overflow:visible; transition:grid-template-rows .25s ease; }
.menu-sub-inner { overflow: hidden; min-height: 0; }
.sidebar:hover .menu-cat.abierto > .menu-sub,
.app-shell.sider-fijo .menu-cat.abierto > .menu-sub{ grid-template-rows: 1fr; }

/* Ítem: el icono va en un cuadro del ancho del rail → SIEMPRE centrado. */
.menu-item{
  display:flex; align-items:center; height:42px; margin:2px 8px;
  color:var(--sidebar-text); border-radius:10px; cursor:pointer; white-space:nowrap;
  text-decoration:none; transition:background .12s, color .12s, padding-left .2s;
}
.sidebar:hover .menu-sub .menu-item,
.app-shell.sider-fijo .menu-sub .menu-item {
  padding-left: 0.65rem;
}
.menu-icono{
  width:calc(var(--sidebar-collapsed) - 16px); min-width:calc(var(--sidebar-collapsed) - 16px);
  display:flex; align-items:center; justify-content:center; font-size:1.15rem; flex:0 0 auto;
  transition: font-size .2s ease;
}
.menu-cat-head .menu-icono { font-size: 1.15rem; }
.sidebar:hover .menu-item .menu-icono,
.app-shell.sider-fijo .menu-item .menu-icono {
  font-size: 1rem;
}
/* Hover: SIN subrayado, solo un tinte muy transparente del acento. */
.menu-item:hover{
  background:color-mix(in srgb, var(--primary) 22%, transparent);
  color:var(--blanco); text-decoration:none;
}
.menu-item.active{ background:color-mix(in srgb, var(--primary) 50%, transparent); color:var(--blanco); }
.menu-text{ opacity:0; transition:opacity .18s; }
.sidebar:hover .menu-text, .app-shell.sider-fijo .menu-text{ opacity:1; }
/* Ítem(s) de INICIO: sueltos arriba del acordeón, separados por una línea sutil. */
.menu-top{ padding-bottom:0.4rem; margin-bottom:0.3rem; border-bottom:1px solid rgba(255,255,255,.08); }

/* ── Contenido: header + scroll + footer, todo corriendo con el sidebar ──── */
.app-main{
  height:100vh; margin-left:var(--sidebar-collapsed);
  display:flex; flex-direction:column; overflow:hidden;
  transition:margin-left .22s cubic-bezier(.25,1,.5,1);
}
.app-shell.sider-fijo .app-main{ margin-left:var(--sidebar-width); }

.topbar{
  height:var(--topbar-h); flex:0 0 auto;
  display:flex; align-items:center; gap:0.75rem;
  padding:0 1.1rem;
  background:var(--surface); border-bottom:1px solid var(--border);
  /* El backdrop-filter del tema aero convierte la topbar en stacking context:
     sin z-index propio, el panel de la campana (z 1060 INTERNO) quedaba
     atrapado al nivel 0 y el contenido pintaba encima. 30 la sube sobre el
     contenido normal, debajo del sider movil (1035+) y de los toasts (1080). */
  position:relative; z-index:30;
}
.hamburguesa{
  width:38px; height:38px; flex:0 0 auto; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
  border:none; background:none; color:var(--text-secondary);
  border-radius:var(--radius); cursor:pointer; font-size:1.25rem; transition:all .12s;
}
.hamburguesa:hover{ background:var(--primary-lt); color:var(--primary); }
.hamburguesa:active{ transform:scale(0.9); }
.topbar-tit{ min-width:0; }
.topbar-titulo{ font-size:1.05rem; font-weight:700; letter-spacing:-0.02em; margin:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topbar-sub{ font-size:0.72rem; color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topbar-spacer{ flex:1 1 auto; }
.topbar .btn-icono { border: none; background: transparent; outline: none; }
.topbar .btn-icono:focus-visible { outline: none; }
.topbar .btn-icono:hover { background: var(--primary-lt); color: var(--primary); }
.topbar-usuario{ display:flex; align-items:center; gap:0.6rem; }
.topbar-avatar{
  width:34px; height:34px; border-radius:50%;
  background:var(--primary); color:var(--blanco); font-weight:700; font-size:0.85rem;
  display:flex; align-items:center; justify-content:center; flex:0 0 auto;
}
.topbar-nombre{ line-height:1.1; text-align:right; }
.topbar-nombre b{ font-size:0.82rem; display:block; }
.topbar-nombre span{ font-size:0.7rem; color:var(--text-muted); }

/* ── Área de contenido: NO scrollea la página. Solo la TABLA scrollea dentro
   de su tarjeta; la cabecera de la tarjeta (toolbar/filtros) queda fija, y las
   columnas (thead) quedan pegadas arriba. ─────────────────────────────────── */
.app-content{
  flex:1 1 auto; min-height:0; overflow:hidden; padding:1.25rem;
  display:flex; flex-direction:column; gap:1rem;
}
/* Las tarjetas de la vista no arrastran su margen (el gap las separa). */
.app-content > .card{ margin:0 !important; }
/* La tarjeta-lista (las vistas le ponen la clase .card-lista) crece y confina
   el scroll a la tabla. Clase explícita, no :has() — soporte universal y
   evita depender de una sola característica CSS. */
.app-content > .card-lista,
.vista-scroll .card-lista{
  flex:1 1 0; min-height:0; display:flex; flex-direction:column; overflow:hidden;
}
.card-lista > .card-cab{ flex:0 0 auto; }
.card-lista > .card-cuerpo{
  flex:1 1 0; min-height:0; padding:0 !important; overflow:hidden;
  display:flex; flex-direction:column;
}
.card-lista .tabla-wrap{ flex:1 1 0; min-height:0; overflow-y:auto; overflow-x:auto; }
/* Estados sin tabla (vacío, etc.) pueden scrollear normalmente. */
.app-content > .estado-vacio{ overflow-y:auto; }

.app-footer{
  flex:0 0 auto; height:38px;
  display:flex; align-items:center; justify-content:center; gap:0.75rem;
  padding:0 1.1rem;
  background:var(--surface); border-top:1px solid var(--border);
  font-size:0.72rem; color:var(--text-muted);
  position:relative;
}
.app-footer strong{ color:var(--text-secondary); font-weight:600; }
.app-footer-info{ position:absolute; right:1.1rem; }

/* Contenedor de vista NO-tabla que puede scrollear dentro del frame fijo. */
.vista-scroll{ flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden;
  display:flex; flex-direction:column; }
.vista-scroll .card + .card{ margin-top:1rem; }
/* Paneles intermedios (tabs de compras/geografía) deben crecer dentro del scroll. */
.vista-scroll > [id^="panel-"]{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }

/* ── Apariencia (módulo de tema) ─────────────────────────────────────────── */
.tema-galeria{ display:grid; grid-template-columns:repeat(auto-fill, minmax(110px, 1fr)); gap:0.6rem; }
.tema-card{
  display:flex; flex-direction:column; align-items:stretch; gap:0.3rem;
  border:2px solid var(--border); border-radius:var(--radius); background:var(--surface);
  padding:0.4rem; cursor:pointer; position:relative; transition:border-color .12s, box-shadow .12s;
}
.tema-card:hover{ border-color:var(--primary); }
.tema-card.activo{ border-color:var(--primary); box-shadow:0 0 0 3px var(--primary-lt); }
.tema-card-nombre{ font-size:0.75rem; font-weight:600; color:var(--text-primary); text-align:center; }
.tema-card-check{
  position:absolute; top:-8px; right:-8px; color:var(--primary); font-size:1.1rem;
  background: var(--surface); border-radius: 50%; width: 1.1rem; height: 1.1rem;
  display: flex; align-items: center; justify-content: center; line-height: 1; box-shadow: 0 0 0 2px var(--surface); z-index: 2;
}
/* Miniatura del diseño: barra de acento + cuerpo. */
.tema-mini{
  height:40px; border-radius:6px; overflow:hidden; display:flex; flex-direction:column;
  border:1px solid var(--border); background:#f0f3f8;
}
.tema-mini-bar{ height:12px; background:var(--mini); }
.tema-mini-body{ flex:1; background:#fff; margin:4px; border-radius:3px; box-shadow:0 0 0 1px rgba(4,32,69,.06); }
.tema-mini.aero .tema-mini-body{ background:rgba(255,255,255,.62); backdrop-filter:blur(2px); }
.tema-mini.aero{ background:linear-gradient(135deg, color-mix(in srgb, var(--mini) 18%, #eef3fb), #f6f8fc); }

.tema-opciones{ display:flex; gap:0.6rem; flex-wrap:wrap; }
.tema-op{
  flex:1 1 180px; text-align:left; border:2px solid var(--border); border-radius:var(--radius);
  background:var(--surface); padding:0.6rem 0.8rem; cursor:pointer; transition:border-color .12s;
}
.tema-op:hover{ border-color:var(--primary); }
.tema-op.activo{ border-color:var(--primary); box-shadow:0 0 0 3px var(--primary-lt); }
.tema-op b{ display:block; font-size:0.85rem; color:var(--text-primary); }
.tema-op span{ display:block; font-size:0.72rem; color:var(--text-muted); }

.tema-acentos{ display:flex; gap:0.6rem; flex-wrap:wrap; }
.tema-acento{
  display:flex; align-items:center; gap:0.45rem;
  border:2px solid var(--border); border-radius:20px; background:var(--surface);
  padding:0.3rem 0.7rem 0.3rem 0.35rem; cursor:pointer; transition:border-color .12s;
}
.tema-acento:hover{ border-color:var(--primary); }
.tema-acento.activo{ border-color:var(--primary); box-shadow:0 0 0 3px var(--primary-lt); }
.tema-acento-nombre{ font-size:0.78rem; color:var(--text-secondary); }
.tema-swatch{ width:22px; height:22px; border-radius:50%; flex:0 0 auto; box-shadow:inset 0 0 0 1px rgba(0,0,0,.1); }

/* Selector de tipografía + recuadro de ejemplo en vivo. */
.tema-fuente-select{ max-width:340px; height:38px; }
.tema-fuente-preview{
  max-width:340px; margin-top:0.55rem; padding:0.7rem 0.9rem;
  border:1px dashed var(--border); border-radius:var(--radius);
  background:var(--primary-lt); color:var(--text-primary);
  font-size:1.05rem; line-height:1.4;
}

/* ── Tarjetas ────────────────────────────────────────────────────────────── */
.card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow-card);
}
.card-cab{
  display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;
  padding:0.85rem 1rem; border-bottom:1px solid var(--border);
}
.card-titulo{ font-size:0.95rem; font-weight:700; margin:0; }
.card-cuerpo{ padding:1rem; }
.card-cab .toolbar-spacer{ flex:1 1 auto; }

/* ── Toolbar de filtros ──────────────────────────────────────────────────── */
.toolbar{ display:flex; align-items:center; gap:0.55rem; flex-wrap:wrap; }
.toolbar .form-control, .toolbar .form-select{ height:36px; font-size:0.82rem; }
/* Toolbar forzado a UNA sola línea: nunca crea un 2º renglón. Los controles fijos
   no encogen; solo la búsqueda y los selects se comprimen (con elipsis) para caber.
   Sin overflow-scroll para no recortar los dropdowns de los custom-select. */
.toolbar.una-linea{ flex-wrap:nowrap; min-width:0; }
.toolbar.una-linea > *{ flex-shrink:0; }
.toolbar.una-linea .buscador{ flex:0 1 150px; min-width:90px; }
.toolbar.una-linea .custom-select{ flex-shrink:1; min-width:0; }
.toolbar.una-linea .custom-select .custom-select-btn{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.buscador{
  min-width:220px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="%237e8896" viewBox="0 0 16 16"><path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/></svg>');
  background-repeat: no-repeat;
  background-position: 0.75rem center;
  padding-left: 2.2rem !important;
}

/* ── Tablas ──────────────────────────────────────────────────────────────── */
.tabla-wrap{ overflow-x:auto; }
table.tabla{ width:100%; border-collapse:separate; border-spacing:0; font-size:0.78rem; }
table.tabla thead th{
  text-align:left; font-weight:600; color:var(--text-secondary);
  font-size:0.72rem; text-transform:none;
  padding:0.6rem 0.75rem; border-bottom:1px solid var(--border); white-space:nowrap;
  background:var(--surface);
  position:sticky; top:0; z-index:2;   /* columnas fijas al scrollear la tabla */
}
th .bi { margin-right: 0.35rem; color: var(--primary); }
table.tabla tbody td{
  padding:0.6rem 0.75rem; border-bottom:1px solid var(--border);
  vertical-align:middle;
}
table.tabla tbody tr:hover{ background:var(--primary-lt); }
table.tabla tbody tr:last-child td{ border-bottom:none; }
.celda-acciones{ display:flex; gap:0.35rem; justify-content:flex-end; }
.tabla-vacia, .tabla-cargando{ text-align:center; color:var(--text-muted); padding:2rem 1rem; font-size:0.85rem; }
.num{ font-variant-numeric:tabular-nums; }
.txt-muted{ color:var(--text-muted); }
.txt-sec{ color:var(--text-secondary); }

/* ── Badges ──────────────────────────────────────────────────────────────── */
.badge-estado{
  display:inline-flex; align-items:center; justify-content:center; gap:0.3rem;
  font-size:0.7rem; font-weight:600; padding:0.2rem 0.55rem; border-radius:10px;
  min-width:90px; text-align:center;
  background-image:linear-gradient(180deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0) 100%);
  box-shadow:0 2px 4px rgba(0,0,0,.10), inset 0 1px 0 rgba(255,255,255,.35);
  border:1px solid rgba(255,255,255,.18);
}
.badge-activo{ background-color:var(--success); color:#fff; }
.badge-inactivo{ background-color:#6c757d; color:#fff; }
.badge-rol{
  display:inline-flex; align-items:center; justify-content:center; gap:0.3rem;
  font-size:0.7rem; font-weight:600; padding:0.2rem 0.55rem; border-radius:10px;
  min-width:90px; text-align:center;
  background-color:var(--primary); color:#fff;
  background-image:linear-gradient(180deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0) 100%);
  box-shadow:0 2px 4px rgba(0,0,0,.10), inset 0 1px 0 rgba(255,255,255,.35);
  border:1px solid rgba(255,255,255,.18);
}
.badge-pill{
  display:inline-flex; align-items:center; gap:0.3rem;
  font-size:0.7rem; font-weight:600; padding:0.2rem 0.55rem; border-radius:10px;
  background-color:#6c757d; color:#fff;
  background-image:linear-gradient(180deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0) 100%);
  box-shadow:0 2px 4px rgba(0,0,0,.10), inset 0 1px 0 rgba(255,255,255,.35);
  border:1px solid rgba(255,255,255,.18);
}
.badge-super{ background-color:var(--warning); color:#fff; }
.badge-materia{ background-color:#1f2937; color:#fff; }
.badge-vacio{ background-color:#7f1d1d; color:#fff; }
.badge-conteo{ font-variant-numeric:tabular-nums; }

/* ── Modales (Bootstrap) ─────────────────────────────────────────────────── */
/* Cabecera = banda de color de marca (equivalente web del patrón de modal del
   APK, en clave luivo-aero). SIN borde en el contenedor: el borde translúcido
   dibujaba una línea blanca alrededor del color de la cabecera. La sombra ya
   da la definición del contorno. overflow:hidden para respetar el radius.
   Flex column + max-height confina TODO modal dentro del viewport: el body
   scrollea si el contenido excede. Aplica globalmente — no hace falta poner
   modal-dialog-scrollable en cada modal individual. */
.modal-dialog{ max-height:calc(100vh - 3.5rem); }
.modal-content{
  border:none; border-radius:var(--radius); overflow:hidden;
  display:flex; flex-direction:column; max-height:calc(100vh - 3.5rem);
}
.modal-header{
  background:var(--primary); color:var(--blanco);
  border-bottom:none; border-radius:var(--radius) var(--radius) 0 0; padding:0.35rem 1.1rem;
  flex:0 0 auto;
}
.modal-title{ font-size:1rem; font-weight:700; display:flex; align-items:center; gap:0.55rem; color:var(--blanco); }
.modal-title .bi{ font-size:1.05rem; opacity:0.9; }
.modal-cab-sub{ font-size:0.72rem; color:rgba(255,255,255,0.75); margin-top:0.15rem; }
/* La X: sin anillo de foco al clic (queda el outline solo para teclado);
   la interacción se comunica por escala — crece al hover, se encoge al presionar. */
.modal-header .btn-close{
  transition:transform .12s ease;
  outline:none;
}
.modal-header .btn-close:focus{ box-shadow:none; outline:none; }
.modal-header .btn-close:focus-visible{ outline:2px solid rgba(255,255,255,.85); outline-offset:2px; }
.modal-header .btn-close:hover{ transform:scale(1.18); }
.modal-header .btn-close:active{ transform:scale(0.82); }
.modal-body{ padding:1.1rem; flex:1 1 auto; overflow-y:auto; min-height:0; }
.modal-footer{ border-top:1px solid var(--border); padding:0.75rem 1.1rem; flex:0 0 auto; }

/* ── Editor de permisos (overrides de usuario y base de rol) ─────────────── */
.permisos-grupo{ margin-bottom:1rem; }
.permisos-grupo-tit{
  font-size:0.72rem; font-weight:700; color:var(--text-muted); text-transform:uppercase;
  letter-spacing:0.03em; margin:0 0 0.4rem; padding-bottom:0.3rem; border-bottom:1px solid var(--border);
}
.permiso-fila{
  display:flex; align-items:center; gap:0.75rem; padding:0.5rem 0.15rem;
}
.permiso-info{ flex:1 1 auto; min-width:0; }
.permiso-nombre{ font-size:0.85rem; font-weight:600; }
.permiso-clave{ font-size:0.7rem; color:var(--text-muted); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
.permiso-hint{ font-size:0.68rem; margin-top:0.1rem; }
.permiso-hint.si{ color:var(--success); }
.permiso-hint.no{ color:var(--text-muted); }

/* Segmentado tri-estado para overrides: Heredado / Conceder / Quitar. */
.segmentado{ display:inline-flex; border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; flex:0 0 auto; }
.segmentado button{
  background:var(--surface); border:none; color:var(--text-secondary);
  font-size:0.72rem; font-weight:600; padding:0.3rem 0.6rem; cursor:pointer;
  border-left:1px solid var(--border);
}
.segmentado button:first-child{ border-left:none; }
.segmentado button.btn-primary{ background:var(--primary); color:var(--blanco); border-color:var(--primary); position:relative; z-index:1; margin:-1px; }
.segmentado button.sel-heredar{ background:var(--gray-lt); color:var(--text-primary); }
.segmentado button.sel-conceder{ background:var(--green-lt); color:var(--success); }
.segmentado button.sel-quitar{ background:var(--red-lt); color:var(--danger); }

/* Checkbox de permiso base de rol. */
.permiso-check{ display:flex; align-items:center; gap:0.6rem; padding:0.4rem 0.15rem; }
.permiso-check input{ width:1.05rem; height:1.05rem; }

/* ── Pestañas dentro de modales (ficha de empleado) ─────────────────────── */
.modal-tabs{ border-bottom:1px solid var(--border); margin-bottom:1rem; gap:0.15rem; }
.modal-tabs .nav-link{
  border:none; border-bottom:2px solid transparent; border-radius:0;
  color:var(--text-secondary); font-size:0.82rem; font-weight:600;
  padding:0.5rem 0.8rem; background:none;
  display:inline-flex; align-items:center; gap:0.4rem;
}
.modal-tabs .nav-link:hover{ color:var(--primary); }
.modal-tabs .nav-link.active{ color:var(--primary); border-bottom-color:var(--primary); background:none; }
.modal-tab-content{ min-height:230px; }

/* Días permitidos (checkboxes en línea) */
.dias-checks{ display:flex; gap:0.4rem; flex-wrap:wrap; }
.dias-checks label{
  display:flex; align-items:center; gap:0.35rem;
  border:1px solid var(--border); border-radius:var(--radius);
  padding:0.3rem 0.6rem; font-size:0.8rem; color:var(--text-secondary);
  cursor:pointer; user-select:none; background:var(--surface);
}
.dias-checks label:has(input:checked){
  border-color:var(--primary); color:var(--primary); background:var(--primary-lt); font-weight:600;
}

/* Documentos del empleado (slots) */
.doc-slot{
  display:flex; align-items:center; gap:0.85rem;
  border:1px solid var(--border); border-radius:var(--radius);
  padding:0.6rem 0.75rem; margin-bottom:0.6rem; background:var(--surface);
}
.doc-thumb{
  width:64px; height:48px; flex:0 0 auto;
  border:1px solid var(--border); border-radius:var(--radius);
  display:flex; align-items:center; justify-content:center;
  color:var(--text-muted); font-size:1.3rem; overflow:hidden; background:var(--body-bg);
}
.doc-thumb img{ width:100%; height:100%; object-fit:cover; }
.doc-datos{ flex:1 1 auto; min-width:0; font-size:0.85rem; }
.doc-estado{ font-size:0.72rem; }
.doc-acciones{ display:flex; gap:0.35rem; }

/* ── Editor de receta (FASE 7) ──────────────────────────────────────────── */
.rc-linea{
  display:flex; align-items:center; gap:0.5rem;
  padding:0.4rem 0; border-bottom:1px dashed var(--border);
}
.rc-linea .rc-insumo{ flex:2 1 0; min-width:0; }
.rc-linea .rc-cantidad-wrap{ flex:0 0 120px; }
.rc-linea .rc-cantidad{ width:100%; text-align:right; }
.rc-unidad{ flex:0 0 65px; font-size:0.75rem; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; }
.rc-costo-linea{ flex:0 0 84px; text-align:right; font-size:0.8rem; }
.rc-costo{ font-size:0.85rem; color:var(--text-secondary); }
.rc-costo b{ color:var(--text-primary); }

/* Stock bajo el mínimo (insumos) */
.stock-bajo{ color:var(--danger); font-weight:700; }

/* Meta del modal de ajuste */
.meta-ajuste{
  background:var(--primary-lt); border-radius:var(--radius);
  padding:0.5rem 0.75rem; font-size:0.82rem;
}

/* ── Toasts ──────────────────────────────────────────────────────────────── */
.toast-zona{ position:fixed; bottom:1.5rem; right:1.5rem; z-index:1080; display:flex; flex-direction:column; gap:0.5rem; }
.toast-item{
  display:flex; align-items:center; gap:0.55rem;
  min-width:240px; max-width:360px;
  background:var(--surface); background:color-mix(in srgb, var(--primary) 4%, transparent); backdrop-filter:blur(24px) saturate(1.5); -webkit-backdrop-filter:blur(24px) saturate(1.5);
  border:1px solid rgba(0, 0, 0, 0.05); border-left:4px solid var(--secondary);
  border-radius:var(--radius); box-shadow:0 10px 30px rgba(0,0,0,.10), 0 4px 10px rgba(0,0,0,.05);
  padding:0.75rem 1rem; font-size:0.85rem; font-weight:500; color:var(--text-primary);
  opacity:0; transform:translateY(16px); transition:opacity .22s, transform .22s;
}
.toast-item.visible{ opacity:1; transform:translateY(0); }
.toast-item .bi{ font-size:1.05rem; flex:0 0 auto; }
.toast-exito{ border-left-color:var(--success); }
.toast-exito .bi{ color:var(--success); }
.toast-error{ border-left-color:var(--danger); }
.toast-error .bi{ color:var(--danger); }
.toast-aviso{ border-left-color:var(--warning); }
.toast-aviso .bi{ color:var(--warning); }
.toast-info{ border-left-color:var(--info); }
.toast-info .bi{ color:var(--info); }

/* ── Confirmación ────────────────────────────────────────────────────────── */
.confirm-overlay{
  position:fixed; inset:0; z-index:1090;
  background:rgba(15,23,42,0.45);
  display:flex; align-items:center; justify-content:center; padding:1.5rem;
  opacity:0; transition:opacity .18s;
}
.confirm-overlay.visible{ opacity:1; }
.confirm-card{
  width:100%; max-width:400px;
  background:var(--surface); border:none; border-radius:var(--radius);
  box-shadow:0 10px 40px rgba(13,38,76,.2); padding:0; overflow:hidden;
  transform:translateY(8px); transition:transform .18s;
}
.confirm-overlay.visible .confirm-card{ transform:translateY(0); }
/* Cabecera de color del diálogo: normal=primario, peligro=rojo, aviso=ámbar
   (el ámbar lleva texto oscuro: blanco sobre ámbar no contrasta). */
.confirm-cab{
  display:flex; align-items:center; gap:0.55rem;
  padding:0.8rem 1.2rem; background:var(--primary); color:var(--blanco);
  border-radius:0; font-size:0.95rem; font-weight:700;
}
.confirm-cab .bi{ font-size:1.1rem; }
.confirm-cab.peligro{ background:var(--danger); }
.confirm-cab.aviso{ background:var(--warning); color:var(--text-primary); }
.confirm-cuerpo{ padding:1.1rem 1.3rem 1.25rem; }
.confirm-mensaje{ font-size:0.85rem; color:var(--text-secondary); margin-bottom:1.1rem; line-height:1.5; }
.confirm-botones{ display:flex; justify-content:flex-end; gap:0.5rem; }

/* ── Sesión activa (login) ──────────────────────────────────────────────── */
.sesion-botones{ display:flex; flex-direction:column; gap:0.5rem; }

/* ── Estado vacío / sin módulos ─────────────────────────────────────────── */
.estado-vacio{ text-align:center; color:var(--text-muted); padding:3rem 1rem; }
.estado-vacio .bi{ font-size:2.5rem; display:block; margin-bottom:0.75rem; opacity:0.5; }

.oculto{ display:none !important; }

/* ── Custom Select (Reemplazo visual) ───────────────────────────────────── */
.custom-select { display: inline-block; vertical-align: middle; }
.custom-select-btn {
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: var(--surface);
  background-image: none !important; /* Quita el chevron nativo de form-select */
  padding-right: 0.85rem !important; /* Mueve el chevron más a la derecha */
}
.custom-select-btn::after {
  margin-left: 0.5rem;
  border-top: 0.45em solid;
  border-right: 0.4em solid transparent;
  border-left: 0.4em solid transparent;
  transition: transform 0.25s ease-in-out;
}
.custom-select .custom-select-btn.show::after {
  transform: rotate(-180deg);
}
.custom-select .custom-select-btn.show {
  border-bottom-left-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
  border-bottom-color: transparent !important; /* Quita la línea inferior */
  border-color: var(--primary) !important;
  box-shadow: none !important;
  background-color: var(--surface) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.custom-select .dropdown-menu {
  width: 100%;
  min-width: 100%;
  border-top-left-radius: 0 !important;
  border-top-right-radius: 0 !important;
  border: 1px solid var(--primary);
  border-top: none !important; /* Quita la línea superior del menú */
  margin-top: -1px !important;
  transform: none !important; /* Anula el espaciado y pos de popper.js */
  top: 100% !important;
  left: 0 !important;
  padding: 0;
  max-height: 280px;
  overflow-y: auto;
  overflow-x: hidden;
  box-shadow: 0 10px 30px rgba(0,0,0,0.15);
  background: var(--surface) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  transition: none !important;
  animation: none !important;
  z-index: 1050;
}
.custom-select .dropdown-item {
  padding: 0.5rem 0.8rem;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--border);
}
.custom-select .dropdown-item:last-child { border-bottom: none; }
.custom-select .dropdown-item:hover,
.custom-select .dropdown-item:focus {
  text-decoration: none !important;
  background-color: var(--primary-lt) !important;
  color: var(--text-primary);
}
.custom-select .dropdown-item.active,
.custom-select .dropdown-item:active,
.custom-select .dropdown-item.active:hover,
.custom-select .dropdown-item.active:focus {
  background-color: var(--primary) !important;
  color: var(--blanco) !important;
}

/* Ajuste al ancho del contenido más largo usando Grid */
.cs-text-wrap {
  display: grid;
  flex: 1;
}
.cs-text-wrap::after {
  content: attr(data-longest);
  visibility: hidden;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}
.cs-text {
  grid-area: 1 / 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Responsivo ──────────────────────────────────────────────────────────────
   En móvil el sidebar es un OVERLAY (no empuja el contenido): oculto por
   defecto, se muestra completo con .sider-movil y un backdrop. El contenido
   ocupa todo el ancho. El acordeón sí aplica (el rail colapsado es de escritorio). */
@media (max-width:768px){
  .app-main, .app-shell.sider-fijo .app-main{ margin-left:0; }
  .sidebar, .sidebar:hover, .app-shell.sider-fijo .sidebar{
    width:var(--sidebar-width);
    transform:translateX(-100%); transition:transform .22s ease;
  }
  .sidebar .menu-text, .sidebar .marca-txt{ opacity:1; }
  .sidebar .menu-cat-head{ display:flex; }
  /* En móvil el menú es overlay completo con acordeón (sin rail auto-oculta). */
  .sidebar .menu-sub{ grid-template-rows: 0fr; }
  .sidebar .menu-cat.abierto > .menu-sub{ grid-template-rows: 1fr; }
  .app-shell.sider-movil .sidebar{ transform:translateX(0); box-shadow:0 0 40px rgba(0,0,0,.4); }
  .app-shell.sider-movil .backdrop-movil{ position:fixed; inset:0; z-index:1035; background:rgba(0,0,0,.45); }
  .buscador{ min-width:140px; flex:1 1 auto; }
}

/* ── Bloque DEV provisional (datos de prueba, al fondo del menú) ───────────── */
/* Bloque simple al FINAL del contenido del menú (no se fuerza flex en el sidebar
   para no romper su comportamiento auto-oculta/rail). */
.menu-dev{ margin-top:1.2rem; padding:0.7rem 0.6rem; border-top:1px dashed var(--border); }
.menu-dev-tit{ display:flex; align-items:center; gap:0.4rem; font-size:0.66rem; text-transform:uppercase; letter-spacing:0.03em; color:var(--text-muted); margin-bottom:0.45rem; white-space:nowrap; overflow:hidden; }
.menu-dev-btns{ display:flex; gap:0.4rem; }
.menu-dev-btns .btn{ flex:1 1 0; min-width:0; font-size:0.74rem; padding:0.32rem 0.4rem; display:flex; align-items:center; justify-content:center; gap:0.3rem; }
.menu-dev-btns .btn i{ font-size:0.9rem; }

/* Animación de entrada de las barras (llenado) */
@keyframes llenarBarra {
  from { width: 0; }
}

/* Animación continua de las rayas */
@keyframes moverRayas {
  from { background-position: 1rem 0; }
  to { background-position: 0 0; }
}

.barra-animada {
  /* La animación de llenado original */
  animation: llenarBarra 0.8s ease-out backwards;
  position: relative;
}

/* Efecto de rayas oblicuas animadas sobre el color base */
.barra-animada::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.25) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.25) 50%,
    rgba(255, 255, 255, 0.25) 75%,
    transparent 75%,
    transparent
  );
  background-size: 1rem 1rem;
  /* Animación infinita para que fluya constantemente */
  animation: moverRayas 1s linear infinite;
  border-radius: inherit;
  pointer-events: none;
}

/* ===== KPIs Estilo Bloque Sólido (AdminLTE/Visitas Web) + Tema Aero ===== */
.kpi-card {
  container-type: inline-size;
  --kpi-accent: var(--primary);
  background: color-mix(in srgb, var(--kpi-accent) 80%, transparent) !important;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.25) !important;
  color: #fff;
  padding: 1.2rem 1.2rem;
  border-radius: var(--radius);
  position: relative;
  overflow: hidden;
  flex: 1 1 0;
  min-width: 140px;
  align-self: stretch;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.kpi-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  background: color-mix(in srgb, var(--kpi-accent) 95%, transparent) !important;
}
.kpi-card .kpi-val {
  font-size: 1.6rem;
  font-size: min(1.6rem, 16cqi);
  font-weight: 600;
  line-height: 1;
  color: #fff;
  z-index: 2;
  margin-bottom: 0.2rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi-card .kpi-lbl {
  font-size: 0.95rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.9);
  z-index: 2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.kpi-card .kpi-icon {
  position: absolute;
  right: 10px;
  top: 4px;
  font-size: 2.5rem;
  color: rgba(0, 0, 0, 0.15);
  z-index: 1;
  transition: transform 0.3s ease;
}
.kpi-card:hover .kpi-icon {
  transform: scale(1.1) rotate(5deg);
}

/* ── Campana de alertas en la cabecera (campana.js) ───────────────────────────
   Badge por severidad MÁS grave (danger/warning/info) + dropdown anclado.
   z-index 1060: sobre los dropdowns de tarjetas (1050), bajo los toasts (1080). */
.campana-zona, .conexion-zona { position:relative; display:flex; align-items:center; margin: 0 -0.25rem; }
.campana-zona:empty, .conexion-zona:empty { display: none; }
.campana-btn{ position:relative; width:34px; height:34px; font-size:1rem; }
.campana-badge{
  position:absolute; top:0px; right:0px;
  min-width:16px; height:16px; padding:0 4px; border-radius:8px;
  font-size:0.6rem; font-weight:700; line-height:16px; text-align:center;
  color:var(--blanco); background:var(--secondary);
  box-shadow:0 0 0 2px var(--surface); pointer-events:none;
}
.campana-badge.sev-danger{ background:var(--danger); }
.campana-badge.sev-warning{ background:var(--warning); }
.campana-badge.sev-info{ background:var(--info); }

.campana-panel{
  position:absolute; top:calc(100% + 10px); right:0;
  width:380px; max-width:min(92vw, 380px); z-index:1060;
}
/* Pantallas angostas: la campana queda a media barra y el panel anclado a ella
   se saldria por la izquierda — se fija al viewport, a lo ancho. */
@media (max-width: 520px){
  .campana-panel{
    position:fixed; top:calc(var(--topbar-h) + 6px); left:8px; right:8px;
    width:auto; max-width:none;
  }
}
.campana-panel{
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius);
  box-shadow:var(--shadow-card), 0 12px 32px rgba(30,38,51,.16);
  display:flex; flex-direction:column; overflow:hidden;
}
.campana-cab{
  display:flex; align-items:center; gap:0.45rem;
  padding:0.6rem 0.85rem; border-bottom:1px solid var(--border);
  font-size:0.85rem; font-weight:700;
}
.campana-cab .bi{ color:var(--primary); }
.campana-cab-info{ margin-left:auto; font-size:0.7rem; font-weight:500; color:var(--text-muted); }
.campana-cuerpo{ max-height:min(60vh, 420px); overflow:auto; }
.campana-cargando{ padding:1.2rem; text-align:center; color:var(--text-muted); font-size:0.8rem; }
.campana-vacio{ padding:1.6rem 1rem; text-align:center; color:var(--text-muted); font-size:0.8rem; }
.campana-vacio .bi{ font-size:1.7rem; display:block; margin-bottom:0.4rem; color:var(--success); }
.campana-vacio .bi-wifi-off{ color:var(--warning); }

/* Cabecera de cada grupo (fuente) dentro del dropdown. */
.campana-grupo{
  display:flex; align-items:center; gap:0.35rem;
  padding:0.5rem 0.85rem 0.25rem;
  font-size:0.66rem; font-weight:700; letter-spacing:0.04em; text-transform:uppercase;
  color:var(--text-muted);
}
.campana-grupo-n{
  margin-left:auto; min-width:16px; padding:0 4px; border-radius:8px; text-align:center;
  font-size:0.62rem; background:var(--gray-lt); color:var(--text-secondary);
}

/* Fila de alerta: borde + punto del color de su severidad; click = deep-link. */
.campana-item{
  display:flex; align-items:flex-start; gap:0.55rem;
  padding:0.5rem 0.85rem; cursor:pointer;
  border-left:3px solid transparent;
}
.campana-item:hover{ background:var(--primary-lt); }
.campana-item:focus-visible{ outline:2px solid var(--primary); outline-offset:-2px; }
.campana-dot{ width:8px; height:8px; border-radius:50%; margin-top:0.32rem; flex:0 0 auto; background:var(--secondary); }
.campana-item.sev-danger{ border-left-color:var(--danger); }
.campana-item.sev-danger .campana-dot{ background:var(--danger); }
.campana-item.sev-warning{ border-left-color:var(--warning); }
.campana-item.sev-warning .campana-dot{ background:var(--warning); }
.campana-item.sev-info{ border-left-color:var(--info); }
.campana-item.sev-info .campana-dot{ background:var(--info); }
.campana-item-txt{ min-width:0; flex:1 1 auto; }
.campana-item-tit{ display:block; font-size:0.79rem; font-weight:600; color:var(--text-primary); }
.campana-item-n{
  display:inline-block; min-width:15px; padding:0 4px; border-radius:8px; text-align:center;
  font-size:0.6rem; font-weight:700; color:var(--blanco); background:var(--secondary); vertical-align:1px;
}
.campana-item.sev-danger .campana-item-n{ background:var(--danger); }
.campana-item.sev-warning .campana-item-n{ background:var(--warning); }
.campana-item-det{
  display:block; font-size:0.7rem; color:var(--text-muted);
  overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
}
.campana-item-meta{ margin-left:auto; text-align:right; white-space:nowrap; flex:0 0 auto; }
.campana-item-monto{ display:block; font-size:0.76rem; font-weight:600; color:var(--text-primary); }
.campana-item-fecha{ display:block; font-size:0.66rem; color:var(--text-muted); }

.campana-pie{ border-top:1px solid var(--border); }
.campana-ver-centro{
  display:flex; align-items:center; justify-content:center; gap:0.4rem;
  width:100%; padding:0.55rem; border:none; background:none; cursor:pointer;
  font-size:0.8rem; font-weight:600; color:var(--primary);
}
.campana-ver-centro:hover{ background:var(--primary-lt); }

/* ── Pestañas ALERTAS | ACTIVIDAD del dropdown (campana.js, mod_movimientos) ──
   Chips coherentes con el design system; la activa usa el acento primario. */
.campana-tabs{
  display:flex; gap:0.35rem; padding:0.5rem 0.6rem;
  border-bottom:1px solid var(--border);
}
.campana-tab{
  display:inline-flex; align-items:center; gap:0.3rem;
  padding:0.28rem 0.7rem; border:1px solid var(--border); border-radius:999px;
  background:var(--surface); color:var(--text-secondary);
  font-size:0.74rem; font-weight:600; cursor:pointer;
}
.campana-tab:hover,
.campana-tab.activo{ color:var(--primary); border-color:var(--primary); background:var(--primary-lt); }
.campana-tab-n{ font-size:0.66rem; font-weight:700; color:var(--info); }

/* Puntito discreto en la campana: hay actividad nueva SIN VER. No toca el
   badge numérico de alertas (que vive arriba a la derecha del botón). */
.campana-dot-nuevo{
  position:absolute; bottom:-3px; right:-3px; width:9px; height:9px;
  border-radius:50%; background:var(--info);
  box-shadow:0 0 0 2px var(--surface); pointer-events:none;
}

/* Fila de la pestaña ACTIVIDAD: icono+borde del color del tipo (venta=éxito,
   abono=info, reversas=danger — mismos tokens que los toasts) + hora HH:MM. */
.campana-act-item{
  display:flex; align-items:flex-start; gap:0.55rem;
  padding:0.5rem 0.85rem; border-left:3px solid transparent;
}
.campana-act-ico{ flex:0 0 auto; font-size:0.95rem; line-height:1.2; }
.campana-act-item.act-exito{ border-left-color:var(--success); }
.campana-act-item.act-exito .campana-act-ico{ color:var(--success); }
.campana-act-item.act-info{ border-left-color:var(--info); }
.campana-act-item.act-info .campana-act-ico{ color:var(--info); }
.campana-act-item.act-danger{ border-left-color:var(--danger); }
.campana-act-item.act-danger .campana-act-ico{ color:var(--danger); }
.campana-act-txt{ flex:1 1 auto; min-width:0; font-size:0.77rem; color:var(--text-primary); }
.campana-act-hora{
  flex:0 0 auto; margin-left:auto; padding-top:0.1rem;
  font-size:0.68rem; color:var(--text-muted); font-variant-numeric:tabular-nums;
}
/* Badge ámbar CRÉDITO (con saldo si la fila lo trae). */
.campana-act-credito{
  display:inline-block; padding:0 5px; border-radius:8px; margin-left:2px;
  font-size:0.62rem; font-weight:700; letter-spacing:0.03em; white-space:nowrap;
  background:var(--yellow-lt); color:var(--warning);
  border:1px solid color-mix(in srgb, var(--warning) 35%, transparent);
}

/* ── Semáforo de conexión de repartidores en la cabecera (conexion.js) ────────
   Botón bi-truck a la IZQUIERDA de la campana. El dropdown REUSA el shell de
   la campana (.campana-panel/.campana-cab/.campana-cuerpo/.campana-pie) para
   verse idéntico; aquí solo lo propio: el ancla, los colores del badge (conteo
   EN LÍNEA: verde si hay, ámbar si 0 pero hay ACTIVOS, gris si nada) y la fila
   por repartidor con punto de estado — verde con pulso (EN_LINEA, espejo del
   marcador vivo de mapas.js), ámbar (ACTIVO), gris (SIN_SENAL). */
.conexion-zona{ position:relative; display:flex; align-items:center; }
.cx-badge.cx-verde{ background:var(--success); }
.cx-badge.cx-ambar{ background:var(--warning); }
.cx-badge.cx-gris{ background:var(--secondary); }

.cx-item{
  display:flex; align-items:center; gap:0.6rem;
  padding:0.5rem 0.85rem; border-left:3px solid transparent;
}
.cx-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 auto; background:var(--secondary); }
.cx-item.cx-en-linea{ border-left-color:var(--success); }
.cx-item.cx-en-linea .cx-dot{ background:var(--success); animation:cxPulso 1.7s ease-out infinite; }
.cx-item.cx-activo{ border-left-color:var(--warning); }
.cx-item.cx-activo .cx-dot{ background:var(--warning); }
.cx-item.cx-sin-senal .cx-nombre{ color:var(--text-secondary); }
.cx-txt{ min-width:0; flex:1 1 auto; }
.cx-nombre{ display:block; font-size:0.79rem; font-weight:600; color:var(--text-primary); }
.cx-estado{
  display:block; font-size:0.7rem; color:var(--text-muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* Pulso del punto EN LÍNEA: espejo de mpRepPulso (marcador vivo del mapa),
   con radio menor porque el punto es chico. */
@keyframes cxPulso{
  0%{ box-shadow:0 0 0 0 color-mix(in srgb, var(--success) 60%, transparent); }
  100%{ box-shadow:0 0 0 8px color-mix(in srgb, var(--success) 0%, transparent); }
}

/* ── Dashboard · pestaña HOY (torre de control del día, dashboard.js) ─────────
   Tarjetas en grid responsivo + barras de la semana hechas con divs (sin
   librerías): la pista da la altura fija y cada barra crece con height %. */
.dsh-hoy-grid{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:.6rem; align-items:start;
}
/* Planta hoy: dos indicadores compactos (piezas / paquetes). */
.dsh-planta{ display:flex; gap:1.2rem; flex-wrap:wrap; }
.dsh-planta-item{ display:flex; align-items:center; gap:.6rem; flex:1 1 140px; min-width:0; }
.dsh-planta-item > i{ font-size:1.6rem; flex:none; }
.dsh-planta-val{ font-size:1.5rem; font-weight:700; line-height:1.1; }
.dsh-planta-lbl{ font-size:.7rem; color:var(--secondary); text-transform:uppercase; letter-spacing:.03em; }
/* Ventas de la semana: barras verticales. */
.dsh-barras{ display:flex; gap:.45rem; align-items:flex-end; padding:.2rem .1rem 0; }
.dsh-barra-col{
  flex:1 1 0; min-width:0; display:flex; flex-direction:column;
  align-items:center; gap:.25rem; cursor:default;
}
.dsh-barra-monto{
  font-size:.62rem; color:var(--secondary); white-space:nowrap;
  min-height:.9rem; max-width:100%; overflow:hidden; text-overflow:ellipsis;
}
.dsh-barra-pista{
  width:100%; height:120px; display:flex; align-items:flex-end;
  border-radius:6px 6px 0 0;
  background:color-mix(in srgb, var(--text) 5%, transparent);
}
.dsh-barra{
  width:100%; border-radius:6px 6px 0 0;
  background:color-mix(in srgb, var(--primary) 45%, transparent);
  transition:height .25s ease;
}
.dsh-barra-col.es-hoy .dsh-barra{ background:var(--primary); }
.dsh-barra-lbl{ font-size:.62rem; color:var(--secondary); text-transform:uppercase; }
.dsh-barra-col.es-hoy .dsh-barra-lbl{ color:var(--primary); font-weight:700; }
/* Actividad reciente: filas compactas del ledger. */
.dsh-act-item{
  display:flex; align-items:center; gap:.5rem;
  padding:.4rem .8rem; border-bottom:1px solid var(--border); font-size:.82rem;
}
.dsh-act-item:last-child{ border-bottom:none; }
.dsh-act-hora{ flex:none; font-size:.72rem; color:var(--secondary); font-variant-numeric:tabular-nums; }
.dsh-act-ico{ flex:none; color:var(--secondary); }
.dsh-act-txt{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Alertas top: top 5 del agregador K, clic = deep-link al módulo de origen. */
.dsh-top-alerta{
  display:flex; align-items:center; gap:.55rem;
  padding:.5rem .8rem; border-bottom:1px solid var(--border); cursor:pointer;
}
.dsh-top-alerta:last-child{ border-bottom:none; }
.dsh-top-alerta:hover{ background:color-mix(in srgb, var(--text) 5%, transparent); }
.dsh-top-txt{ flex:1 1 auto; min-width:0; font-size:.82rem; }
.dsh-top-meta{
  flex:none; display:flex; flex-direction:column; align-items:flex-end;
  gap:.2rem; font-size:.78rem;
}

/* ── Dashboard · pestaña HOY v2 — dashboard visual de ANCHO COMPLETO ──────────
   Layout en columna con gaps + grids de 2 columnas que colapsan a 1 solo en
   pantallas chicas (auto-fit; nada de franjas vacías). Las gráficas son SVG
   inline generadas en JS: el host mide su ancho REAL y el SVG se dibuja a esa
   medida (viewBox = píxeles) → texto nítido y del tamaño correcto en cualquier
   pantalla; el ResizeObserver lo re-genera al cambiar el tamaño. Los colores
   salen de var(--…) vía `style="fill:var(--…)"` (declaración CSS) y de estas
   clases, así que el acento del tema (tema.js) los sigue. */
.dsh-pane{ display:flex; flex-direction:column; gap:.7rem; }
.dsh-grid-2{
  display:grid; gap:.7rem; align-items:start;
  grid-template-columns:repeat(auto-fit, minmax(min(100%, 420px), 1fr));
}
/* Fila HERO del dashboard HOY: 3 gráficas en un renglón (ritmo del día ANCHO ·
   semana · mix de pago). Colapsa a 2 y luego 1 columna en pantallas chicas. */
.dsh-hero{ display:grid; gap:.7rem; align-items:stretch; grid-template-columns:minmax(0,1.7fr) minmax(0,1fr) minmax(0,1fr); }
/* Cada celda del hero LLENA su alto (bordes de tarjeta parejos entre las 3). */
.dsh-hero > *{ min-width:0; display:flex; }
.dsh-hero > * > .card{ flex:1 1 auto; width:100%; }
/* El mix (donut + leyenda) se centra vertical cuando la tarjeta es más alta. */
.dsh-hero #dshHoyMix .dsh-mix-cuerpo{ min-height:100%; }
@media (max-width:1080px){ .dsh-hero{ grid-template-columns:1fr 1fr; } }
@media (max-width:720px){ .dsh-hero{ grid-template-columns:1fr; } }
/* Nómina · pestaña "Nómina semanal": SOLO el cuerpo de la tabla scrollea; el
   encabezado (thead) queda fijo, y los KPIs/acciones de arriba tambien. */
#nmSemPane .tabla-wrap{ max-height:calc(100vh - 390px); overflow:auto; }
#nmSemPane #nmTabla thead th{ position:sticky; top:0; background:var(--surface,#fff); z-index:2; }
.dsh-chart-cuerpo{ padding:.55rem .8rem .45rem !important; }
.dsh-chart-host{ width:100%; min-width:0; }
/* El SVG llena el ancho y conserva su relación de aspecto (viewBox). overflow
   visible para que las etiquetas de valor no se recorten en los bordes. */
.dsh-svg{ display:block; width:100%; height:auto; overflow:visible; }
.dsh-svg text{ font-family:inherit; }
/* Rejilla / ejes sutiles + etiquetas apagadas (tokens del tema). */
.dsh-grid{ stroke:var(--border); stroke-width:1; shape-rendering:crispEdges; }
.dsh-axl{ fill:var(--text-muted); font-size:11px; }
.dsh-axl.es-hoy{ fill:var(--primary); font-weight:700; }
.dsh-barv{ fill:var(--text-muted); font-size:11px; font-variant-numeric:tabular-nums; }
.dsh-barv.es-hoy{ fill:var(--primary); font-weight:700; }
.dsh-pt{ stroke:var(--surface); stroke-width:1.5; }
.dsh-hname{ fill:var(--text-primary); font-size:12px; }
.dsh-hval{ fill:var(--text-muted); font-size:11px; font-weight:600; font-variant-numeric:tabular-nums; }
/* Donut de mix de pago APILADO: donut arriba (centrado) + leyenda debajo a ANCHO
   COMPLETO. Antes iba al lado y en columnas angostas la leyenda se estrujaba y las
   etiquetas se rompían a media palabra ("Cont/ado"). Apilado nunca se desborda. */
.dsh-mix-cuerpo{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.65rem; padding:.7rem .9rem !important; }
.dsh-donut{ flex:0 0 auto; }
.dsh-donut-vacio{ stroke:color-mix(in srgb, var(--text-muted) 22%, transparent); }
.dsh-donut-top{ fill:var(--text-primary); font-size:26px; font-weight:700; }
.dsh-donut-sub{ fill:var(--text-muted); font-size:11px; text-transform:uppercase; letter-spacing:.04em; }
.dsh-leyenda{ width:100%; flex:0 0 auto; display:flex; flex-direction:column; gap:.45rem; }
.dsh-leyenda-item{ display:flex; align-items:center; gap:.5rem; font-size:.82rem; }
.dsh-leyenda-punto{ width:.7rem; height:.7rem; border-radius:2px; flex:none; }
.dsh-leyenda-lbl{ flex:1 1 auto; min-width:0; color:var(--text-secondary); white-space:nowrap; }
.dsh-leyenda-val{ font-weight:700; white-space:nowrap; font-variant-numeric:tabular-nums; }
.dsh-leyenda-pct{ color:var(--text-muted); font-size:.72rem; white-space:nowrap; min-width:2.2rem; text-align:right; }
