/* ==========================================================================
   zenith.css — capa de tema "Zenith / shadcn" sobre Bootstrap 5 + AdminLTE 4

   NO se toca el markup: este archivo solo redefine variables CSS y afina la
   anatomía de los componentes. Se carga en view/include/header.php, login.php
   y password.php; para desactivarlo, comentar esos tres <link>.

   Debe cargarse DESPUÉS de adminlte.css y de los CSS de los plugins (incluidos
   los propios: selects.css, filepond.css y permisos.css).

   Los tokens son los de shadcn/ui en formato oklch, extraídos del bundle de
   https://zenith-shadcn.dashboardpack.com (preset "neutral", el default).
   Cada token lleva su equivalente sRGB al lado porque Bootstrap necesita
   tripletas de canales para sus variables *-rgb (las usa dentro de rgba()).
   ========================================================================== */

/* Geist local (variable, un solo archivo para todos los pesos) */
@font-face {
  font-family: "Geist";
  src: url("../fonts/geist/Geist-VariableFont_wght.ttf") format("truetype");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* Superficies */
  --zn-background:            oklch(100% 0 0);      /* #ffffff */
  --zn-foreground:            oklch(14.5% 0 0);     /* #0a0a0a */
  --zn-card:                  oklch(100% 0 0);      /* #ffffff */
  --zn-card-foreground:       oklch(14.5% 0 0);     /* #0a0a0a */
  --zn-popover:               oklch(100% 0 0);      /* #ffffff */
  --zn-popover-foreground:    oklch(14.5% 0 0);     /* #0a0a0a */
  /* Fondo del area de contenido (detras de las cards). Es el gris que antes
     tenia el sidebar; el sidebar, header y footer quedan en blanco. */
  --zn-content-bg:            oklch(98.5% 0 0);     /* #fafafa */

  /* Acentos */
  --zn-primary:               oklch(20.5% 0 0);     /* #171717 */
  --zn-primary-foreground:    oklch(98.5% 0 0);     /* #fafafa */
  --zn-secondary:             oklch(96.5% 0 0);     /* #f3f3f3 */
  --zn-secondary-foreground:  oklch(20.5% 0 0);     /* #171717 */
  --zn-muted:                 oklch(96.5% 0 0);     /* #f3f3f3 */
  --zn-muted-foreground:      oklch(55.6% 0 0);     /* #737373 */
  --zn-accent:                oklch(96.5% 0 0);     /* #f3f3f3 */
  --zn-accent-foreground:     oklch(20.5% 0 0);     /* #171717 */

  /* Bordes y foco */
  --zn-border:                oklch(92.2% 0 0);     /* #e5e5e5 */
  --zn-input:                 oklch(92.2% 0 0);     /* #e5e5e5 */
  --zn-ring:                  oklch(70.8% 0 0);     /* #a1a1a1 */

  /* Sidebar */
  --zn-sidebar:                     oklch(100% 0 0);    /* #ffffff */
  --zn-sidebar-foreground:          oklch(14.5% 0 0);   /* #0a0a0a */
  --zn-sidebar-accent:              oklch(96.5% 0 0);   /* #f3f3f3 */
  --zn-sidebar-accent-foreground:   oklch(20.5% 0 0);   /* #171717 */
  --zn-sidebar-primary:             oklch(20.5% 0 0);   /* #171717 */
  --zn-sidebar-primary-foreground:  oklch(98.5% 0 0);   /* #fafafa */
  --zn-sidebar-border:              oklch(92.2% 0 0);   /* #e5e5e5 */
  /* Items del menu en reposo: texto gris oscuro e icono gris medio, para que
     el menu no pese tanto. Hover y activo vuelven al casi-negro. */
  --zn-sidebar-link:                oklch(44.6% 0 0);   /* #545454 = negro al 70%, como Zenith */
  --zn-sidebar-icon:                oklch(61.7% 0 0);   /* #858585 = negro al 50% */

  /* Estado del menu lateral. Zenith usa --sidebar-accent (96.5%) tanto para
     hover como para activo, pero contra un sidebar de 98.5% eso es un solo
     tono de diferencia y no se percibe. Aca se separan los dos estados y se
     baja la luminosidad del activo. Subir/bajar estos dos numeros es todo lo
     que hace falta para calibrar cuanto se nota. */
  --zn-sidebar-hover:               oklch(95.5% 0 0);   /* #f1f1f1 */
  --zn-sidebar-active:              oklch(90% 0 0);     /* #e0e0e0 */

  /* Semánticos. shadcn solo define destructive; success/warning/info se
     agregan acá porque la app los usa (btn-success aparece 14 veces).
     Están tomados de la paleta oklch de Tailwind v4 para que armonicen. */
  --zn-destructive:           oklch(57.7% 0.245 27.325);  /* #e7000b */
  --zn-success:               oklch(59.6% 0.145 163);     /* #009965 */
  --zn-warning:               oklch(76.9% 0.161 70.08);   /* #f49f1a */
  --zn-info:                  oklch(62.3% 0.214 259.8);   /* #2b7fff */

  /* Tripletas sRGB (Bootstrap las usa dentro de rgba()) */
  --zn-rgb-background:        255, 255, 255;
  --zn-rgb-foreground:        10, 10, 10;
  --zn-rgb-primary:           23, 23, 23;
  --zn-rgb-secondary:         243, 243, 243;
  --zn-rgb-muted-foreground:  115, 115, 115;
  --zn-rgb-border:            229, 229, 229;
  --zn-rgb-ring:              161, 161, 161;
  --zn-rgb-destructive:       231, 0, 11;
  --zn-rgb-success:           0, 153, 101;
  --zn-rgb-warning:           244, 159, 26;
  --zn-rgb-info:              43, 127, 255;

  /* Alturas del shell. El sidebar y el area de contenido son columnas
     independientes, asi que sus barras solo quedan alineadas si comparten
     la misma altura.
     Nota: el footer de la pagina esta desactivado en index.php, asi que
     --zn-shell-footer-h hoy solo lo usa el pie del sidebar. Las reglas de
     .app-footer se dejan listas por si se vuelve a activar. */
  --zn-shell-header-h:        3.5rem;
  --zn-shell-footer-h:        3.5rem;

  /* La cabecera del sidebar sale por separado a proposito: AdminLTE le fija
     3.5rem a .sidebar-brand, pero el navbar termina midiendo un poco mas por
     el alto de sus .nav-link. Este es el numero a mover para que las dos
     lineas coincidan; el default es el mismo que el navbar. */
  --zn-sidebar-header-h:      var(--zn-shell-header-h);

  /* Geometría. shadcn parte de --radius y deriva el resto. */
  --zn-radius:                0.5rem;                      /* 8px */
  --zn-radius-sm:             calc(var(--zn-radius) - 4px);
  --zn-radius-md:             calc(var(--zn-radius) - 2px);
  --zn-radius-lg:             var(--zn-radius);
  --zn-radius-xl:             calc(var(--zn-radius) + 4px);
  --zn-radius-contenedor:     5px;                         /* cards, modales y list-group */
  --zn-radius-full:           9999px;                      /* pastillas y avatares redondos */

  /* Sombras: shadcn las usa muy sutiles. El look "plano con borde fino"
     es justamente lo que lo distingue de Bootstrap/AdminLTE. */
  --zn-shadow-xs:  0 1px 2px 0 rgb(0 0 0 / 0.05);
  --zn-shadow-sm:  0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --zn-shadow-md:  0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --zn-shadow-lg:  0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}

[data-bs-theme="dark"] {
  --zn-background:            oklch(7.5% 0 0);      /* #010101 */
  --zn-foreground:            oklch(98.5% 0 0);     /* #fafafa */
  --zn-card:                  oklch(19% 0 0);       /* #141414 */
  --zn-card-foreground:       oklch(98.5% 0 0);     /* #fafafa */
  --zn-popover:               oklch(21% 0 0);       /* #181818 */
  --zn-popover-foreground:    oklch(98.5% 0 0);     /* #fafafa */
  --zn-content-bg:            oklch(11% 0 0);       /* #040404 */

  --zn-primary:               oklch(92.2% 0 0);     /* #e5e5e5 */
  --zn-primary-foreground:    oklch(20.5% 0 0);     /* #171717 */
  --zn-secondary:             oklch(23.5% 0 0);     /* #1e1e1e */
  --zn-secondary-foreground:  oklch(98.5% 0 0);     /* #fafafa */
  --zn-muted:                 oklch(23.5% 0 0);     /* #1e1e1e */
  --zn-muted-foreground:      oklch(70.8% 0 0);     /* #a1a1a1 */
  --zn-accent:                oklch(23.5% 0 0);     /* #1e1e1e */
  --zn-accent-foreground:     oklch(98.5% 0 0);     /* #fafafa */

  --zn-border:                oklch(28% 0 0);       /* #292929 */
  --zn-input:                 oklch(28% 0 0);       /* #292929 */
  --zn-ring:                  oklch(55.6% 0 0);     /* #737373 */

  /* El fondo del sidebar en dark no venía en el bundle que extraje:
     está inferido para quedar entre --background (7.5%) y --card (19%),
     con el accent de hover (20%) lo bastante separado para que se note. */
  --zn-sidebar:                     oklch(7.5% 0 0);    /* #010101 */
  --zn-sidebar-foreground:          oklch(98.5% 0 0);   /* #fafafa */
  --zn-sidebar-accent:              oklch(20% 0 0);     /* #161616 */
  --zn-sidebar-accent-foreground:   oklch(98.5% 0 0);   /* #fafafa */
  --zn-sidebar-primary:             oklch(92.2% 0 0);   /* #e5e5e5 */
  --zn-sidebar-primary-foreground:  oklch(20.5% 0 0);   /* #171717 */
  --zn-sidebar-border:              oklch(26% 0 0);     /* #242424 */
  --zn-sidebar-link:                oklch(75.5% 0 0);   /* #afafaf = blanco al 70% */
  --zn-sidebar-icon:                oklch(59.5% 0 0);   /* #7e7e7e = blanco al 50% */
  --zn-sidebar-hover:               oklch(18% 0 0);     /* #131313 */
  --zn-sidebar-active:              oklch(27% 0 0);     /* #282828 */

  --zn-destructive:           oklch(70.4% 0.191 22.216); /* #ff6467 */

  --zn-rgb-background:        1, 1, 1;
  --zn-rgb-foreground:        250, 250, 250;
  --zn-rgb-primary:           229, 229, 229;
  --zn-rgb-secondary:         30, 30, 30;
  --zn-rgb-muted-foreground:  161, 161, 161;
  --zn-rgb-border:            41, 41, 41;
  --zn-rgb-ring:              115, 115, 115;
  --zn-rgb-destructive:       255, 100, 103;

  /* En dark las sombras casi no se ven; shadcn las sube un poco. */
  --zn-shadow-xs:  0 1px 2px 0 rgb(0 0 0 / 0.3);
  --zn-shadow-sm:  0 1px 3px 0 rgb(0 0 0 / 0.4), 0 1px 2px -1px rgb(0 0 0 / 0.4);
  --zn-shadow-md:  0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4);
  --zn-shadow-lg:  0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.5);
}

/* Tokens derivados. Van en los mismos scopes que el puente de la sección 2
   para que cada tema los recalcule con SU --zn-rgb-ring (un var() se resuelve
   donde se declara, no donde se usa). */
:root,
[data-bs-theme="light"],
[data-bs-theme="dark"] {
  /* el anillo de foco de 3px, firma de shadcn (botones, inputs, plugins) */
  --zn-focus-ring: 0 0 0 3px rgba(var(--zn-rgb-ring), 0.5);
}

/* --------------------------------------------------------------------------
   2. PUENTE HACIA BOOTSTRAP
   Redefinir las variables --bs-* hace que TODO componente de Bootstrap que
   no esté explícitamente estilizado más abajo igual tome la paleta correcta.
   Es lo que permite que esto sea barato.
   -------------------------------------------------------------------------- */

