/* ============================================================
   VORECOL DESIGN SYSTEM
   custom.css — Tabler / Bootstrap 5.3 override layer
   ============================================================ */

/* ============================================================
   §01. CSS Custom Properties — Brand Tokens
   ============================================================ */
:root {
  --vorecol-primary:        #1A67B7;
  --vorecol-primary-dark:   #1A5797;
  --vorecol-primary-light:  #4090CB;
  --vorecol-primary-50:     #EBF2FB;
  --vorecol-gray-50:   #F8FAFC;
  --vorecol-gray-100:  #F1F5F9;
  --vorecol-gray-200:  #E2E8F0;
  --vorecol-gray-300:  #CBD5E1;
  --vorecol-gray-400:  #94A3B8;
  --vorecol-gray-500:  #64748B;
  --vorecol-gray-600:  #475569;
  --vorecol-gray-700:  #334155;
  --vorecol-gray-800:  #1E293B;
  --vorecol-gray-900:  #0F172A;
  --vorecol-blue-50:   #EBF2FB;
  --vorecol-blue-100:  #C5D9F2;
  --vorecol-blue-500:  #1A67B7;
  --vorecol-blue-700:  #0F3D6B;
  --vorecol-blue-900:  #0A2540;
  --vorecol-body-bg:    #F1F5F9;
  --vorecol-radius:     0.75rem;
  --vorecol-radius-sm:  0.5rem;
  --vorecol-radius-xs:  0.25rem;
  --vorecol-shadow-sm: 0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04);
  --vorecol-shadow:    0 4px 6px -1px rgba(0,0,0,.07), 0 2px 4px -1px rgba(0,0,0,.05);
  --vorecol-shadow-lg: 0 10px 15px -3px rgba(0,0,0,.08), 0 4px 6px -2px rgba(0,0,0,.04);
  --vorecol-transition: 0.15s ease;
  --tblr-primary:          #1A67B7;
  --tblr-primary-darken:   #1A5797;
  --tblr-primary-lighten:  #4090CB;
  --tblr-primary-rgb:      26, 103, 183;
  /* Variante DE — Unificar barras + rail 48px (2026-04-23).
     Las 2 barras (rail + nav) del MISMO azul intermedio cohesivo.
     Resuelve "dos barras pegadas" sin perder los íconos del rail. */
  --vorecol-sidebar-bg:     #14253c;  /* azul intermedio entre blue-700 y blue-900 */
  --vorecol-sidebar-active: var(--vorecol-blue-500);  /* azul brillante para active */
}

/* ============================================================
   §02. Base / Body
   ============================================================ */
body { background-color: var(--vorecol-body-bg); font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--vorecol-gray-300); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--vorecol-gray-400); }

/* ============================================================
   §03. Sidebar — Dual Panel (App Rail + Main Nav)
   ============================================================
   Estructura enterprise multi-producto (Rippling/Workday pattern):
     [rail 64px] módulos como iconos
     [nav 240px] menú del módulo activo
   Total: 304px en desktop.  Mobile: solo el nav (drawer clásico).
   ============================================================ */

/* menu_sistems_all: módulos contratados / activables (super_usuario)
   Por default escondidos. Visibilidad controlada por .menu-visible (cerrado)
   o .menu-active (abierto) — ver sidebar.php para la lógica de cuándo aplicar
   cada clase. */
.menu_sistems_all { display: none; }

/* ───────── App Rail (columna izquierda, icon-only) ───────── */
.app-rail {
  position: fixed;
  top: 0;
  left: 0;
  width: 56px;                              /* FLYOUT-LIGHT: rail angosto pero cómodo para clickear */
  height: 100vh;
  z-index: 1032;                            /* encima del panel fly-out */
  flex-direction: column;
  align-items: center;
  padding: 0.75rem 0 0.75rem 0;
  background: var(--vorecol-sidebar-bg);    /* azul oscuro Vorecol */
  border-right: 1px solid rgba(255,255,255,0.04);
  overflow: hidden;
}

.app-rail .rail-brand {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--vorecol-radius-sm);
  margin-bottom: 1rem;
  overflow: hidden;
}
.app-rail .rail-brand img {
  width: 28px;
  height: 28px;
  object-fit: contain;
  filter: brightness(0) invert(1);
}

.app-rail .rail-modules {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  width: 100%;
  align-items: center;
  padding: 0.25rem 0;
}
.app-rail .rail-modules::-webkit-scrollbar { width: 0; }

/* Responsive (raíz) — SIN scroll horizontal de PÁGINA. Un offcanvas-end CERRADO
   (position:fixed + transform:translateX(100%)) se va fuera del viewport a la derecha y
   extiende el scrollWidth en algunos navegadores → barra/scroll horizontal en móvil (caso
   #offcanvas-notifications del topbar, visible en bulk_load_evaluated). Clip a nivel html lo
   contiene SIN crear scroll-container (no rompe position:sticky); el offcanvas se sigue
   abriendo normal (translateX(0) entra al viewport). El contenido que deba scrollear horizontal
   usa SU propio contenedor (.table-responsive). Evita que cada página lo parche por separado.
   §16/§19. PBI-PSICO-ADMINEVAL-MOVIL-ACCESO-001.
   NOTA: Tabler pone body{overflow-y:auto} → el contenedor de scroll es BODY (no html);
   por eso la regla va en html Y body. */
html, body { overflow-x: hidden; overflow-x: clip; }

.app-rail .rail-link {
  position: relative;
  width: 40px;                              /* FLYOUT-LIGHT: 40px dentro del rail de 56 */
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 7px;
  color: rgba(255,255,255,0.75);
  text-decoration: none;
  transition: background var(--vorecol-transition), color var(--vorecol-transition), transform var(--vorecol-transition);
  flex-shrink: 0;
}
.app-rail .rail-link i {
  font-size: 1.15rem;
  line-height: 1;
}
.app-rail .rail-link:hover {
  background: rgba(255,255,255,0.08);
  color: #fff;
}
.app-rail .rail-link.active {
  background: var(--vorecol-sidebar-active); /* DE: azul-500 brillante para destacar */
  color: #fff;
  box-shadow: 0 2px 8px rgba(26,103,183,0.35);
}
.app-rail .rail-link.active::before {
  content: "";
  position: absolute;
  left: -8px;                               /* FLYOUT-LIGHT: accent al borde del rail */
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 22px;
  background: var(--vorecol-blue-100);
  border-radius: 0 3px 3px 0;
}
/* Módulos activables (no contratados, super_usuario):
   más atenuados + badge "+" para indicar que se puede activar.
   Click abre el dialog "Mi cuenta y vigencia" para solicitar activación. */
.app-rail .rail-link-activable {
  opacity: 0.35;
  filter: saturate(0.4);
  transition: opacity var(--vorecol-transition), filter var(--vorecol-transition);
}
.app-rail .rail-link-activable:hover {
  opacity: 0.95;
  filter: saturate(1);
  background: rgba(255,255,255,0.08);
}
.app-rail .rail-link-activable .rail-link-plus {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--vorecol-primary);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--vorecol-sidebar-bg);
  pointer-events: none;
}

.app-rail .rail-footer {
  padding-top: 0.5rem;
  border-top: 1px solid rgba(255,255,255,0.08);
  width: 100%;
  display: flex;
  justify-content: center;
}
.app-rail .rail-user {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  text-decoration: none;
  transition: transform var(--vorecol-transition);
}
.app-rail .rail-user:hover { transform: scale(1.08); }
.app-rail .rail-avatar-initials {
  background: var(--vorecol-primary);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  width: 36px;
  height: 36px;
}

/* ───────── Main Nav (menú del módulo activo) ─────────
   Nota: base dark — se usa tal cual en mobile drawer. En desktop (≥992px)
   se repinta BLANCO desde §03.5 FLYOUT-LIGHT más abajo. */
.app-nav.navbar-vertical {
  left: 56px;                       /* FLYOUT-LIGHT: rail 56 */
  width: 240px;
  background: var(--vorecol-sidebar-bg);  /* dark — override desktop en §03.5 */
  border-right: 1px solid rgba(255,255,255,0.04);
  box-shadow: var(--vorecol-shadow);
}
.app-nav.navbar-vertical .navbar-brand { padding: 1rem 1.25rem; }
.app-nav.navbar-vertical .navbar-brand-image { filter: brightness(0) invert(1); }

/* Collapse de submenús: Tabler fuerza display:flex en .navbar-collapse — restablecer block.
   Solo en desktop: en mobile el toggler debe controlar visibilidad (show/hide) del menú.
   Prefijo `body ` para subir la especificidad a (0,4,0) y GANARLE a la regla anti-FOUC
   `.app-nav .collapse:not(.show){display:none!important}` (línea ~907, misma especificidad
   0,3,0 pero declarada después): el #sidebar-menu es un .collapse SIN .show en desktop, así
   que esa regla lo escondía por completo. Mismo patrón que el fix de .menu-active de abajo. */
@media (min-width: 992px) {
  body .app-nav.navbar-vertical .navbar-collapse { display: block !important; }
}

/* El submenu del módulo activo SIEMPRE visible — defensa en profundidad:
   el JS intenta expandir el sb-mod-<id> vía BS5 Collapse, pero si falla
   (initialId vacío, colisión con legacy JS, script diferido), este CSS
   asegura que el usuario vea los items. */
.app-nav .menu_sistems_all.menu-active > .collapse { display: block !important; }

/* nav-link flex para alinear icono + texto (Tabler solo aplica a expand-sm) */
.app-nav.navbar-vertical .nav-link {
  display: flex !important;
  align-items: center;
  white-space: normal;
  word-break: break-word;
  border-radius: var(--vorecol-radius-sm);
  transition: background var(--vorecol-transition), color var(--vorecol-transition);
}

.app-nav.navbar-vertical .nav-link-icon {
  flex-shrink: 0 !important;
  width: 1.25rem !important;
  height: 1.25rem !important;
  margin: 0 0.625rem 0 0 !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  color: #fff !important;
  opacity: 0.95;
}
.app-nav.navbar-vertical .nav-link-icon .ti,
.app-nav.navbar-vertical .nav-link-icon i {
  font-size: 1.05rem !important;
  line-height: 1;
  color: inherit !important;
  display: inline-block !important;
  min-width: 1rem;
  text-align: center;
}
/* Fallback cuando no hay .nav-link-icon wrapper (íconos directos en .nav-link) */
.app-nav.navbar-vertical .nav-link > i {
  color: #fff !important;
  font-size: 1.05rem !important;
  margin-right: 0.625rem;
  flex-shrink: 0;
  display: inline-block;
  min-width: 1rem;
  text-align: center;
  opacity: 0.95;
}

.app-nav.navbar-vertical .nav-link-title {
  flex: 1;
  min-width: 0;
  white-space: normal;
  word-break: break-word;
  line-height: 1.3;
}
.app-nav.navbar-vertical .nav-link-toggle { flex-shrink: 0; margin-left: auto; }
.app-nav.navbar-vertical .nav-link-toggle::after {
  content: "";
  display: inline-block;
  width: 0.5rem; height: 0.5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  opacity: 0.7;
  transition: transform 0.2s ease;
}
.app-nav.navbar-vertical .nav-link[aria-expanded="true"] .nav-link-toggle::after,
.app-nav.navbar-vertical .nav-link.nav-link-toggle[aria-expanded="true"]::after {
  transform: rotate(45deg);
}

/* ── Nivel 1: módulo raíz (directo en .navbar-nav) ── */
.app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link {
  color: #fff;
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.6rem 0.85rem;
  margin: 0.15rem 0.5rem;
}
.app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link:hover {
  color: #fff;
  background: rgba(255,255,255,0.06);
}
.app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link.active {
  color: #fff;
  background: var(--vorecol-sidebar-active); /* DE: azul-500 brillante para destacar */
}

/* ── Nivel 2: dentro del primer collapse (sb-mod-N) ── */
.app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link {
  color: rgba(255,255,255,0.88);
  font-size: 0.8125rem;
  font-weight: 500;
  padding: 0.45rem 0.75rem 0.45rem 1rem !important;
  margin: 0.1rem 0.5rem;
  position: relative;
}
.app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link:hover {
  color: #fff;
  background: rgba(255,255,255,0.06);
}
.app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active {
  color: #fff;
  background: var(--vorecol-sidebar-active); /* DE: azul-500 brillante */
  font-weight: 600;
}
/* Accent lateral en estado activo (patrón Microsoft Fluent) */
.app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 1.125rem;
  background: var(--vorecol-primary-light);
  border-radius: 0 3px 3px 0;
}

/* ── Nivel 3: dentro del segundo collapse (sb-sub-N-M) ── */
.app-nav.navbar-vertical .collapse .collapse > ul.nav {
  border-left: 1px solid rgba(255,255,255,0.15);
  margin-left: 1.375rem;
  padding-left: 0;
}
.app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link,
.app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child {
  color: rgba(255,255,255,0.78);
  font-size: 0.8rem;
  font-weight: 400;
  padding: 0.38rem 0.75rem 0.38rem 0.875rem !important;
  margin: 0.06rem 0.25rem 0.06rem 0;
}
.app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link:hover,
.app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child:hover {
  color: #fff;
  background: rgba(255,255,255,0.05);
}
.app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link.active,
.app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child.active {
  color: #fff;
  background: var(--vorecol-sidebar-active); /* DE: azul-500 brillante */
}
/* Iconos en nivel 2: un pelo más atenuados */
.app-nav.navbar-vertical .collapse .nav-link-icon,
.app-nav.navbar-vertical .collapse .nav-link > i {
  opacity: 0.85;
}