:root,
[data-bs-theme="light"],
[data-bs-theme="dark"] {
  --bs-body-bg:                 var(--zn-background);
  --bs-body-bg-rgb:             var(--zn-rgb-background);
  --bs-body-color:              var(--zn-foreground);
  --bs-body-color-rgb:          var(--zn-rgb-foreground);

  --bs-emphasis-color:          var(--zn-foreground);
  --bs-emphasis-color-rgb:      var(--zn-rgb-foreground);
  --bs-heading-color:           var(--zn-foreground);

  --bs-secondary-color:         var(--zn-muted-foreground);
  --bs-secondary-color-rgb:     var(--zn-rgb-muted-foreground);
  --bs-secondary-bg:            var(--zn-secondary);
  --bs-secondary-bg-rgb:        var(--zn-rgb-secondary);

  --bs-tertiary-color:          var(--zn-muted-foreground);
  --bs-tertiary-bg:             var(--zn-muted);

  --bs-border-color:            var(--zn-border);
  --bs-border-color-translucent: var(--zn-border);

  --bs-primary:                 var(--zn-primary);
  --bs-primary-rgb:             var(--zn-rgb-primary);
  --bs-secondary:               var(--zn-secondary);
  --bs-secondary-rgb:           var(--zn-rgb-secondary);
  --bs-success:                 var(--zn-success);
  --bs-success-rgb:             var(--zn-rgb-success);
  --bs-danger:                  var(--zn-destructive);
  --bs-danger-rgb:              var(--zn-rgb-destructive);
  --bs-warning:                 var(--zn-warning);
  --bs-warning-rgb:             var(--zn-rgb-warning);
  --bs-info:                    var(--zn-info);
  --bs-info-rgb:                var(--zn-rgb-info);

  --bs-link-color:              var(--zn-foreground);
  --bs-link-color-rgb:          var(--zn-rgb-foreground);
  --bs-link-hover-color:        var(--zn-muted-foreground);

  --bs-border-radius:           var(--zn-radius-md);
  --bs-border-radius-sm:        var(--zn-radius-sm);
  --bs-border-radius-lg:        var(--zn-radius-lg);
  --bs-border-radius-xl:        var(--zn-radius-xl);

  --bs-box-shadow:              var(--zn-shadow-md);
  --bs-box-shadow-sm:           var(--zn-shadow-xs);
  --bs-box-shadow-lg:           var(--zn-shadow-lg);

  --bs-font-sans-serif: "Geist", system-ui, -apple-system, "Segoe UI", Roboto,
                        "Helvetica Neue", Arial, sans-serif;
}

/* Bootstrap NO resuelve el azul de sus componentes via var(--bs-primary): lo
   compila como #0d6efd literal dentro de cada componente (--bs-list-group-active-bg,
   --bs-dropdown-link-active-bg, etc). Y una variable con scope de componente le
   gana a la heredada de :root, asi que el puente de arriba no las alcanza.
   Las de .btn-* se pisan con reglas propias mas abajo; estas son las que
   faltaban. Si aparece otro azul suelto, el patron es este (RULES.md #20). */
:root {
  --bs-focus-ring-color: rgba(var(--zn-rgb-ring), 0.5);
}

.list-group {
  --bs-list-group-active-bg: var(--zn-accent);
  --bs-list-group-active-border-color: var(--zn-border);
  --bs-list-group-active-color: var(--zn-accent-foreground);
  --bs-list-group-action-hover-bg: var(--zn-muted);
}

.dropdown-menu {
  --bs-dropdown-link-active-bg: var(--zn-accent);
  --bs-dropdown-link-active-color: var(--zn-accent-foreground);
  --bs-dropdown-link-hover-bg: var(--zn-accent);
  --bs-dropdown-link-hover-color: var(--zn-accent-foreground);
}

/* la pestaña activa de las pills es la superficie elevada (ver Nav pills abajo) */
.nav-pills {
  --bs-nav-pills-link-active-bg: var(--zn-background);
  --bs-nav-pills-link-active-color: var(--zn-foreground);
}

.progress {
  --bs-progress-bar-bg: var(--zn-primary);
}

/* Con esto los botones de las puntas toman el mismo radio que los del medio
   (.page-link, sección 5) sin necesitar !important. */
.pagination {
  --bs-pagination-border-radius: var(--zn-radius-sm);
}

/* .bg-body-tertiary vive en el <body> de index.php y es una utilidad con
   !important: solo se le puede ganar con otro. (El .bg-body-secondary del
   <aside> se neutraliza en .app-sidebar, sección 3.) */
body.bg-body-tertiary { background-color: var(--zn-content-bg) !important; }

body {
  font-family: var(--bs-font-sans-serif);
  font-size: 0.875rem;          /* shadcn trabaja en 14px, no en 16px */
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.006em;     /* el tracking apretado de Geist */
}

/* Iconos Lucide (assets/plugins/lucide, los de shadcn/Zenith). Su CSS solo pone
   la fuente; esto los alinea con el texto de al lado sin mover la linea. */
[class^="icon-"],
[class*=" icon-"] {
  display: inline-block;
  line-height: 1;
  vertical-align: -0.125em;
}

/* Texto seleccionado con el mouse. Sin esto manda el color del sistema
   (Windows: texto blanco), que dentro de los inputs claros no se distinguia.
   Mismo azul suave que la fila seleccionada de las tablas, texto normal. */
::selection {
  background-color: color-mix(in oklab, var(--zn-info) 25%, transparent);
  color: var(--zn-foreground);
}

h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* --------------------------------------------------------------------------
   3. SHELL (sidebar / header / main)
   -------------------------------------------------------------------------- */

/* El <aside> de menu.php trae data-bs-theme="dark" hardcodeado (RULES.md #19),
   y ese atributo TAMBIEN matchea el bloque de tokens oscuros de arriba: sin
   esto, todos los --zn-* resuelven a sus valores oscuros dentro del sidebar y
   queda negro aunque la pagina este en claro. Aca se les devuelve el valor
   claro, solo cuando el <html> NO esta en modo oscuro (si algun dia se
   reactiva el dark, el sidebar lo sigue).
   Color elegido en Ajustes: --zn-menu-* (header.php, components/colores_tema.php).
   Sin color propio no existen y rige el fallback, que es el blanco de siempre. */
html:not([data-bs-theme="dark"]) .app-sidebar[data-bs-theme="dark"] {
  --zn-sidebar:                     var(--zn-menu-bg, oklch(100% 0 0));          /* #ffffff */
  --zn-sidebar-foreground:          var(--zn-menu-fg, oklch(14.5% 0 0));         /* #0a0a0a */
  --zn-sidebar-accent:              var(--zn-menu-accent, oklch(96.5% 0 0));     /* #f3f3f3 */
  --zn-sidebar-accent-foreground:   var(--zn-menu-fg-fuerte, oklch(20.5% 0 0));  /* #171717 */
  --zn-sidebar-primary:             var(--zn-menu-primary, oklch(20.5% 0 0));    /* #171717 */
  --zn-sidebar-primary-foreground:  oklch(98.5% 0 0);   /* #fafafa */
  --zn-sidebar-border:              var(--zn-menu-border, oklch(92.2% 0 0));     /* #e5e5e5 */
  --zn-sidebar-link:                var(--zn-menu-link, oklch(44.6% 0 0));       /* #545454 */
  --zn-sidebar-icon:                var(--zn-menu-icon, oklch(61.7% 0 0));       /* #858585 */
  --zn-sidebar-hover:               var(--zn-menu-hover, oklch(95.5% 0 0));      /* #f1f1f1 */
  --zn-sidebar-active:              var(--zn-menu-active, oklch(90% 0 0));       /* #e0e0e0 */
  --zn-muted-foreground:            var(--zn-menu-muted, oklch(55.6% 0 0));      /* #737373 */
  --zn-border:                      var(--zn-menu-border, oklch(92.2% 0 0));     /* #e5e5e5 */
}

/* AdminLTE pinta el menu con SUS propias variables --lte-sidebar-*, y como el
   <aside> declara data-bs-theme="dark" toma los valores pensados para fondo
   negro: texto gris claro (#c2c7d0) y hover blanco translucido. Aca se
   reencaminan a los tokens de Zenith, que ya resuelven solos segun el tema de
   la pagina. El segundo selector es para ganarle a las de AdminLTE con scope
   [data-bs-theme="dark"] sin tocar el HTML. */
.app-sidebar,
.app-sidebar[data-bs-theme="dark"] {
  /* el color del item en reposo sale de aca: la regla de AdminLTE
     (.sidebar-wrapper .sidebar-menu > .nav-item > .nav-link) le gana en
     especificidad a cualquier color puesto en .nav-link mas abajo */
  --lte-sidebar-color:                  var(--zn-sidebar-link);
  --lte-sidebar-hover-bg:               var(--zn-sidebar-hover);
  --lte-sidebar-hover-color:            var(--zn-sidebar-accent-foreground);
  --lte-sidebar-active-color:           var(--zn-sidebar-accent-foreground);
  --lte-sidebar-menu-active-bg:         var(--zn-sidebar-active);
  --lte-sidebar-menu-active-color:      var(--zn-sidebar-accent-foreground);
  --lte-sidebar-header-color:           var(--zn-muted-foreground);
  --lte-sidebar-submenu-bg:             transparent;
  --lte-sidebar-submenu-color:          var(--zn-muted-foreground);
  --lte-sidebar-submenu-hover-bg:       var(--zn-sidebar-accent);
  --lte-sidebar-submenu-hover-color:    var(--zn-sidebar-accent-foreground);
  --lte-sidebar-submenu-active-bg:      var(--zn-sidebar-accent);
  --lte-sidebar-submenu-active-color:   var(--zn-sidebar-accent-foreground);

  /* !important: el <aside> trae .bg-body-secondary y .shadow, utilidades con !important */
  background-color: var(--zn-sidebar) !important;
  color: var(--zn-sidebar-foreground);
  border-right: 1px solid var(--zn-sidebar-border);
  box-shadow: none !important;
}

.app-sidebar .sidebar-brand {
  background-color: transparent;
  border-bottom: 1px solid var(--zn-sidebar-border);
  height: var(--zn-sidebar-header-h);
  min-height: var(--zn-sidebar-header-h);
  padding: 0 0.75rem;
  display: flex;
  align-items: center;
  justify-content: flex-start;   /* ver "Modo mini": el rail no centra, mueve el padding */
}

.app-sidebar .brand-link {
  color: var(--zn-sidebar-foreground);
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0;
  border-radius: var(--zn-radius-md);
  overflow: hidden;
}

.app-sidebar .brand-text {
  font-size: 0.875rem;
  font-weight: 600 !important;   /* el markup trae .fw-light, utilidad con !important */
  letter-spacing: -0.01em;
  color: var(--zn-sidebar-foreground);
}

.app-sidebar .brand-image { box-shadow: none !important; }   /* el markup trae .shadow */

/* El item de menú de shadcn: radio medio, icono chico, hover por fondo
   (no por color de texto, que es lo que hace AdminLTE).
   El color y el fondo (reposo, hover y activo) NO se ponen aca: los pinta
   AdminLTE con .sidebar-wrapper .sidebar-menu > .nav-item > .nav-link, que gana
   en especificidad, leyendo las --lte-sidebar-* redirigidas en .app-sidebar. */
.app-sidebar .sidebar-menu .nav-link {
  position: relative;   /* ancla la barra indicadora del activo */
  border-radius: var(--zn-radius-md);
  padding: 0.5rem 0.625rem;
  margin-bottom: 0.125rem;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: normal;   /* sin el tracking apretado del body, como Zenith */
  display: flex;
  align-items: center;
  gap: 0.625rem;   /* + 3px que sobran de la caja de 24px del icono = ~13px visibles */
  transition: background-color .15s ease, color .15s ease;
}

/* AdminLTE le pone padding-left: 0.5rem al texto; sumado al gap dejaba ~23px
   entre icono y texto (Zenith: 12px). La separacion la da solo el gap. */
.app-sidebar .sidebar-menu .nav-link p { margin: 0; padding-left: 0; }

/* el ancho no se toca: AdminLTE fija la caja del icono en 1.5rem (min/max-width) */
.app-sidebar .sidebar-menu .nav-link .nav-icon {
  font-size: 1.125rem;   /* 18px, como los iconos de Zenith */
  color: var(--zn-sidebar-icon);
  margin: 0;
  transition: color .15s ease;
}

/* Señales del activo: fondo mas oscuro que el hover (--zn-sidebar-active),
   texto e icono en casi-negro (contra el gris de los demas) y una barra a la
   izquierda. El peso queda en 500 como Zenith (2026-10-11): el contraste de
   color ya lo marca. El casi-negro de la barra es --sidebar-primary. */
.app-sidebar .sidebar-menu .nav-link.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 20%;
  bottom: 20%;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background-color: var(--zn-sidebar-primary);
}

/* el activo no cambia de fondo al pasar el mouse: empata en especificidad con
   el :hover de AdminLTE y gana por ir despues */
.app-sidebar .sidebar-menu .nav-link.active:hover {
  background-color: var(--zn-sidebar-active);
}

.app-sidebar .sidebar-menu .nav-link:hover .nav-icon,
.app-sidebar .sidebar-menu .nav-link.active .nav-icon { color: var(--zn-sidebar-accent-foreground); }

/* Titulos de seccion del menu (patron de Zenith). */
.app-sidebar .sidebar-menu .nav-header {
  display: block;
  padding: 1rem 0.625rem 0.375rem;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--zn-muted-foreground);
}

.app-sidebar .sidebar-menu .nav-header:first-child { padding-top: 0.25rem; }

/* Rail: el titulo pasa a linea divisoria (AdminLTE lo oculta). */
.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-menu .nav-header {
  height: 1px;
  padding: 0;
  margin: 0.5rem 0.5rem;
  overflow: hidden;
  font-size: 0;
  background-color: var(--zn-sidebar-border);
}

.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-menu .nav-header:first-child { display: none; }

/* Pie del sidebar con el usuario (patron de Zenith).
   El <aside> pasa a flex-column para que el pie quede abajo del todo y el
   menu ocupe el resto. El min-height:0 del wrapper es lo que permite que el
   menu scrollee en vez de empujar el pie fuera de la pantalla. (El padding
   del wrapper, 0.5rem, ya lo trae AdminLTE.) */
.app-sidebar {
  display: flex;
  flex-direction: column;
}

.app-sidebar .sidebar-wrapper {
  flex: 1 1 auto;
  min-height: 0;
}

/* AdminLTE le clava al menu `height: calc(100vh - 3.5rem)` (regla
   .sidebar-expand-lg.layout-fixed .app-sidebar .sidebar-wrapper). Ese calculo
   solo descuenta la cabecera y no sabe del pie de usuario que agregamos, asi
   que el pie terminaba colgando por fuera del sidebar. Con alto automatico el
   flex de arriba reparte el espacio y el pie queda anclado abajo. Los
   selectores repiten los de AdminLTE para empatarle en especificidad. */
.layout-fixed .app-sidebar .sidebar-wrapper,
.sidebar-expand-lg.layout-fixed .app-sidebar .sidebar-wrapper {
  height: auto;
  overflow-x: hidden;
  overflow-y: auto;
}

.sidebar-footer {
  flex: 0 0 auto;
  border-top: 1px solid var(--zn-sidebar-border);
  height: var(--zn-shell-footer-h);
  padding: 0 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.sidebar-user {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.375rem 0.5rem;
  border-radius: var(--zn-radius-md);
  text-decoration: none;
  color: var(--zn-sidebar-foreground);
}

.sidebar-user:hover { background-color: var(--zn-sidebar-accent); }

/* Sin permiso de perfil el bloque no es clickeable: no debe fingir que lo es. */
.sidebar-user-static { pointer-events: none; }

.sidebar-user-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: var(--zn-radius-full);
  object-fit: cover;
  flex: 0 0 auto;
}

.sidebar-user-info {
  display: flex;
  flex-direction: column;
  min-width: 0;      /* deja que el text-overflow funcione */
  line-height: 1.2;
  transition: opacity 0.3s ease;
}

.sidebar-user-nombre {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--zn-sidebar-foreground);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-rol {
  font-size: 0.75rem;
  color: var(--zn-muted-foreground);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-user-salir {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--zn-radius-md);
  color: var(--zn-muted-foreground);
  font-size: 1rem;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}

.sidebar-user-salir:hover {
  background-color: var(--zn-sidebar-accent);
  color: var(--zn-menu-danger, var(--zn-destructive));
}

/* Menu flotante del avatar (solo contraido); left/bottom los calcula menu.php. */
.sidebar-user-menu {
  position: fixed;
  top: auto;
  z-index: 1060;
  min-width: 11rem;
}

.sidebar-user-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.sidebar-user-menu .sidebar-user-menu-salir:hover,
.sidebar-user-menu .sidebar-user-menu-salir:focus {
  color: var(--zn-destructive);
}

/* --- Modo mini (rail de iconos) ---
   Se activa con la clase `sidebar-mini` en el <body> de index.php. AdminLTE ya
   se encarga del ancho (4.6rem), de encoger los .nav-link y de ocultar los
   textos del menu y de la marca. Lo unico que no conoce es el pie de usuario,
   que lo agregamos nosotros: eso es lo que se ajusta aca.

   El <body> lleva `sidebar-without-hover`: el sidebar NO se expande solo al
   pasar el mouse, porque eso resultaba molesto. En su lugar el nombre de cada
   opcion aparece como tooltip (ver el init en index.php).
   Por eso estas reglas NO llevan :not(:hover): el rail se queda angosto
   siempre, pase o no pase el mouse por encima.

   Logo y avatar NO se centran con justify-content: la clase sidebar-collapse
   entra de golpe y el centrado se aplicaba sobre el sidebar todavia ancho, asi
   que saltaban al medio y recien despues se encogia el menu (parpadeo,
   incidente #23). En su lugar quedan alineados a la izquierda y lo que cambia
   es el padding, animado con la misma duracion que el ancho (0.3s). El padding
   del rail se calcula para que queden centrados en 4.6rem (menos 1px del borde
   derecho). */
.app-sidebar .sidebar-brand,
.sidebar-footer,
.sidebar-user {
  transition: padding 0.3s ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  .app-sidebar .sidebar-brand,
  .sidebar-footer,
  .sidebar-user,
  .sidebar-user-info {
    transition: none;
  }
}

/* El logo trae 38px fijos por estilo inline en menu.php. */
.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-brand {
  padding: 0 0 0 calc((4.6rem - 1px - 38px) / 2);
}

/* avatar 2rem + 0.375rem de padding por lado */
.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-footer {
  padding: 0 0 0 calc((4.6rem - 1px - 2.75rem) / 2);
}

.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-user {
  flex: 0 0 auto;
  gap: 0;
  padding: 0.375rem;
}

.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-user-info {
  max-width: 0;
  opacity: 0;
}

.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-user-salir {
  display: none;
}

/* Contraido: clickeable sin permiso de perfil, abre el menu flotante (menu.php). */
.sidebar-mini.sidebar-collapse .app-sidebar .sidebar-user-static {
  pointer-events: auto;
  cursor: pointer;
}

/* AdminLTE usa `max-width: 100vw` en el wrapper, el header y el main. La
   unidad vw NO descuenta la barra de scroll: con barra vertical presente,
   100vw es mas ancho que el area visible y sobran unos pixeles por la derecha.
   Eso genera una barra horizontal que nadie pidio. Con 100% se mide contra el
   contenedor real, que si la descuenta. */
.app-wrapper,
.app-header,
.app-main {
  max-width: 100%;
}

/* Header. --zn-navbar-* = color elegido en Ajustes; sin el, fallback a los tokens. */
.app-header {
  background-color: var(--zn-navbar-bg, var(--zn-background)) !important;   /* el markup trae .bg-body */
  border-bottom: 1px solid var(--zn-navbar-border, var(--zn-border));
  box-shadow: none;
  height: var(--zn-shell-header-h);
  min-height: var(--zn-shell-header-h);
  padding-top: 0;
  padding-bottom: 0;
}

.app-header > .container-fluid {
  height: 100%;
  display: flex;
  align-items: center;
}

.app-header .nav-link { color: var(--zn-navbar-fg, var(--zn-foreground)); }
.app-header .nav-link:hover { color: var(--zn-navbar-muted, var(--zn-muted-foreground)); }

.app-main { background-color: var(--zn-content-bg); }

.app-content { padding-top: 1.25rem; padding-bottom: 1.25rem; }

.app-content-header { padding: 0 0 1rem; }
.app-content-header h3 { font-size: 1.25rem; font-weight: 600; margin: 0; }

/* Footer de la pagina: hoy desactivado (include comentado en index.php); la
   regla queda lista por si se reactiva.
   AdminLTE le pone `width: inherit`, que copia el ancho del .app-wrapper
   entero (toda la ventana). Pero el footer vive en la columna 2 del grid, asi
   que arranca despues del menu y se extiende el ancho completo: se sale por la
   derecha y se encarama sobre el menu por la izquierda. Ese desborde crea una
   barra horizontal que a su vez dispara la vertical, y de ahi el scroll que
   aparece sin que el contenido lo necesite.
   Con `auto` el footer ocupa exactamente su celda del grid.
   Mismo motivo para el max-width: 100vw incluye el ancho de la barra de
   scroll, asi que cuando hay barra vertical sobra por la derecha. */
.app-footer {
  width: auto;
  max-width: none;
  background-color: var(--zn-background);
  border-top: 1px solid var(--zn-border);
  color: var(--zn-muted-foreground);
  font-size: 0.8125rem;
  height: var(--zn-shell-footer-h);
  padding: 0 1rem;
  /* centrado vertical con line-height, no con flex: el markup de footer.php
     usa .float-end y dentro de un contenedor flex el float se ignora, lo que
     mandaria el "V1" a la izquierda. */
  line-height: var(--zn-shell-footer-h);
}

/* Pantalla de carga (#pantallaCarga en index.php, components/pantalla_carga.js):
   tapa la vista hasta que la página termina de cargar y vuelve al hacer clic en
   otra vista (pedido del cliente, 2026-10-28: "todas entran de golpe"). Sale
   pintada desde el HTML, sin esperar al JS. Si el JS no llegara a quitarla, la
   animación la quita sola a los 10 s (nunca deja la pantalla tapada). */
.pantalla-carga {
  position: fixed;
  inset: 0;
  z-index: 2000; /* sobre el navbar, el sidebar y los modales (1055) */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  background-color: var(--zn-content-bg);
  transition: opacity .25s ease, visibility .25s ease;
  animation: pantalla-carga-salida 0s 10s forwards;
}

.pantalla-carga.oculta {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* al irse a otra vista (clic) aparece con una pequeña demora: si la página nueva
   llega rápido, ni se nota. Con el mismo seguro de los 10 s (va segunda: gana). */
.pantalla-carga.saliendo {
  animation: pantalla-carga-entrada .2s .15s both, pantalla-carga-salida 0s 10s forwards;
}

@keyframes pantalla-carga-salida { to { opacity: 0; visibility: hidden; pointer-events: none; } }
@keyframes pantalla-carga-entrada { from { opacity: 0; } to { opacity: 1; } }

.pantalla-carga-icono {
  width: 64px;
  height: 64px;
  object-fit: contain;
  border-radius: var(--zn-radius-lg);
}

.pantalla-carga-spinner {
  width: 1.75rem;
  height: 1.75rem;
  border-width: .2rem;
  color: var(--zn-muted-foreground);
}

@media (prefers-reduced-motion: reduce) {
  .pantalla-carga { transition: none; }
}

/* --------------------------------------------------------------------------
   4. COMPONENTES
   -------------------------------------------------------------------------- */

/* Card: el cambio más visible. shadcn = borde fino + radio grande + sombra
   casi nula. AdminLTE = sombra marcada sin borde. */
.card {
  --bs-card-bg: var(--zn-card);
  --bs-card-color: var(--zn-card-foreground);
  --bs-card-border-color: var(--zn-border);
  --bs-card-border-radius: var(--zn-radius-contenedor);
  --bs-card-inner-border-radius: calc(var(--zn-radius-contenedor) - 1px);
  --bs-card-spacer-x: 1.5rem;
  --bs-card-spacer-y: 1.25rem;
  border: 1px solid var(--zn-border);
  box-shadow: var(--zn-shadow-xs);
}

.card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--zn-border);
  padding: 1rem 1.5rem;
}