.app-nav.navbar-vertical .form-select { background-color: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.15); color: #fff; font-size: 0.8125rem; }
.app-nav.navbar-vertical .form-select option { background-color: var(--vorecol-blue-900); color: #fff; }
.app-nav.navbar-vertical hr { border-color: rgba(255,255,255,0.1); }
.app-nav.navbar-vertical .nav-item .badge.bg-azure-lt { font-size: 0.6rem; padding: 0.2em 0.5em; }
/* PBI-EMPRESA-BADGE-NUEVO-001: Tabler posiciona los badges de nav-link como dot de
   notificación (position:absolute + transform) → el "Nuevo" del menú salía del item y
   se veía cortado. Dentro del título fluye inline (baja de línea si no cabe). */
.app-nav.navbar-vertical .nav-link-title .badge { position: static; transform: none; display: inline-block; vertical-align: baseline; }

/* ═══════════════════════════════════════════════════════════════════════
   §03.5  FLYOUT-LIGHT — Rail azul + panel blanco al hover (desktop only)
   Patrón: VS Code / Adobe CC / AWS Console / Azure Portal / MS Dynamics.
   ─ Default (desktop): solo rail visible. Panel aparece al hover del rail
     o del propio panel (delay 150ms abrir / 400ms cerrar, evita triangle bug).
   ─ Modo pinned (body.app-nav-pinned): panel fijo en layout clásico 2 cols.
     Persistido en localStorage 'vorecol-appnav-pinned'.
   ─ Mobile (<992px): NO aplica — queda el offcanvas drawer original.
   ═══════════════════════════════════════════════════════════════════════ */

/* ───── Botón pin (en rail-footer) ───── */
.app-rail .rail-collapse-toggle {
  width: 40px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  color: rgba(255,255,255,0.55);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background var(--vorecol-transition), color var(--vorecol-transition), transform 0.25s ease;
  margin-bottom: 0.5rem;
}
.app-rail .rail-collapse-toggle:hover {
  background: rgba(255,255,255,0.08);
  color: #fff;
}
.app-rail .rail-collapse-toggle i { font-size: 1.05rem; line-height: 1; transition: transform 0.25s ease; }
/* Pinned: rotar 45° para indicar "fijado" (como tachuela clavada) */
body.app-nav-pinned .app-rail .rail-collapse-toggle {
  color: var(--vorecol-blue-100);
  background: rgba(255,255,255,0.1);
}
body.app-nav-pinned .app-rail .rail-collapse-toggle i { transform: rotate(-45deg); }

/* ───── Hint flotante descubribilidad (primera vez) ───── */
.flyout-hint {
  position: fixed;
  left: 64px;
  top: 80px;
  background: var(--vorecol-blue-900);
  color: #fff;
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  font-size: 0.75rem;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
  z-index: 1033;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.flyout-hint::before {
  content: '';
  position: absolute;
  left: -5px; top: 50%;
  transform: translateY(-50%);
  border: 5px solid transparent;
  border-right-color: var(--vorecol-blue-900);
}
body.show-flyout-hint .flyout-hint { opacity: 1; }
@media (max-width: 991.98px) { .flyout-hint { display: none !important; } }

/* ═══════════════════════════════════════════════════════════════════════
   Desktop (≥992px) — FLYOUT-LIGHT overrides
   ═══════════════════════════════════════════════════════════════════════ */
@media (min-width: 992px) {
  /* Panel flotante: position fixed, oculto por default (translateX -100%) */
  .app-nav.navbar-vertical {
    background: #ffffff !important;
    color: var(--vorecol-gray-800);
    border-right: 1px solid var(--vorecol-gray-200);
    box-shadow: 4px 0 16px rgba(10,37,64,0.08);
    transform: translateX(-100%);
    opacity: 0;
    pointer-events: none;
    /* Cierre: delay de 500ms para tolerar movimiento diagonal rail→panel
       (incl. paths que cruzan rail-link-activable). */
    transition: transform 0.22s ease, opacity 0.22s ease;
    transition-delay: 0.5s;
    z-index: 1031;
  }

  /* Hover en el rail (excepto pin button) o en el panel → abrir el panel.
     Usamos .app-rail:hover (todos los 56px del rail), pero excluimos cuando
     el cursor está sobre el #rail-collapse-toggle (botón de fijar/desfijar).
     Esto evita que hovers sobre el pin abran el panel, y al mismo tiempo
     mantiene cobertura completa (incl. los 8px de margen alrededor de cada
     rail-link, que de otro modo serían una "zona muerta" al cruzar al panel). */
  .app-rail:hover:not(:has(#rail-collapse-toggle:hover)) ~ .app-nav.navbar-vertical,
  .app-nav.navbar-vertical:hover {
    transform: translateX(0);
    opacity: 1;
    pointer-events: auto;
    transition-delay: 0.15s;
  }

  /* Excepción: si el ícono hovered es ACTIVABLE (no contratado), NO abrir
     el panel — no tiene submenu real, solo se usa para disparar el dialog
     "Mi cuenta y vigencia" al clickear. Evita el flash de panel vacío. */
  .app-rail:has(.rail-link-activable:hover) ~ .app-nav.navbar-vertical:not(:hover) {
    transform: translateX(-100%) !important;
    opacity: 0 !important;
    pointer-events: none !important;
  }

  /* Tooltips del rail: ignorar pointer-events. El tooltip se renderiza en
     document.body (default BS5), encima del área del panel. Sin esto, mover
     el mouse del rail al panel pasando sobre el tooltip rompe el hover chain
     (rail pierde :hover, panel todavía no, tooltip captura el evento) y el
     panel inicia su cierre. Con pointer-events:none el cursor "atraviesa"
     el tooltip y mantiene el hover sobre rail/panel. */
  .tooltip.tooltip-rail { pointer-events: none; }

  /* JS-managed: bloquea el panel ABIERTO mientras flyoutShowTemp() muta el DOM
     (cambio de id de módulo al hover). Sin esto, la mutación display:none/list-item
     puede inducir un mouseleave fantasma que dispara el cierre. */
  body.app-nav-locked-open .app-nav.navbar-vertical {
    transform: translateX(0) !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    transition-delay: 0s !important;
  }

  /* JS-managed: al des-fijar (click pin → unpin), forzar el cierre del panel
     ignorando :hover por ~500ms. Sin esto, el cursor sigue sobre el rail
     manteniendo el panel visible (por la regla de hover) y el panel queda
     sobrepuesto sobre el contenido recién reposicionado.
     El body NO se overrride aquí — usa el transition normal (0.22s) del
     margin-left default. Así panel y body animan SIMULTÁNEAMENTE: el panel
     se desliza fuera (0.22s) y al mismo tiempo el contenido se desplaza a la
     izquierda (0.22s) — sin "salto delayed" entre uno y otro. */
  body.app-nav-unpinning .app-nav.navbar-vertical {
    transform: translateX(-100%) !important;
    opacity: 0 !important;
    pointer-events: none !important;
    transition: transform 0.22s ease, opacity 0.22s ease !important;
    transition-delay: 0s !important;
  }

  /* Pinned: panel siempre visible, sin transición, sombra mínima */
  body.app-nav-pinned .app-nav.navbar-vertical {
    transform: translateX(0) !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    box-shadow: var(--vorecol-shadow-sm);
    transition: none;
  }

  /* ──── Repintar el nav a claro (desktop only) ──── */
  .app-nav.navbar-vertical .navbar-brand-image { filter: none; }

  /* Nivel 1 — módulo raíz (Generales / módulo activo) */
  .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link {
    color: var(--vorecol-gray-900);
    font-weight: 700;
  }
  .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link:hover {
    color: var(--vorecol-blue-500);
    background: var(--vorecol-blue-50);
  }
  .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link.active {
    color: var(--vorecol-blue-500);
    background: var(--vorecol-blue-50);
  }

  /* Nivel 2 — dentro de sb-mod-N */
  .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link {
    color: var(--vorecol-gray-700);
    font-weight: 500;
  }
  .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link:hover {
    color: var(--vorecol-blue-500);
    background: var(--vorecol-blue-50);
  }
  .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active {
    color: var(--vorecol-blue-500);
    background: var(--vorecol-blue-50);
    font-weight: 600;
  }
  .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active::before {
    background: var(--vorecol-blue-500);
  }

  /* Nivel 3 — sub-submenu */
  .app-nav.navbar-vertical .collapse .collapse > ul.nav {
    border-left-color: var(--vorecol-gray-200);
  }
  .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link,
  .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child {
    color: var(--vorecol-gray-600);
  }
  .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link:hover,
  .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child:hover {
    color: var(--vorecol-blue-500);
    background: var(--vorecol-blue-50);
  }
  .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link.active,
  .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child.active {
    color: var(--vorecol-blue-500);
    background: var(--vorecol-blue-50);
    font-weight: 600;
  }

  /* Iconos en panel claro: grises por default, azules en active */
  .app-nav.navbar-vertical .nav-link-icon { color: var(--vorecol-gray-500) !important; opacity: 1; }
  .app-nav.navbar-vertical .nav-link > i { color: var(--vorecol-gray-500) !important; opacity: 1; }
  .app-nav.navbar-vertical .nav-link.active .nav-link-icon,
  .app-nav.navbar-vertical .nav-link.active > i { color: var(--vorecol-blue-500) !important; }
  .app-nav.navbar-vertical .nav-link-toggle::after { opacity: 0.55; }

  /* Separadores y controles secundarios */
  .app-nav.navbar-vertical hr { border-color: var(--vorecol-gray-200); }
  .app-nav.navbar-vertical .form-select {
    background-color: var(--vorecol-gray-50);
    border-color: var(--vorecol-gray-200);
    color: var(--vorecol-gray-800);
  }
  .app-nav.navbar-vertical .form-select option { background-color: #fff; color: var(--vorecol-gray-800); }
  .app-nav.navbar-vertical .nav-item .badge.bg-azure-lt { font-size: 0.6rem; padding: 0.2em 0.5em; }

  /* Scrollbar del panel (ahora claro) */
  .app-nav.navbar-vertical ::-webkit-scrollbar-thumb { background: var(--vorecol-gray-300); }
  .app-nav.navbar-vertical ::-webkit-scrollbar-thumb:hover { background: var(--vorecol-gray-400); }

  /* ──── Page wrapper / topbar margins ──── */
  /* Default (fly-out): solo se reserva el rail */
  .app-nav ~ .page-wrapper,
  .page:has(.app-nav) .page-wrapper { margin-left: 56px !important; transition: margin-left 0.22s ease; }
  body:has(.app-rail) .topbar .navbar-custom { margin-left: 56px !important; transition: margin-left 0.22s ease; }
  .app-nav ~ header.navbar { margin-left: 56px !important; transition: margin-left 0.22s ease; }

  /* ──── Modo 1 COLUMNA: portales internos de 1 módulo (developer/contenidos/marketing/comercial).
     Sin rail; el panel queda como sidebar fijo normal (240px), no flyout. PBI-PSICO-PORTALES-1COL-001. ──── */
  body.app-onecol .app-rail { display: none !important; }
  body.app-onecol .app-nav.navbar-vertical {
    left: 0 !important;
    transform: translateX(0) !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    transition: none !important;
    box-shadow: var(--vorecol-shadow-sm);
  }

  /* ──── Modo 1 COLUMNA en AZUL: el panel se queda NAVY (como el riel) en vez de
     blanco. Los portales internos (developer/contenidos/marketing/comercial) piden
     el menú en 1 columna pero azul, no tan blanco. §03.5 repinta el panel claro en
     desktop; aquí lo re-oscurecemos reusando los tonos base navy (mismos valores que
     el panel sin flyout). PBI-PSICO-PORTALES-MENU-AZUL-001. ──── */
  body.app-onecol .app-nav.navbar-vertical {
    background: var(--vorecol-sidebar-bg) !important;
    border-right: 1px solid rgba(255,255,255,0.06);
    box-shadow: var(--vorecol-shadow);
  }
  body.app-onecol .app-nav.navbar-vertical .navbar-brand-image { filter: brightness(0) invert(1); }
  /* Nivel 1 (módulo activo) */
  body.app-onecol .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link { color: #fff; }
  body.app-onecol .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link:hover { color: #fff; background: rgba(255,255,255,0.06); }
  body.app-onecol .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link.active { color: #fff; background: var(--vorecol-sidebar-active); }
  /* Nivel 2 */
  body.app-onecol .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link { color: rgba(255,255,255,0.88); }
  body.app-onecol .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link:hover { color: #fff; background: rgba(255,255,255,0.06); }
  body.app-onecol .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active { color: #fff; background: var(--vorecol-sidebar-active); }
  /* Nivel 3 */
  body.app-onecol .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link,
  body.app-onecol .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child { color: rgba(255,255,255,0.72); }
  body.app-onecol .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link:hover,
  body.app-onecol .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child:hover { color: #fff; background: rgba(255,255,255,0.06); }
  /* Iconos claros (el FLYOUT-LIGHT los pone grises con !important) */
  body.app-onecol .app-nav.navbar-vertical .nav-link-icon { color: rgba(255,255,255,0.7) !important; }
  body.app-onecol .app-nav.navbar-vertical .nav-link > i { color: rgba(255,255,255,0.7) !important; }
  body.app-onecol .app-nav.navbar-vertical .nav-link.active .nav-link-icon,
  body.app-onecol .app-nav.navbar-vertical .nav-link.active > i { color: #fff !important; }
  /* Separadores / selects / scrollbar oscuros */
  body.app-onecol .app-nav.navbar-vertical hr { border-color: rgba(255,255,255,0.1); }
  body.app-onecol .app-nav.navbar-vertical .form-select { background-color: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.15); color: #fff; }
  body.app-onecol .app-nav.navbar-vertical .form-select option { background-color: var(--vorecol-blue-900); color: #fff; }
  body.app-onecol .app-nav.navbar-vertical ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.25); }

  body.app-onecol .app-nav ~ .page-wrapper,
  body.app-onecol .page:has(.app-nav) .page-wrapper { margin-left: 240px !important; }
  body.app-onecol .topbar .navbar-custom,
  body.app-onecol .app-nav ~ header.navbar { margin-left: 240px !important; }
  /* El footer también respeta el offset del menú (240px) — SOLO cuando cuelga directo de
     .page (caso comercial: por_vencer/vencidos/historial), donde queda a left:0 y el texto
     centrado se mete debajo del menú navy (solo asoma "y Vorecol."). NO tocar el footer que
     ya vive dentro de .page-wrapper (marketing/contenidos), que ya está offset. PBI-PSICO-PORTALES-MENU-AZUL-001. */
  body.app-onecol .page > .footer { margin-left: 240px !important; }

  /* Veltrix (psicosmart): evitar doble offset del .content-page */
  .page-wrapper .content-page { margin-left: 0 !important; }

  /* Veltrix (recruiting + otros legacy): el .footer estaba hardcoded con
     position:absolute + left:240px (ancho del sidebar legacy). Con FLYOUT-LIGHT
     ese left:240px choca con el rail (56px) o el nav pinned (296px) —
     queda cortado o con hueco lateral. Restaurar al flow Tabler normal:
     position:static + sin offsets fijos + ancho 100% del page-wrapper. */
  .page-wrapper > .footer,
  .page-wrapper .footer.footer-transparent {
    position: static !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    background: transparent !important;
    padding: 1rem 0 !important;
  }

  /* Pinned: reservar rail + panel (56 + 240 = 296px) */
  body.app-nav-pinned .app-nav ~ .page-wrapper,
  body.app-nav-pinned .page:has(.app-nav) .page-wrapper { margin-left: 296px !important; }
  body.app-nav-pinned:has(.app-rail) .topbar .navbar-custom { margin-left: 296px !important; }
  body.app-nav-pinned .app-nav ~ header.navbar { margin-left: 296px !important; }
}

/* ═══════════════════════════════════════════════════════════════════════
   §03.6  FLYOUT-LIGHT — overrides para modo oscuro (data-bs-theme=dark)
   Cuando el usuario activa el tema oscuro, el panel blanco se convierte
   en un panel gris-oscuro con texto claro, manteniendo el patrón fly-out.
   El rail sigue siendo azul Vorecol en ambos modos (siempre dark).
   ═══════════════════════════════════════════════════════════════════════ */
@media (min-width: 992px) {
  /* Panel: dark bg + light text */
  [data-bs-theme="dark"] .app-nav.navbar-vertical {
    background: var(--vorecol-sidebar-bg) !important;   /* azul intermedio oscuro */
    color: rgba(255,255,255,0.88);
    border-right: 1px solid rgba(255,255,255,0.05);
    box-shadow: 4px 0 16px rgba(0,0,0,0.35);
  }
  /* Nivel 1 */
  [data-bs-theme="dark"] .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link {
    color: #fff;
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link:hover {
    color: #fff;
    background: rgba(255,255,255,0.08);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link.active {
    color: #fff;
    background: var(--vorecol-sidebar-active);          /* azul-500 brillante */
  }
  /* Nivel 2 */
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link {
    color: rgba(255,255,255,0.82);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link:hover {
    color: #fff;
    background: rgba(255,255,255,0.06);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active {
    color: #fff;
    background: var(--vorecol-sidebar-active);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse > ul.nav > li > .nav-link.active::before {
    background: var(--vorecol-primary-light);
  }
  /* Nivel 3 */
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav {
    border-left-color: rgba(255,255,255,0.12);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link,
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child {
    color: rgba(255,255,255,0.75);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link:hover,
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child:hover {
    color: #fff;
    background: rgba(255,255,255,0.05);
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > .nav-link.active,
  [data-bs-theme="dark"] .app-nav.navbar-vertical .collapse .collapse > ul.nav > li > a.nav-link-child.active {
    color: #fff;
    background: var(--vorecol-sidebar-active);
  }
  /* Iconos, separadores, form-select en dark */
  [data-bs-theme="dark"] .app-nav.navbar-vertical .nav-link-icon,
  [data-bs-theme="dark"] .app-nav.navbar-vertical .nav-link > i { color: rgba(255,255,255,0.85) !important; }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .nav-link.active .nav-link-icon,
  [data-bs-theme="dark"] .app-nav.navbar-vertical .nav-link.active > i { color: #fff !important; }
  [data-bs-theme="dark"] .app-nav.navbar-vertical hr { border-color: rgba(255,255,255,0.1); }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .form-select {
    background-color: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.15);
    color: #fff;
  }
  [data-bs-theme="dark"] .app-nav.navbar-vertical .form-select option {
    background-color: var(--vorecol-blue-900);
    color: #fff;
  }
  /* Logo del nav (d-lg-none en desktop, pero por si acaso) */
  [data-bs-theme="dark"] .app-nav.navbar-vertical .navbar-brand-image { filter: brightness(0) invert(1); }
}

@media (max-width: 991.98px) {
  .app-rail { display: none !important; }
  /* En mobile: el <aside navbar-vertical> queda como top-bar compacta con
     hamburger + brand + controles user. El contenido del menu se abre como
     DRAWER LATERAL IZQUIERDO (no como collapse hacia abajo). */
  .app-nav.navbar-vertical {
    left: 0;
    right: 0;
    width: 100%;
    max-width: 100%;
    height: auto;
    min-height: auto;
    bottom: auto;
    padding: 0.25rem 0.5rem;
    box-shadow: var(--vorecol-shadow-sm);
    /* z-index normal: debajo de los offcanvas de contenido (manual, notif, etc)
       que usan 1045 por default, para no tapar su boton de cerrar. */
    z-index: 1030;
    /* PBI-MENU-MOVIL-STICKY-001: barra superior FIJA en móvil para que el
       hamburger (☰) no se suba/desaparezca al hacer scroll y el menú siga
       siempre alcanzable. Antes quedaba position:relative → al bajar el ☰
       salía de pantalla. El drawer (body.sidebar-drawer-open) ya eleva el
       z-index aparte; position:fixed del drawer es relativo al viewport, no
       al sticky → abre/cierra igual. */
    position: sticky;
    top: 0;
  }
  /* Cuando el drawer del sidebar esta abierto, elevar el aside encima del
     backdrop (1040) y del drawer (1045) para que el hamburger/X siga
     clickeable. Solo aplica con drawer activo. */
  body.sidebar-drawer-open .app-nav.navbar-vertical {
    z-index: 1050;
  }
  /* Bloquear scroll del body mientras el drawer mobile está abierto. El drawer
     internamente ya scrollea (overflow-y:auto). Solo overflow:hidden — quité
     touch-action:none y overscroll-behavior porque dejaban el body bloqueado
     después de cerrar en iOS Safari. */
  body.sidebar-drawer-open {
    overflow: hidden !important;
  }
  .app-nav.navbar-vertical > .container-fluid {
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.25rem;
  }
  .app-nav.navbar-vertical .navbar-toggler {
    color: rgba(255,255,255,0.85);
    border-color: rgba(255,255,255,0.15);
    background: transparent;
    padding: 0.375rem 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* Swap hamburger <-> X segun aria-expanded del toggler */
  .app-nav .nav-toggler-icons .toggler-ico-open,
  .app-nav .nav-toggler-icons .toggler-ico-close {
    font-size: 1.5rem;
    line-height: 1;
    color: rgba(255,255,255,0.9);
  }
  .app-nav .nav-toggler-icons .toggler-ico-close { display: none; }
  .app-nav .nav-toggler-icons[aria-expanded="true"] .toggler-ico-open { display: none; }
  .app-nav .nav-toggler-icons[aria-expanded="true"] .toggler-ico-close { display: inline-block; }
  .app-nav.navbar-vertical .navbar-brand-image { height: 1.75rem; }
  /* Drawer lateral: #sidebar-menu fixed left, slide-in con transform.
     padding-top amplio para que el contenido no quede tapado por el topbar
     (aside navbar-vertical) que queda visible encima del drawer. */
  .app-nav.navbar-vertical .navbar-collapse {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    bottom: 0 !important;
    width: 85vw !important;
    max-width: 320px !important;
    height: 100vh !important;
    max-height: 100vh !important;
    /* Light por default (consistente con la flyout panel en desktop). Solo
       oscurece cuando el usuario activa el theme toggle (html[data-bs-theme="dark"]). */
    background: var(--tblr-bg-surface, #fff);
    color: var(--tblr-body-color, #1e293b);
    box-shadow: 4px 0 20px rgba(0,0,0,0.3);
    z-index: 1045 !important;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    overflow-y: auto !important;
    display: block !important;
    /* padding-top:60px era para reservar espacio bajo el .btn-close-drawer
       absolute-positioned legacy. Ahora el close button vive inline en la flex-row
       junto al selector mobile (ver sidebar.php), así que no hay nada que reservar. */
    padding-top: 0;
    flex-basis: auto;
  }
  .app-nav.navbar-vertical .navbar-collapse.show {
    transform: translateX(0) !important;
  }
  /* Backdrop real (div) para que el tap cierre el drawer en mobile */
  .sidebar-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 1040;
    opacity: 0;
    transition: opacity 0.2s ease;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .sidebar-backdrop.show { opacity: 1; }
  /* Padding del menu en mobile drawer */
  .app-nav.navbar-vertical .navbar-nav { padding: 0.25rem 0; }
  .app-nav.navbar-vertical .navbar-nav > li.nav-item > .nav-link {
    margin: 0.1rem 0.25rem;
  }
  .app-rail .rail-collapse-toggle { display: none; }
  /* Topbar: oculto en mobile — los controles viven en el app-nav mobile */
  body .app-nav ~ header.navbar { margin-left: 0 !important; }
  /* Boton cerrar drawer mobile (top-right del panel) */
  .app-nav.navbar-vertical .navbar-collapse .btn-close-drawer {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: rgba(255,255,255,0.12);
    border: 1px solid rgba(255,255,255,0.2);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    z-index: 2;
    cursor: pointer;
  }
  .app-nav.navbar-vertical .navbar-collapse .btn-close-drawer:hover,
  .app-nav.navbar-vertical .navbar-collapse .btn-close-drawer:active {
    background: rgba(255,255,255,0.22);
  }

  /* DRAWER MOBILE — modo claro por default.
     El sidebar mobile usa light theme por default (consistente con la flyout
     panel en desktop). Los nav-link de Tabler tienen color:#fff hardcodeado
     en TODOS los niveles (raíz, collapse, collapse-collapse, nav-link-child).
     Forzamos colores legibles sobre fondo blanco con !important porque las
     reglas originales tienen alta especificidad. En modo oscuro
     (html[data-bs-theme="dark"]) las variables Tabler se invierten y queda
     coherente solo. */
  .app-nav.navbar-vertical .nav-link,
  .app-nav.navbar-vertical .nav-link-child,
  .app-nav.navbar-vertical .nav-link-title {
    color: var(--tblr-body-color, #1e293b) !important;
  }
  .app-nav.navbar-vertical .nav-link:hover,
  .app-nav.navbar-vertical .nav-link-child:hover {
    color: var(--tblr-body-color, #1e293b) !important;
    background: var(--tblr-bg-surface-secondary, #f6f8fb) !important;
  }
  .app-nav.navbar-vertical .nav-link.active,
  .app-nav.navbar-vertical .nav-link-child.active {
    color: var(--tblr-primary, #066fd1) !important;
    background: var(--tblr-primary-lt, rgba(6,111,209,.12)) !important;
  }
  .app-nav.navbar-vertical .nav-link-icon,
  .app-nav.navbar-vertical .nav-link > i {
    color: var(--tblr-secondary, #6c7a91) !important;
  }
  .app-nav.navbar-vertical .nav-link.active .nav-link-icon,
  .app-nav.navbar-vertical .nav-link.active > i {
    color: var(--tblr-primary, #066fd1) !important;
  }
  /* Separadores y bordes internos del drawer */
  .app-nav.navbar-vertical hr {
    border-color: var(--tblr-border-color, #e6e7e9) !important;
  }
  .app-nav.navbar-vertical .collapse .collapse > ul.nav {
    border-left-color: var(--tblr-border-color, #e6e7e9) !important;
  }
}

/* DE: Retro-compat: estilos legacy sin .app-nav (en páginas que aún no actualizaron su header) */
.navbar-vertical:not(.app-nav) {
  background: var(--vorecol-sidebar-bg);
  border-right: none;
  box-shadow: var(--vorecol-shadow);
}

/* ───────── Anti-FOUC sidebar — fix "el menú se abre al recargar" (2026-04-23) ─────────
   Causa H1 (PENDING_sidebar_fixes.md): el primer paint puede mostrar los .collapse
   abiertos por una fracción de segundo antes de que el CSS termine de aplicar.
   Forzar display:none !important asegura que el primer paint ya tenga el estado
   correcto. Los handlers BS5 Collapse manuales (al click del user) siguen animando
   normalmente porque toggleamos la clase .show desde JS. */
.app-nav .collapse:not(.show) {
  display: none !important;
}
/* FLYOUT-LIGHT (2026-04-24): específicidad extra para que la regla de
   .menu-active > .collapse gane a la anti-FOUC de arriba. Sin esto, hover
   sobre un módulo mostraba el título pero no abría su submenu. */
body .app-nav .menu_sistems_all.menu-active > .collapse {
  display: block !important;
}
.navbar-vertical:not(.app-nav) .nav-link { display: flex !important; align-items: center; }

/* ============================================================
   §04. Topbar
   ============================================================ */
header.navbar.navbar-expand-lg { border-bottom: 1px solid var(--vorecol-gray-200); background: #fff; box-shadow: var(--vorecol-shadow-sm); }
.topbar-search { display: none !important; }
.topbar-search .search-icon { position: absolute; left: 0.75rem; color: var(--vorecol-gray-400); font-size: 1rem; pointer-events: none; }
.topbar-search .form-control { padding-left: 2.25rem; border-radius: 2rem; background: var(--vorecol-gray-100); border-color: transparent; width: 220px; font-size: 0.875rem; transition: width var(--vorecol-transition), background var(--vorecol-transition); }
.topbar-search .form-control:focus { width: 280px; background: #fff; border-color: var(--vorecol-primary); box-shadow: 0 0 0 3px rgba(26,103,183,.12); }
.badge-notification { position: absolute; top: 4px; right: 4px; min-width: 1rem; height: 1rem; font-size: 0.625rem; padding: 0.15rem 0.3rem; border-radius: 10rem; border: 2px solid #fff; }

/* ============================================================
   §05. Cards
   ============================================================ */
.card { border-radius: var(--vorecol-radius); border: 1px solid var(--vorecol-gray-200); box-shadow: var(--vorecol-shadow-sm); transition: box-shadow var(--vorecol-transition); }
.card:hover { box-shadow: var(--vorecol-shadow); }
.card-header { border-bottom: 1px solid var(--vorecol-gray-200); background: transparent; padding: 1rem 1.25rem; }
.card-footer { border-top: 1px solid var(--vorecol-gray-200); background: transparent; }
.stat-card { border-left: 3px solid var(--vorecol-primary); border-radius: var(--vorecol-radius); }

/* ============================================================
   §06. Tables
   ============================================================ */
.table thead th { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--vorecol-gray-500); border-bottom: 2px solid var(--vorecol-gray-200); }
.table tbody tr:hover { background-color: var(--vorecol-gray-50); }

/* ============================================================
   §07. Buttons
   ============================================================ */
.btn { border-radius: var(--vorecol-radius-sm); font-weight: 500; font-size: 0.875rem; transition: all var(--vorecol-transition); }
.btn-rounded, .btn-pill { border-radius: 50rem !important; }
.btn-icon-label { display: inline-flex; align-items: center; gap: 0.375rem; }
.btn-ripple { position: relative; overflow: hidden; }
.btn-icon { white-space: normal; }
.waves-effect { position: relative; overflow: hidden; }

/* ============================================================
   §08. Badges
   ============================================================ */
.badge { border-radius: var(--vorecol-radius-xs); }

/* ============================================================
   §09. Forms
   ============================================================ */
.form-control, .form-select { border-radius: var(--vorecol-radius-sm); border-color: var(--vorecol-gray-300); font-size: 0.875rem; }
.form-control:focus, .form-select:focus { border-color: var(--vorecol-primary); box-shadow: 0 0 0 3px rgba(26,103,183,.12); }
.form-label { font-weight: 500; font-size: 0.875rem; }

/* ============================================================
   §10. Alerts
   ============================================================ */
.alert { border-radius: var(--vorecol-radius-sm); border: none; }

/* ============================================================
   §11. List Groups
   ============================================================ */
.list-group-item { border-color: var(--vorecol-gray-200); }

/* ============================================================
   §12. Modals / jQuery UI Dialogs
   ============================================================ */
.modal-content { border-radius: var(--vorecol-radius); border: none; box-shadow: var(--vorecol-shadow-lg); }
.modal-header { border-bottom: 1px solid var(--vorecol-gray-200); }
.modal-footer { border-top: 1px solid var(--vorecol-gray-200); }
.ui-dialog { border-radius: var(--vorecol-radius) !important; border: none !important; box-shadow: var(--vorecol-shadow-lg) !important; }
.ui-dialog-titlebar { border-radius: var(--vorecol-radius) var(--vorecol-radius) 0 0 !important; background: var(--vorecol-primary) !important; color: #fff !important; }
.ui-dialog-titlebar-close { color: #fff !important; }
.ui-dialog-buttonset .ui-button { border-radius: var(--vorecol-radius-sm) !important; }
.ui-widget-overlay { background: rgba(0,0,0,0.5) !important; }

/* ============================================================
   §13. Page Header
   ============================================================ */
.page-header { padding: 1.5rem 0; }
.page-pretitle { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--vorecol-gray-400); margin-bottom: 0.25rem; }
.page-title { font-size: 1.25rem; font-weight: 700; color: var(--vorecol-gray-900); margin: 0; }

/* ============================================================
   §14. Login — Split Layout
   ============================================================ */
.login-split { min-height: calc(100vh - 58px); }
.login-brand-panel { background: linear-gradient(135deg, var(--vorecol-blue-900) 0%, var(--vorecol-blue-700) 60%, var(--vorecol-primary) 100%); display: flex; align-items: center; justify-content: center; padding: 3rem; position: relative; overflow: hidden; }
.login-brand-panel::before { content: ''; position: absolute; top: -50%; right: -20%; width: 80%; height: 80%; background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 70%); border-radius: 50%; }
.brand-content { position: relative; z-index: 1; max-width: 420px; color: #fff; }
.brand-content img { height: 2.5rem; margin-bottom: 2rem; filter: brightness(0) invert(1); }
.brand-tagline { font-size: 1.875rem; font-weight: 700; line-height: 1.25; margin-bottom: 1rem; }
.brand-subtitle { font-size: 1rem; color: rgba(255,255,255,0.75); margin-bottom: 2rem; line-height: 1.6; }
.brand-features { display: flex; flex-direction: column; gap: 0.875rem; }
.brand-feature { display: flex; align-items: center; gap: 0.75rem; font-size: 0.9375rem; color: rgba(255,255,255,0.85); }
.brand-feature .ti { font-size: 1.125rem; color: rgba(255,255,255,0.6); }
.login-form-panel { display: flex; align-items: center; justify-content: center; background: #fff; padding: 2rem 1.5rem; }
.login-form-wrapper { width: 100%; max-width: 420px; }

/* ============================================================
   §15. Error Pages
   ============================================================ */
.error-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; background: var(--vorecol-body-bg); padding: 2rem; }
.error-page-container { text-align: center; max-width: 480px; }
.error-page-illustration { font-size: 5rem; color: var(--vorecol-gray-300); margin-bottom: 1.5rem; line-height: 1; }
.error-page-code { font-size: 6rem; font-weight: 800; line-height: 1; background: linear-gradient(135deg, var(--vorecol-primary) 0%, var(--vorecol-blue-700) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 0.5rem; }
.error-page-title { font-size: 1.5rem; font-weight: 700; color: var(--vorecol-gray-800); margin-bottom: 0.75rem; }
.error-page-text { font-size: 0.9375rem; color: var(--vorecol-gray-500); margin-bottom: 2rem; line-height: 1.6; }

/* ============================================================
   §16. Skeleton Loading
   ============================================================ */
.skeleton { background: linear-gradient(90deg, var(--vorecol-gray-100) 25%, var(--vorecol-gray-200) 50%, var(--vorecol-gray-100) 75%); background-size: 200% 100%; animation: skeleton-shimmer 1.5s infinite; border-radius: var(--vorecol-radius-xs); display: block; }
.skeleton-text { height: 1em; margin-bottom: 0.5em; }
.skeleton-text:last-child { width: 60%; }
.skeleton-title { height: 1.5em; margin-bottom: 0.75em; }
.skeleton-avatar { border-radius: 50%; }
.skeleton-card { height: 120px; border-radius: var(--vorecol-radius); }

/* ============================================================
   §16b. Avatares circulares (estandar Microsoft 365 / Google / LinkedIn).
   Override del default Tabler que es rounded square.
   Aplica a .avatar en topbar, listas, preview del upload, etc.
   aspect-ratio + flex-shrink: 0 previenen que se deforme en óvalo
   cuando el avatar está en un flex container con texto largo al lado.
   ============================================================ */
.avatar {
    border-radius: 50% !important;
    aspect-ratio: 1 / 1;
    flex-shrink: 0;
}

/* ============================================================
   §17. Sparklines
   ============================================================ */
.sparkline { display: block; overflow: visible; }
.sparkline-path { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.sparkline-area { opacity: 0.15; stroke: none; }

/* ============================================================
   §18. Progress Rings
   ============================================================ */
.progress-ring-wrap { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.progress-ring__track { stroke: var(--vorecol-gray-200); fill: none; }
.progress-ring__fill { fill: none; stroke-linecap: round; transition: stroke-dashoffset 0.6s ease; transform: rotate(-90deg); transform-origin: 50% 50%; }
.progress-ring__label { position: absolute; font-weight: 700; font-size: 0.875rem; }

/* ============================================================
   §19. Empty States
   ============================================================ */
.empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 3rem 1.5rem; color: var(--vorecol-gray-400); }
.empty-state-icon { font-size: 3.5rem; margin-bottom: 1.25rem; opacity: 0.5; }
.empty-state-title { font-size: 1.125rem; font-weight: 600; color: var(--vorecol-gray-700); margin-bottom: 0.5rem; }
.empty-state-text { font-size: 0.875rem; max-width: 320px; line-height: 1.6; }
.empty-state .btn { margin-top: 1.5rem; }
/* Tabler estiliza `.empty-icon svg`; nuestros empty-states usan `<i class="ti">` (íconos de
   fuente), que Tabler NO dimensiona → salían diminutos. Tamaño estándar 2.5rem. El font-size
   inline por página (donde exista) sigue ganando; esto cubre las que lo omiten + futuras. */
.empty-icon i { font-size: 2.5rem; opacity: 0.5; line-height: 1; }

/* ============================================================
   §20. Toasts
   ============================================================ */
.toast { border-radius: var(--vorecol-radius-sm); box-shadow: var(--vorecol-shadow-lg); border: none; overflow: hidden; }
.toast-progress { height: 3px; background: rgba(255,255,255,0.4); position: absolute; bottom: 0; left: 0; animation: toast-progress-bar linear forwards; }

/* ============================================================
   §21. Module Accent Colors
   ============================================================ */
/* Paleta validada con legacy + variaciones tonales — PBI-MICUENTA-002 */
.module-accent-app           { --module-accent: #4090cb; }
.module-accent-psicosmart    { --module-accent: #df8852; }
.module-accent-360           { --module-accent: #8fcd59; }
.module-accent-learning      { --module-accent: #5071b7; }
.module-accent-performance   { --module-accent: #2596BE; }
.module-accent-climate       { --module-accent: #536270; }
.module-accent-compensations { --module-accent: #2e3d8d; }
.module-accent-recruiting    { --module-accent: #F9AC4B; }
.module-accent-035           { --module-accent: #55b94e; }
.module-accent-attendance    { --module-accent: #836cc1; }
.module-accent-nomina        { --module-accent: #059669; }

/* ============================================================
   §22. Keyboard Shortcuts
   ============================================================ */
kbd { background: var(--vorecol-gray-100); border: 1px solid var(--vorecol-gray-300); border-bottom-width: 2px; border-radius: var(--vorecol-radius-xs); color: var(--vorecol-gray-600); font-family: inherit; font-size: 0.75em; padding: 0.1em 0.4em; }

/* ============================================================
   §23. Command Palette
   ============================================================ */
.command-palette-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 9998; display: flex; align-items: flex-start; justify-content: center; padding-top: 8vh; }
.command-palette { background: #fff; border-radius: var(--vorecol-radius); box-shadow: var(--vorecol-shadow-lg); width: 100%; max-width: 560px; overflow: hidden; }
.command-palette-input { border: none; border-bottom: 1px solid var(--vorecol-gray-200); padding: 1rem 1.25rem; font-size: 1rem; width: 100%; outline: none; }
.command-palette-results { max-height: 360px; overflow-y: auto; }
.command-palette-item { padding: 0.75rem 1.25rem; cursor: pointer; display: flex; align-items: center; gap: 0.75rem; font-size: 0.875rem; }
.command-palette-item:hover { background: var(--vorecol-gray-50); }

/* ============================================================
   §24. Session Timeout Warning
   ============================================================ */
.session-warning-modal .modal-header { background: #f59e0b; color: #fff; }
.session-warning-countdown { font-size: 3rem; font-weight: 800; text-align: center; color: #f59e0b; }

/* ============================================================
   §25. Stepper / Wizard
   ============================================================ */
.stepper { display: flex; align-items: flex-start; }
.stepper-item { flex: 1; display: flex; flex-direction: column; align-items: center; position: relative; }
.stepper-item:not(:last-child)::after { content: ''; position: absolute; top: 1.125rem; left: calc(50% + 1.25rem); right: calc(-50% + 1.25rem); height: 2px; background: var(--vorecol-gray-200); }
.stepper-item.completed::after { background: var(--vorecol-primary); }
.stepper-icon { width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--vorecol-gray-200); color: var(--vorecol-gray-500); display: flex; align-items: center; justify-content: center; font-size: 0.875rem; font-weight: 700; position: relative; z-index: 1; transition: background var(--vorecol-transition), color var(--vorecol-transition); }
.stepper-item.active .stepper-icon,
.stepper-item.completed .stepper-icon { background: var(--vorecol-primary); color: #fff; }
.stepper-title { font-size: 0.75rem; font-weight: 600; margin-top: 0.5rem; text-align: center; }

/* ============================================================
   §26. NProgress
   ============================================================ */
#nprogress .bar { background: var(--vorecol-primary) !important; height: 3px !important; }
#nprogress .peg { box-shadow: 0 0 10px var(--vorecol-primary), 0 0 5px var(--vorecol-primary) !important; }
#nprogress .spinner-icon { border-top-color: var(--vorecol-primary) !important; border-left-color: var(--vorecol-primary) !important; }

/* ============================================================
   §27. Rate / feedback / botones de módulo
   ============================================================ */
.rate_vorecol { display: flex; gap: 0.25rem; }
.div_rate { cursor: pointer; }
.button_psicosmart  { background: linear-gradient(135deg, #7B61FF 0%, #5B3FFF 100%); color: #fff; border: none; }
.button_human       { background: linear-gradient(135deg, #10B981 0%, #059669 100%); color: #fff; border: none; }
.button_performance { background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%); color: #fff; border: none; }
.button_climate     { background: linear-gradient(135deg, #06B6D4 0%, #0891B2 100%); color: #fff; border: none; }
.button_360         { background: linear-gradient(135deg, #0EA5E9 0%, #0284C7 100%); color: #fff; border: none; }

/* ============================================================
   §28. File Upload / Drag & Drop
   ============================================================ */
.dropzone { border: 2px dashed var(--vorecol-gray-300); border-radius: var(--vorecol-radius); padding: 2.5rem; text-align: center; transition: border-color var(--vorecol-transition), background var(--vorecol-transition); cursor: pointer; }
.dropzone:hover, .dropzone.drag-over { border-color: var(--vorecol-primary); background: var(--vorecol-primary-50, #EBF2FB); }
.dropzone-icon { font-size: 2.5rem; color: var(--vorecol-gray-300); margin-bottom: 0.75rem; }

/* ============================================================
   §29. Animaciones
   ============================================================ */
@keyframes skeleton-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@keyframes toast-progress-bar { from { width: 100%; } to { width: 0%; } }
@keyframes pulse-dot { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.4); opacity: 0.7; } }
@keyframes float-up { 0% { transform: translateY(0); } 50% { transform: translateY(-6px); } 100% { transform: translateY(0); } }
@keyframes pop-in { 0% { transform: scale(0.8); opacity: 0; } 70% { transform: scale(1.05); } 100% { transform: scale(1); opacity: 1; } }
@keyframes chart-fade-in { from { opacity: 0; transform: scaleY(0.85); } to { opacity: 1; transform: scaleY(1); } }
@keyframes celebration-bounce { 0%, 100% { transform: translateY(0) rotate(0deg); } 25% { transform: translateY(-12px) rotate(-3deg); } 75% { transform: translateY(-8px) rotate(3deg); } }
@keyframes ripple { to { transform: scale(4); opacity: 0; } }

.animate-stagger > * { animation: pop-in 0.3s ease both; }
.animate-stagger > *:nth-child(1) { animation-delay: 0.05s; }
.animate-stagger > *:nth-child(2) { animation-delay: 0.10s; }
.animate-stagger > *:nth-child(3) { animation-delay: 0.15s; }
.animate-stagger > *:nth-child(4) { animation-delay: 0.20s; }
.animate-stagger > *:nth-child(5) { animation-delay: 0.25s; }
.animate-stagger > *:nth-child(6) { animation-delay: 0.30s; }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }

.btn-ripple::after { content: ''; position: absolute; top: 50%; left: 50%; width: 5px; height: 5px; background: rgba(255,255,255,0.4); border-radius: 50%; transform: translate(-50%, -50%) scale(0); opacity: 0; }
.btn-ripple:active::after { animation: ripple 0.4s ease-out; }
.pulse-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: currentColor; animation: pulse-dot 1.5s ease-in-out infinite; }

/* ============================================================
   §30. Dark Mode
   ============================================================ */
[data-bs-theme="dark"] { --vorecol-body-bg: #141414; --vorecol-gray-50: #1a1a1a; --vorecol-gray-100: #242424; --vorecol-gray-200: #2e2e2e; --vorecol-gray-300: #3a3a3a; --vorecol-gray-400: #6b6b6b; --vorecol-gray-500: #8a8a8a; --vorecol-gray-600: #a0a0a0; --vorecol-gray-700: #c0c0c0; --vorecol-gray-800: #d8d8d8; --vorecol-gray-900: #f0f0f0; }
[data-bs-theme="dark"] body { background-color: var(--vorecol-body-bg); }
[data-bs-theme="dark"] .card { background: var(--vorecol-gray-50); border-color: var(--vorecol-gray-200); }
[data-bs-theme="dark"] header.navbar.navbar-expand-lg { background: #1a1a1a; border-bottom-color: var(--vorecol-gray-200); }
[data-bs-theme="dark"] .topbar-search .form-control { background: var(--vorecol-gray-100); color: var(--vorecol-gray-700); border-color: transparent; }
[data-bs-theme="dark"] .modal-content { background: var(--vorecol-gray-50); border-color: var(--vorecol-gray-200); }
[data-bs-theme="dark"] .modal-header, [data-bs-theme="dark"] .modal-footer { border-color: var(--vorecol-gray-200); }
[data-bs-theme="dark"] .table thead th { color: var(--vorecol-gray-500); border-bottom-color: var(--vorecol-gray-200); }
[data-bs-theme="dark"] .table tbody tr:hover { background: var(--vorecol-gray-50); }
[data-bs-theme="dark"] .form-control, [data-bs-theme="dark"] .form-select { background: var(--vorecol-gray-100); border-color: var(--vorecol-gray-300); color: var(--vorecol-gray-800); }
[data-bs-theme="dark"] .login-form-panel { background: #1a1a1a; }
[data-bs-theme="dark"] .login-layout-nav { background-color: #1a1a1a !important; border-bottom-color: rgba(255,255,255,.1) !important; }
[data-bs-theme="dark"] .login-layout-nav .navbar-brand img { filter: brightness(0) invert(1); }
[data-bs-theme="dark"] .login-layout-nav .nav-link { color: rgba(255,255,255,.85); }
[data-bs-theme="dark"] .command-palette { background: var(--vorecol-gray-50); }
[data-bs-theme="dark"] .command-palette-input { background: var(--vorecol-gray-50); color: var(--vorecol-gray-800); border-bottom-color: var(--vorecol-gray-200); }
[data-bs-theme="dark"] .command-palette-item:hover { background: var(--vorecol-gray-100); }
[data-bs-theme="dark"] .dropzone { border-color: var(--vorecol-gray-300); }
[data-bs-theme="dark"] .error-page { background: var(--vorecol-body-bg); }
[data-bs-theme="dark"] .error-page-title { color: var(--vorecol-gray-800); }
[data-bs-theme="dark"] .error-page-text { color: var(--vorecol-gray-500); }
[data-bs-theme="dark"] kbd { background: var(--vorecol-gray-100); border-color: var(--vorecol-gray-300); color: var(--vorecol-gray-600); }

/* ============================================================
   §31. Responsive
   ============================================================ */
@media (max-width: 991.98px) { .navbar-vertical { border-radius: 0; } .login-split { min-height: auto; } .login-form-panel { padding: 2rem 1rem; } .page-header { padding: 1rem 0; } .page-title { font-size: 1.125rem; } }
@media (max-width: 767.98px) { .topbar-search { display: none; } .brand-tagline { font-size: 1.5rem; } .error-page-code { font-size: 4rem; } .stepper-title { display: none; } }
@media (max-width: 575.98px) { .error-page-container { padding: 1rem; } .card-body { padding: 1rem; } }
@media print { .navbar, aside { display: none !important; } .page-wrapper { margin: 0 !important; } .card { box-shadow: none !important; border: 1px solid #ddd !important; } }

/* ============================================================
   §32. Bootstrap 4 → Bootstrap 5 Compatibility Shims
   ============================================================ */

/* input-group-prepend / input-group-append */
.input-group-prepend, .input-group-append { display: contents; }
.input-group-prepend[class*="select-"], .input-group-append[class*="select-"] { display: flex; flex: 1 1 auto; }
.input-group-prepend[class*="select-"] select, .input-group-append[class*="select-"] select { width: 100%; }

/* Spacing ml-/mr-/pl-/pr- */
.ml-0{margin-left:0!important}.ml-1{margin-left:.25rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:1rem!important}.ml-4{margin-left:1.5rem!important}.ml-5{margin-left:3rem!important}
.mr-0{margin-right:0!important}.mr-1{margin-right:.25rem!important}.mr-2{margin-right:.5rem!important}.mr-3{margin-right:1rem!important}.mr-4{margin-right:1.5rem!important}.mr-5{margin-right:3rem!important}
.pl-0{padding-left:0!important}.pl-1{padding-left:.25rem!important}.pl-2{padding-left:.5rem!important}.pl-3{padding-left:1rem!important}.pl-4{padding-left:1.5rem!important}.pl-5{padding-left:3rem!important}
.pr-0{padding-right:0!important}.pr-1{padding-right:.25rem!important}.pr-2{padding-right:.5rem!important}.pr-3{padding-right:1rem!important}.pr-4{padding-right:1.5rem!important}.pr-5{padding-right:3rem!important}

/* float / text alignment */
.float-left{float:left!important}.float-right{float:right!important}
.text-left{text-align:left!important}.text-right{text-align:right!important}

/* no-gutters / media */
.no-gutters{--bs-gutter-x:0;--bs-gutter-y:0}
.media{display:flex;align-items:flex-start}.media-body{flex:1}

/* custom-select */
.custom-select { display: block; width: 100%; padding: 0.375rem 2.25rem 0.375rem 0.75rem; font-size: 0.875rem; line-height: 1.5; color: var(--bs-body-color); background-color: var(--bs-body-bg); background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 16px 12px; border: 1px solid var(--vorecol-gray-300); border-radius: var(--vorecol-radius-sm); appearance: none; }
.custom-select:focus { border-color: var(--vorecol-primary); box-shadow: 0 0 0 3px rgba(26,103,183,.12); outline: none; }

/* .close (BS4) */
.close { background: transparent; border: 0; padding: 0.5rem; font-size: 1.25rem; font-weight: 700; line-height: 1; color: var(--vorecol-gray-500); opacity: 0.5; cursor: pointer; float: right; }
.close:hover { opacity: 0.75; color: var(--vorecol-gray-700); }

/* badge-pill */
.badge-pill { border-radius: 50rem !important; }

/* Tabler Icons: forzar font-family sobre Themify legacy (carga primero) */
.ti { font-family: "tabler-icons" !important; }

/* input-group-text: inline height:35px rompe stretch de BS5 */
.input-group > .input-group-text { height: auto !important; align-self: stretch !important; }

/* dropdown-item.btn: BS5 centra contenido, forzar alineación izquierda */
.dropdown-menu .dropdown-item.btn { justify-content: flex-start; text-align: left; }

/* img[height]: BS5 tiene img{height:auto} que sobreescribe el atributo HTML */
img[height] { height: revert; }
/* PBI-INDEXA-IMG-DESPROP-001: atributo height con "px" (p.ej. height="13px") es INVÁLIDO en HTML
   → el navegador lo ignora y Tabler (img{height:auto}) infla la imagen (logos a 500px+). Acotamos:
   íconos sueltos a un máximo razonable, y los logos del breadcrumb a 1rem (intención real). */
img[height$="px"] { height: revert; max-height: 1.75rem; width: auto; }
.breadcrumb img { height: 1rem !important; width: auto !important; vertical-align: -0.125em; }
/* .ico_opciones (íconos de opción en encuestas de Compensaciones): PNG natural ~128px. La regla
   .ico_opciones de la página solo da borde, así que img[height]{height:revert} los dejaba a tamaño
   natural (130px). Acotar por la clase (intención ~35px). img.ico_opciones gana a img[height]. */
img.ico_opciones { height: 2.2rem !important; width: auto !important; }

/* badge-* colores (BS4) */
.badge-primary  {background-color:var(--tblr-primary,  #1A67B7)!important;color:#fff!important}
.badge-secondary{background-color:var(--tblr-secondary,#6c757d)!important;color:#fff!important}
.badge-success  {background-color:var(--tblr-success,  #2fb344)!important;color:#fff!important}
.badge-danger   {background-color:var(--tblr-danger,   #d63939)!important;color:#fff!important}
.badge-warning  {background-color:var(--tblr-warning,  #f76707)!important;color:#fff!important}
.badge-info     {background-color:var(--tblr-info,     #4299e1)!important;color:#fff!important}
.badge-light    {background-color:#f8f9fa!important;color:#1e293b!important}
.badge-dark     {background-color:#1e293b!important;color:#fff!important}

/* embed-responsive */
.embed-responsive{position:relative;width:100%}
.embed-responsive::before{display:block;content:""}
.embed-responsive-16by9::before{padding-top:56.25%}
.embed-responsive-4by3::before{padding-top:75%}
.embed-responsive-1by1::before{padding-top:100%}
.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;width:100%;height:100%;border:0}

/* custom-control */
.custom-control{display:flex;align-items:center;gap:.5rem;min-height:1.5rem}
.custom-control-input{flex-shrink:0;width:1rem;height:1rem;accent-color:var(--tblr-primary,#1a67b7);cursor:pointer}
.custom-control-label{cursor:pointer;margin-bottom:0}
.custom-switch .custom-control-input{width:2rem;height:1rem}

/* form-group / sr-only */
.form-group{margin-bottom:1rem}
.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}

/* ============================================================
   §sidebar-collapse-fix
   Prevent the module-selector nav (ul.navbar-nav direct child of
   .navbar-collapse) from flex-growing and pushing module items
   to the bottom when content fits the viewport.
   ============================================================ */
.navbar-vertical .navbar-collapse > .navbar-nav {
  flex-grow: 0 !important;
}

/* ============================================================
   §psicosmart-icon-sizing
   Tabler's  img { height: auto }  overrides HTML height="" attr.
   Restore expected sizes for psicosmart status/indicator images.
   ============================================================ */
/* filter-row status icons */
.td_filtro img {
  height: 25px !important;
  width: auto !important;
}
/* candidate-row status icons rendered by JS (id="avance{id}") */
img[id^="avance"] {
  height: 25px !important;
  width: auto !important;
}
/* warning / misc content icons that use height attr (invalid "px" suffix ignored by browsers) */
img[src*="warn.png"],
img[src*="arrow_rtl.png"] {
  height: 25px !important;
  width: auto !important;
}

/* ============================================================
   §psicosmart-dropdown-icons
   Dropdown action menus: fix oversized icons and left-align.
   height attr "28;" (with semicolon) is invalid HTML → ignored
   by browser → Tabler's height:auto shows at native SVG size.
   ============================================================ */
.dropdown-menu .dropdown-item {
  display: flex !important;
  align-items: center;
}
/* BUG-PSI-EMP-003: respetar el ocultado inline (jQuery .hide() -> style="display: none")
   para que el flex !important de arriba no muestre opciones que el JS oculto. */
.dropdown-menu .dropdown-item[style*="display: none"] {
  display: none !important;
}
.dropdown-menu .dropdown-item img {
  height: 20px !important;
  width: auto !important;
  flex-shrink: 0;
  margin-right: 0.4rem;
}

/* ============================================================
   §scrollbar-mac
   Scrollbar siempre visible en Mac (Safari/Chrome ocultan por defecto).
   Aplica a: offcanvas, sidebar, tablas con overflow, page body.
   ============================================================ */
:root {
  --scrollbar-width: 6px;
  --scrollbar-thumb: rgba(0,0,0,0.22);
  --scrollbar-thumb-hover: rgba(0,0,0,0.42);
}
.offcanvas-body,
.navbar-vertical .navbar-collapse,
.table-responsive,
.page-wrapper {
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb) transparent;
}
.offcanvas-body::-webkit-scrollbar,
.navbar-vertical .navbar-collapse::-webkit-scrollbar,
.table-responsive::-webkit-scrollbar,
.page-wrapper::-webkit-scrollbar {
  width: var(--scrollbar-width);
  height: var(--scrollbar-width);
}
.offcanvas-body::-webkit-scrollbar-track,
.navbar-vertical .navbar-collapse::-webkit-scrollbar-track,
.table-responsive::-webkit-scrollbar-track,
.page-wrapper::-webkit-scrollbar-track {
  background: transparent;
}
.offcanvas-body::-webkit-scrollbar-thumb,
.navbar-vertical .navbar-collapse::-webkit-scrollbar-thumb,
.table-responsive::-webkit-scrollbar-thumb,
.page-wrapper::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: 999px;
}
.offcanvas-body::-webkit-scrollbar-thumb:hover,
.navbar-vertical .navbar-collapse::-webkit-scrollbar-thumb:hover,
.table-responsive::-webkit-scrollbar-thumb:hover,
.page-wrapper::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-thumb-hover);
}
[data-bs-theme="dark"] {
  --scrollbar-thumb: rgba(255,255,255,0.2);
  --scrollbar-thumb-hover: rgba(255,255,255,0.4);
}

/* ============================================================
   §41. Bootstrap Notify z-index fix (temporal — ver §41c para reemplazo)
   Los avisos legacy del sistema (aviso/mensaje/error1) usan bootstrap-notify
   que inyecta <div data-notify="container"> con z-index bajo por default.
   Tapados por offcanvas (1045) / modal (1055). Subir a >1060.
   ============================================================ */
body > [data-notify="container"],
body > .alert[data-notify="container"] {
  z-index: 1070 !important;
}

/* ============================================================
   §41c. Toasts Vorecol (notificaciones modernas — Sonner/Fluent style)
   Reemplaza bootstrap-notify legacy. Ver /app/js/notificaciones_len.js
   Estilo: bordes redondeados, sombra suave, border-left color semántico,
   slide-in desde la derecha en desktop, arriba full-width en mobile.
   ============================================================ */
#vorecol-toast-container {
  z-index: 1080;
  bottom: 0;
  right: 0;
  max-width: 100%;
  pointer-events: none; /* los eventos pasan — el toast individual los captura */
}
#vorecol-toast-container .toast { pointer-events: auto; }

.vorecol-toast {
  min-width: 320px;
  max-width: 400px;
  background: var(--tblr-bg-surface, #fff);
  color: var(--tblr-body-color, #232e3c);
  border: 1px solid var(--tblr-border-color, #e4e6e9);
  border-radius: 0.5rem;
  box-shadow: 0 10px 40px -10px rgba(0, 0, 0, 0.15), 0 4px 12px -4px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  animation: vorecolToastSlideIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
[data-bs-theme="dark"] .vorecol-toast {
  background: #1a2232;
  border-color: rgba(255,255,255,0.08);
}

/* Border-left color por tipo (señal semántica Fluent/Sonner) */
.vorecol-toast-success { border-left: 3px solid var(--tblr-success, #2fb344); }
.vorecol-toast-warning { border-left: 3px solid var(--tblr-warning, #f59f00); }
.vorecol-toast-danger  { border-left: 3px solid var(--tblr-danger,  #d63939); }
.vorecol-toast-info    { border-left: 3px solid var(--tblr-info,    #4299e1); }

.vorecol-toast-icon {
  font-size: 1.25rem;
  line-height: 1.25;
  margin-top: 0.0625rem;
}
.vorecol-toast-content { min-width: 0; }
.vorecol-toast-title {
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1.3;
  margin-bottom: 0.125rem;
}
.vorecol-toast-msg {
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--tblr-secondary, #667080);
  word-wrap: break-word;
}
.vorecol-toast-close {
  font-size: 0.7rem;
  opacity: 0.5;
  transition: opacity 0.15s ease;
  margin-top: 0.125rem;
}
.vorecol-toast-close:hover { opacity: 1; }

@keyframes vorecolToastSlideIn {
  from { transform: translateX(24px); opacity: 0; }
  to   { transform: translateX(0);     opacity: 1; }
}

/* Mobile: toasts arriba full-width (sidebar drawer sale desde la izquierda,
   abajo-derecha puede quedar oculto por otras UI). */
@media (max-width: 575.98px) {
  #vorecol-toast-container {
    top: 0;
    bottom: auto;
    right: 0;
    left: 0;
    padding: 0.75rem !important;
  }
  .vorecol-toast {
    min-width: 0;
    max-width: 100%;
    width: 100%;
  }
  @keyframes vorecolToastSlideIn {
    from { transform: translateY(-16px); opacity: 0; }
    to   { transform: translateY(0);     opacity: 1; }
  }
}

/* ============================================================
   §41a. Tabla "persona+acciones" stack mobile (assign_privileges)
   En mobile (<576px) cada fila se apila verticalmente: usuario arriba,
   acciones debajo alineadas a la derecha. Evita scroll horizontal y
   hace los botones mas tocables. Patron Gmail/LinkedIn/Twitter mobile.
   ============================================================ */
@media (max-width: 575.98px) {
  #tab-cuentas,
  #tab-cuentas tbody,
  #tab-cuentas tr,
  #tab-cuentas td {
    display: block;
    width: 100%;
  }
  #tab-cuentas thead { display: none; }
  #tab-cuentas tr {
    border-bottom: 1px solid var(--tblr-border-color, #e4e6e9);
    padding: 0.75rem 0.5rem;
  }
  #tab-cuentas tr:last-child { border-bottom: 0; }
  #tab-cuentas td {
    border: 0;
    padding: 0.25rem 0;
  }
  /* Acciones alineadas al borde derecho, debajo del usuario */
  #tab-cuentas td.text-end .btn-list {
    justify-content: flex-end !important;
  }
}

/* ============================================================
   §41b. Meta links (email/tel clickeable en listas)
   Gris inherit por default, underline + color primary on hover.
   Patron Gmail / Slack / Intercom: señal clara de interactividad
   sin saturar la tabla con azul fuerte.
   ============================================================ */
.meta-link {
  color: inherit;
  text-decoration: none;
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.meta-link:hover,
.meta-link:focus-visible {
  color: var(--tblr-primary, #1A67B7);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================================================
   §42. Responsive width utilities (faltan en Bootstrap base)
   Necesarios para layouts mobile-first donde w-100 en mobile y
   w-auto en sm+ (ej: card-header con bloques que apilan).
   ============================================================ */
@media (min-width: 576px) {
  .w-sm-auto { width: auto !important; }
  .w-sm-100  { width: 100% !important; }
}
@media (min-width: 768px) {
  .w-md-auto { width: auto !important; }
  .w-md-100  { width: 100% !important; }
}
@media (min-width: 992px) {
  .w-lg-auto { width: auto !important; }
  .w-lg-100  { width: 100% !important; }
}

/* ============================================================
   §21. Row flash highlight (return-from-detail) — shared.
   Al volver de editar un elemento, JS aplica .row-just-edited
   a la fila. Efecto amarillo con border-left que se desvanece.
   Estandar Notion/Linear/Google Sheets. Ver docs/nueva_imagen/19 §21.
   ============================================================ */
@keyframes rowJustEditedFlash {
    0%   { background-color: rgba(250, 204, 21, .35); box-shadow: inset 3px 0 0 var(--tblr-yellow); }
    60%  { background-color: rgba(250, 204, 21, .12); box-shadow: inset 3px 0 0 var(--tblr-yellow); }
    100% { background-color: transparent; box-shadow: inset 3px 0 0 transparent; }
}
.row-just-edited {
    animation: rowJustEditedFlash 2.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

/* ============================================================
   §22. Offcanvas responsive — Fluent-style enterprise standard.
   Ver docs/nueva_imagen/19 §26.
   ============================================================
   Reglas (alineadas a Microsoft Fluent UI <Panel> y Linear side panel):
   1. Footer (sibling de .offcanvas-body) siempre sticky al fondo.
   2. Altura: 100dvh con fallback 100vh (evita problemas con barra dinamica
      de Safari iOS y Chrome Android).
   3. Padding reducido del body en <576px (Fluent narrow).
   4. Scrollbar delgado (ya definido en §scrollbar-mac para offcanvas-body).
   ============================================================ */

/* Altura dinamica para manejar barras de browser mobile */
.offcanvas.offcanvas-end,
.offcanvas.offcanvas-start,
.offcanvas.offcanvas-top,
.offcanvas.offcanvas-bottom {
    height: 100vh;           /* fallback */
    height: 100dvh;          /* navegadores modernos */
}

/* Footer sticky: cualquier div sibling DESPUES de .offcanvas-body
   (patron: border-top + p-3 + bg-body-tertiary). Bootstrap 5 ya usa
   flex-direction:column en .offcanvas, por lo que el sibling queda
   naturalmente al fondo — esta regla refuerza el comportamiento
   agregando sombra sutil y manteniendo estructura aunque el body
   tenga contenido corto. */
.offcanvas > .offcanvas-body {
    flex: 1 1 auto;
    min-height: 0;
}
.offcanvas > .offcanvas-body ~ .border-top {
    position: sticky;
    bottom: 0;
    z-index: 2;
    box-shadow: 0 -2px 8px rgba(0,0,0,0.04);
}

/* Padding reducido en mobile narrow (<576px) */
@media (max-width: 575.98px) {
    .offcanvas-body { padding: 0.75rem; }
    .offcanvas-header { padding: 0.75rem 1rem; }
    .offcanvas > .offcanvas-body ~ .border-top { padding: 0.75rem !important; }
}

/* ============================================================
   §23. Tabla de permisos responsive — cards apiladas en mobile.
   Ver docs/nueva_imagen/19 §26.
   ============================================================
   Patron Microsoft Entra / Google Admin: en <768px cada <tr> se renderiza
   como tarjeta apilada. Requiere que cada <td> tenga atributo data-label
   con el nombre de la columna (se agrega desde JS al generar el HTML).
   Sin data-label igual funciona, solo que no aparecen labels — es fallback
   seguro no rompe nada si se aplica antes del cambio en JS.

   Primer <td> (sin data-label) actua como "titulo" de la card:
   full-width + border-bottom + padding extra. Resto de <td>s apilados
   como "label: control" estilo Fluent Panel.
   ============================================================ */
@media (max-width: 767.98px) {
    /* Reset completo de table-layout: browsers fuerzan display:table-row-group
       en tbody aunque tr tenga display:block — hay que resetear toda la cadena
       para que el flex en td funcione consistente en Safari iOS / Chrome mobile. */
    .perm-table-responsive > table,
    .perm-table-responsive > table > tbody,
    .perm-table-responsive > table > tbody > tr,
    .perm-table-responsive > table > tbody > tr > td {
        display: block !important;
        width: 100% !important;
    }
    .perm-table-responsive > table > thead { display: none !important; }

    /* Cada <tr> = card */
    .perm-table-responsive > table > tbody > tr {
        padding: 0.875rem !important;
        margin-bottom: 0.5rem !important;
        border: 1px solid var(--tblr-border-color, #e6e7e9) !important;
        border-radius: var(--vorecol-radius-sm, 0.5rem) !important;
        background: var(--tblr-bg-surface, #fff) !important;
    }

    /* Cada <td> = fila "label | control" */
    .perm-table-responsive > table > tbody > tr > td {
        display: flex !important;
        align-items: center !important;
        gap: 0.75rem !important;
        padding: 0.4rem 0 !important;
        border: 0 !important;
        text-align: left !important; /* override .text-center Bootstrap */
    }

    /* Label como ::before — absorbe espacio, empuja el control al borde derecho */
    .perm-table-responsive > table > tbody > tr > td::before {
        content: attr(data-label);
        font-weight: 600;
        color: #6c757d;
        font-size: 0.8125rem;
        flex: 1 1 auto;
        text-align: left;
        line-height: 1.3;
    }
    .perm-table-responsive > table > tbody > tr > td:not([data-label])::before {
        content: none !important;
    }

    /* TODO hijo directo del td queda a la derecha, ancho natural, sin margenes.
       Regla amplia (aplica a <input>, <button>, <select>, <div> de controles). */
    .perm-table-responsive > table > tbody > tr > td > * {
        flex: 0 0 auto !important;
        margin: 0 !important;
    }

    /* Primer <td> sin data-label = card title (full-width, sin ::before) */
    .perm-table-responsive > table > tbody > tr > td:first-child:not([data-label]) {
        padding: 0 0 0.625rem 0 !important;
        margin-bottom: 0.625rem !important;
        border-bottom: 1px solid var(--tblr-border-color, #e6e7e9) !important;
    }
    .perm-table-responsive > table > tbody > tr > td:first-child:not([data-label]) > * {
        flex: 1 1 auto !important;
        min-width: 0;
    }
}

/* ============================================================
   §24. Scroll-shadow en .table-responsive — hint visual de overflow.
   Ver docs/nueva_imagen/19 §27.
   ============================================================
   Problema: en iOS Safari y Chrome Android el scrollbar nativo se oculta,
   usuario no sabe que hay mas contenido a la derecha. Patron clasico Lea
   Verou con background-attachment: local + scroll para gradientes que
   aparecen/desaparecen segun posicion de scroll:

   - Al inicio: sombra derecha visible (hay mas →)
   - Mitad: ambas sombras visibles
   - Al final: sombra izquierda visible (hay mas ←)
   - Sin overflow: ninguna sombra

   Excluye .perm-table-responsive (esas se convierten a cards, no scrollean).
   ============================================================ */
.table-responsive:not(.perm-table-responsive) {
    background:
        /* Cobertor blanco local (scrollea con contenido) — tapa sombra izq al inicio */
        linear-gradient(to right, var(--tblr-bg-surface, #fff) 30%, transparent) 0 center / 40px 100% no-repeat local,
        /* Cobertor blanco local — tapa sombra der al final */
        linear-gradient(to left, var(--tblr-bg-surface, #fff) 30%, transparent) 100% center / 40px 100% no-repeat local,
        /* Sombra izquierda fija (visible cuando scrolleado a derecha) */
        radial-gradient(ellipse farthest-side at 0% 50%, rgba(0,0,0,0.20), transparent) 0 center / 18px 100% no-repeat scroll,
        /* Sombra derecha fija (visible al inicio, desaparece al final) */
        radial-gradient(ellipse farthest-side at 100% 50%, rgba(0,0,0,0.20), transparent) 100% center / 18px 100% no-repeat scroll;
    background-color: var(--tblr-bg-surface, #fff);
}

/* ============================================================
   §25. Select2 inside Bootstrap input-group — integration fix.
   Ver docs/nueva_imagen/19 §28.
   ============================================================
   Problema: Select2 reemplaza el <select> con un <div.select2-container>.
   Ese div no hereda el flex:1 que Bootstrap asigna a .form-select dentro
   de .input-group. Resultado: ancho incorrecto, bordes cortados, altura
   desalineada con el icono .input-group-text.

   Fix: tratar el select2-container como un flex item valido, alinear
   altura con .form-control, quitar border-radius izquierdo (la
   .input-group-text de la izquierda ya lo provee). */
.input-group > .select2-container {
    /* flex: 1 1 0% con min-width:0 permite que Select2 tome todo el espacio
       sobrante del input-group sin depender del option width:'100%' del JS
       init. Antes quedaba con ancho minimo cuando el init no lo especificaba
       (ver filtros de employees.php). */
    flex: 1 1 0% !important;
    min-width: 0 !important;
    width: 100% !important;
}
.input-group > .select2-container .select2-selection--single {
    height: calc(2.3125rem + 2px) !important;
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
    border-color: var(--tblr-border-color, #dadcde);
    background: var(--tblr-bg-forms, #fff);
}
.input-group > .select2-container .select2-selection--single .select2-selection__rendered {
    line-height: calc(2.3125rem + 2px) !important;
    padding-left: 0.75rem;
    padding-right: 1.75rem;
    color: var(--tblr-body-color, #1e293b);
}
.input-group > .select2-container .select2-selection--single .select2-selection__arrow {
    height: calc(2.3125rem + 2px) !important;
}
/* Dark mode: Select2 usa bg y border claros por default — fuerza dark */
[data-bs-theme="dark"] .input-group > .select2-container .select2-selection--single,
[data-bs-theme="dark"] .select2-dropdown {
    background: var(--tblr-bg-forms, #1e293b) !important;
    border-color: var(--tblr-border-color, #344358) !important;
    color: var(--tblr-body-color, #e5e7eb) !important;
}
[data-bs-theme="dark"] .select2-selection__rendered,
[data-bs-theme="dark"] .select2-results__option {
    color: var(--tblr-body-color, #e5e7eb) !important;
}

/* PBI-GEN-SUPERVISORS-SELECT-MODAL-001: el dropdown de Select2 trae z-index:1051
   (select2-4.0.13.css) y queda DETRÁS de los modales BS5 (z-index 1055) que genera el
   shim vorecol-dialog → las opciones se ven tapadas (caso: "Reporta a" en gen/supervisors).
   Lo subimos a 1060: por ENCIMA del modal/offcanvas (1055/1045) y por DEBAJO de
   toasts/notify (1070-1080) para no tapar avisos. Fix GLOBAL — cubre cualquier select2
   dentro de un modal del shim en todos los módulos, sin tocar JS. Selector con doble clase
   (--open) para ganar especificidad sobre el 1051 del plugin. */
.select2-container--open .select2-dropdown {
    z-index: 1060;
}

/* Responsive de diálogos del shim (vorecol-dialog: .dialog → modal BS5). El shim pone
   `width:Xpx` inline en el .modal-dialog (ej. 450px). En móvil ese ancho fijo desborda el
   viewport y deja la X de cerrar fuera de pantalla → el modal "no se puede cerrar". En pantallas
   chicas, cap al viewport para que el modal quepa y la X sea alcanzable. (PBI-EMP-MODAL-RESP-001) */
@media (max-width: 767.98px) {
    .modal-dialog[style*="width"] { width: auto !important; max-width: calc(100vw - 1rem) !important; }
}

/* ============================================================
   §37. VorecolFileUpload — Drop zone reusable (Tabler style).
   Usado por carga_logo.js (upload_logo) y potencialmente otros
   uploads single/multi-file. Ver docs/nueva_imagen/19 §19, §30.
   ============================================================ */
.file-upload-zone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 2.5rem 2rem;
    min-height: 240px;
    border: 2px dashed var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
    background-color: var(--tblr-bg-surface-secondary);
    cursor: pointer;
    user-select: none;
    text-align: center;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}
.file-upload-zone:hover,
.file-upload-zone.dragover {
    border-color: var(--tblr-primary);
    background-color: var(--tblr-primary-lt);
}
.file-upload-zone.dragover { transform: scale(1.01); }
.file-upload-zone input[type="file"] {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    opacity: 0; cursor: pointer; z-index: 1;
}
.file-upload-icon {
    font-size: 3rem; line-height: 1;
    color: var(--tblr-primary);
    margin-bottom: .75rem;
}
.file-upload-title {
    font-size: 1.0625rem; font-weight: 600;
    color: var(--tblr-body-color);
    margin-bottom: .25rem;
}
.file-upload-text {
    font-size: .875rem;
    color: var(--tblr-secondary);
    margin-bottom: 1rem;
}
.file-upload-text .link {
    color: var(--tblr-primary);
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 2px;
    /* NO z-index: dejar que el <input> absoluto (z-index:1) capture clicks.
       Si le damos z-index mayor al link, bloquea el click al input y abre
       nada (el span no es label). Estetica se preserva igual. */
}
.file-upload-formats {
    display: flex; flex-wrap: wrap; gap: .375rem;
    justify-content: center; margin-top: .25rem;
    /* Mismo motivo que .link: sin z-index para no interceptar clicks */
}
.file-upload-formats > span {
    display: inline-flex; align-items: center;
    padding: .125rem .5rem;
    font-size: .6875rem; font-weight: 600;
    letter-spacing: .03em;
    color: var(--tblr-secondary);
    background-color: var(--tblr-bg-surface);
    border: 1px solid var(--tblr-border-color);
    border-radius: 4px;
    text-transform: uppercase;
}
.file-preview-list {
    display: flex; flex-direction: column; gap: .5rem;
    margin-top: 1rem;
}
.file-preview-list:empty { margin-top: 0; }
.file-preview-item {
    display: flex; align-items: center; gap: .75rem;
    padding: .75rem;
    background: var(--tblr-bg-surface);
    border: 1px solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
}
.file-preview-icon {
    flex-shrink: 0;
    width: 40px; height: 40px;
    border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.125rem;
}
.file-preview-info { flex: 1; min-width: 0; }
.file-preview-name {
    font-weight: 500; font-size: .875rem;
    color: var(--tblr-body-color);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.file-preview-size {
    font-size: .75rem;
    color: var(--tblr-secondary);
    margin-top: 2px;
}
.file-preview-progress {
    height: 4px;
    background: var(--tblr-bg-surface-secondary);
    border-radius: 2px; overflow: hidden;
    margin-top: .5rem;
}
.file-preview-progress-bar {
    height: 100%;
    background: var(--tblr-primary);
    transition: width .2s ease;
}
.file-preview-actions {
    flex-shrink: 0;
    display: flex; gap: .25rem;
}

/* ============================================================
   §26. Popover Vorecol — estilo para badges clickables con breakdown.
   Ver docs/nueva_imagen/19 §30.
   ============================================================
   Usado por badges interactivos con Bootstrap 5 Popover (customClass:
   'popover-vorecol'). Pattern Linear/GitHub para "click-to-drill" en
   una celda de tabla — resumen visible, detalle en popover.
   ============================================================ */
.popover.popover-vorecol {
    --bs-popover-max-width: 320px;
    --bs-popover-border-radius: var(--vorecol-radius-sm);
    --bs-popover-box-shadow: var(--vorecol-shadow-lg);
    --bs-popover-header-font-size: 0.875rem;
    --bs-popover-header-padding-y: 0.625rem;
    --bs-popover-body-padding-y: 0.625rem;
    border: 1px solid var(--tblr-border-color, #e6e7e9);
}
.popover.popover-vorecol .popover-header {
    background: var(--tblr-bg-surface, #fff);
    font-weight: 600;
    border-bottom: 1px solid var(--tblr-border-color, #e6e7e9);
}
.popover.popover-vorecol .popover-body {
    color: var(--tblr-body-color);
}
.popover.popover-vorecol .popover-body .badge {
    font-size: 0.75rem;
}
/* En mobile: cuerpo del popover se adapta al ancho del viewport */
@media (max-width: 575.98px) {
    .popover.popover-vorecol {
        --bs-popover-max-width: min(320px, calc(100vw - 2rem));
    }
}
/* Dark mode: el popover default de Bootstrap queda claro sobre dark bg.
   Forzar tokens de Tabler dark. */
[data-bs-theme="dark"] .popover.popover-vorecol {
    --bs-popover-bg: var(--tblr-bg-surface, #1e293b);
    border-color: var(--tblr-border-color, #344358);
}
[data-bs-theme="dark"] .popover.popover-vorecol .popover-header {
    background: var(--tblr-bg-surface, #1e293b);
    color: var(--tblr-body-color, #e5e7eb);
    border-bottom-color: var(--tblr-border-color, #344358);
}
/* Badges clickables con popover: cursor pointer + hover sutil */
.badge[data-popover="1"] {
    transition: transform .1s ease, box-shadow .1s ease;
}
.badge[data-popover="1"]:hover,
.badge[data-popover="1"]:focus-visible {
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0,0,0,.08);
    outline: none;
}

/* ======================================================================
   §33 (doc decisiones) — Entity pill + toast de cambio de entidad.
   Patron: BambooHR / Rippling / Linear (pill) + Workday (auto-hide topbar).
   Ver docs/nueva_imagen/19_decisiones_ui_componentes.md §33.
   ====================================================================== */

/* Pill en page-header — estilo BambooHR/Rippling: aire, tipografia limpia, sin ruido. */
.vorecol-entity-pill {
    margin-left: 0.25rem;
}
.vorecol-entity-pill .btn-pill-entity {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 260px;
    background: rgba(var(--tblr-azure-rgb, 74 144 226), 0.08);
    border: 1px solid rgba(var(--tblr-azure-rgb, 74 144 226), 0.22);
    color: var(--tblr-azure, #4a90e2);
    font-size: 0.82rem;
    font-weight: 500;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    line-height: 1.1;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0,0,0,.03);
    transition: background-color .15s ease, border-color .15s ease, transform .1s ease, box-shadow .15s ease;
}
.vorecol-entity-pill .btn-pill-entity:hover,
.vorecol-entity-pill .btn-pill-entity:focus-visible {
    background: rgba(var(--tblr-azure-rgb, 74 144 226), 0.14);
    border-color: rgba(var(--tblr-azure-rgb, 74 144 226), 0.40);
    box-shadow: 0 2px 6px rgba(var(--tblr-azure-rgb, 74 144 226), 0.14);
    outline: none;
}
.vorecol-entity-pill .btn-pill-entity:active {
    transform: scale(0.97);
}
.vorecol-entity-pill .btn-pill-entity[aria-expanded="true"] {
    background: rgba(var(--tblr-azure-rgb, 74 144 226), 0.16);
    border-color: rgba(var(--tblr-azure-rgb, 74 144 226), 0.50);
}
.vorecol-entity-pill .btn-pill-entity::after { display: none; }
.vorecol-entity-pill .pill-icon {
    font-size: 1rem;
    flex-shrink: 0;
    opacity: 0.85;
}
.vorecol-entity-pill .pill-label {
    max-width: 180px;
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.vorecol-entity-pill .pill-caret {
    font-size: 0.85rem;
    opacity: 0.6;
    transition: transform .15s ease;
    flex-shrink: 0;
}
.vorecol-entity-pill .btn-pill-entity[aria-expanded="true"] .pill-caret {
    transform: rotate(180deg);
}

.vorecol-entity-pill .dropdown-menu {
    min-width: 260px;
    max-width: 340px;
    padding: 0.35rem 0;
    border: 1px solid var(--tblr-border-color, #e0e6ed);
    box-shadow: 0 8px 24px rgba(0,0,0,.10), 0 2px 6px rgba(0,0,0,.05);
}
.vorecol-entity-pill .dropdown-header {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--tblr-secondary, #626976);
    letter-spacing: 0.02em;
    padding: 0.4rem 0.9rem;
}
.vorecol-entity-pill .dropdown-item {
    padding: 0.5rem 0.9rem;
    font-size: 0.85rem;
    transition: background-color .1s ease;
}
.vorecol-entity-pill .dropdown-item .ti-building-community {
    opacity: 0.55;
    font-size: 1rem;
}
.vorecol-entity-pill .dropdown-item.active,
.vorecol-entity-pill .dropdown-item.active:focus,
.vorecol-entity-pill .dropdown-item.active:hover {
    background-color: rgba(var(--tblr-azure-rgb, 74 144 226), 0.10);
    color: var(--tblr-azure, #4a90e2);
    font-weight: 600;
}
.vorecol-entity-pill .dropdown-item.active .ti-building-community {
    opacity: 1;
}

/* Dark mode tweaks */
[data-bs-theme="dark"] .vorecol-entity-pill .btn-pill-entity {
    background: rgba(var(--tblr-azure-rgb, 74 144 226), 0.18);
    border-color: rgba(var(--tblr-azure-rgb, 74 144 226), 0.35);
    color: #7cb7ff;
}

/* Variante compacta (breadcrumb-style en page-pretitle). Patron Linear/Stripe. */
#vorecol-entity-pill .pill-divider {
    color: var(--tblr-secondary, #94a3b8);
    opacity: 0.55;
    font-weight: 600;
    margin: 0 0.15rem;
    user-select: none;
}
.vorecol-entity-pill--sm {
    margin-left: 0 !important;
    vertical-align: baseline;
}
.vorecol-entity-pill--sm .btn-pill-entity {
    padding: 0.2rem 0.65rem;
    font-size: 0.75rem;
    gap: 0.35rem;
    max-width: 220px;
    line-height: 1.15;
    background: rgba(var(--tblr-azure-rgb, 74 144 226), 0.08);
    border-color: transparent;
    box-shadow: none;
}
.vorecol-entity-pill--sm .btn-pill-entity:hover,
.vorecol-entity-pill--sm .btn-pill-entity:focus-visible {
    background: rgba(var(--tblr-azure-rgb, 74 144 226), 0.16);
    border-color: rgba(var(--tblr-azure-rgb, 74 144 226), 0.30);
    box-shadow: none;
}
.vorecol-entity-pill--sm .pill-icon { font-size: 0.85rem; }
.vorecol-entity-pill--sm .pill-caret { font-size: 0.8rem; }
.vorecol-entity-pill--sm .pill-label { max-width: 150px; }

/* Toast de cambio de entidad (estilo Sonner / Fluent, esquina inferior derecha) */
.toast-vorecol-entity {
    position: fixed;
    right: 1.25rem;
    bottom: 1.25rem;
    z-index: 2060;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 280px;
    max-width: 360px;
    padding: 0.75rem 1rem;
    background: #fff;
    border: 1px solid var(--tblr-border-color, #e0e6ed);
    border-left: 4px solid var(--tblr-green, #2fb344);
    border-radius: 0.6rem;
    box-shadow: 0 10px 28px rgba(0,0,0,.10), 0 2px 6px rgba(0,0,0,.06);
    font-size: 0.875rem;
    color: var(--tblr-body-color, #1e293b);
    transform: translateY(10px);
    opacity: 0;
    animation: toastEntityIn .28s cubic-bezier(.2,.9,.3,1.2) forwards;
}
.toast-vorecol-entity.hiding {
    animation: toastEntityOut .22s ease forwards;
}
.toast-vorecol-entity .toast-entity-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(var(--tblr-green-rgb, 47 179 68), 0.14);
    color: var(--tblr-green, #2fb344);
    font-size: 1rem;
}
.toast-vorecol-entity .toast-entity-body { flex: 1; min-width: 0; }
.toast-vorecol-entity .toast-entity-title {
    font-weight: 600;
    font-size: 0.78rem;
    color: var(--tblr-secondary, #626976);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    line-height: 1.2;
    margin-bottom: 2px;
}
.toast-vorecol-entity .toast-entity-text {
    line-height: 1.35;
}
[data-bs-theme="dark"] .toast-vorecol-entity {
    background: #1e293b;
    border-color: #334155;
    color: #e2e8f0;
}

@keyframes toastEntityIn {
    to { transform: translateY(0); opacity: 1; }
}
@keyframes toastEntityOut {
    to { transform: translateY(10px); opacity: 0; }
}

@media (max-width: 575.98px) {
    .toast-vorecol-entity {
        left: 1rem;
        right: 1rem;
        bottom: 1rem;
        min-width: 0;
        max-width: none;
    }
    .vorecol-entity-pill .pill-label { max-width: 110px; }
}

/* ============================================================
   Botones "disabled con razon" — click muestra aviso en vez de actuar.
   Patron BambooHR / Linear: cuando una accion esta bloqueada,
   el boton se ve deshabilitado pero al hacer click dispara un
   toast/aviso explicando la razon. Imprescindible en mobile
   donde no hay hover para ver el tooltip.
   Override del .disabled de Bootstrap (que pone pointer-events:none
   y bloquea el click handler).
   ============================================================ */
.btn.disabled[data-disabled-reason],
.btn.disabled-with-reason {
    pointer-events: auto !important;
    cursor: not-allowed;
}

/* ============================================================
   Responsive stack table — tabla con thead se transforma en "cards"
   en mobile (<768px). Patron estandar BS5/Tabler/MDN responsive tables.
   Cada <td> debe tener data-label="Nombre columna" — se usa como
   prefijo visible en mobile. Desktop ignora el data-label.

   Quien lo usa:
   - BambooHR mobile (Employees -> cards apiladas)
   - Workday mobile (reports -> stacked)
   - GitHub Actions mobile (runs -> card por fila)
   - MDN responsive tables (referencia pedagogica)

   Uso: agregar clase .table-responsive-stack a la <table>, y data-label
   a cada <td>. La fila de empty state (class="xym") queda intacta
   (colspan la pone full-width sin label prefix).
   ============================================================ */
@media (max-width: 767.98px) {
    /* Forzar block layout en TODA la jerarquia table — sin esto, HTML sigue
       tratando <tbody>/<tr>/<td> como tabla y los anchos quedan colapsados. */
    .table-responsive-stack,
    .table-responsive-stack tbody,
    .table-responsive-stack tbody tr,
    .table-responsive-stack tbody td {
        display: block !important;
        width: 100% !important;
    }
    .table-responsive-stack thead { display: none !important; }

    .table-responsive-stack tbody tr {
        margin-bottom: 0.75rem;
        padding: 0.75rem;
        border: 1px solid var(--tblr-border-color, rgba(0,0,0,0.08));
        border-radius: 0.5rem;
        background: var(--tblr-card-bg, #fff);
    }

    /* Empty state: NO aplicar el block-stack (se ve como mensaje centrado). */
    .table-responsive-stack tbody tr.xym {
        display: block !important;
        padding: 0;
        border: none;
        margin-bottom: 0;
        background: transparent;
    }
    .table-responsive-stack tbody tr.xym td {
        display: block !important;
        padding: 0;
        border: none;
        text-align: center;
    }
    .table-responsive-stack tbody tr.xym td::before { content: none; }

    /* Cada celda = label arriba (pequeno, gris) + valor abajo.
       Patron BambooHR / GitHub / Notion mobile cuando los valores son largos
       (usuario + correo + telefono). Evita que label y valor peleen por ancho
       cuando se desborda — se apilan verticalmente con jerarquia clara. */
    .table-responsive-stack tbody td {
        display: block !important;
        padding: 0.25rem 0 !important;
        border: none !important;
        text-align: left !important;
        min-height: unset;
    }
    .table-responsive-stack tbody td::before {
        content: attr(data-label);
        display: block;
        font-weight: 600;
        color: var(--tblr-secondary, #6c757d);
        font-size: 0.75rem;
        margin-bottom: 0.125rem;
        text-transform: uppercase;
        letter-spacing: 0.02em;
        line-height: 1.2;
    }
    /* Opciones en mobile: alineadas a la izquierda para respetar el flujo stack */
    .table-responsive-stack tbody td.text-end {
        text-align: left !important;
    }
    .table-responsive-stack tbody td.text-end .btn-list {
        justify-content: flex-start !important;
    }
    /* Si el data-label es vacio o es "#", no mostrar prefijo "Contenido: " */
    .table-responsive-stack tbody td:not([data-label])::before,
    .table-responsive-stack tbody td[data-label=""]::before {
        content: none;
    }
    /* Columna # en mobile: menos prominente */
    .table-responsive-stack tbody td[data-label="#"] {
        color: var(--tblr-secondary, #6c757d);
        font-size: 0.75rem;
        padding-bottom: 0.25rem !important;
    }
    /* Dark mode: cards con fondo sutil del tema */
    [data-bs-theme="dark"] .table-responsive-stack tbody tr {
        background: var(--tblr-bg-surface-secondary, #1a1f2e);
        border-color: var(--tblr-border-color, rgba(255,255,255,0.1));
    }
}

/* ============================================================ */
/* §LEGACY-DIALOG-SHIM — Overrides para markup BS3/HTML4 dentro */
/* del modal de vorecol-dialog.js. Aplica solo dentro de        */
/* .ui-dialog para no afectar otras partes del HRMS.            */
/* ============================================================ */

/* Bootstrap 3 .well → look Tabler card-body */
.ui-dialog .well {
    background: var(--tblr-bg-surface-secondary, #f7f8fa);
    border: 1px solid var(--tblr-border-color, #e6e7e9);
    border-radius: 4px;
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
    box-shadow: none;
}
[data-bs-theme="dark"] .ui-dialog .well {
    background: var(--tblr-bg-surface-secondary, #1a1f2e);
    border-color: var(--tblr-border-color, rgba(255,255,255,0.1));
}

/* Bootstrap 3 .panel → look Tabler card */
.ui-dialog .panel,
.ui-dialog .panel-default {
    background: var(--tblr-bg-surface, #fff);
    border: 1px solid var(--tblr-border-color, #e6e7e9);
    border-radius: 4px;
    margin-bottom: 1rem;
    box-shadow: none;
}
.ui-dialog .panel-heading {
    background: var(--tblr-bg-surface-secondary, #f7f8fa);
    border-bottom: 1px solid var(--tblr-border-color, #e6e7e9);
    padding: 0.625rem 1rem;
    border-radius: 4px 4px 0 0;
    font-weight: 600;
    font-size: 0.875rem;
    color: inherit;
}
.ui-dialog .panel-body { padding: 0.875rem 1rem; }
.ui-dialog .panel-footer {
    background: var(--tblr-bg-surface-secondary, #f7f8fa);
    border-top: 1px solid var(--tblr-border-color, #e6e7e9);
    padding: 0.5rem 1rem;
    border-radius: 0 0 4px 4px;
    font-size: 0.875rem;
}
[data-bs-theme="dark"] .ui-dialog .panel,
[data-bs-theme="dark"] .ui-dialog .panel-default {
    background: var(--tblr-bg-surface, #1a1f2e);
    border-color: var(--tblr-border-color, rgba(255,255,255,0.1));
}
[data-bs-theme="dark"] .ui-dialog .panel-heading,
[data-bs-theme="dark"] .ui-dialog .panel-footer {
    background: var(--tblr-bg-surface-secondary, #131724);
}

/* HTML4 <font> — neutralizar size/color forzados, mapear size legacy */
.ui-dialog font[size] { font-size: inherit !important; }
.ui-dialog font[size="1"] { font-size: 0.7rem !important; }
.ui-dialog font[size="2"] { font-size: 0.875rem !important; }
.ui-dialog font[size="3"] { font-size: 1rem !important; }
.ui-dialog font[size="4"] { font-size: 1.125rem !important; }
.ui-dialog font[size="5"] { font-size: 1.25rem !important; font-weight: 600; }
.ui-dialog font[size="6"] { font-size: 1.5rem !important; font-weight: 600; }
.ui-dialog font[face] { font-family: inherit !important; }

/* HTML4 <center> */
.ui-dialog center {
    display: block;
    text-align: center;
    margin: 0.5rem 0;
}

/* Atributos align="..." (HTML4) */
.ui-dialog [align="center"] { text-align: center; }
.ui-dialog [align="right"]  { text-align: right; }
.ui-dialog [align="left"]   { text-align: left; }

/* Tablas legacy con border="N" cellspacing/cellpadding */
.ui-dialog table[border] {
    border-collapse: collapse;
    width: 100%;
    margin: 0.5rem 0;
    font-size: 0.875rem;
}
.ui-dialog table[border="0"] td,
.ui-dialog table[border="0"] th { border: 0; }
.ui-dialog table[border="1"] {
    border: 1px solid var(--tblr-border-color, #e6e7e9) !important;
}
.ui-dialog table[border="1"] td,
.ui-dialog table[border="1"] th {
    border: 1px solid var(--tblr-border-color, #e6e7e9);
    padding: 0.4rem 0.6rem;
}
.ui-dialog table[border="1"] th {
    background: var(--tblr-bg-surface-secondary, #f7f8fa);
    font-weight: 600;
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
[data-bs-theme="dark"] .ui-dialog table[border="1"] th {
    background: var(--tblr-bg-surface-secondary, #131724);
}

/* hr legacy */
.ui-dialog hr {
    border: 0;
    border-top: 1px solid var(--tblr-border-color, #e6e7e9);
    margin: 0.875rem 0;
    height: 0;
}

/* <b>/<strong> dentro del body */
.ui-dialog .modal-body b,
.ui-dialog .modal-body strong { font-weight: 600; }

/* Inputs/forms sin clases BS5 — sanitización mínima */
.ui-dialog input[type="text"]:not(.form-control):not(.form-select),
.ui-dialog input[type="email"]:not(.form-control):not(.form-select),
.ui-dialog input[type="password"]:not(.form-control):not(.form-select),
.ui-dialog input[type="number"]:not(.form-control):not(.form-select),
.ui-dialog input[type="tel"]:not(.form-control):not(.form-select),
.ui-dialog input[type="url"]:not(.form-control):not(.form-select),
.ui-dialog input[type="date"]:not(.form-control):not(.form-select),
.ui-dialog input[type="datetime-local"]:not(.form-control):not(.form-select),
.ui-dialog textarea:not(.form-control),
.ui-dialog select:not(.form-control):not(.form-select) {
    display: inline-block;
    width: auto;
    min-width: 200px;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--tblr-border-color, #e6e7e9);
    border-radius: 4px;
    background: var(--tblr-bg-surface, #fff);
    color: inherit;
    font-size: 0.875rem;
    line-height: 1.4;
    box-sizing: border-box;
}
.ui-dialog input[type="text"]:not(.form-control):focus,
.ui-dialog input[type="email"]:not(.form-control):focus,
.ui-dialog input[type="password"]:not(.form-control):focus,
.ui-dialog input[type="number"]:not(.form-control):focus,
.ui-dialog input[type="tel"]:not(.form-control):focus,
.ui-dialog textarea:not(.form-control):focus,
.ui-dialog select:not(.form-control):focus {
    border-color: var(--tblr-primary, #206bc4);
    outline: 0;
    box-shadow: 0 0 0 3px rgba(32, 107, 196, 0.1);
}
[data-bs-theme="dark"] .ui-dialog input:not(.form-control),
[data-bs-theme="dark"] .ui-dialog textarea:not(.form-control),
[data-bs-theme="dark"] .ui-dialog select:not(.form-control) {
    background: var(--tblr-bg-surface, #1a1f2e);
    border-color: var(--tblr-border-color, rgba(255,255,255,0.15));
}

/* <p>/párrafos y listas dentro del modal-body — espaciado consistente */
.ui-dialog .modal-body > p:first-child { margin-top: 0; }
.ui-dialog .modal-body > p:last-child { margin-bottom: 0; }
.ui-dialog .modal-body ul,
.ui-dialog .modal-body ol {
    padding-left: 1.5rem;
    margin: 0.5rem 0;
}
.ui-dialog .modal-body li { margin-bottom: 0.25rem; }

/* ============================================================
 * PBI-LIBS-005-PSI v18 — DESIGN.md §28: marcador visual de campo obligatorio.
 * Cualquier label con clase .required muestra " *" rojo después del texto.
 * Uso: <label class="form-label required">Nombre</label>
 * ============================================================ */
label.required::after,
.form-label.required::after {
    content: " *";
    color: var(--tblr-danger, #d63939);
    font-weight: 700;
    margin-left: 2px;
}

/* ============================================================
 * PBI-LIBS-005-PSI v18 — offcanvas-footer (Tabler no la trae built-in).
 * Sticky bottom + border-top + padding consistente con offcanvas-header.
 * Usado por vorecol-dialog.js v4 cuando .dialog() se renderiza como offcanvas.
 * ============================================================ */
.offcanvas-footer {
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--tblr-border-color, #e6e7e9);
    background: var(--tblr-bg-surface, #fff);
    flex-shrink: 0;
}
.offcanvas-footer .ui-dialog-buttonset {
    margin: 0;
}

/* ============================================================
 * §19 — MÓVIL: el footer de modales/offcanvas BS5 NATIVOS apila los botones a
 * TODO EL ANCHO (en vez de fila apretada). Los diálogos del shim (vorecol-dialog)
 * ya lo hacen en jquery-ui-dialog-bridge.css; aquí cubrimos los modales/offcanvas
 * escritos a mano. Scoped a los botones DIRECTOS del footer (y .btn-list/.btn-group)
 * para NO afectar el contenido del cuerpo ni los botones del shim (anidados en
 * .ui-dialog-buttonset). PBI-PSICO-ADMINEVAL-MOVIL-ACCESO-001.
 * ============================================================ */
@media (max-width: 575.98px) {
    .modal-footer,
    .offcanvas-footer {
        flex-direction: column;
        align-items: stretch;
    }
    .modal-footer > .btn,
    .modal-footer > .btn-group,
    .offcanvas-footer > .btn,
    .offcanvas-footer > .btn-group {
        width: 100%;
        margin-left: 0;
        margin-right: 0;
    }
    .modal-footer > .btn-list,
    .offcanvas-footer > .btn-list {
        width: 100%;
        flex-direction: column;
        align-items: stretch;
    }
    .modal-footer > .btn-list > .btn,
    .offcanvas-footer > .btn-list > .btn {
        width: 100%;
    }
}

/* ============================================================
 * PBI-LIBS-005-PSI v4.9 — override jquery-ui.css para offcanvas/modal
 * vorecol-dialog.js agrega .ui-dialog al wrapper para compat legacy
 * (closest('.ui-dialog')). jquery-ui.css define
 * .ui-dialog { position:absolute; left:0; top:0; } y pisa el
 * posicionamiento de BS5. Sin overrides el offcanvas-end se ve a la
 * izquierda (left:0) en vez de la derecha. ROOT CAUSE del bug v4.1-v4.8.
 * ============================================================ */
.offcanvas.ui-dialog {
    position: fixed !important;
    top: 0 !important;
    padding: 0 !important;
    outline: 0 !important;
}
.offcanvas.offcanvas-end.ui-dialog {
    left: auto !important;
    right: 0 !important;
}
.offcanvas.offcanvas-start.ui-dialog {
    left: 0 !important;
    right: auto !important;
}
.modal.ui-dialog {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    padding: 0 !important;
    outline: 0 !important;
}

/* ============================================================
   §28. xdsoft_datetimepicker — restyle moderno con paleta Tabler.
   ============================================================
   El plugin jquery.datetimepicker viene con un look 2014 (bordes grises,
   degradados, hover negro). Re-skin sin tocar el CSS del plugin: solo
   sobreescribimos las clases .xdsoft_* aprovechando que la calc del
   plugin pone el picker en `position:fixed` con z-index alto.

   Paleta: --tblr-primary, --tblr-bg-surface, --tblr-border-color,
            --tblr-body-color, --tblr-secondary, --tblr-danger.
   ============================================================ */
.xdsoft_datetimepicker {
    background: var(--tblr-bg-surface, #fff) !important;
    border: 1px solid var(--tblr-border-color, #e6e7e9) !important;
    border-radius: 12px !important;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .14),
                0 4px 12px rgba(15, 23, 42, .08) !important;
    padding: 12px !important;
    font-family: inherit !important;
    color: var(--tblr-body-color, #1e293b) !important;
    z-index: 1080 !important;
    /* Tamaño compacto: el plugin computa width inline; nosotros lo forzamos
       a un ancho fijo cómodo (7 cols × ~36px + padding + scroll). */
    width: 308px !important;
    box-sizing: border-box !important;
}
/* Si timepicker:true → el plugin agrega .xdsoft_timepicker.active y necesita
   más ancho para acomodarlo a la derecha del calendario. */
.xdsoft_datetimepicker:has(> .xdsoft_timepicker.active) {
    width: 388px !important;
}
/* Mantener el layout original del plugin (float) — no metemos flex porque
   el contenedor es `position:fixed` y no tiene ancho intrínseco. */
.xdsoft_datetimepicker > .xdsoft_datepicker {
    width: 100% !important;
    margin: 0 !important;
}
.xdsoft_datetimepicker:has(> .xdsoft_timepicker.active) > .xdsoft_datepicker {
    width: calc(100% - 80px) !important;
}
.xdsoft_datetimepicker > .xdsoft_timepicker.active {
    width: 72px !important;
}
.xdsoft_datetimepicker .xdsoft_mounthpicker,
.xdsoft_datetimepicker .xdsoft_monthpicker {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}
/* Botones de navegación prev/next/today — convertir en chevrones modernos */
.xdsoft_datetimepicker .xdsoft_prev,
.xdsoft_datetimepicker .xdsoft_next,
.xdsoft_datetimepicker .xdsoft_today_button {
    background: transparent !important;
    border: 1px solid transparent !important;
    border-radius: 8px !important;
    width: 32px !important;
    height: 32px !important;
    opacity: 1 !important;
    position: relative !important;
    margin: 0 !important;
    float: none !important;
    transition: background-color .15s ease, border-color .15s ease;
}
.xdsoft_datetimepicker .xdsoft_prev:hover,
.xdsoft_datetimepicker .xdsoft_next:hover,
.xdsoft_datetimepicker .xdsoft_today_button:hover {
    background: var(--tblr-bg-surface-secondary, #f6f8fb) !important;
    border-color: var(--tblr-border-color, #e6e7e9) !important;
}
.xdsoft_datetimepicker .xdsoft_prev::after,
.xdsoft_datetimepicker .xdsoft_next::after,
.xdsoft_datetimepicker .xdsoft_today_button::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--tblr-body-color, #1e293b);
    border-bottom: 2px solid var(--tblr-body-color, #1e293b);
    transform: translate(-50%, -50%) rotate(135deg);
}
.xdsoft_datetimepicker .xdsoft_next::after {
    transform: translate(-65%, -50%) rotate(-45deg);
}
.xdsoft_datetimepicker .xdsoft_today_button::after {
    width: 12px;
    height: 12px;
    border: 2px solid var(--tblr-primary, #066fd1);
    border-radius: 3px;
    transform: translate(-50%, -50%);
}
/* Labels mes / año */
.xdsoft_datetimepicker .xdsoft_label {
    background: transparent !important;
    color: var(--tblr-body-color, #1e293b) !important;
    font-weight: 600 !important;
    font-size: .9375rem !important;
    border-radius: 8px !important;
    padding: 6px 12px !important;
    transition: background-color .15s ease;
}
.xdsoft_datetimepicker .xdsoft_label:hover {
    background: var(--tblr-bg-surface-secondary, #f6f8fb) !important;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select {
    background: var(--tblr-bg-surface, #fff) !important;
    border: 1px solid var(--tblr-border-color, #e6e7e9) !important;
    border-radius: 10px !important;
    box-shadow: 0 6px 18px rgba(15, 23, 42, .12) !important;
    padding: 4px !important;
    color: var(--tblr-body-color, #1e293b) !important;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option {
    padding: 6px 12px !important;
    border-radius: 6px !important;
    font-size: .875rem !important;
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover {
    background: var(--tblr-bg-surface-secondary, #f6f8fb) !important;
    color: var(--tblr-body-color, #1e293b) !important;
}
.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current {
    background: var(--tblr-primary, #066fd1) !important;
    color: #fff !important;
}
/* Tabla del calendario — headers + celdas */
.xdsoft_datetimepicker .xdsoft_calendar {
    margin-top: 4px;
}
.xdsoft_datetimepicker .xdsoft_calendar table {
    border-collapse: separate !important;
    border-spacing: 1px !important;
    border: none !important;
    width: 100% !important;
    table-layout: fixed !important;
}
.xdsoft_datetimepicker .xdsoft_calendar th {
    background: transparent !important;
    color: var(--tblr-secondary, #6c7a91) !important;
    font-size: .75rem !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    letter-spacing: .04em !important;
    border: none !important;
    padding: 6px 0 !important;
    text-align: center;
}
.xdsoft_datetimepicker .xdsoft_calendar td {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    text-align: center;
}
.xdsoft_datetimepicker .xdsoft_calendar td > div {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin: 0 auto;
    border-radius: 50%;
    font-size: .8125rem;
    font-weight: 500;
    color: var(--tblr-body-color, #1e293b);
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease, transform .08s ease;
}
.xdsoft_datetimepicker .xdsoft_calendar td:hover > div,
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_date:hover > div {
    background: var(--tblr-bg-surface-secondary, #f6f8fb) !important;
    color: var(--tblr-body-color, #1e293b) !important;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month > div {
    color: var(--tblr-secondary, #6c7a91) !important;
    opacity: .45;
}
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_weekend > div {
    color: var(--tblr-danger, #d63939);
}
/* "Hoy" — anillo primario sutil */
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_today > div {
    color: var(--tblr-primary, #066fd1) !important;
    font-weight: 700;
    box-shadow: inset 0 0 0 1.5px var(--tblr-primary, #066fd1);
}
/* Día seleccionado / current — pill sólido primario */
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current > div,
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_default > div {
    background: var(--tblr-primary, #066fd1) !important;
    color: #fff !important;
    font-weight: 600;
    box-shadow: 0 4px 10px rgba(6, 111, 209, .25);
}
/* Día deshabilitado */
.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled > div {
    color: var(--tblr-secondary, #6c7a91) !important;
    opacity: .35;
    cursor: not-allowed;
    background: transparent !important;
    box-shadow: none !important;
}
/* Columna de horas (timepicker) */
.xdsoft_datetimepicker .xdsoft_timepicker {
    width: 64px !important;
    margin-left: 8px !important;
    padding-left: 8px !important;
    border-left: 1px solid var(--tblr-border-color, #e6e7e9) !important;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box {
    border: none !important;
    border-radius: 8px !important;
    background: var(--tblr-bg-surface-secondary, #f6f8fb) !important;
    overflow: hidden;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time {
    border: none !important;
    padding: 6px 10px !important;
    font-size: .8125rem !important;
    color: var(--tblr-body-color, #1e293b) !important;
    text-align: center;
    border-radius: 6px;
    margin: 1px 4px;
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time:hover {
    background: var(--tblr-bg-surface, #fff) !important;
    color: var(--tblr-primary, #066fd1) !important;
}
.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time.xdsoft_current {
    background: var(--tblr-primary, #066fd1) !important;
    color: #fff !important;
    font-weight: 600;
}
/* Scrollbars internos del plugin */
.xdsoft_datetimepicker .xdsoft_scrollbar > .xdsoft_scroller {
    background: var(--tblr-border-color, #e6e7e9) !important;
    border-radius: 4px !important;
}
/* Triángulo decorativo de los labels — ocultar (más limpio) */
.xdsoft_datetimepicker .xdsoft_label i {
    display: none !important;
}

/* ============================================================
   Tema oscuro — utilidad .bg-white (PBI-PSICO-DARK-BGWHITE-001)
   La utilidad BS/Tabler .bg-white fija #fff SIEMPRE, ignorando el tema:
   en dark, los <tbody class="bg-white"> de los listados quedaban como un
   bloque blanco brillante sobre el fondo oscuro (visible en psicosmart:
   admin_evaluated, admin_employees, etc). Se redirige .bg-white a la
   superficie del tema. Solo afecta la CLASE .bg-white — los reportes PDF
   usan style="background:#fff" inline y NO se tocan (fidelidad de impresión).
   Global e intencional: .bg-white en dark es bug en cualquier módulo. */
[data-bs-theme="dark"] .bg-white {
    background-color: var(--tblr-bg-surface, #1a2234) !important;
    color: var(--tblr-body-color, #c9d1e0);
}
/* Skeleton loaders (tablas id="loader…") traen <tr style="background-color:#ffffff">
   inline — el inline gana a la clase, así que en dark el bloque de carga queda
   blanco. !important sobre la regla vence al inline (no-!important). Se neutraliza
   el fondo de fila/celda; las barras .skeleton conservan su shimmer propio. */
[data-bs-theme="dark"] table[id^="loader"] tr,
[data-bs-theme="dark"] table[id^="loader"] td {
    background-color: transparent !important;
}
/* Checkbox/radio en dark: el borde por defecto de Tabler queda a ~14% de opacidad,
   un cuadro casi invisible sobre el fondo oscuro de la tarjeta (el usuario no veía la
   casilla para aceptar términos). Se sube el contraste del borde SOLO en estado
   no-marcado (el marcado ya pinta el primary). Global e intencional: aplica a cualquier
   módulo en dark. WCAG: mejora el contraste del control. */
[data-bs-theme="dark"] .form-check-input:not(:checked):not(:indeterminate) {
    border-color: rgba(255, 255, 255, 0.45);
}

/* PBI-PSICO-PIPELINE-PULIDO-001 (#4): .arrow-none es una clase legacy (Veltrix) cuyo propósito es
   ocultar el caret ▼ que Bootstrap dibuja en .dropdown-toggle. En Tabler esa regla no existía, así
   que botones marcados como arrow-none (que NO son desplegables) mostraban una flecha falsa. Esto la
   oculta en todos los módulos, cumpliendo el propósito de la clase. */
.arrow-none::after,
.arrow-none::before { display: none !important; }