.card-title { font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; margin: 0; }

.card-footer {
  background-color: transparent;
  border-top: 1px solid var(--zn-border);
  padding: 1rem 1.5rem;
}

/* Botones */
.btn {
  --bs-btn-border-radius: var(--zn-radius-md);
  --bs-btn-padding-y: 0.5rem;
  --bs-btn-padding-x: 1rem;
  --bs-btn-font-size: 0.875rem;
  --bs-btn-font-weight: 500;
  --bs-btn-focus-box-shadow: var(--zn-focus-ring);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  line-height: 1.25rem;
  box-shadow: var(--zn-shadow-xs);
  transition: background-color .15s ease, border-color .15s ease, opacity .15s ease;
  white-space: nowrap;
}

.btn:disabled, .btn.disabled { opacity: .5; box-shadow: none; }

/* Acciones de cabecera de card (ej. "Agregar Usuario"): tamaño btn-sm. */
.card-tools > .btn {
  --bs-btn-padding-y: 0.3125rem;
  --bs-btn-padding-x: 0.75rem;
  --bs-btn-font-size: 0.8125rem;
}

/* Movil: titulo y acciones en una fila flex con separacion, ambos mas compactos */
@media (max-width: 575.98px) {
  .card-header:has(> .card-tools) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
  }
  .card-header:has(> .card-tools)::after { display: none; }
  .card-header:has(> .card-tools) > .card-title {
    float: none;
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.9375rem;
  }
  .card-header > .card-tools {
    float: none;
    flex-shrink: 0;
    margin: 0;
  }
  .card-tools > .btn {
    --bs-btn-padding-y: 0.25rem;
    --bs-btn-padding-x: 0.625rem;
    --bs-btn-font-size: 0.75rem;
    gap: 0.375rem;
  }
  /* .filtro-compacto (en el .card-tools): el select del filtro de fecha más angosto, para
     que un título como "Paquetes" quepa a su lado. !important: INIT_FILTRO_FECHA le
     pone el ancho (12rem) en línea a Select2 */
  .card-tools.filtro-compacto > .select2-container { width: 9.5rem !important; }
  /* "Desde - hasta" (components/filtro_fecha.js) no cabe al lado del título: el filtro
     baja a su propia línea, el select junto al ↻ y el campo de fechas a lo ancho debajo */
  /* .card-header-apilado: el título en su línea y las herramientas a lo ancho debajo, cuando
     no caben al lado (botones con texto, o un filtro de fecha con un título largo): el
     .card-tools no se encoge y el título quedaba de una letra por línea. Con
     .card-tools-repartidos los botones se reparten el ancho (el ↻ del filtro no). */
  .card-header-apilado:has(> .card-tools) { flex-wrap: wrap; }
  .card-header-apilado > .card-title { flex: 1 1 100%; }
  .card-header-apilado > .card-tools { flex: 1 1 100%; min-width: 0; }
  .card-header-apilado > .card-tools > .select2-container { flex: 1 1 auto; width: auto !important; } /* el ancho de INIT_FILTRO_FECHA va en línea */
  .card-tools-repartidos > .btn { flex: 1 1 auto; }
  .card-header:has(.filtro-rango:not(.d-none)) { flex-wrap: wrap; }
  .card-header:has(.filtro-rango:not(.d-none)) > .card-tools { flex: 1 1 100%; }
  .card-tools:has(.filtro-rango:not(.d-none)) > .select2-container {
    flex: 1 1 calc(100% - 3.5rem);
    min-width: 0;
    width: auto !important; /* el de INIT_FILTRO_FECHA va en línea */
  }
  .card-tools:has(.filtro-rango:not(.d-none)) > .btn-reset-filtro { order: 1; }
  .card-tools > .filtro-rango { order: 2; flex: 1 1 100%; }
}

.btn-sm {
  --bs-btn-padding-y: 0.375rem;
  --bs-btn-padding-x: 0.75rem;
  --bs-btn-font-size: 0.8125rem;
  --bs-btn-border-radius: var(--zn-radius-sm);
}

.btn-primary {
  --bs-btn-bg: var(--zn-primary);
  --bs-btn-border-color: var(--zn-primary);
  --bs-btn-color: var(--zn-primary-foreground);
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-primary) 88%, var(--zn-background));
  --bs-btn-hover-border-color: color-mix(in oklab, var(--zn-primary) 88%, var(--zn-background));
  --bs-btn-hover-color: var(--zn-primary-foreground);
  --bs-btn-active-bg: color-mix(in oklab, var(--zn-primary) 80%, var(--zn-background));
  --bs-btn-active-border-color: color-mix(in oklab, var(--zn-primary) 80%, var(--zn-background));
  --bs-btn-disabled-bg: var(--zn-primary);
  --bs-btn-disabled-border-color: var(--zn-primary);
  --bs-btn-disabled-color: var(--zn-primary-foreground);
}

.btn-secondary {
  --bs-btn-bg: var(--zn-secondary);
  --bs-btn-border-color: var(--zn-secondary);
  --bs-btn-color: var(--zn-secondary-foreground);
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-secondary) 92%, var(--zn-foreground));
  --bs-btn-hover-border-color: color-mix(in oklab, var(--zn-secondary) 92%, var(--zn-foreground));
  --bs-btn-hover-color: var(--zn-secondary-foreground);
  --bs-btn-disabled-bg: var(--zn-secondary);
  --bs-btn-disabled-border-color: var(--zn-secondary);
  --bs-btn-disabled-color: var(--zn-secondary-foreground);
}

.btn-success {
  --bs-btn-bg: var(--zn-success);
  --bs-btn-border-color: var(--zn-success);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-success) 88%, black);
  --bs-btn-hover-border-color: color-mix(in oklab, var(--zn-success) 88%, black);
  --bs-btn-hover-color: #fff;
  --bs-btn-active-bg: color-mix(in oklab, var(--zn-success) 80%, black);
  --bs-btn-disabled-bg: var(--zn-success);
  --bs-btn-disabled-border-color: var(--zn-success);
  --bs-btn-disabled-color: #fff;
}

/* En esta app btn-danger es siempre "Cancelar": rojo suave (fondo tenue, texto
   rojo, sin borde) para que no compita con Guardar, que es el sólido. */
.btn-danger {
  --bs-btn-bg: color-mix(in oklab, var(--zn-destructive) 10%, transparent);
  --bs-btn-border-color: transparent;
  --bs-btn-color: var(--zn-destructive);
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-destructive) 16%, transparent);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--zn-destructive);
  --bs-btn-active-bg: color-mix(in oklab, var(--zn-destructive) 22%, transparent);
  --bs-btn-active-border-color: transparent;
  --bs-btn-active-color: var(--zn-destructive);
  --bs-btn-focus-box-shadow: 0 0 0 3px rgba(var(--zn-rgb-destructive), 0.25);
  --bs-btn-disabled-bg: color-mix(in oklab, var(--zn-destructive) 10%, transparent);
  --bs-btn-disabled-border-color: transparent;
  --bs-btn-disabled-color: var(--zn-destructive);
}

/* Campo de fecha con calendario (components/calendario.js): readonly, se elige tocándolo */
.campo-calendario { cursor: pointer; }
/* el "Desde - hasta" de los filtros: cabe "01/10/2026 – 15/10/2026" */
.filtro-rango { width: 13.5rem; }

/* Exportar a Excel: verde suave (como el Cancelar en rojo) y más chico que un btn-sm,
   pedido del cliente (2026-10-16); no compite con el Guardar verde sólido (RULES #24) */
.btn-excel {
  --bs-btn-padding-y: 0.1875rem;
  --bs-btn-padding-x: 0.5rem;
  --bs-btn-font-size: 0.75rem;
  --bs-btn-bg: color-mix(in oklab, var(--zn-success) 10%, transparent);
  --bs-btn-border-color: transparent;
  --bs-btn-color: var(--zn-success);
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-success) 16%, transparent);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--zn-success);
  --bs-btn-active-bg: color-mix(in oklab, var(--zn-success) 22%, transparent);
  --bs-btn-active-border-color: transparent;
  --bs-btn-active-color: var(--zn-success);
  --bs-btn-focus-box-shadow: 0 0 0 3px rgba(var(--zn-rgb-success), 0.25);
  gap: 0.25rem;
}

/* Descargar imagen (ámbar suave) y PDF (rojo suave) del estado de cuenta: los colores del
   viejo, pedido del cliente (2026-10-19); correo y WhatsApp igual. Mismo patrón que
   .btn-excel (que queda con su tono aprobado: no se mete aquí) */
.btn-imagen,
.btn-pdf,
.btn-correo,
.btn-whatsapp-ec {
  --bs-btn-bg: color-mix(in oklab, var(--zn-color-boton) 12%, transparent);
  --bs-btn-border-color: transparent;
  --bs-btn-color: color-mix(in oklab, var(--zn-color-boton) 85%, var(--zn-foreground));
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-color-boton) 20%, transparent);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: color-mix(in oklab, var(--zn-color-boton) 85%, var(--zn-foreground));
  --bs-btn-active-bg: color-mix(in oklab, var(--zn-color-boton) 26%, transparent);
  --bs-btn-active-border-color: transparent;
  --bs-btn-active-color: color-mix(in oklab, var(--zn-color-boton) 85%, var(--zn-foreground));
  --bs-btn-disabled-bg: color-mix(in oklab, var(--zn-color-boton) 8%, transparent);
  --bs-btn-disabled-border-color: transparent;
  --bs-btn-disabled-color: color-mix(in oklab, var(--zn-color-boton) 60%, var(--zn-foreground));
}

.btn-imagen { --zn-color-boton: var(--zn-warning); --bs-btn-focus-box-shadow: 0 0 0 3px rgba(var(--zn-rgb-warning), 0.25); }
.btn-pdf { --zn-color-boton: var(--zn-destructive); --bs-btn-focus-box-shadow: 0 0 0 3px rgba(var(--zn-rgb-destructive), 0.25); }
/* enviar al cliente: correo en azul suave (el del viejo) y WhatsApp en el verde de WhatsApp */
.btn-correo { --zn-color-boton: var(--zn-info); --bs-btn-focus-box-shadow: 0 0 0 3px color-mix(in oklab, var(--zn-info) 25%, transparent); }
.btn-whatsapp-ec { --zn-color-boton: #1da851; --bs-btn-focus-box-shadow: 0 0 0 3px rgba(29, 168, 81, 0.25); }

.btn-warning {
  --bs-btn-bg: var(--zn-warning);
  --bs-btn-border-color: var(--zn-warning);
  --bs-btn-color: oklch(20.5% 0 0);
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-warning) 88%, black);
  --bs-btn-hover-border-color: color-mix(in oklab, var(--zn-warning) 88%, black);
  --bs-btn-hover-color: oklch(20.5% 0 0);
}

.btn-info {
  --bs-btn-bg: var(--zn-info);
  --bs-btn-border-color: var(--zn-info);
  --bs-btn-color: #fff;
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-info) 88%, black);
  --bs-btn-hover-border-color: color-mix(in oklab, var(--zn-info) 88%, black);
  --bs-btn-hover-color: #fff;
}

/* El "outline" de shadcn es en realidad un botón con fondo propio y borde
   neutro, no el outline coloreado de Bootstrap. */
.btn-outline-secondary {
  --bs-btn-bg: var(--zn-background);
  --bs-btn-border-color: var(--zn-border);
  --bs-btn-color: var(--zn-foreground);
  --bs-btn-hover-bg: var(--zn-accent);
  --bs-btn-hover-border-color: var(--zn-border);
  --bs-btn-hover-color: var(--zn-accent-foreground);
  --bs-btn-active-bg: var(--zn-accent);
  --bs-btn-active-border-color: var(--zn-border);
  --bs-btn-active-color: var(--zn-accent-foreground);
}

.btn-outline-primary {
  --bs-btn-bg: var(--zn-background);
  --bs-btn-border-color: var(--zn-border);
  --bs-btn-color: var(--zn-foreground);
  --bs-btn-hover-bg: var(--zn-accent);
  --bs-btn-hover-border-color: var(--zn-border);
  --bs-btn-hover-color: var(--zn-accent-foreground);
}

.btn-outline-danger {
  --bs-btn-bg: var(--zn-background);
  --bs-btn-border-color: color-mix(in oklab, var(--zn-destructive) 35%, var(--zn-background));
  --bs-btn-color: var(--zn-destructive);
  --bs-btn-hover-bg: color-mix(in oklab, var(--zn-destructive) 10%, var(--zn-background));
  --bs-btn-hover-border-color: color-mix(in oklab, var(--zn-destructive) 45%, var(--zn-background));
  --bs-btn-hover-color: var(--zn-destructive);
}

/* Formularios: el anillo de foco de 3px es una de las firmas de shadcn. */
.form-control, .form-select {
  background-color: var(--zn-background);
  border: 1px solid var(--zn-input);
  border-radius: var(--zn-radius-md);
  color: var(--zn-foreground);
  font-size: 0.875rem;
  padding: 0.5rem 0.75rem;
  box-shadow: var(--zn-shadow-xs);
  transition: border-color .15s ease, box-shadow .15s ease;
}

.form-control-sm, .form-select-sm {
  font-size: 0.8125rem;
  padding: 0.375rem 0.625rem;
  border-radius: var(--zn-radius-sm);
}

/* Bootstrap dibuja la flecha del select como background-image y le reserva
   sitio con padding-right. Al unificar el padding arriba se perdio ese espacio
   y el texto quedaba montado debajo de la flecha. Aca se devuelve. */
.form-select                       { padding-right: 2.25rem; }
.form-select-sm                    { padding-right: 2rem; }

.form-control:focus, .form-select:focus {
  background-color: var(--zn-background);
  border-color: var(--zn-ring);
  color: var(--zn-foreground);
  box-shadow: var(--zn-focus-ring);
  outline: none;
}

.form-control::placeholder { color: var(--zn-muted-foreground); opacity: 1; }

/* Placeholder más chico que lo que se escribe: para un texto de ayuda largo en un
   campo grande que en celular se cortaba (ej. el de Entregar paquetes) */
.form-control.placeholder-chico::placeholder { font-size: 0.875rem; }

/* "Dirección registrada" u "Otra" de un envío (components/direccion_envio.js): selector
   como las pestañas (pista gris, la elegida en blanco con sombra). Con el gris suave del
   btn-outline-secondary no se distinguía cuál estaba marcada. */
.direccion-envio-opciones {
  background-color: var(--zn-muted);
  border-radius: var(--zn-radius-lg);
  padding: 0.25rem;
  gap: 0.25rem;
}

/* las dos opciones se reparten el ancho por igual y se encogen: en una columna angosta
   (Agregar delivery de Generar) "Otra" se salía de la pista */
.direccion-envio-opciones > .btn {
  --bs-btn-bg: transparent;
  --bs-btn-border-color: transparent;
  --bs-btn-color: var(--zn-muted-foreground);
  --bs-btn-hover-bg: transparent;
  --bs-btn-hover-border-color: transparent;
  --bs-btn-hover-color: var(--zn-foreground);
  border-radius: var(--zn-radius-md) !important;
  font-weight: 500;
  flex: 1 1 0;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.direccion-envio-opciones > .btn-check:checked + .btn {
  background-color: var(--zn-background);
  border-color: var(--zn-background);
  color: var(--zn-foreground);
  box-shadow: var(--zn-shadow-xs);
}

.direccion-envio-opciones > .btn-check:disabled + .btn {
  opacity: 0.5;
}

/* la registrada: el texto con su pin, como dato (no como campo deshabilitado);
   alto según el texto (una dirección larga ocupa dos líneas) */
.direccion-envio-registrada {
  height: auto;
  min-height: calc(1.5em + 0.75rem + 2px);
  background-color: var(--zn-background);
  color: var(--zn-foreground);
  white-space: normal;
  overflow-wrap: anywhere;
  border-style: dashed;
}

.direccion-envio-registrada::before {
  content: "\e111"; /* icon-map-pin de Lucide */
  font-family: lucide;
  margin-right: 0.4rem;
  color: var(--zn-muted-foreground);
}

.form-control:disabled, .form-select:disabled {
  background-color: var(--zn-muted);
  opacity: .6;
}

.form-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--zn-foreground);
  margin-bottom: 0.5rem;
}

.form-text { color: var(--zn-muted-foreground); font-size: 0.8125rem; }

.input-group-text {
  background-color: var(--zn-muted);
  border: 1px solid var(--zn-input);
  color: var(--zn-muted-foreground);
  border-radius: var(--zn-radius-md);
  font-size: 0.875rem;
  padding: 0.5rem 0.75rem;
}

.form-check-input {
  border: 1px solid var(--zn-input);
  border-radius: var(--zn-radius-sm);
  box-shadow: var(--zn-shadow-xs);
}

/* vale tambien para los switches (.form-switch) */
.form-check-input:checked {
  background-color: var(--zn-primary);
  border-color: var(--zn-primary);
}

.form-check-input:focus {
  border-color: var(--zn-ring);
  box-shadow: var(--zn-focus-ring);
}

.form-check-label { font-size: 0.875rem; }

/* Tablas: shadcn no usa zebra. Separa por línea inferior y pone el header en
   muted-foreground con peso medio. Se anula .table-striped a propósito. */
.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--zn-foreground);
  --bs-table-border-color: var(--zn-border);
  --bs-table-striped-bg: transparent;
  --bs-table-striped-color: var(--zn-foreground);
  --bs-table-hover-bg: var(--zn-muted);
  --bs-table-hover-color: var(--zn-foreground);
  font-size: 0.875rem;
  margin-bottom: 0;
}

.table > thead > tr > th {
  background-color: transparent;
  border-bottom: 1px solid var(--zn-border);
  color: var(--zn-muted-foreground);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0;
  padding: 0.625rem 0.75rem;
  white-space: nowrap;
}

.table > tbody > tr > td {
  border-bottom: 1px solid var(--zn-border);
  padding: 0.5rem 0.75rem;
  vertical-align: middle;
}

.table > tbody > tr:last-child > td { border-bottom: 0; }

.table-secondary {
  --bs-table-bg: var(--zn-muted);
  --bs-table-color: var(--zn-foreground);
}

/* Badges: en shadcn son sutiles (fondo tenue + texto del mismo tono),
   no bloques de color saturado. Los .text-bg-* de Bootstrap son utilidades
   con !important: por eso fondo y color lo llevan tambien. */
.badge {
  border-radius: var(--zn-radius-full);
  font-size: 0.75rem;
  font-weight: 500;
  padding: 0.1875rem 0.5rem;
  letter-spacing: 0;
  border: 1px solid transparent;
}

.badge.text-bg-secondary {
  background-color: var(--zn-secondary) !important;
  color: var(--zn-secondary-foreground) !important;
  border-color: var(--zn-border);
}

.badge.text-bg-light {
  background-color: var(--zn-muted) !important;
  color: var(--zn-muted-foreground) !important;
  border-color: var(--zn-border);
}

.badge.text-bg-success {
  background-color: color-mix(in oklab, var(--zn-success) 14%, var(--zn-background)) !important;
  color: color-mix(in oklab, var(--zn-success) 85%, var(--zn-foreground)) !important;
  border-color: color-mix(in oklab, var(--zn-success) 30%, var(--zn-background));
}

.badge.text-bg-danger {
  background-color: color-mix(in oklab, var(--zn-destructive) 14%, var(--zn-background)) !important;
  color: color-mix(in oklab, var(--zn-destructive) 85%, var(--zn-foreground)) !important;
  border-color: color-mix(in oklab, var(--zn-destructive) 30%, var(--zn-background));
}

.badge.text-bg-warning {
  background-color: color-mix(in oklab, var(--zn-warning) 18%, var(--zn-background)) !important;
  color: color-mix(in oklab, var(--zn-warning) 80%, var(--zn-foreground)) !important;
  border-color: color-mix(in oklab, var(--zn-warning) 35%, var(--zn-background));
}

.badge.text-bg-primary {
  background-color: var(--zn-primary) !important;
  color: var(--zn-primary-foreground) !important;
}

/* Modales */
.modal-content {
  background-color: var(--zn-popover);
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-contenedor);
  box-shadow: var(--zn-shadow-lg);
}

.modal-header {
  border-bottom: 1px solid var(--zn-border);
  padding: 1.25rem 1.5rem;
}

.modal-title { font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; }

/* el padding va en variables para que el pie (abajo) lo devuelva exacto */
.modal-body {
  --zn-modal-pad-y: 1.5rem;
  --zn-modal-pad-x: 1.5rem;
  padding: var(--zn-modal-pad-y) var(--zn-modal-pad-x);
}

/* El .card-footer va anidado DENTRO de .modal-body (ver RULES.md #5), así que
   hay que devolverle márgenes negativos para que pegue contra el borde. El
   fondo transparente (mismo blanco del modal, pedido del cliente 2026-10-11),
   la línea de arriba y el padding salen de la regla general .card-footer.
   La mayoría de los modales lo envuelven en un <div class="align-self-center">:
   sin la segunda línea el pie sumaba su padding al del body (línea 24px
   adentro, botones a 48px del borde y el doble de aire abajo). Incidente #32.
   :last-of-type y no :last-child: con dropdownParent en el .modal-body, Select2
   agrega su lista (<span class="select2-container">) al final del body al
   abrirse, el pie dejaba de ser el último hijo y se encogía mientras estaba
   abierta. Un <span> no cuenta para :last-of-type de un <div>. */
.modal-body > .card-footer:last-of-type,
.modal-body > div:last-of-type > .card-footer:last-of-type {
  margin: var(--zn-modal-pad-y) calc(var(--zn-modal-pad-x) * -1) calc(var(--zn-modal-pad-y) * -1);
}

/* En un modal con scroll (.modal-dialog-scrollable) el pie se queda fijo abajo y
   el contenido pasa por detrás: fondo opaco para que no se transparente. Solo
   con el pie como hijo directo del .modal-body (envuelto en un div, el sticky
   quedaría atrapado en ese div). */
.modal-dialog-scrollable .modal-body > .card-footer:last-of-type {
  position: sticky;
  bottom: calc(var(--zn-modal-pad-y) * -1);
  z-index: 2;
  background-color: var(--zn-background);
}

.modal-backdrop.show { opacity: .5; }

/* El modal de permisos de Roles (#modalPermisos) tiene sus reglas propias,
   tabla y tarjetas, en assets/css/permisos.css. */

/* Dropdowns */
.dropdown-menu {
  background-color: var(--zn-popover);
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-lg);
  box-shadow: var(--zn-shadow-md);
  padding: 0.25rem;
  font-size: 0.875rem;
}

/* hover/foco y activo: --bs-dropdown-link-* (sección 2) */
.dropdown-item {
  border-radius: var(--zn-radius-sm);
  color: var(--zn-popover-foreground);
  padding: 0.4375rem 0.625rem;
}

.dropdown-divider { border-color: var(--zn-border); }

/* Selector de sección de Ajustes en celular (view/ajustes.php): botón con el
   aspecto de un .form-select y un menú con el icono de cada sección (lo arma
   INIT_SELECTOR_SECCION_AJUSTES en js/base/ajustes.js). El fondo del activo
   sale de --bs-dropdown-link-active-* (sección 2). */
.selector-seccion .selector-seccion-actual,
.selector-seccion .dropdown-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.selector-seccion .selector-seccion-actual { text-align: left; }

.selector-seccion .dropdown-item [class*="icon-"] { color: var(--zn-muted-foreground); }

.selector-seccion .dropdown-item.active,
.selector-seccion .dropdown-item:active { font-weight: 500; }

.selector-seccion .dropdown-item.active [class*="icon-"] { color: var(--zn-foreground); }

/* Menú de usuario original del navbar: hoy apagado (if (false) en navbar.php,
   el usuario vive en el pie del sidebar); estas reglas quedan para cuando se
   reactive. El header viene con .text-bg-primary (bloque de color, utilidad
   con !important); en shadcn eso sería una superficie muted. */
.user-menu .dropdown-menu .user-header.text-bg-primary {
  background-color: var(--zn-muted) !important;
  color: var(--zn-foreground) !important;
  border-bottom: 1px solid var(--zn-border);
  border-radius: calc(var(--zn-radius-lg) - 2px) calc(var(--zn-radius-lg) - 2px) 0 0;
}

.user-menu .dropdown-menu .user-header p small { color: var(--zn-muted-foreground); }

.user-menu .dropdown-menu .user-footer {
  background-color: transparent;
  padding: 0.75rem;
  border-radius: 0 0 calc(var(--zn-radius-lg) - 2px) calc(var(--zn-radius-lg) - 2px);
}

/* --- Botón "Refrescar el sistema" del navbar (components/refrescar.js) ---
   Botón "fantasma" de shadcn: solo el icono, sin borde ni sombra (dos píldoras
   con borde juntas, la suya y la del usuario, se veían pesadas). Mide lo mismo
   que la píldora del usuario (40px) para que queden alineados; al pasar el
   mouse toma fondo suave y el icono gira un cuarto, y mientras refresca gira
   sin parar. */
.btn-refrescar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-right: 0.25rem;
  padding: 0;
  border: 0;
  border-radius: var(--zn-radius-md);
  background-color: transparent;
  color: var(--zn-navbar-muted, var(--zn-muted-foreground));
  transition: background-color .15s ease, color .15s ease;
}

.btn-refrescar [class*="icon-"] {
  font-size: 1.125rem;
  transition: transform .35s ease;
}

.btn-refrescar:hover {
  background-color: var(--zn-navbar-accent, var(--zn-accent));
  color: var(--zn-navbar-fg, var(--zn-foreground));
}

.btn-refrescar:hover [class*="icon-"] { transform: rotate(90deg); }

.btn-refrescar:focus-visible {
  outline: none;
  box-shadow: var(--zn-focus-ring);
}

.btn-refrescar.refrescando {
  color: var(--zn-info);
  pointer-events: none;
}

.btn-refrescar.refrescando [class*="icon-"] { animation: zn-girar 0.8s linear infinite; }

@keyframes zn-girar { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .btn-refrescar [class*="icon-"] { transition: none; }
  .btn-refrescar:hover [class*="icon-"] { transform: none; }
  .btn-refrescar.refrescando [class*="icon-"] { animation-duration: 2s; }
}

/* --- Usuario en el navbar (solo movil, view/include/navbar.php) --- */
.navbar-user-toggle {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.5rem 0.25rem 0.25rem;
  border: 1px solid var(--zn-navbar-border, var(--zn-border));
  border-radius: var(--zn-radius-full);
  color: var(--zn-navbar-muted, var(--zn-muted-foreground));
  text-decoration: none;
}
.navbar-user-toggle:hover { background-color: var(--zn-navbar-accent, var(--zn-accent)); }
.navbar-user-toggle [class*="icon-"] { font-size: 0.75rem; }

.navbar-user-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: var(--zn-radius-full);
  object-fit: cover;
}

/* En el navbar Bootstrap no usa Popper: separa el menú con margin-top:
   var(--bs-dropdown-spacer) desde .dropdown-menu[data-bs-popper]. */
.navbar-user-menu {
  --bs-dropdown-spacer: 0.5rem;
  min-width: 15rem;
  padding: 0.5rem;
  border-radius: var(--zn-radius-lg);
}

.navbar-user-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.625rem;
}

.navbar-user-header-avatar {
  width: 3rem;
  height: 3rem;
  border-radius: var(--zn-radius-full);
  object-fit: cover;
  flex-shrink: 0;
}

.navbar-user-nombre { font-weight: 600; color: var(--zn-foreground); line-height: 1.3; }
.navbar-user-rol { font-size: 0.8125rem; color: var(--zn-muted-foreground); }

.navbar-user-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: var(--zn-radius-md);
}
/* le gana al color de hover de .dropdown-item por ir despues, misma especificidad */
.navbar-user-menu .navbar-user-salir { color: var(--zn-destructive); }

.navbar-user-menu .navbar-user-salir:hover,
.navbar-user-menu .navbar-user-salir:focus {
  background-color: rgba(var(--zn-rgb-destructive), .08);
}

/* Tooltips. Bootstrap los inyecta en el <body>, fuera del sidebar, asi que
   NO heredan sus tokens: hay que estilarlos aparte. */
.tooltip {
  --bs-tooltip-bg: var(--zn-primary);
  --bs-tooltip-color: var(--zn-primary-foreground);
  --bs-tooltip-border-radius: var(--zn-radius-md);
  --bs-tooltip-font-size: 0.8125rem;
  --bs-tooltip-opacity: 1;
  --bs-tooltip-padding-x: 0.625rem;
  --bs-tooltip-padding-y: 0.375rem;
  font-family: var(--bs-font-sans-serif);
}

.tooltip .tooltip-inner {
  font-weight: 500;
  letter-spacing: -0.005em;
  box-shadow: var(--zn-shadow-md);
  white-space: nowrap;
  max-width: none;
}

/* El del sidebar se separa un poco del rail para no quedar pegado al icono. */
.tooltip-sidebar { --bs-tooltip-arrow-width: 0.5rem; --bs-tooltip-arrow-height: 0.3125rem; }

/* Alerts */
.alert {
  border-radius: var(--zn-radius-lg);
  border: 1px solid var(--zn-border);
  font-size: 0.875rem;
  padding: 0.875rem 1rem;
}

.alert-danger {
  background-color: color-mix(in oklab, var(--zn-destructive) 8%, var(--zn-background));
  border-color: color-mix(in oklab, var(--zn-destructive) 25%, var(--zn-background));
  color: color-mix(in oklab, var(--zn-destructive) 80%, var(--zn-foreground));
}

.alert-success {
  background-color: color-mix(in oklab, var(--zn-success) 8%, var(--zn-background));
  border-color: color-mix(in oklab, var(--zn-success) 25%, var(--zn-background));
  color: color-mix(in oklab, var(--zn-success) 80%, var(--zn-foreground));
}

.alert-warning {
  background-color: color-mix(in oklab, var(--zn-warning) 12%, var(--zn-background));
  border-color: color-mix(in oklab, var(--zn-warning) 30%, var(--zn-background));
  color: color-mix(in oklab, var(--zn-warning) 75%, var(--zn-foreground));
}

.alert-info {
  background-color: color-mix(in oklab, var(--zn-info) 8%, var(--zn-background));
  border-color: color-mix(in oklab, var(--zn-info) 25%, var(--zn-background));
  color: color-mix(in oklab, var(--zn-info) 80%, var(--zn-foreground));
}

/* Nav pills HORIZONTALES: en shadcn el patron es una pista muted con la
   pestana activa como superficie elevada.
   El :not() importa. En view/ajustes.php el menu lateral combina las clases
   `list-group` y `nav nav-pills flex-column`. Sin excluirlo, el inline-flex de
   aca lo encoge al ancho de su contenido en vez de llenar la col-md-3, y queda
   un hueco enorme contra la tarjeta de la derecha. */
.nav-pills:not(.flex-column):not(.list-group) {
  background-color: var(--zn-muted);
  border-radius: var(--zn-radius-lg);
  padding: 0.25rem;
  gap: 0.25rem;
  display: inline-flex;
  flex-wrap: wrap;
}

.nav-pills .nav-link {
  color: var(--zn-muted-foreground);
  border-radius: var(--zn-radius-md);
  font-size: 0.875rem;
  font-weight: 500;
  padding: 0.375rem 0.75rem;
}

.nav-pills .nav-link:hover { color: var(--zn-foreground); }

/* fondo y color: --bs-nav-pills-link-active-* (sección 2) */
.nav-pills .nav-link.active { box-shadow: var(--zn-shadow-xs); }

/* List group */
.list-group-item {
  background-color: var(--zn-card);
  border-color: var(--zn-border);
  color: var(--zn-foreground);
  font-size: 0.875rem;
  padding: 0.75rem 1rem;
}

/* Fondo, borde y color del activo y del hover: --bs-list-group-* (sección 2).
   El activo usa el gris de acento, igual que el item activo del sidebar: en
   Zenith lo activo se marca con superficie (y una barra), no con color. */
.list-group-item.active {
  position: relative;
  font-weight: 600;
}

.list-group-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 20%;
  bottom: 20%;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background-color: var(--zn-primary);
}

.list-group-item:first-child { border-radius: var(--zn-radius-contenedor) var(--zn-radius-contenedor) 0 0; }
.list-group-item:last-child  { border-radius: 0 0 var(--zn-radius-contenedor) var(--zn-radius-contenedor); }

/* Utilidades de texto */
.text-muted, .text-secondary { color: var(--zn-muted-foreground) !important; }

/* --------------------------------------------------------------------------
   5. PLUGINS
   Cada uno trae su CSS pensado para Bootstrap. Acá se los realinea con los
   tokens. Es la parte que más trabajo da y la que más se nota.
   -------------------------------------------------------------------------- */

/* --- DataTables --- */
div.dt-container .dt-length,
div.dt-container .dt-search,
div.dt-container .dt-info,
div.dt-container .dt-paging { color: var(--zn-muted-foreground); font-size: 0.8125rem; }

div.dt-container .dt-length select,
div.dt-container .dt-search input {
  background-color: var(--zn-background);
  border: 1px solid var(--zn-input);
  border-radius: var(--zn-radius-md);
  color: var(--zn-foreground);
  padding: 0.25rem 0.5rem;
  font-size: 0.8125rem;
  box-shadow: var(--zn-shadow-xs);
}

/* Va DESPUES del bloque de arriba a proposito: ese usa el shorthand `padding`,
   que borra el padding-right. Misma especificidad -> gana la regla posterior. */
div.dt-container .dt-length select { padding-right: 1.5rem; }

div.dt-container .dt-search input:focus,
div.dt-container .dt-length select:focus {
  border-color: var(--zn-ring);
  box-shadow: var(--zn-focus-ring);
  outline: none;
}

table.dataTable > thead > tr > th.dt-orderable-asc:hover,
table.dataTable > thead > tr > th.dt-orderable-desc:hover {
  background-color: var(--zn-muted);
  border-radius: var(--zn-radius-sm);
}

table.dataTable > thead > tr > th.dt-ordering-asc,
table.dataTable > thead > tr > th.dt-ordering-desc { color: var(--zn-foreground); }

/* Sombreado de filas. DataTables no pinta con background sino con
   `box-shadow: inset 0 0 0 9999px`, y trae un zebra gris al 5% y la fila
   seleccionada en azul Bootstrap solido con texto blanco. Se reemplazan por
   tonos del tema: zebra casi imperceptible, hover apenas mas marcado y la
   seleccion como tinte suave + barra a la izquierda (mismo patron que el item
   activo del sidebar). Los selectores repiten los de datatables.min.css para
   ganarle en especificidad. */
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) > * {
  box-shadow: inset 0 0 0 9999px color-mix(in oklab, var(--zn-foreground) 2.5%, transparent);
}

table.table.dataTable > tbody > tr {
  transition: box-shadow .15s ease;
}

table.table.dataTable > tbody > tr:hover > *,
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1):hover > * {
  box-shadow: inset 0 0 0 9999px color-mix(in oklab, var(--zn-foreground) 4.5%, transparent);
}

table.table.dataTable > tbody > tr.selected > *,
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1).selected > *,
table.table.dataTable > tbody > tr.selected:hover > * {
  box-shadow: inset 0 0 0 9999px color-mix(in oklab, var(--zn-info) 10%, transparent);
  color: var(--zn-foreground);
}

table.table.dataTable > tbody > tr.selected > *:first-child,
table.table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1).selected > *:first-child {
  box-shadow:
    inset 3px 0 0 var(--zn-info),
    inset 0 0 0 9999px color-mix(in oklab, var(--zn-info) 10%, transparent);
}

table.table.dataTable > tbody > tr.selected a { color: var(--zn-foreground); }

/* Paginacion. DataTables genera DOS elementos por boton:
     <li class="dt-paging-button page-item"><button class="page-link">3</button></li>
   Todo el estilo vive en el <button>; el <li> no lleva caja (incidente #19).
   El estado (activo/deshabilitado) lo trae el <li>, pero se pinta el <button>.
   El radio de los botones de las puntas sale de --bs-pagination-border-radius
   (sección 2). */
.page-link {
  background-color: var(--zn-background);
  border: 1px solid var(--zn-border);
  color: var(--zn-foreground);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.25rem;
  padding: 0.1875rem 0.5rem;
  min-width: 1.75rem;
  text-align: center;
  border-radius: var(--zn-radius-sm);
  margin: 0 0.125rem;
  box-shadow: var(--zn-shadow-xs);
}

.page-link:hover {
  background-color: var(--zn-accent);
  border-color: var(--zn-border);
  color: var(--zn-accent-foreground);
}

.page-item.active .page-link {
  background-color: var(--zn-primary);
  border-color: var(--zn-primary);
  color: var(--zn-primary-foreground);
}

.page-item.disabled .page-link {
  background-color: transparent;
  color: var(--zn-muted-foreground);
  opacity: .45;
  box-shadow: none;
}

/* --- Select2 (4.1) ---
   Aca va el color y el borde (tokens). La geometria propia del select simple
   (alto, flecha, boton de limpiar) vive en assets/css/selects.css. */
.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
  background-color: var(--zn-background);
  border: 1px solid var(--zn-input);
  /* !important: abierto, select2 le quita el radio del lado del desplegable
     con un selector de 4 clases; aca el campo conserva sus cuatro esquinas */
  border-radius: var(--zn-radius-md) !important;
  box-shadow: var(--zn-shadow-xs);
  min-height: 2.375rem;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
  color: var(--zn-foreground);
  line-height: 2.25rem;
  font-size: 0.875rem;
  padding-left: 0.75rem;
}

.select2-container--default .select2-selection--single .select2-selection__arrow { height: 2.25rem; }

.select2-container--default .select2-selection--single .select2-selection__placeholder {
  color: var(--zn-muted-foreground);
}

.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--single {
  border-color: var(--zn-ring);
  box-shadow: var(--zn-focus-ring);
}

.select2-dropdown {
  background-color: var(--zn-popover);
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-lg);
  box-shadow: var(--zn-shadow-md);
  overflow: hidden;
}

.select2-container--default .select2-results__option {
  color: var(--zn-popover-foreground);
  font-size: 0.875rem;
  padding: 0.4375rem 0.75rem;
}

/* Opcion ya elegida. (En 4.1 aria-selected marca la resaltada, no la elegida:
   la elegida lleva --selected.) */
.select2-container--default .select2-results__option--selected {
  background-color: var(--zn-muted);
  color: var(--zn-foreground);
}

/* Resaltada con el mouse o el teclado: mismo selector que select2, que va
   antes, y mas especifico que el de la elegida. */
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
  background-color: var(--zn-accent);
  color: var(--zn-accent-foreground);
}

.select2-container--default .select2-search--dropdown .select2-search__field {
  background-color: var(--zn-background);
  border: 1px solid var(--zn-input);
  border-radius: var(--zn-radius-sm);
  color: var(--zn-foreground);
  font-size: 0.875rem;
  padding: 0.375rem 0.625rem;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
  background-color: var(--zn-secondary);
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-sm);
  color: var(--zn-secondary-foreground);
  font-size: 0.8125rem;
}

/* --- SweetAlert2 (v11) ---
   Su CSS (que ademas sweetalert2.all.min.js inyecta en el <head>, despues de
   este archivo) envuelve casi todo en :where(), asi que pesa poco: con una
   clase propia alcanza para ganarle. Las excepciones llevan su !important
   comentado. */
.swal2-popup {
  background-color: var(--zn-popover);
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-xl);
  box-shadow: var(--zn-shadow-lg);
  color: var(--zn-popover-foreground);
  font-family: var(--bs-font-sans-serif);
  font-size: 0.875rem;
}

.swal2-title {
  color: var(--zn-foreground);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.swal2-html-container { color: var(--zn-muted-foreground); font-size: 0.875rem; }

/* Botones: los mismos de los modales de la app (RULES.md #24). Confirmar =
   verde (btn-success), cancelar = rojo suave (btn-danger); compactos y sin
   sombra. */
.swal2-styled.swal2-confirm,
.swal2-styled.swal2-cancel {
  border: 0;
  border-radius: var(--zn-radius-md);
  font-size: 0.8125rem;
  font-weight: 500;
  padding: 0.4375rem 0.875rem;
  box-shadow: none;
}

.swal2-styled.swal2-confirm {
  background-color: var(--zn-success);
  color: #fff;
}

.swal2-styled.swal2-confirm:hover { background-color: color-mix(in oklab, var(--zn-success) 88%, black); }

.swal2-styled.swal2-cancel {
  background-color: color-mix(in oklab, var(--zn-destructive) 10%, transparent);
  color: var(--zn-destructive);
}

.swal2-styled.swal2-cancel:hover { background-color: color-mix(in oklab, var(--zn-destructive) 16%, transparent); }

/* Tercera opción (showDenyButton, ej. "WhatsApp Web"): acción secundaria,
   con el contorno gris de btn-outline-secondary (RULES.md #24) */
.swal2-styled.swal2-deny {
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-md);
  background-color: transparent;
  color: var(--zn-foreground);
  font-size: 0.8125rem;
  font-weight: 500;
  padding: 0.4375rem 0.875rem;
  box-shadow: none;
}

.swal2-styled.swal2-deny:hover { background-color: var(--zn-muted); }

.swal2-styled:focus { box-shadow: var(--zn-focus-ring); }

/* Confirmar siempre a la derecha, como Guardar en los modales. SweetAlert los
   pone al revés (confirmar | cancelar); se invierte acá para no tener que
   pasar reverseButtons en cada llamada. */
.swal2-actions { flex-direction: row-reverse; }

/* Iconos: el ?, ! e i son texto (en Geist parecían un glifo roto) y el check y
   la X son dibujos grandes con borde. Los cinco pasan al patrón de shadcn:
   icono Lucide sobre un círculo con fondo suave del color del aviso. Requiere
   lucide.css cargado (header.php, login.php y password.php lo traen). */
.swal2-icon {
  --zn-swal-icono: var(--zn-info);   /* question e info */
  width: 3.5rem;
  height: 3.5rem;
  margin: 1.75rem auto 0.25rem;
  border: 0;
  background-color: color-mix(in oklab, var(--zn-swal-icono) 12%, transparent);
  /* !important: el color de cada tipo viene de div:where(.swal2-icon).swal2-warning,
     que suma la clase del tipo */
  color: var(--zn-swal-icono) !important;
  align-items: center;
  justify-content: center;
}

.swal2-icon.swal2-warning { --zn-swal-icono: var(--zn-warning); }
.swal2-icon.swal2-success { --zn-swal-icono: var(--zn-success); }
.swal2-icon.swal2-error   { --zn-swal-icono: var(--zn-destructive); }

/* fuera el contenido original (texto o dibujo animado); un iconHtml propio
   tambien quedaria oculto. !important: SweetAlert los muestra con selectores
   que suman la clase del tipo (.swal2-success [class^=swal2-success-line]...) */
.swal2-icon > * { display: none !important; }

.swal2-icon::before {
  font-family: "lucide";
  font-size: 1.75rem;
  line-height: 1;
}

/* codigos de assets/plugins/lucide/lucide.css */
.swal2-icon.swal2-question::before { content: "\e082"; }   /* circle-help */
.swal2-icon.swal2-warning::before  { content: "\e193"; }   /* triangle-alert */
.swal2-icon.swal2-info::before     { content: "\e0f9"; }   /* info */
.swal2-icon.swal2-success::before  { content: "\e06c"; }   /* check */
.swal2-icon.swal2-error::before    { content: "\e1b2"; }   /* x */

/* con .swal2-popup delante: el select de SweetAlert trae
   div:where(.swal2-container) .swal2-select, una clase y un tipo */
.swal2-popup .swal2-input,
.swal2-popup .swal2-textarea,
.swal2-popup .swal2-select {
  background-color: var(--zn-background);
  border: 1px solid var(--zn-input);
  border-radius: var(--zn-radius-md);
  color: var(--zn-foreground);
  font-size: 0.875rem;
  box-shadow: var(--zn-shadow-xs);
}

/* --- Toastify ---
   El fondo lo pasa cada llamada como estilo inline (components/toastify.js). */
.toastify {
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-lg);
  box-shadow: var(--zn-shadow-lg);
  font-family: var(--bs-font-sans-serif);
  font-size: 0.875rem;
  font-weight: 500;
  padding: 0.75rem 1rem;
}

/* --- FilePond ---
   Aca va el color (tokens); el tamaño del cuadro, los textos y lo que se
   oculta del preview viven en assets/css/filepond.css. */
.filepond--root { font-family: var(--bs-font-sans-serif); font-size: 0.875rem; }

.filepond--panel-root {
  background-color: var(--zn-muted);
  border: 1px dashed var(--zn-border);
  border-radius: var(--zn-radius-lg);
}

.filepond--drop-label { color: var(--zn-muted-foreground); }

.filepond--label-action { text-decoration-color: var(--zn-muted-foreground); color: var(--zn-foreground); }

.filepond--item-panel { background-color: var(--zn-secondary); border-radius: var(--zn-radius-md); }

/* --- Vanilla Calendar Pro (components/calendario.js) ---
   Colores por sus variables --vc-*, con el look de shadcn: el día elegido casi
   negro, el rango en gris y sin fines de semana en rojo (selectedWeekends: []).
   Se monta en <body>: el z-index lo deja sobre los modales de Bootstrap (1055). */
[data-vc=calendar] {
  --vc-bg: var(--zn-popover);
  --vc-color: var(--zn-popover-foreground);
  --vc-header-color: var(--zn-foreground);
  --vc-title-color: var(--zn-foreground);
  --vc-title-color-hover: var(--zn-muted-foreground);
  --vc-title-color-disabled: var(--zn-border);
  --vc-week-day-color: var(--zn-muted-foreground);
  --vc-date-color: var(--zn-foreground);
  --vc-date-bg: transparent;
  --vc-date-bg-hover: var(--zn-accent);
  --vc-date-hover-bg: var(--zn-accent);
  --vc-date-hover-edge-bg: var(--zn-border);
  --vc-date-outside-color: color-mix(in oklab, var(--zn-muted-foreground) 70%, transparent);
  --vc-date-disabled-color: color-mix(in oklab, var(--zn-muted-foreground) 40%, transparent);
  --vc-date-today-bg: var(--zn-accent);
  --vc-date-today-color: var(--zn-foreground);
  --vc-date-today-outside-color: var(--zn-muted-foreground);
  --vc-date-selected-bg: var(--zn-primary);
  --vc-date-selected-color: var(--zn-primary-foreground);
  --vc-date-selected-outside-bg: var(--zn-border);
  --vc-date-selected-outside-color: var(--zn-muted-foreground);
  --vc-date-range-middle-bg: var(--zn-accent);
  --vc-date-range-middle-color: var(--zn-accent-foreground);
  --vc-date-range-middle-outside-bg: var(--zn-muted);
  --vc-date-range-middle-outside-color: var(--zn-muted-foreground);
  --vc-months-years-bg: transparent;
  --vc-months-years-bg-hover: var(--zn-accent);
  --vc-months-years-bg-selected: var(--zn-primary);
  --vc-months-years-color: var(--zn-foreground);
  --vc-months-years-color-selected: var(--zn-primary-foreground);
  --vc-months-years-color-disabled: var(--zn-border);
  --vc-focus-outline-color: var(--zn-ring);
  font-family: var(--bs-font-sans-serif);
  padding: 0.75rem;
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-lg);
  z-index: 1060;
}
/* le gana a la sombra del tema light ([data-vc-theme=light].vc[data-vc-input]) */
.vc[data-vc=calendar][data-vc-input] { box-shadow: var(--zn-shadow-md); }
[data-vc=calendar] [data-vc=month],
[data-vc=calendar] [data-vc=year] { font-size: 0.875rem; font-weight: 600; text-transform: capitalize; }
[data-vc=calendar] [data-vc-week-day] { font-weight: 500; text-transform: capitalize; }
[data-vc=calendar] [data-vc-date-btn] { min-height: 2.125rem; font-size: 0.8125rem; }


/* --- html5-qrcode (components/escaner.js): línea roja del lector sobre la cámara ---
   Centrada y del ancho del recuadro de lectura (qrbox: 85% del visor). Va fuera de
   #escanerVisor porque la librería reescribe su contenido; se ve con .activo (la
   cámara ya encendida). Pulsa suave; sin animación si el sistema pide menos movimiento. */
.escaner-marco { position: relative; }

.escaner-linea {
  position: absolute;
  top: 50%;
  left: 7.5%;
  width: 85%;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background: rgba(255, 45, 45, .7);
  box-shadow: 0 0 5px 1px rgba(255, 45, 45, .45), 0 0 12px 2px rgba(255, 45, 45, .15);
  pointer-events: none;
  z-index: 2;
  opacity: 0;
  transition: opacity .2s ease;
}

.escaner-marco.activo .escaner-linea {
  opacity: .85;
  animation: escaner-linea-pulso 1.4s ease-in-out infinite;
}

@keyframes escaner-linea-pulso {
  0%, 100% { opacity: .85; }
  50% { opacity: .45; }
}

@media (prefers-reduced-motion: reduce) {
  .escaner-marco.activo .escaner-linea { animation: none; }
}

/* --- html5-qrcode (components/escaner.js): el código leído en el aviso "no parece un track" --- */
.escaner-codigo-leido {
  max-height: 9rem;
  overflow-y: auto;
  padding: 0.5rem;
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-md);
  background: var(--zn-muted);
  font-family: ui-monospace, monospace;
  font-size: 0.8125rem;
  text-align: start;
  word-break: break-all;
}

/* --- Driver.js (components/ayuda.js): la guía paso a paso ---
   driver.css se carga después (al tocar el "?"): aquí todo lleva una clase más para ganarle */
.driver-popover.ayuda-popover {
  padding: 1rem;
  min-width: 16rem;
  max-width: min(20rem, calc(100vw - 2rem));
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-lg);
  background-color: var(--zn-popover);
  color: var(--zn-foreground);
  box-shadow: var(--zn-shadow-lg);
}

.ayuda-popover.driver-popover *,
.ayuda-popover .driver-popover-title,
.ayuda-popover .driver-popover-description,
.ayuda-popover .driver-popover-footer button {
  font-family: var(--bs-font-sans-serif);
}

.ayuda-popover .driver-popover-title {
  padding-right: 1.5rem; /* la × */
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
}

.ayuda-popover .driver-popover-description {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--zn-muted-foreground);
}

.ayuda-popover .driver-popover-description b { color: var(--zn-foreground); font-weight: 600; }

.ayuda-popover .ayuda-progreso {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.75rem;
  color: var(--zn-muted-foreground);
}

.ayuda-popover .driver-popover-close-btn {
  top: 0.375rem;
  right: 0.375rem;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--zn-radius-md);
  color: var(--zn-muted-foreground);
  font-size: 1.125rem;
  line-height: 1.75rem;
}

.ayuda-popover .driver-popover-close-btn:hover { background-color: var(--zn-accent); color: var(--zn-foreground); }

/* "Siguiente" / "Listo" = confirmar: verde, a la derecha (RULES #24) */
.ayuda-popover .driver-popover-footer { margin-top: 0.75rem; }

.ayuda-popover .driver-popover-footer button {
  padding: 0.3rem 0.75rem;
  border: 0;
  border-radius: var(--zn-radius-md);
  background-color: var(--zn-success);
  color: #fff;
  text-shadow: none;
  font-size: 0.8125rem;
  font-weight: 500;
}

.ayuda-popover .driver-popover-footer button:hover,
.ayuda-popover .driver-popover-footer button:focus {
  background-color: color-mix(in oklab, var(--zn-success) 88%, #000);
}

/* "Atrás" = acción secundaria: borde gris, a la izquierda del verde */
.ayuda-popover .driver-popover-footer button.driver-popover-prev-btn {
  border: 1px solid var(--zn-border);
  background-color: var(--zn-background);
  color: var(--zn-foreground);
}

.ayuda-popover .driver-popover-footer button.driver-popover-prev-btn:hover,
.ayuda-popover .driver-popover-footer button.driver-popover-prev-btn:focus {
  background-color: var(--zn-accent);
}

.ayuda-popover .driver-popover-navigation-btns { gap: 0.375rem; }
.ayuda-popover .driver-popover-navigation-btns button + button { margin-left: 0; }

/* sin flecha, como los popovers de shadcn */
.ayuda-popover .driver-popover-arrow { display: none; }

/* Driver.js deja tocar solo lo resaltado. Lo que se abre desde ahí sí se toca: la lista de
   un Select2, el calendario de un campo de fecha, un aviso de SweetAlert (ej. "Guardar igual"),
   la cámara del escáner y la lista de secciones de Ajustes en el celular. Mientras
   están abiertos, la capa oscura y el globo se quitan para que se vean (en el celular el
   globo tapaba la lista del Select2) */
.driver-active .select2-container--open,
.driver-active .select2-container--open *,
.driver-active [data-vc=calendar],
.driver-active [data-vc=calendar] *,
.driver-active .swal2-container,
.driver-active .swal2-container *,
.driver-active #selectorSeccionAjustes .dropdown-menu.show,
.driver-active #selectorSeccionAjustes .dropdown-menu.show *,
.driver-active #modalEscaner,
.driver-active #modalEscaner * {
  pointer-events: auto;
}

/* Driver.js le pone overflow: hidden al padre de lo resaltado. El pie de los modales lleva
   sus botones flotando sin clearfix y con eso crecía (el botón se movía bajo el resaltado), y
   un menú ⋯ resaltado entero quedaba recortado por su celda */
.driver-active .card-footer:has(> .driver-active-element),
.driver-active :has(> .dropdown-menu.driver-active-element) { overflow: visible !important; }

.driver-active:has(.select2-dropdown) .driver-overlay,
.driver-active:has(.select2-dropdown) .driver-popover,
.driver-active:has([data-vc=calendar]:not([data-vc-calendar-hidden])) .driver-overlay,
.driver-active:has([data-vc=calendar]:not([data-vc-calendar-hidden])) .driver-popover,
.driver-active:has(#selectorSeccionAjustes .dropdown-menu.show) .driver-overlay,
.driver-active:has(#selectorSeccionAjustes .dropdown-menu.show) .driver-popover,
.driver-active:has(.swal2-container) .driver-overlay,
.driver-active:has(.swal2-container) .driver-popover,
.driver-active:has(#modalEscaner.show) .driver-overlay,
.driver-active:has(#modalEscaner.show) .driver-popover {
  display: none !important; /* el globo trae display en línea */
}

/* "¿Qué quieres hacer?" (SweetAlert) */
.ayuda-elegir .ayuda-tareas {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  max-height: min(55vh, 26rem);
  overflow-y: auto;
  text-align: start;
}

.ayuda-tarea {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  width: 100%;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-md);
  background-color: var(--zn-background);
  color: var(--zn-foreground);
  text-align: start;
  transition: background-color .15s ease, border-color .15s ease;
}

.ayuda-tarea:hover,
.ayuda-tarea:focus-visible {
  border-color: color-mix(in oklab, var(--zn-info) 40%, var(--zn-border));
  background-color: color-mix(in oklab, var(--zn-info) 6%, var(--zn-background));
  outline: none;
}

.ayuda-tarea > [class*="icon-"] {
  flex: none;
  margin-top: 0.125rem;
  font-size: 1.125rem;
  color: var(--zn-muted-foreground);
}

.ayuda-tarea-titulo { display: block; font-size: 0.875rem; font-weight: 500; }
.ayuda-tarea-texto  { display: block; font-size: 0.8125rem; color: var(--zn-muted-foreground); }

.ayuda-elegir .ayuda-sin-resultados,
.ayuda-elegir .ayuda-pie {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  color: var(--zn-muted-foreground);
}

/* --- OverlayScrollbars (sidebar) --- */
.os-theme-light > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle,
.os-theme-dark  > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
  background: color-mix(in oklab, var(--zn-muted-foreground) 45%, transparent);
  border-radius: var(--zn-radius-full);
}

/* --------------------------------------------------------------------------
   6. LOGIN / PASSWORD (viven fuera del shell)
   -------------------------------------------------------------------------- */

/* fondo liso; login.php le suma la imagen de Ajustes como estilo inline */
body.login-page {
  background-color: var(--zn-muted);
  padding-inline: 1rem;   /* gutter lateral: en movil la tarjeta no toca los bordes */
}

.login-box { width: 100%; max-width: 25rem; }

/* .card-login va en la card y en su card-body: una sola superficie (la del
   card-body), sin doble borde */
.login-box .card.card-login { border: 0; background: transparent; box-shadow: none; }

.login-card-body {
  background-color: var(--zn-card);
  border: 1px solid var(--zn-border);
  border-radius: var(--zn-radius-xl);
  box-shadow: var(--zn-shadow-lg);
  padding: 1.75rem;
}

/* ojo dentro del input de password, a la izquierda del candado
   (components/ver_password.js; en login.php y en password.php) */
.login-box .input-group-text { width: 2.75rem; justify-content: center; }
.login-box .input-group:has(.btn-ver-password) .form-control { padding-right: 2.5rem; }
.btn-ver-password {
  position: absolute;
  top: 50%;
  right: 2.75rem;
  transform: translateY(-50%);
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--zn-muted-foreground);
  cursor: pointer;
}
.btn-ver-password:hover, .btn-ver-password:focus-visible { color: var(--zn-foreground); }

/* asignar contraseña (password.php): encabezado */
.password-titulo {
  margin: 0;
  text-align: center;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--zn-foreground);
}
.password-subtitulo {
  margin: 0.25rem 0 1.5rem;
  text-align: center;
  font-size: 0.875rem;
  color: var(--zn-muted-foreground);
}

/* los dos campos en verde si coinciden y en rojo si no (password.js); el
   candado de la derecha toma el mismo color */
.campo-password .form-control,
.campo-password .input-group-text { transition: border-color .15s ease, color .15s ease, box-shadow .15s ease; }
.campo-coincide .form-control,
.campo-coincide .input-group-text { border-color: var(--zn-success); }
.campo-coincide .input-group-text { color: var(--zn-success); }
.campo-coincide .form-control:focus {
  border-color: var(--zn-success);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--zn-success) 20%, transparent);
}
.campo-no-coincide .form-control,
.campo-no-coincide .input-group-text { border-color: var(--zn-destructive); }
.campo-no-coincide .input-group-text { color: var(--zn-destructive); }
.campo-no-coincide .form-control:focus {
  border-color: var(--zn-destructive);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--zn-destructive) 20%, transparent);
}

/* requisitos que se marcan solos: gris pendiente, verde cumple, rojo falla */
.password-requisitos {
  margin: 0.75rem 0 1.25rem;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
  color: var(--zn-muted-foreground);
}
.password-requisitos li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.125rem 0;
  transition: color .15s ease;
}
.password-requisitos li.cumple { color: var(--zn-success); }
.password-requisitos li.falla { color: var(--zn-destructive); }

@media (max-width: 575.98px) {
  .login-card-body { padding: 1.5rem 1.25rem; }
  /* boton a lo ancho en movil */
  .login-box #formLogin .row > .col-8 { display: none; }
  .login-box #formLogin .row > .col-4 { flex: 0 0 100%; max-width: 100%; }
  .password-subtitulo { margin-bottom: 1.25rem; }
}
