/* ============================================================
   TimeTrack — Premium SaaS HRIS · Mobile-first
   Inter 400–800 · Bootstrap 5.3.8 · Bootstrap Icons 1.13.1
   ============================================================ */

/* ── Design tokens ──────────────────────────────────────────── */
:root {
  --tt-sidebar-w: 260px;
  --tt-radius: 14px;
  --tt-radius-sm: 10px;
  --tt-radius-lg: 18px;
  --tt-radius-xl: 22px;
  --tt-shadow-xs: 0 1px 2px rgba(0,0,0,.04);
  --tt-shadow-sm: 0 1px 3px rgba(0,0,0,.05), 0 1px 2px rgba(0,0,0,.04);
  --tt-shadow: 0 4px 6px -1px rgba(0,0,0,.06), 0 2px 4px -2px rgba(0,0,0,.04);
  --tt-shadow-md: 0 8px 16px -4px rgba(0,0,0,.08), 0 4px 6px -2px rgba(0,0,0,.03);
  --tt-shadow-lg: 0 20px 40px -8px rgba(0,0,0,.12), 0 8px 16px -4px rgba(0,0,0,.04);
  --tt-transition: .18s cubic-bezier(.4,0,.2,1);

  /* ── Semantic palette (color theory) ──
     Primary: Indigo-600 — trust, professionalism
     Shifts: analogous temporal spectrum (cool morning → warm afternoon → deep night)
     Status: semantic (emerald=positive, amber=caution, rose=alert)
     Data: sequential diverging for intensity */
  --tt-morning:   #0d9488;  /* Teal-600    — freshness, sunrise clarity          */
  --tt-afternoon: #d97706;  /* Amber-600   — warmth, afternoon sun               */
  --tt-night:     #7c3aed;  /* Violet-600  — depth, calm night sky               */
  --tt-split:     #ea580c;  /* Orange-600  — energy, dynamic transition           */
  --tt-rest:      #94a3b8;  /* Slate-400   — neutral, absence of activity         */
  --tt-custom:    #db2777;  /* Pink-600    — unique, personalized                 */

  --tt-positive:  #059669;  /* Emerald-600 — success, on-time, full attendance    */
  --tt-caution:   #d97706;  /* Amber-600   — partial, warning                     */
  --tt-alert:     #e11d48;  /* Rose-600    — absence, late, low attendance        */

  --tt-vac:       #0d9488;  /* Teal-600    — vacation, leisure                    */
  --tt-sick:      #e11d48;  /* Rose-600    — medical, urgency                     */
  --tt-leave:     #2563eb;  /* Blue-600    — formal leave, institutional          */
  --tt-maternity: #9333ea;  /* Purple-600  — nurturing, care                      */
  --tt-paternity: #6366f1;  /* Indigo-500  — nurturing, harmonious w/ primary     */
  --tt-other:     #64748b;  /* Slate-500   — generic, undefined                   */

  /* Bootstrap overrides */
  --bs-primary: #6366f1;
  --bs-primary-rgb: 99,102,241;
  --bs-link-color-rgb: 99,102,241;
  --bs-link-hover-color-rgb: 79,70,229;
  --bs-border-radius: 10px;
  --bs-border-radius-lg: 14px;
  --bs-body-font-family: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --bs-body-font-size: .875rem;
  --bs-body-color: #0f172a;       /* Slate-900 — más contraste que default #212529 */
  --bs-body-bg: #f8fafc;          /* Slate-50 — lienzo, no superficies */
  --bs-secondary-color: #475569;  /* Slate-600 — contraste WCAG AA sobre superficies blancas */
  --bs-secondary-bg: #f1f5f9;     /* Slate-100 — hover states / barras */
  --bs-tertiary-bg: #e2e8f0;      /* Slate-200 — tracks / muted areas */
  --bs-border-color: #e5e7eb;
  /* SURFACE token — fix crítico v3.43.x: antes las cards usaban var(--bs-body-bg)
     que es el mismo color del lienzo → cero contraste, todo se veía "plano".
     Ahora cards/KPIs/tablas/modales usan --tt-surface (blanco puro en light,
     slate-800 en dark) → elevación correcta sobre el body. */
  --tt-surface: #ffffff;
  --tt-surface-2: #fafbfc;        /* Variante ligeramente más tenue para zebra/hover */
}

/* ── Base typography ────────────────────────────────────────── */
html, body { height: 100%; }
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Inter character variants: cv02 ('a' single-storey), cv03 (open '4'),
     cv04 ('6'/'9' tail), cv11 (open '0'), ss01 (alt 'g' SaaS — Linear/Vercel). */
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11', 'ss01';
  letter-spacing: -.011em;
}

h1, h2, h3, .h1, .h2, .h3 {
  /* Headings grandes — weight 800 + tracking más ceñido (autoridad SaaS) */
  font-weight: 800;
  letter-spacing: -.03em;
}
h4, h5, h6, .h4, .h5, .h6 {
  font-weight: 700;
  letter-spacing: -.022em;
}
.tabular, .timer, .clock {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' on, 'cv11' on;
}

/* ── Bootstrap component overrides ──────────────────────────── */
.btn {
  font-weight: 600;
  font-size: .8125rem;
  border-radius: var(--tt-radius-sm);
  letter-spacing: -.005em;
  transition: all var(--tt-transition);
}
.btn-sm { font-size: .75rem; padding: .375rem .75rem; }
.btn-primary {
  --bs-btn-bg: var(--bs-primary);
  --bs-btn-border-color: var(--bs-primary);
  --bs-btn-hover-bg: #4f46e5;
  --bs-btn-hover-border-color: #4338ca;
  --bs-btn-active-bg: #4338ca;
  --bs-btn-active-border-color: #3730a3;
  --bs-btn-disabled-bg: var(--bs-primary);
  --bs-btn-disabled-border-color: var(--bs-primary);
  box-shadow: 0 1px 2px rgba(var(--bs-primary-rgb),.2), inset 0 1px 0 rgba(255,255,255,.12);
}
.btn-primary:hover { box-shadow: 0 2px 8px rgba(var(--bs-primary-rgb),.35), inset 0 1px 0 rgba(255,255,255,.1); transform: translateY(-1px); }
.btn-outline-primary {
  --bs-btn-color: var(--bs-primary);
  --bs-btn-border-color: var(--bs-primary);
  --bs-btn-hover-bg: var(--bs-primary);
  --bs-btn-hover-border-color: var(--bs-primary);
  --bs-btn-active-bg: #4f46e5;
}
.btn-light { --bs-btn-bg: var(--bs-body-bg); border-color: var(--bs-border-color); }
.btn-light:hover { background: var(--bs-tertiary-bg); border-color: var(--bs-border-color); }

.form-control, .form-select {
  border-color: var(--bs-border-color);
  border-radius: var(--tt-radius-sm);
  font-size: .8125rem;
  padding: .5rem .75rem;
  transition: border-color var(--tt-transition), box-shadow var(--tt-transition);
}
.form-control:focus, .form-select:focus {
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb),.12);
}
/* v2.6.12 — Restaurar `white-space: nowrap` que Bootstrap 5 quitó del
   `.btn` default. Sin esto, cuando un botón con icono+texto está en un
   flex container con `flex-shrink: 1` (default) Y el ancho disponible
   es justo, el browser intenta ajustar el contenido envolviendo el texto
   palabra-por-palabra, produciendo botones rotos visualmente con icono
   en una línea + cada palabra del texto en otra línea (ej. en
   Mantenimiento: 'Exportar JSON' → icono / 'Exportar' / 'JSON').
   `flex-shrink: 0` defensivo para que los botones nunca se compriman
   por debajo de su tamaño natural; en su lugar, flex-wrap del parent
   los pasa a la siguiente línea limpiamente. */
.btn {
  white-space: nowrap;
  flex-shrink: 0;
}
.form-control-sm { font-size: .75rem; padding: .375rem .625rem; }
/* v2.6.12 — Separar `.form-select-sm` del shorthand para preservar
   el right-padding del chevron Bootstrap (background-image SVG en
   `right .5rem center`). Antes ambas reglas compartían el shorthand
   `padding: .375rem .625rem` que estripa el espacio del chevron y
   provoca solapamiento visual con el texto ("Pendientes✓" en cambios
   de turno, festivos, jornadas, etc.). Bootstrap default es
   `padding: .25rem 2rem .25rem .5rem`. Mantenemos font-size pero
   restauramos el right-padding para evitar el clipping. */
.form-select-sm {
  font-size: .75rem;
  /* `!important` defensivo: hay reglas legacy en style.css que pueden
     re-aplicar el shorthand `padding: .375rem .625rem` y eliminar el
     room del chevron. */
  padding: .375rem 2rem .375rem .625rem !important;
  background-position: right .5rem center !important;
  background-size: 14px 12px;
}
/* v2.6.12 — Inputs de tipo TIME/DATE/DATETIME tienen un picker nativo
   del browser (clock icon en Chrome/Edge, chevron en otros) que se
   renderiza INSIDE el content area del input.  Con padding-right
   .625rem (~10px) el icon nativo se solapa con el texto, mostrando
   "06:00" como "06:0C" (donde la C es realmente el clock icon).
   Aumentamos padding-right a 2rem para dar room al picker nativo en
   TODOS los inputs time/date/week/month (modal de turnos rotativos,
   horarios admin, ausencias, etc.). */
.form-control-sm[type="time"],
.form-control-sm[type="date"],
.form-control-sm[type="datetime-local"],
.form-control-sm[type="week"],
.form-control-sm[type="month"],
.form-control[type="time"],
.form-control[type="date"],
.form-control[type="datetime-local"],
.form-control[type="week"],
.form-control[type="month"] {
  padding-right: 2rem;
}
.form-label { font-weight: 600; font-size: .75rem; margin-bottom: 6px; color: var(--bs-body-color); letter-spacing: .01em; }

/* v2.6.11 — Hide browser-native password reveal/clear controls.
   La app expone su propio botón toggle (#togglePwd con eye/eye-slash en
   index.html, signup.html, recover, change-password modal).  Sin esta
   regla, Edge/IE inyectan ::-ms-reveal/::-ms-clear DENTRO del input y
   Safari añade un autofill key icon — visualmente parecen un segundo
   toggle eye al lado del nuestro (redundancia visible en login). */
input[type="password"]::-ms-reveal,
input[type="password"]::-ms-clear,
input[type="search"]::-ms-clear,
input[type="text"]::-ms-clear {
  display: none;
  width: 0;
  height: 0;
}
input[type="password"]::-webkit-credentials-auto-fill-button,
input[type="password"]::-webkit-strong-password-auto-fill-button {
  visibility: hidden;
  display: none !important;
  pointer-events: none;
  height: 0;
  width: 0;
  margin: 0;
}

.modal-content { border: 0; border-radius: var(--tt-radius-lg); overflow: hidden; box-shadow: var(--tt-shadow-lg); }
.modal-header { border-bottom-color: var(--bs-border-color); padding: 1.125rem 1.25rem; }
.modal-header .modal-title { font-size: 1rem; font-weight: 700; letter-spacing: -.02em; }
.modal-footer { border-top-color: var(--bs-border-color); padding: 1rem 1.25rem; }
.modal-body { padding: 1.25rem; }

.dropdown-menu {
  border: 1px solid var(--bs-border-color);
  box-shadow: var(--tt-shadow-md);
  border-radius: var(--tt-radius);
  padding: 6px;
  font-size: .8125rem;
}
.dropdown-item { border-radius: var(--tt-radius-sm); padding: 8px 12px; font-size: .8125rem; transition: background .1s; }
.dropdown-item:active { background: var(--bs-primary); }

.table > :not(caption) > * > * { padding: .75rem .875rem; vertical-align: middle; font-size: .8125rem; }
.table th { font-weight: 600; }

.nav-tabs { border-bottom-color: var(--bs-border-color); }
.nav-tabs .nav-link {
  color: var(--bs-secondary-color);
  font-weight: 600; font-size: .8125rem; border: 0;
  border-bottom: 2px solid transparent;
  padding: 10px 16px;
  transition: color var(--tt-transition);
}
.nav-tabs .nav-link.active {
  color: var(--bs-primary);
  border-bottom-color: var(--bs-primary);
  background: transparent;
}

.badge { font-weight: 600; font-size: .675rem; letter-spacing: .02em; }
.alert { border-radius: var(--tt-radius-sm); font-size: .8125rem; }

/* ── Surface elevation utility ─────────────────────────────────
   Modal/dropdown/Bootstrap card sobre --tt-surface en lugar del bg de
   Bootstrap (que en light coincide con el body → sin elevación). */
.modal-content, .dropdown-menu, .card {
  background-color: var(--tt-surface);
  border-color: var(--bs-border-color);
}

/* ── Scrollbar refinement ───────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(0,0,0,.12); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,.2); }

/* ============================================================
   LOGIN
   ============================================================ */
/* Acciones flotantes (idioma + tema) en index.html. Sobreviven sobre el
   gradiente del hero (que ocupa la mitad derecha en desktop y la parte
   superior en mobile), por lo que necesitan look glassy + texto blanco
   independientemente del data-bs-theme/color. */
.login-actions { gap: 6px; }
.login-actions .btn-icon {
  color: #fff;
  background: rgba(255,255,255,.14);
  border: 1px solid rgba(255,255,255,.22);
  backdrop-filter: blur(10px) saturate(160%);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
  box-shadow: 0 2px 8px rgba(15,23,42,.18);
  transition: background .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
              border-color .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
              transform .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.login-actions .btn-icon:hover {
  background: rgba(255,255,255,.24);
  border-color: rgba(255,255,255,.38);
  color: #fff;
  transform: translateY(-1px);
}
.login-actions .btn-icon i.bi { color: inherit; }
/* v3.x — Mobile fix: en mobile el layout es column-reverse (hero arriba,
   form abajo) y los botones son position:fixed. Al hacer scroll para ver
   el formulario, los botones quedan sobre el fondo claro/oscuro del form
   → el glass blanco translúcido desaparecía (blanco sobre blanco).
   En mobile cambiamos a fondo primary sólido + texto blanco: legible
   tanto sobre el gradiente del hero como sobre el fondo del form. */
@media (max-width: 991.98px) {
  .login-actions .btn-icon {
    color: #fff;
    background: var(--bs-primary);
    border-color: rgba(255, 255, 255, 0.28);
    box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);
  }
  .login-actions .btn-icon:hover,
  .login-actions .btn-icon:focus-visible {
    background: var(--bs-primary);
    border-color: rgba(255, 255, 255, 0.5);
    color: #fff;
    filter: brightness(1.08);
  }
  .login-actions .btn-icon[aria-expanded="true"] {
    background: var(--bs-primary);
    filter: brightness(0.92);
  }
}
@media (max-width: 575.98px) {
  .login-actions .btn-icon { width: 34px; height: 34px; font-size: .95rem; }
}
.login-wrap {
  min-height: 100vh;
  display: flex;
  flex-direction: column-reverse;
}
.login-hero {
  background: linear-gradient(135deg, #6366f1 0%, #818cf8 30%, #a78bfa 60%, #ec4899 100%);
  color: #fff;
  padding: 32px 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
  overflow: hidden;
}
.login-hero::after {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 30% 80%, rgba(255,255,255,.08) 0%, transparent 70%);
  pointer-events: none;
}
.login-hero h1 { font-size: 1.6rem; font-weight: 800; line-height: 1.15; margin: 0 0 12px; letter-spacing: -.035em; }
.login-hero p { opacity: .92; font-size: .9rem; line-height: 1.6; max-width: 480px; margin-bottom: 0; }
.login-features { display: grid; gap: 14px; margin-top: 24px; }
.login-features div { display: flex; align-items: center; gap: 12px; font-size: .85rem; font-weight: 500; }
.login-features i {
  width: 38px; height: 38px; background: rgba(255,255,255,.15); backdrop-filter: blur(8px);
  border-radius: 10px; display: grid; place-items: center; font-size: 1.05rem; flex-shrink: 0;
}
.login-form-side {
  display: flex; align-items: center; justify-content: center;
  padding: 32px 20px;
  background: var(--bs-body-bg);
  flex: 1;
}
.login-card { width: 100%; max-width: 380px; }
.login-card h2 { font-weight: 800; margin: 0 0 6px; font-size: 1.5rem; letter-spacing: -.035em; }
.login-card .subtitle { color: var(--bs-secondary-color); margin-bottom: 24px; font-size: .875rem; }
.demo-box {
  margin-top: 18px; padding: 14px 16px;
  background: rgba(var(--bs-primary-rgb), .05);
  border: 1px solid rgba(var(--bs-primary-rgb), .12);
  border-radius: var(--tt-radius-sm);
  font-size: .75rem; color: var(--bs-body-color); line-height: 1.6;
}
.demo-box code {
  background: rgba(var(--bs-primary-rgb), .1);
  padding: 2px 7px; border-radius: 5px;
  color: var(--bs-primary); font-size: .7rem; font-weight: 600;
}

@media (min-width: 992px) {
  .login-wrap { flex-direction: row; }
  .login-hero { padding: 60px 56px; min-height: 100vh; flex: 1; }
  .login-hero h1 { font-size: 2.5rem; }
  .login-form-side { flex: 0 0 48%; padding: 48px; }
}

/* ============================================================
   APP SHELL — mobile-first grid
   ============================================================ */
.app-shell { min-height: 100vh; }
@media (min-width: 992px) {
  .app-shell { display: grid; grid-template-columns: var(--tt-sidebar-w) 1fr; }
}

/* ── Sidebar ────────────────────────────────────────────────── */
.sidebar {
  background: #0f172a;
  color: #94a3b8;
  width: var(--tt-sidebar-w);
  display: flex;
  flex-direction: column;
}
@media (min-width: 992px) {
  .sidebar { position: sticky; top: 0; height: 100vh; overflow-y: auto; }
}
/* v3.x — incluye offcanvas-lg explícito: el markup usa
   class="offcanvas-lg offcanvas-start sidebar" (no .offcanvas), por
   lo que la regla original `.offcanvas.sidebar` nunca matchaba y los
   CSS vars no aplicaban → offcanvas se abría con bg blanco default
   en lugar del navy del sidebar. */
.offcanvas.sidebar,
.offcanvas-lg.sidebar { --bs-offcanvas-width: var(--tt-sidebar-w); --bs-offcanvas-bg: #0f172a; }

.sidebar-brand {
  padding: 18px 20px; display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid rgba(255,255,255,.06);
}
.sidebar-brand .logo {
  width: 36px; height: 36px; border-radius: 10px;
  background: linear-gradient(135deg, #6366f1, #a855f7, #ec4899);
  display: grid; place-items: center; color: #fff; font-weight: 800; font-size: .85rem; flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(99,102,241,.4);
}
.sidebar-brand strong { color: #f1f5f9; font-size: .9375rem; letter-spacing: -.02em; }
/* v3.43.x — contraste AA: #64748b (slate-500) sobre #0f172a (slate-900) da
   3.7:1 → falla WCAG AA para texto pequeño (≥6rem). Subido a slate-400
   #94a3b8 → ratio 5.5:1, AA conforme. Aplica a sidebar de admin y app. */
.sidebar-brand small { color: #94a3b8; display: block; font-size: .675rem; letter-spacing: .02em; }

/* Nav-section labels (cabeceras "PRINCIPAL", "GESTIÓN"...). #475569 sobre
   navy oscuro daba 2.5:1 — invisible. Slate-400 con uppercase → 5.5:1 AA. */
.nav-section { padding: 18px 20px 6px; font-size: .625rem; color: #94a3b8; text-transform: uppercase; letter-spacing: .1em; font-weight: 700; }
.sidebar nav { padding: 6px 12px; flex: 1; }
.sidebar nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: var(--tt-radius-sm); color: #94a3b8; font-weight: 500; font-size: .8125rem;
  text-decoration: none; transition: all var(--tt-transition); position: relative;
}
.sidebar nav a:hover { background: rgba(255,255,255,.06); color: #e2e8f0; }
.sidebar nav a.active {
  background: var(--bs-primary); color: #fff; font-weight: 600;
  box-shadow: 0 4px 14px rgba(var(--bs-primary-rgb),.45);
}
.sidebar nav a i { font-size: 1.05rem; flex-shrink: 0; width: 20px; text-align: center; }
.sidebar nav a .badge { margin-left: auto; font-size: .6rem; }

.sidebar-footer { padding: 14px 16px; border-top: 1px solid rgba(255,255,255,.06); }
.sidebar-footer .who { color: #f1f5f9; font-weight: 600; font-size: .8125rem; min-width: 0; }
.sidebar-footer .who span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Rol del usuario en sidebar-footer ("Admin Principal", "Empleado", etc.).
   Era #64748b → invisible en modo claro porque la atención está en el
   contraste del cuerpo blanco; ahora slate-400 con weight 500 para mejor
   discernibilidad sin saturar la jerarquía visual. */
.sidebar-footer .who small { color: #94a3b8; display: block; font-weight: 500; font-size: .675rem; letter-spacing: .01em; }

.main { display: flex; flex-direction: column; min-width: 0; min-height: 100vh; background: var(--bs-body-bg); }

/* ── Topbar ─────────────────────────────────────────────────── */
.topbar {
  background: color-mix(in srgb, var(--bs-body-bg) 82%, transparent);
  border-bottom: 1px solid var(--bs-border-color);
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  position: sticky; top: 0; z-index: 30;
  min-height: 56px;
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
}
.topbar h1 { font-size: .9375rem; font-weight: 700; margin: 0; letter-spacing: -.02em; }
@media (min-width: 768px) {
  .topbar { padding: 10px 24px; }
  .topbar h1 { font-size: 1rem; }
}
.topbar .clock {
  font-variant-numeric: tabular-nums; color: var(--bs-secondary-color);
  font-weight: 500; font-size: .8125rem; letter-spacing: -.01em;
}

/* ── Icon button (global) ───────────────────────────────────── */
.btn-icon {
  width: 36px; height: 36px; padding: 0; display: grid; place-items: center;
  background: transparent; border: 1px solid var(--bs-border-color); border-radius: var(--tt-radius-sm);
  color: var(--bs-body-color); position: relative; transition: all var(--tt-transition);
  cursor: pointer; font-size: 1rem; line-height: 1;
}
.btn-icon:hover {
  background: rgba(var(--bs-primary-rgb), .08);
  border-color: rgba(var(--bs-primary-rgb), .3);
  color: var(--bs-primary);
}
.btn-icon .dot {
  position: absolute; top: 5px; right: 5px;
  width: 8px; height: 8px; border-radius: 50%;
  background: #ef4444;
  border: 2px solid var(--bs-body-bg);
  box-shadow: 0 0 0 1px rgba(239,68,68,.2);
}

/* ── Content area ───────────────────────────────────────────── */
.content { padding: 16px; }
@media (min-width: 768px) { .content { padding: 24px 28px; } }
@media (min-width: 1200px) { .content { padding: 28px 32px; } }
.content > section { display: none; }
.content > section.active { display: block; animation: fadeIn .25s ease-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── Bottom mobile nav ──────────────────────────────────────── */
.bottom-nav {
  display: flex;
  position: sticky; bottom: 0; left: 0; right: 0;
  background: color-mix(in srgb, var(--bs-body-bg) 92%, transparent);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  border-top: 1px solid var(--bs-border-color);
  padding: 4px 4px calc(env(safe-area-inset-bottom, 4px) + 4px);
  z-index: 20;
}
.bottom-nav a {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 6px 2px; border-radius: var(--tt-radius-sm);
  color: var(--bs-secondary-color); text-decoration: none;
  font-size: .625rem; font-weight: 600; transition: all var(--tt-transition);
  letter-spacing: .01em;
}
.bottom-nav a i { font-size: 1.15rem; }
.bottom-nav a.active {
  color: var(--bs-primary);
  background: rgba(var(--bs-primary-rgb), .1);
}
@media (min-width: 992px) { .bottom-nav { display: none; } }

/* ============================================================
   KPI CARDS — premium metric tiles
   ============================================================ */
.kpi {
  /* Permite que .kpi .value se reduzca con clamp(cqi) cuando la card
     queda estrecha (e.g. col-md-3 en 992-1199px) y así evitar el clip
     de valores con signo + dígitos extra como "-15h 27m". */
  container-type: inline-size;
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius);
  padding: 14px 16px; display: flex; align-items: center; gap: 14px;
  box-shadow: var(--tt-shadow-xs);
  height: 100%;
  transition: box-shadow var(--tt-transition), transform var(--tt-transition);
}
.kpi:hover { box-shadow: var(--tt-shadow); transform: translateY(-1px); }
@media (min-width: 768px) { .kpi { padding: 18px 20px; } }

.kpi .icon {
  width: 42px; height: 42px; border-radius: var(--tt-radius-sm); display: grid; place-items: center;
  font-size: 1.15rem; flex-shrink: 0;
}
@media (min-width: 768px) { .kpi .icon { width: 48px; height: 48px; font-size: 1.25rem; } }
.kpi .icon.primary { background: rgba(var(--bs-primary-rgb), .1); color: var(--bs-primary); }
.kpi .icon.success { background: rgba(var(--bs-success-rgb), .1); color: var(--bs-success); }
.kpi .icon.warning { background: rgba(var(--bs-warning-rgb), .12); color: var(--bs-warning); }
.kpi .icon.danger  { background: rgba(var(--bs-danger-rgb), .1); color: var(--bs-danger); }
.kpi .icon.info    { background: rgba(var(--bs-info-rgb), .1); color: var(--bs-info); }
.kpi .icon.purple  { background: #ede9fe; color: #7c3aed; }

.kpi .label {
  color: var(--bs-secondary-color);
  font-size: .6875rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 600;
}
.kpi .value {
  font-size: 1.375rem; font-weight: 800; line-height: 1;
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  /* Evita que valores como "48h 33m" o "-7h 27m" rompan en dos líneas
     cuando la card está en col-md-3 (≈ 280px en desktop md). */
  white-space: nowrap;
}
@media (min-width: 768px) { .kpi .value { font-size: 1.5rem; } }
.kpi .sub { color: var(--bs-secondary-color); font-size: .6875rem; margin-top: 2px; font-weight: 500; }
/* Asegura que el contenedor de info dentro de la card no overflowee la
   value pill cuando hay nowrap (Bootstrap-flex genera min-width:auto). */
.kpi > div:not(.icon) { min-width: 0; }

/* ── Card surface ───────────────────────────────────────────── */
.card-soft {
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius);
  box-shadow: var(--tt-shadow-xs);
}

/* ============================================================
   PUNCH CARD — hero clock-in widget
   ============================================================ */
.punch-card {
  background: linear-gradient(135deg, #4f46e5 0%, #6366f1 30%, #818cf8 70%, #a78bfa 100%);
  color: #fff; border-radius: var(--tt-radius-xl); padding: 24px;
  box-shadow: 0 12px 32px rgba(var(--bs-primary-rgb), .3), inset 0 1px 0 rgba(255,255,255,.1);
  position: relative;
}
.punch-card::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(ellipse at 80% 20%, rgba(255,255,255,.08) 0%, transparent 65%);
  pointer-events: none;
}
@media (min-width: 768px) { .punch-card { padding: 32px; } }
.punch-card .timer {
  font-size: 2.75rem; font-weight: 800; font-variant-numeric: tabular-nums;
  letter-spacing: -.03em; line-height: 1;
}
@media (min-width: 768px) { .punch-card .timer { font-size: 3.5rem; } }
/* v2.6.89 — Removido `text-transform: capitalize`: en español ponía
   mayúscula a "de" → "Domingo, 17 De Mayo De 2026". La capitalización
   del weekday se hace ahora en JS (app.js renderDashboard) solo en la
   primera letra: "Domingo, 17 de mayo de 2026". */
.punch-card .date { opacity: .85; font-size: .8125rem; margin-bottom: 16px; font-weight: 500; }
.punch-card .status-pill {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 14px;
  background: rgba(255,255,255,.15); backdrop-filter: blur(8px);
  border-radius: 999px; font-size: .75rem; font-weight: 600;
}
.punch-card .status-pill.working::before {
  content: ''; width: 8px; height: 8px; background: #4ade80; border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(74,222,128,.3); animation: pulse 2s ease-in-out infinite;
}
.punch-card .status-pill.paused::before { content: ''; width: 8px; height: 8px; background: #fbbf24; border-radius: 50%; }
@keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .6; transform: scale(1.15); } }
.punch-card .actions { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.punch-card .btn-punch {
  padding: 12px 20px; border-radius: var(--tt-radius-sm); font-weight: 700; border: 0;
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  transition: all .15s; font-size: .8125rem; min-height: 46px;
  flex: 1; justify-content: center; letter-spacing: -.005em;
}
@media (min-width: 576px) { .punch-card .btn-punch { flex: 0 1 auto; padding: 12px 24px; } }
.punch-card .btn-punch:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,.2); }
.punch-card .btn-punch:active { transform: translateY(0); }
.btn-clock-in { background: #fff; color: #4f46e5; box-shadow: 0 2px 8px rgba(0,0,0,.12); }
.btn-clock-out { background: #ef4444; color: #fff; box-shadow: 0 2px 8px rgba(239,68,68,.3); }
.btn-pause { background: rgba(255,255,255,.18); backdrop-filter: blur(4px); color: #fff; }
.punch-card .meta {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 16px;
  margin-top: 18px; font-size: .75rem; opacity: .85;
}
@media (min-width: 576px) { .punch-card .meta { display: flex; gap: 24px; } }
.punch-card .meta div { display: flex; flex-direction: column; gap: 2px; }
.punch-card .meta span { font-weight: 500; font-size: .6875rem; text-transform: uppercase; letter-spacing: .04em; opacity: .8; }
.punch-card .meta strong { font-size: 1.0625rem; font-weight: 700; opacity: 1; font-variant-numeric: tabular-nums; }

/* ============================================================
   TABLES — clean data display
   ============================================================ */
.table-wrap {
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius); overflow: hidden;
  box-shadow: var(--tt-shadow-xs);
}
.table-wrap > .table-responsive { margin: 0; }
.table-wrap table { margin: 0; }
.table-wrap thead th {
  background: var(--bs-tertiary-bg);
  font-weight: 700; font-size: .6875rem;
  color: var(--bs-secondary-color);
  text-transform: uppercase; letter-spacing: .05em;
  border-bottom: 1px solid var(--bs-border-color);
  white-space: nowrap;
  padding: .625rem .875rem;
}
.table-wrap tbody tr { transition: background .1s; }
.table-wrap tbody tr:hover { background: rgba(var(--bs-primary-rgb), .02); }
.table-wrap td { vertical-align: middle; }

/* ── Fecha column: nunca wrappear "dom, 10 may 2026" en 4 líneas ────
   Aplica a las columnas con `Utils.fmtDate()` ("vie, 14 ene 2021"):
     · Jornadas/Reportes/Ausencias → fecha es la 1ª columna del cuerpo
     · Empleados → Alta es la 6ª por orden DOM (independiente del
       breakpoint, ya que d-none oculta sin alterar nth-child).
   El header ya tiene white-space:nowrap; aquí lo replicamos en el cuerpo
   para que el contenido quede en una sola línea y la columna reserve
   el ancho que necesita sin reventar la altura de la fila. */
#jornTable td:first-child,
#repTable td:first-child,
#absTable td:first-child,
#empTable td:nth-child(6) {
  white-space: nowrap;
}

/* ── FAB safe-area: bottom padding del contenido para que las FABs
   flotantes (help-center, what's-new, etc.) no tapen la última fila ni
   los botones de acción de la última fila visible.  En mobile ya hay
   bottom-nav (~64px) + FAB elevada (76px), por eso solo aplica desktop. */
@media (min-width: 992px) {
  .content { padding-bottom: 88px; }
}

/* ── Avatars ────────────────────────────────────────────────── */
.avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: rgba(var(--bs-primary-rgb), .08);
  color: var(--bs-primary);
  display: inline-grid; place-items: center; font-weight: 700; font-size: .75rem;
  flex-shrink: 0; letter-spacing: .01em; overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.avatar.lg { width: 56px; height: 56px; font-size: 1.05rem; }
.avatar.sm { width: 30px; height: 30px; font-size: .675rem; }
.avatar.xs { width: 22px; height: 22px; font-size: .6rem; }

/* ── Avatar upload widget ──────────────────────────────────── */
.avatar-upload-wrap {
  position: relative; width: 72px; height: 72px; cursor: pointer; border-radius: 50%;
}
.avatar-upload-wrap .avatar.lg { width: 72px; height: 72px; font-size: 1.3rem; }
.avatar-upload-overlay {
  position: absolute; inset: 0; border-radius: 50%;
  background: rgba(0,0,0,.45); color: #fff; display: grid; place-items: center;
  opacity: 0; transition: opacity .2s; font-size: .85rem;
}
.avatar-upload-wrap:hover .avatar-upload-overlay { opacity: 1; }

/* ── Logo upload widget ────────────────────────────────────── */
.logo-upload-wrap {
  position: relative; width: 52px; height: 52px; cursor: pointer; border-radius: 12px; flex-shrink: 0;
}
.logo-preview {
  width: 52px; height: 52px; border-radius: 12px;
  background: linear-gradient(135deg, #5b5ff5, #ec4899); color: #fff;
  display: grid; place-items: center; font-weight: 800; font-size: 1.3rem;
  overflow: hidden;
}
.logo-preview img { width: 100%; height: 100%; object-fit: cover; }
.logo-upload-overlay {
  position: absolute; inset: 0; border-radius: 12px;
  background: rgba(0,0,0,.45); color: #fff; display: grid; place-items: center;
  opacity: 0; transition: opacity .2s; font-size: .75rem;
}
.logo-upload-wrap:hover .logo-upload-overlay { opacity: 1; }
.sidebar .logo img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }

/* ── Pills & badges ─────────────────────────────────────────── */
.dept-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px; font-size: .6875rem; font-weight: 600;
  background: rgba(var(--bs-primary-rgb), .08);
  color: var(--bs-primary); white-space: nowrap;
}
.status-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: .6875rem; font-weight: 600; white-space: nowrap;
}
.status-badge::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.status-badge.success { background: rgba(var(--bs-success-rgb), .1); color: var(--bs-success-text-emphasis); }
.status-badge.success::before { background: var(--bs-success); }
.status-badge.warning { background: rgba(var(--bs-warning-rgb), .12); color: var(--bs-warning-text-emphasis); }
.status-badge.warning::before { background: var(--bs-warning); }
.status-badge.danger  { background: rgba(var(--bs-danger-rgb), .1); color: var(--bs-danger-text-emphasis); }
.status-badge.danger::before  { background: var(--bs-danger); }
.status-badge.info    { background: rgba(var(--bs-info-rgb), .1); color: var(--bs-info-text-emphasis); }
.status-badge.info::before    { background: var(--bs-info); }
.status-badge.muted   { background: var(--bs-secondary-bg); color: var(--bs-secondary-color); }
.status-badge.muted::before   { background: var(--bs-secondary-color); opacity: .5; }

/* ============================================================
   CALENDAR
   ============================================================ */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
@media (min-width: 768px) { .cal-grid { gap: 5px; } }
.cal-head { font-size: .625rem; font-weight: 700; color: var(--bs-secondary-color); text-transform: uppercase; text-align: center; padding: 4px; letter-spacing: .06em; }
.cal-day {
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius-sm);
  padding: 4px; min-height: 52px; font-size: .75rem; position: relative;
  transition: border-color .15s;
}
@media (min-width: 768px) { .cal-day { padding: 7px; min-height: 76px; font-size: .8125rem; } }
.cal-day.muted { background: var(--bs-tertiary-bg); color: var(--bs-secondary-color); }
.cal-day.today { border-color: var(--bs-primary); box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb), .12); }
.cal-day.holiday { background: rgba(var(--bs-warning-rgb), .08); }
.cal-day .num { font-weight: 700; font-size: .75rem; }
.cal-day .marker {
  display: block; margin-top: 2px; padding: 2px 5px; border-radius: 4px;
  font-size: .6rem; font-weight: 600; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (min-width: 768px) { .cal-day .marker { padding: 2px 6px; font-size: .65rem; } }
.cal-day .m-vac     { background: rgba(244,63,94,.12);  color: #be123c; }
.cal-day .m-tele    { background: rgba(13,148,136,.12); color: #115e59; }
.cal-day .m-baja    { background: rgba(225,29,72,.12);  color: #9f1239; }
.cal-day .m-perm    { background: rgba(217,119,6,.14);  color: #92400e; }
.cal-day .m-pers    { background: rgba(37,99,235,.12);  color: #1e3a8a; }
.cal-day .m-mud     { background: rgba(234,88,12,.12);  color: #9a3412; }
.cal-day .m-mat     { background: rgba(147,51,234,.12); color: #6b21a8; }
/* Ribbon edges (multi-day spans) */
.cal-day .marker.ribbon-start  { border-top-right-radius: 0; border-bottom-right-radius: 0; margin-right: -5px; }
.cal-day .marker.ribbon-mid    { border-radius: 0; margin-left: -5px; margin-right: -5px; color: transparent; }
.cal-day .marker.ribbon-end    { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -5px; color: transparent; }
@media (min-width: 768px) {
  .cal-day .marker.ribbon-start { margin-right: -6px; }
  .cal-day .marker.ribbon-mid   { margin-left: -6px; margin-right: -6px; }
  .cal-day .marker.ribbon-end   { margin-left: -6px; }
}
.cal-day .m-work { background: rgba(var(--bs-success-rgb), .1); color: var(--bs-success-text-emphasis); }
.cal-day .m-hol  { background: #fef3c7; color: #78350f; }

/* ============================================================
   MISC UI COMPONENTS
   ============================================================ */

/* Section header */
.section-title { font-size: 1rem; font-weight: 700; margin: 0; letter-spacing: -.02em; }
.section-sub { color: var(--bs-secondary-color); font-size: .8125rem; margin: 0; }
.section-header { display: flex; flex-direction: column; gap: 12px; margin-bottom: 18px; }
.section-header > div:first-child { flex: 1; }
.section-header .actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
@media (min-width: 768px) { .section-header { flex-direction: row; align-items: center; } }

/* ── Empty state v2 (illustrated) ────────────────────────── */
.empty {
  text-align: center; padding: 40px 20px; color: var(--bs-secondary-color);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.empty .empty-illust {
  width: 120px; height: 120px; margin-bottom: 8px;
  opacity: .85; transition: opacity .25s;
}
.empty:hover .empty-illust { opacity: 1; }
.empty .empty-illust svg { width: 100%; height: 100%; }
/* Fallback icon if no SVG illustration */
.empty > i.bi {
  font-size: 2.5rem; opacity: .18; display: block; margin-bottom: 10px;
  background: linear-gradient(135deg, var(--bs-primary), var(--bs-info, #06b6d4));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text;
}
.empty .title {
  font-weight: 700; color: var(--bs-body-color);
  margin-bottom: 2px; font-size: .875rem; line-height: 1.4;
}
.empty .subtitle {
  font-size: .78rem; color: var(--bs-secondary-color);
  max-width: 280px; line-height: 1.45;
}
.empty .empty-action {
  margin-top: 14px;
}
@media (prefers-reduced-motion: reduce) {
  .empty .empty-illust { transition: none; }
}

/* ── Skeleton Loader ─────────────────────────────────────── */
@keyframes tt-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
.skeleton {
  background: linear-gradient(90deg,
    var(--bs-tertiary-bg) 25%,
    rgba(var(--bs-emphasis-color-rgb), .06) 37%,
    var(--bs-tertiary-bg) 63%);
  background-size: 800px 100%;
  animation: tt-shimmer 1.6s infinite linear;
  border-radius: var(--tt-radius-sm);
}
.skeleton-line {
  height: .85rem; margin-bottom: 10px; border-radius: 6px;
}
.skeleton-line:last-child { margin-bottom: 0; }
.skeleton-line.w-60 { width: 60%; }
.skeleton-line.w-40 { width: 40%; }
.skeleton-line.w-80 { width: 80%; }
.skeleton-line.w-50 { width: 50%; }
.skeleton-circle {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
}
.skeleton-row {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 4px; border-bottom: 1px solid var(--bs-border-color);
}
.skeleton-row:last-child { border-bottom: 0; }
.skeleton-row .skeleton-body { flex: 1; }
.skeleton-kpi {
  display: flex; flex-direction: column; gap: 8px; padding: 16px;
}
.skeleton-kpi .skeleton-value { height: 1.4rem; width: 45%; border-radius: 6px; }
.skeleton-kpi .skeleton-label { height: .7rem; width: 65%; border-radius: 4px; }
.skeleton-table-row {
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--bs-border-color);
}
.skeleton-table-row:last-child { border-bottom: 0; }
.skeleton-table-row .skeleton-cell { height: .8rem; border-radius: 4px; }
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

/* ── Animated KPI counter ────────────────────────────────── */
.kpi .value[data-countup] {
  transition: none;      /* JS handles the animation */
}
@keyframes tt-kpi-pop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
.kpi .value.counted {
  animation: tt-kpi-pop .35s ease-out;
}

/* List item */
.list-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 4px; border-bottom: 1px solid var(--bs-border-color);
  transition: background .1s;
}
.list-item:last-child { border-bottom: 0; }
.list-item:hover { background: rgba(var(--bs-primary-rgb), .02); }
.list-item .body { flex: 1; min-width: 0; }
.list-item .title { font-weight: 600; font-size: .8125rem; }
.list-item .meta { font-size: .6875rem; color: var(--bs-secondary-color); margin-top: 1px; }

/* Notification panel */
.notif-panel { width: 380px; max-width: 92vw; padding: 0; max-height: 520px; overflow-y: auto; }
.notif-bulk-bar { background: var(--bs-tertiary-bg); font-size: .75rem; }
.notif-bulk-bar .form-check-input { width: .85em; height: .85em; }
.notif-item {
  padding: 10px 14px;
  border-bottom: 1px solid var(--bs-border-color);
  cursor: pointer; transition: background .12s, transform .25s ease, opacity .25s ease;
  overflow: hidden;
}
.notif-item:hover { background: var(--bs-tertiary-bg); }
.notif-item.unread { background: rgba(var(--bs-primary-rgb), .06); border-left: 3px solid var(--bs-primary); }
.notif-item .title { font-weight: 600; font-size: .8125rem; line-height: 1.4; }
.notif-item .meta { font-size: .6875rem; color: var(--bs-secondary-color); margin-top: 2px; }
.notif-item .notif-del-btn { opacity: 0; transition: opacity .15s; font-size: .7rem; }
.notif-item:hover .notif-del-btn { opacity: .7; }
.notif-item:hover .notif-del-btn:hover { opacity: 1; }
.notif-item .notif-check { width: .8em; height: .8em; }
.notif-item .min-w-0 { min-width: 0; }

/* Announcement card */
.announce {
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-left: 3px solid var(--bs-primary);
  border-radius: var(--tt-radius-sm); padding: 14px 16px;
  transition: box-shadow .15s;
}
.announce:hover { box-shadow: var(--tt-shadow-sm); }
.announce.pinned { border-left-color: var(--bs-warning); background: rgba(var(--bs-warning-rgb), .04); }
.announce .title { font-weight: 700; margin-bottom: 3px; font-size: .875rem; }
.announce .meta { font-size: .6875rem; color: var(--bs-secondary-color); }
.announce .body { font-size: .8125rem; margin-top: 6px; white-space: pre-wrap; line-height: 1.6; }

/* Document item */
.doc-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius-sm);
  background: var(--tt-surface); margin-bottom: 8px;
  transition: all var(--tt-transition);
}
.doc-item:hover { box-shadow: var(--tt-shadow-sm); border-color: rgba(var(--bs-primary-rgb), .2); }
.doc-item .icon {
  width: 40px; height: 40px;
  background: rgba(var(--bs-primary-rgb), .08);
  color: var(--bs-primary);
  border-radius: var(--tt-radius-sm);
  display: grid; place-items: center; font-size: 1.1rem; flex-shrink: 0;
}
.doc-item .body { flex: 1; min-width: 0; }
.doc-item .name { font-weight: 600; font-size: .8125rem; word-break: break-word; }
.doc-item .meta { font-size: .6875rem; color: var(--bs-secondary-color); }

/* Schedule editor */
.sched-row {
  display: grid; grid-template-columns: 1fr; gap: 8px;
  padding: 12px; border-radius: var(--tt-radius-sm);
}
.sched-row:nth-child(odd) { background: var(--bs-tertiary-bg); }
@media (min-width: 768px) { .sched-row { grid-template-columns: 1fr 130px 130px 110px; align-items: center; } }

/* Person card (org) */
.person-card {
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius);
  padding: 20px; text-align: center;
  transition: all var(--tt-transition);
}
.person-card:hover { transform: translateY(-2px); box-shadow: var(--tt-shadow-md); border-color: rgba(var(--bs-primary-rgb), .15); }
.person-card .avatar { width: 64px; height: 64px; font-size: 1.15rem; margin: 0 auto 12px; }
.person-card .name { font-weight: 700; font-size: .875rem; letter-spacing: -.01em; }
.person-card .role { color: var(--bs-secondary-color); font-size: .75rem; }

/* Onboarding checklist */
.checklist-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 4px; border-bottom: 1px solid var(--bs-border-color);
}
.checklist-item:last-child { border-bottom: 0; }
.checklist-item.done .text { text-decoration: line-through; color: var(--bs-secondary-color); }

/* Form switches */
.form-check.form-switch .form-check-input { width: 2.4em; height: 1.3em; }

/* Table scroll mobile */
.table-responsive { -webkit-overflow-scrolling: touch; }

/* ============================================================
   MOBILE REFINEMENTS
   ============================================================ */
@media (max-width: 991.98px) { .main { padding-bottom: 4px; } }

@media (max-width: 575.98px) {
  .table > :not(caption) > * > * { padding: .5rem .5rem; font-size: .75rem; }
  .table-wrap thead th { font-size: .6rem; padding: .5rem; }
  .kpi { padding: 12px 14px; gap: 10px; }
  .kpi .icon { width: 38px; height: 38px; font-size: 1.05rem; }
  .kpi .value { font-size: 1.25rem; }
  .kpi .label { font-size: .625rem; }
  .section-title { font-size: .9375rem; }
  .section-sub { font-size: .75rem; }
  .content { padding: 12px; }
}

/* ── Helpers ─────────────────────────────────────────────────── */
.text-truncate-2 { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cursor-pointer { cursor: pointer; }
.dot-online { display: inline-block; width: 8px; height: 8px; background: var(--bs-success); border-radius: 50%; margin-right: 6px; }

/* ============================================================
   DARK MODE
   Only rules that Bootstrap 5.3 can't auto-handle
   ============================================================ */
[data-bs-theme="dark"] {
  /* ── Color Theory: Dark Mode ──────────────────────────────
     Lienzo (body): Slate-950 ultra-dark → surfaces elevate visibly.
     Surface 1: Slate-800 (+1 step) → cards, KPIs, tables, modals.
     Surface 2: Slate-750 (+1.5 steps) → zebra, hover, nested surfaces.
     Borders: Slate-700 (visible separation, WCAG 3:1 non-text contrast).
     Text primary: Slate-100 (#f1f5f9) → 15.4:1 on slate-950, AAA.
     Text secondary: Slate-400 (#94a3b8) → 5.5:1 on slate-800, AA.
     ────────────────────────────────────────────────────────── */
  --bs-body-bg: #0b1220;
  --bs-body-color: #f1f5f9;
  --bs-secondary-color: #94a3b8;
  --bs-secondary-bg: #1e293b;
  --bs-tertiary-bg: #1a2332;
  --bs-tertiary-color: #64748b;
  --bs-border-color: #293548;
  --bs-emphasis-color: #f8fafc;
  --bs-emphasis-color-rgb: 248,250,252;
  --tt-surface: #162032;
  --tt-surface-2: #1e293b;
  --tt-shadow-xs: 0 1px 2px rgba(0,0,0,.35);
  --tt-shadow-sm: 0 1px 3px rgba(0,0,0,.45);
  --tt-shadow: 0 4px 12px rgba(0,0,0,.55);
  --tt-shadow-md: 0 8px 24px rgba(0,0,0,.6);
  --tt-shadow-lg: 0 20px 40px rgba(0,0,0,.7);
  /* Semantic palette — lightened for dark bg (400 weight of each hue) */
  --tt-morning:   #2dd4bf;
  --tt-afternoon: #fbbf24;
  --tt-night:     #a78bfa;
  --tt-split:     #fb923c;
  --tt-rest:      #64748b;
  --tt-custom:    #f472b6;
  --tt-positive:  #34d399;
  --tt-caution:   #fbbf24;
  --tt-alert:     #fb7185;
  --tt-vac:       #2dd4bf;
  --tt-sick:      #fb7185;
  --tt-leave:     #60a5fa;
  --tt-maternity: #c084fc;
  --tt-paternity: #818cf8;
  --tt-other:     #94a3b8;
}

/* ── Dark: Layout shells ──────────────────────────────────── */
[data-bs-theme="dark"] .sidebar { background: #020617; }
[data-bs-theme="dark"] .offcanvas.sidebar,
[data-bs-theme="dark"] .offcanvas-lg.sidebar { --bs-offcanvas-bg: #020617; }
[data-bs-theme="dark"] .login-form-side { background: var(--bs-body-bg); }

/* ── Dark: Form controls & inputs ─────────────────────────── */
[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select {
  background-color: var(--tt-surface);
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
}
[data-bs-theme="dark"] .form-control::placeholder { color: var(--bs-tertiary-color); }
[data-bs-theme="dark"] .form-control:focus,
[data-bs-theme="dark"] .form-select:focus {
  background-color: var(--tt-surface-2);
  color: var(--bs-body-color);
  border-color: var(--bs-primary);
}
[data-bs-theme="dark"] .form-label { color: var(--bs-secondary-color); }

/* ── Dark: Dropdown menus ─────────────────────────────────── */
[data-bs-theme="dark"] .dropdown-menu {
  background-color: var(--tt-surface);
  border-color: var(--bs-border-color);
  box-shadow: var(--tt-shadow-md);
}
[data-bs-theme="dark"] .dropdown-item {
  color: var(--bs-body-color);
}
[data-bs-theme="dark"] .dropdown-item:hover,
[data-bs-theme="dark"] .dropdown-item:focus {
  background: var(--tt-surface-2);
  color: var(--bs-body-color);
}
[data-bs-theme="dark"] .dropdown-item:active {
  background: var(--bs-primary);
  color: #fff;
}

/* ── Dark: Modals ─────────────────────────────────────────── */
[data-bs-theme="dark"] .modal-content {
  background: var(--tt-surface);
  color: var(--bs-body-color);
}
[data-bs-theme="dark"] .modal-header { border-bottom-color: var(--bs-border-color); }
[data-bs-theme="dark"] .modal-footer { border-top-color: var(--bs-border-color); }

/* ── Dark: Cards & surfaces ───────────────────────────────── */
[data-bs-theme="dark"] .kpi .icon.purple { background: rgba(139,92,246,.15); color: #a78bfa; }
[data-bs-theme="dark"] .cal-day .m-hol { background: rgba(var(--bs-warning-rgb), .12); color: #fcd34d; }
[data-bs-theme="dark"] .announce { background: var(--tt-surface); }
[data-bs-theme="dark"] .announce.pinned { background: rgba(var(--bs-warning-rgb), .08); }
[data-bs-theme="dark"] .punch-card {
  background: linear-gradient(135deg, #312e81 0%, #4338ca 30%, #6366f1 70%, #818cf8 100%);
  box-shadow: 0 12px 32px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
}
[data-bs-theme="dark"] .btn-primary {
  box-shadow: 0 1px 2px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.08);
}
[data-bs-theme="dark"] .btn-light {
  --bs-btn-bg: var(--tt-surface);
  border-color: var(--bs-border-color);
  color: var(--bs-body-color);
}
[data-bs-theme="dark"] .btn-light:hover {
  background: var(--tt-surface-2);
  border-color: var(--bs-border-color);
  color: var(--bs-body-color);
}

/* ── Dark: Tables ─────────────────────────────────────────── */
[data-bs-theme="dark"] .table-wrap thead th {
  background: var(--tt-surface-2);
  color: var(--bs-secondary-color);
  border-bottom-color: var(--bs-border-color);
}
[data-bs-theme="dark"] .table-wrap tbody tr:hover { background: rgba(255,255,255,.02); }
[data-bs-theme="dark"] .table > :not(caption) > * > * {
  color: var(--bs-body-color);
  border-bottom-color: var(--bs-border-color);
}
[data-bs-theme="dark"] .list-item:hover { background: rgba(255,255,255,.02); }

/* ── Dark: Nav tabs ───────────────────────────────────────── */
[data-bs-theme="dark"] .nav-tabs { border-bottom-color: var(--bs-border-color); }
[data-bs-theme="dark"] .nav-tabs .nav-link { color: var(--bs-secondary-color); }
[data-bs-theme="dark"] .nav-tabs .nav-link.active { color: var(--bs-primary); }

/* ── Dark: Scrollbar ──────────────────────────────────────── */
[data-bs-theme="dark"] ::-webkit-scrollbar-thumb { background: rgba(255,255,255,.1); }
[data-bs-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.18); }

/* ── Dark: Consent / legal / banners ──────────────────────── */
[data-bs-theme="dark"] .consent-banner { background: var(--tt-surface); border-top-color: var(--bs-border-color); }
[data-bs-theme="dark"] .consent-modal { background: var(--tt-surface); }
[data-bs-theme="dark"] .legal-footer { color: var(--bs-secondary-color); }
[data-bs-theme="dark"] .legal-footer a { color: var(--bs-secondary-color); }

/* ── Dark: Icon buttons ───────────────────────────────────── */
[data-bs-theme="dark"] .btn-icon {
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
}
[data-bs-theme="dark"] .btn-icon:hover {
  background: rgba(var(--bs-primary-rgb), .12);
  border-color: rgba(var(--bs-primary-rgb), .35);
  color: var(--bs-primary);
}

/* Dark-mode adjustments for Factorial-inspired components */
[data-bs-theme="dark"] .vac-counter-card { background: var(--bs-tertiary-bg); }
[data-bs-theme="dark"] .abs-type-badge.vacaciones    { background: rgba(244,63,94,.18);  color: #fda4af; }
[data-bs-theme="dark"] .abs-type-badge.baja_medica   { background: rgba(225,29,72,.18);  color: #fda4af; }
[data-bs-theme="dark"] .abs-type-badge.permiso       { background: rgba(217,119,6,.20);  color: #fcd34d; }
[data-bs-theme="dark"] .abs-type-badge.asuntos_propios { background: rgba(37,99,235,.20); color: #93c5fd; }
[data-bs-theme="dark"] .abs-type-badge.maternidad    { background: rgba(147,51,234,.20); color: #d8b4fe; }
[data-bs-theme="dark"] .abs-type-badge.teletrabajo   { background: rgba(13,148,136,.20); color: #5eead4; }
[data-bs-theme="dark"] .abs-type-badge.mudanza       { background: rgba(234,88,12,.20);  color: #fdba74; }
[data-bs-theme="dark"] .falta-fichaje-pill { background: rgba(225,29,72,.18); color: #fda4af; border-color: rgba(225,29,72,.32); }
[data-bs-theme="dark"] .cal-day .m-vac     { background: rgba(244,63,94,.20);  color: #fda4af; }
[data-bs-theme="dark"] .cal-day .m-tele    { background: rgba(13,148,136,.20); color: #5eead4; }
[data-bs-theme="dark"] .cal-day .m-baja    { background: rgba(225,29,72,.20);  color: #fda4af; }
[data-bs-theme="dark"] .cal-day .m-perm    { background: rgba(217,119,6,.22);  color: #fcd34d; }
[data-bs-theme="dark"] .cal-day .m-pers    { background: rgba(37,99,235,.20);  color: #93c5fd; }
[data-bs-theme="dark"] .cal-day .m-mud     { background: rgba(234,88,12,.20);  color: #fdba74; }
[data-bs-theme="dark"] .cal-day .m-mat     { background: rgba(147,51,234,.20); color: #d8b4fe; }
[data-bs-theme="dark"] .cal-day .m-work    { background: rgba(34,197,94,.18);  color: #86efac; }

/* ──────────────────────────────────────────────────────────────────
   Pendiente de fichar 2.0 — Modern SaaS design
   • Severity-based color tone (on-time / slight / late / critical)
   • Lateness badges with icons
   • Inline quick actions (remind / view profile)
   • Stagger entrance animation
   • Glass-morphism card surface
   ────────────────────────────────────────────────────────────────── */

/* Severity tokens (CSS custom properties) */
.pending-punch-section {
  --pps-tone-bg-start: rgba(99,102,241,.06);
  --pps-tone-bg-end:   rgba(99,102,241,.02);
  --pps-tone-border:   rgba(99,102,241,.15);
  --pps-tone-accent:   #6366f1;
  --pps-tone-accent-soft: rgba(99,102,241,.10);
}
.pending-punch-section.pps-sev-on-time {
  --pps-tone-bg-start: rgba(16,185,129,.06);
  --pps-tone-bg-end:   rgba(16,185,129,.02);
  --pps-tone-border:   rgba(16,185,129,.18);
  --pps-tone-accent:   #059669;
  --pps-tone-accent-soft: rgba(16,185,129,.10);
}
.pending-punch-section.pps-sev-slight {
  --pps-tone-bg-start: rgba(217,119,6,.06);
  --pps-tone-bg-end:   rgba(217,119,6,.02);
  --pps-tone-border:   rgba(217,119,6,.20);
  --pps-tone-accent:   #d97706;
  --pps-tone-accent-soft: rgba(217,119,6,.10);
}
.pending-punch-section.pps-sev-late {
  --pps-tone-bg-start: rgba(234,88,12,.08);
  --pps-tone-bg-end:   rgba(234,88,12,.02);
  --pps-tone-border:   rgba(234,88,12,.25);
  --pps-tone-accent:   #ea580c;
  --pps-tone-accent-soft: rgba(234,88,12,.10);
}
.pending-punch-section.pps-sev-critical {
  --pps-tone-bg-start: rgba(225,29,72,.10);
  --pps-tone-bg-end:   rgba(225,29,72,.02);
  --pps-tone-border:   rgba(225,29,72,.28);
  --pps-tone-accent:   #e11d48;
  --pps-tone-accent-soft: rgba(225,29,72,.10);
}

/* Section container — uses severity tone tokens */
.pending-punch-section {
  margin: -4px -4px 16px;
  padding: 12px 14px 14px;
  border-radius: var(--tt-radius);
  background: linear-gradient(135deg, var(--pps-tone-bg-start), var(--pps-tone-bg-end));
  border: 1px solid var(--pps-tone-border);
  min-width: 0;
  position: relative;
  overflow: hidden;
}
/* Subtle accent stripe on the left edge */
.pending-punch-section::before {
  content: '';
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 3px; background: var(--pps-tone-accent);
  opacity: .6; border-radius: 0 2px 2px 0;
}

.pending-punch-section .pps-header {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-bottom: 12px; padding-bottom: 10px;
  border-bottom: 1px dashed var(--pps-tone-border);
  min-width: 0;
}
.pending-punch-section .pps-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: .82rem; color: var(--pps-tone-accent);
  min-width: 0; letter-spacing: -.01em;
}
.pending-punch-section .pps-title .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--pps-tone-accent);
  box-shadow: 0 0 0 4px var(--pps-tone-accent-soft);
  animation: pulse 2s ease-in-out infinite;
  flex-shrink: 0;
}
.pending-punch-section .pps-count {
  background: var(--pps-tone-accent); color: #fff; font-weight: 800; font-size: .68rem;
  min-width: 22px; text-align: center;
  padding: 2px 8px; border-radius: 999px;
  font-feature-settings: 'tnum'; letter-spacing: .02em;
  flex-shrink: 0;
  box-shadow: 0 1px 3px var(--pps-tone-accent-soft);
}
.pending-punch-section .pps-clock {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .72rem; color: var(--bs-secondary-color);
  font-feature-settings: 'tnum';
  padding: 2px 8px; border-radius: 999px;
  background: rgba(var(--bs-emphasis-color-rgb), .04);
  border: 1px solid var(--bs-border-color);
}
.pending-punch-section .pps-clock i { opacity: .7; font-size: .68rem; }
.pending-punch-section .pps-bulk-btn {
  margin-left: auto;
  font-size: .72rem; font-weight: 600;
  padding: .3rem .7rem;
  border-radius: var(--tt-radius-sm);
  background: var(--pps-tone-accent); color: #fff;
  border: 1px solid var(--pps-tone-accent);
  transition: all .15s ease;
  flex-shrink: 0;
}
.pending-punch-section .pps-bulk-btn:hover {
  filter: brightness(1.08);
  box-shadow: 0 4px 12px var(--pps-tone-accent-soft);
  transform: translateY(-1px);
}
@media (max-width: 480px) {
  .pending-punch-section .pps-bulk-btn { margin-left: 0; flex: 1 1 100%; text-align: center; }
}

.pending-punch-list {
  display: grid; gap: 8px;
  /* Container-aware: 2 cols only when there's genuinely room for avatar + info + actions.
     Falls back to 1 col on narrow containers (e.g. col-lg-7 at 1200–1500px viewport). */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
}

/* Stagger entrance animation */
@keyframes ppsRowIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.pending-punch-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: var(--tt-radius-sm);
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-left: 3px solid var(--bs-border-color);
  transition: all .18s cubic-bezier(.4,0,.2,1);
  text-align: left; width: 100%;
  min-width: 0;
  opacity: 0;
  animation: ppsRowIn .35s ease-out forwards;
}
/* Severity-aware left border per row */
.pending-punch-row.sev-on-time   { border-left-color: #10b981; }
.pending-punch-row.sev-slight    { border-left-color: #d97706; }
.pending-punch-row.sev-late      { border-left-color: #ea580c; }
.pending-punch-row.sev-critical  { border-left-color: #e11d48; }
.pending-punch-row:hover {
  background: rgba(var(--bs-emphasis-color-rgb), .02);
  box-shadow: var(--tt-shadow-sm);
}
@media (hover: hover) {
  .pending-punch-row:hover { transform: translateX(2px); }
}

.pending-punch-row .pps-avatar { position: relative; flex-shrink: 0; }
.pending-punch-row .pps-avatar .badge-x {
  position: absolute; bottom: -2px; right: -2px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #6366f1; border: 2px solid var(--bs-body-bg);
  display: grid; place-items: center;
  color: #fff; font-size: .55rem; line-height: 1;
  box-shadow: 0 1px 3px rgba(0,0,0,.18);
}
.pending-punch-row .pps-avatar .badge-x.sev-on-time   { background: #10b981; }
.pending-punch-row .pps-avatar .badge-x.sev-slight    { background: #d97706; }
.pending-punch-row .pps-avatar .badge-x.sev-late      { background: #ea580c; }
.pending-punch-row .pps-avatar .badge-x.sev-critical  { background: #e11d48; animation: pulse 1.6s ease-in-out infinite; }

.pending-punch-row .pps-info {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.pending-punch-row .pps-info .name {
  font-weight: 600; font-size: .85rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  letter-spacing: -.005em;
}
.pending-punch-row .pps-info .meta {
  font-size: .68rem; color: var(--bs-secondary-color);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pending-punch-row .pps-tags {
  display: flex; align-items: center; gap: 6px; margin-top: 4px;
  flex-wrap: wrap;
}
.pending-punch-row .pps-start {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .68rem; font-weight: 600;
  padding: 2px 7px; border-radius: 999px;
  white-space: nowrap;
  background: rgba(var(--bs-emphasis-color-rgb), .05);
  color: var(--bs-secondary-color);
  font-feature-settings: 'tnum';
}
.pending-punch-row .pps-start i { font-size: .62rem; opacity: .7; }

.pending-punch-row .pps-late {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .68rem; font-weight: 700;
  padding: 2px 8px; border-radius: 999px;
  white-space: nowrap;
  font-feature-settings: 'tnum';
  letter-spacing: -.005em;
  border: 1px solid transparent;
}
.pending-punch-row .pps-late.sev-on-time {
  background: rgba(16,185,129,.10); color: #059669;
  border-color: rgba(16,185,129,.20);
}
.pending-punch-row .pps-late.sev-slight {
  background: rgba(217,119,6,.10); color: #b45309;
  border-color: rgba(217,119,6,.22);
}
.pending-punch-row .pps-late.sev-late {
  background: rgba(234,88,12,.12); color: #c2410c;
  border-color: rgba(234,88,12,.25);
}
.pending-punch-row .pps-late.sev-critical {
  background: rgba(225,29,72,.12); color: #be123c;
  border-color: rgba(225,29,72,.28);
}
.pending-punch-row .pps-late i { font-size: .62rem; }

/* Inline action buttons */
.pending-punch-row .pps-actions {
  display: flex; gap: 4px; flex-shrink: 0;
}
.pending-punch-row .pps-action {
  width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center;
  background: transparent;
  color: var(--bs-secondary-color);
  border: 1px solid transparent;
  font-size: .82rem;
  cursor: pointer;
  transition: all .15s ease;
  padding: 0;
}
.pending-punch-row .pps-action:hover {
  background: var(--pps-tone-accent-soft);
  color: var(--pps-tone-accent);
  border-color: var(--pps-tone-border);
  transform: scale(1.08);
}
.pending-punch-row .pps-action:active {
  transform: scale(.95);
}
/* v25 (#13) — Botón "enviado" tras quickRemindEmployee: verde + disabled */
.pending-punch-row .pps-action.remind.sent {
  background: rgba(16, 185, 129, .12);
  color: #059669;
  border-color: rgba(16, 185, 129, .25);
  cursor: default;
  pointer-events: none;
}
.pending-punch-row .pps-action.remind.sent:hover { transform: none; }
[data-bs-theme="dark"] .pending-punch-row .pps-action.remind.sent {
  background: rgba(52, 211, 153, .15);
  color: #34d399;
  border-color: rgba(52, 211, 153, .28);
}
/* Botón "Personalizar" (puerta a modal) — discreto */
.pending-punch-row .pps-action.customize:hover {
  background: rgba(148, 163, 184, .12);
  color: var(--bs-body-color);
}
/* Botón link "Personalizar..." en el header de la sección */
.pending-punch-section .pps-customize-btn {
  padding: .15rem .35rem;
  font-size: .75rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.pending-punch-section .pps-customize-btn:hover {
  color: var(--bs-primary);
}
.pending-punch-row .pps-action.remind:hover {
  background: rgba(99,102,241,.10);
  color: #4f46e5;
  border-color: rgba(99,102,241,.20);
}

/* Dark theme adjustments */
[data-bs-theme="dark"] .pending-punch-row {
  background: var(--bs-tertiary-bg);
}
[data-bs-theme="dark"] .pending-punch-row:hover {
  background: rgba(255,255,255,.03);
}
[data-bs-theme="dark"] .pending-punch-row .pps-avatar .badge-x {
  border-color: var(--bs-tertiary-bg);
}
[data-bs-theme="dark"] .pending-punch-section .pps-clock {
  background: rgba(255,255,255,.04);
}
[data-bs-theme="dark"] .pending-punch-row .pps-late.sev-on-time {
  background: rgba(16,185,129,.16); color: #6ee7b7;
}
[data-bs-theme="dark"] .pending-punch-row .pps-late.sev-slight {
  background: rgba(217,119,6,.18); color: #fcd34d;
}
[data-bs-theme="dark"] .pending-punch-row .pps-late.sev-late {
  background: rgba(234,88,12,.20); color: #fdba74;
}
[data-bs-theme="dark"] .pending-punch-row .pps-late.sev-critical {
  background: rgba(225,29,72,.20); color: #fda4af;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .pending-punch-row { animation: none; opacity: 1; }
  .pending-punch-section .pps-title .dot { animation: none; }
  .pending-punch-row .pps-avatar .badge-x.sev-critical { animation: none; }
}

/* ── Tip card (lightbulb hint, Image 4) ── */
.tip-card {
  display: flex; gap: 10px; align-items: flex-start;
  background: rgba(217,119,6,.06);
  border: 1px solid rgba(217,119,6,.15);
  border-radius: var(--tt-radius);
  padding: 10px 12px; font-size: .78rem;
  position: relative;
}
.tip-card .tip-icon {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 8px;
  background: rgba(217,119,6,.12); color: #d97706;
  display: grid; place-items: center; font-size: 1rem;
}
.tip-card .tip-body { flex: 1; min-width: 0; line-height: 1.4; color: var(--bs-body-color); }
.tip-card .tip-body strong { color: #92400e; }
.tip-card .tip-close {
  background: transparent; border: 0; padding: 2px 4px; line-height: 1;
  color: var(--bs-secondary-color); cursor: pointer; font-size: .85rem;
}
[data-bs-theme="dark"] .tip-card { background: rgba(217,119,6,.10); border-color: rgba(217,119,6,.22); }
[data-bs-theme="dark"] .tip-card .tip-body strong { color: #fcd34d; }

/* ── +1d badge for overnight shifts (Image 12) ── */
.shift-overnight-badge {
  display: inline-block; vertical-align: middle;
  background: rgba(147,51,234,.10); color: #6b21a8;
  font-size: .58rem; font-weight: 800; letter-spacing: .03em;
  padding: 1px 5px; border-radius: 4px; margin-left: 4px;
  font-feature-settings: 'tnum';
}
[data-bs-theme="dark"] .shift-overnight-badge { background: rgba(147,51,234,.22); color: #d8b4fe; }

/* ── Project pill (project tracking) ── */
.project-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: .68rem; font-weight: 600;
  background: rgba(99,102,241,.10); color: #4338ca;
  white-space: nowrap;
}
.project-pill::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--p-color, #6366f1);
}
[data-bs-theme="dark"] .project-pill { background: rgba(99,102,241,.22); color: #a5b4fc; }

/* ── Project card (admin grid) ── */
.project-card {
  background: var(--tt-surface); border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius-lg); padding: 14px 16px;
  border-left: 4px solid var(--p-color, var(--bs-primary));
  transition: all .15s ease;
}
.project-card:hover { box-shadow: var(--tt-shadow-md); transform: translateY(-1px); }
.project-card .project-name { font-weight: 700; font-size: .9rem; color: var(--bs-body-color); }
.project-card .project-desc { font-size: .72rem; color: var(--bs-secondary-color); margin-top: 2px; }
.project-card .project-stats { display: flex; gap: 10px; margin-top: 10px; font-size: .7rem; color: var(--bs-secondary-color); }
.project-card .project-stats strong { color: var(--bs-body-color); font-feature-settings: 'tnum'; }
.project-card .actions { display: flex; gap: 4px; margin-top: 10px; }

/* ── Shift swap pill ── */
.shift-swap-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: .68rem; font-weight: 600;
  background: rgba(13,148,136,.10); color: #115e59;
}
[data-bs-theme="dark"] .shift-swap-pill { background: rgba(13,148,136,.22); color: #5eead4; }

/* Picker dropdown: hide current active item so user only sees alternatives */
li:has(> .lang-picker-item.active),
li:has(> .color-theme-item.active) {
  display: none;
}
.color-theme-item, .lang-picker-item { display: flex; align-items: center; }

/* ── Offline indicator ─────────────────────────────────────── */
.offline-banner {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 9999;
  background: linear-gradient(135deg, #f59e0b, #d97706);
  color: #fff; text-align: center;
  font-size: .8125rem; font-weight: 600;
  padding: .5rem 1rem;
  letter-spacing: .01em;
  animation: slideUp .3s ease;
}
.offline-banner.show { display: block; }
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
.offline-banner i { margin-right: .375rem; }

/* ════════════════════════════════════════════════════════════
   v2.6.10 · UPDATE BANNER premium · theme-aware
   ------------------------------------------------------------
   Hereda gradient de la paleta activa (Atlántico/Factorial/Nimbus
   o branding custom).  La sombra y los acentos también heredan
   el RGB del primary del tema actual via rgba(var(--bs-primary-
   rgb), …) para que la barra se sienta nativa del tema.

   Componentes:
     · Bg principal:  var(--tt-grad-primary)
     · Inner highlight: 1px blanco interior para premium feel
     · Box-shadow: dual layer (depth + halo theme-tinted)
     · Icono arrow-repeat: spin animation suave (--pe-ease)
     · .btn-update: white card-style con lift + halo theme primary
     · .btn-dismiss: ghost outline con bg hover sutil
   ════════════════════════════════════════════════════════════ */
.update-banner {
  display: none;
  position: fixed; top: 0; left: 0; right: 0; z-index: 1060;
  background: var(--tt-grad-primary, linear-gradient(135deg, var(--bs-primary, #6366f1), color-mix(in srgb, var(--bs-primary, #6366f1) 70%, #fff)));
  color: #fff;
  padding: .65rem 1rem;
  font-size: .85rem;
  font-weight: 500;
  text-align: center;
  /* Dual shadow: depth (neutral) + halo (theme-tinted) */
  box-shadow:
    0 4px 14px -2px rgba(0,0,0,.20),
    0 2px 8px -2px rgba(var(--bs-primary-rgb, 99,102,241), .35),
    inset 0 1px 0 rgba(255,255,255,.14);
  animation: slideDown .35s cubic-bezier(.2,.9,.2,1);
  letter-spacing: -.005em;
}
.update-banner.show { display: flex; align-items: center; justify-content: center; gap: .75rem; flex-wrap: wrap; }
@keyframes slideDown { from { transform: translateY(-100%); } to { transform: translateY(0); } }

.update-banner .update-msg {
  flex: 1 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-weight: 600;
}
/* Spin sutil sólo cuando aún no se ha aplicado (banner visible) */
.update-banner .update-msg .bi-arrow-repeat {
  display: inline-block;
  animation: updateBannerSpin 2.4s linear infinite;
  font-size: 1rem;
  opacity: .92;
}
@keyframes updateBannerSpin {
  to { transform: rotate(360deg); }
}
.update-banner .update-version {
  opacity: .82;
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* Update CTA: card blanco con halo theme primary */
.update-banner .btn-update {
  background: #fff;
  color: var(--bs-primary, #4f46e5);
  border: none;
  padding: .42rem 1rem;
  border-radius: 8px;
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  letter-spacing: -.005em;
  box-shadow:
    0 2px 6px -1px rgba(0,0,0,.18),
    inset 0 -1px 0 rgba(0,0,0,.04);
  transition:
    transform .15s cubic-bezier(.2,.9,.2,1),
    box-shadow .15s cubic-bezier(.2,.9,.2,1);
}
.update-banner .btn-update:hover {
  transform: translateY(-1px);
  box-shadow:
    0 5px 14px -2px rgba(0,0,0,.30),
    0 0 0 3px rgba(255,255,255,.22),
    inset 0 -1px 0 rgba(0,0,0,.04);
}
.update-banner .btn-update:active {
  transform: translateY(0);
  box-shadow:
    0 1px 3px -1px rgba(0,0,0,.18),
    inset 0 1px 0 rgba(0,0,0,.06);
}

/* Dismiss CTA: ghost outline */
.update-banner .btn-dismiss {
  background: transparent;
  border: 1px solid rgba(255,255,255,.32);
  color: #fff;
  padding: .38rem .85rem;
  border-radius: 8px;
  font-size: .8rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  letter-spacing: -.005em;
  transition:
    background .15s cubic-bezier(.2,.9,.2,1),
    border-color .15s cubic-bezier(.2,.9,.2,1);
}
.update-banner .btn-dismiss:hover {
  background: rgba(255,255,255,.12);
  border-color: rgba(255,255,255,.48);
}
.update-banner .btn-dismiss:active {
  background: rgba(255,255,255,.18);
}

/* Reduced motion: kill the spin + slide */
@media (prefers-reduced-motion: reduce) {
  .update-banner { animation: none; }
  .update-banner .update-msg .bi-arrow-repeat { animation: none; }
}

/* Cookie consent banner */
.consent-banner {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1070;
  background: var(--bs-body-bg, #fff); border-top: 1px solid var(--bs-border-color, #dee2e6);
  box-shadow: 0 -4px 24px rgba(0,0,0,.12); padding: 1.25rem 1.5rem;
  animation: slideUp .35s ease;
}
.consent-banner.show { display: block; }
.consent-inner { max-width: 960px; margin: 0 auto; }
.consent-text strong { display: block; font-size: .95rem; margin-bottom: .35rem; }
.consent-text p { font-size: .82rem; color: var(--bs-secondary-color, #6c757d); margin-bottom: .75rem; line-height: 1.5; }
.consent-text a { color: var(--primary, #4f46e5); text-decoration: underline; }
.consent-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.btn-consent {
  padding: .45rem 1rem; border-radius: 6px; font-size: .82rem; font-weight: 600;
  border: none; cursor: pointer; transition: opacity .15s; white-space: nowrap;
}
.btn-consent-accept { background: var(--primary, #4f46e5); color: #fff; }
.btn-consent-accept:hover { opacity: .9; }
.btn-consent-reject { background: var(--bs-tertiary-bg, #f0f0f0); color: var(--bs-body-color, #212529); }
.btn-consent-reject:hover { opacity: .85; }
.btn-consent-config { background: transparent; color: var(--primary, #4f46e5); border: 1px solid var(--primary, #4f46e5); }
.btn-consent-config:hover { opacity: .85; }

/* Consent settings modal */
.consent-modal-overlay {
  display: none; position: fixed; inset: 0; z-index: 1080;
  background: rgba(0,0,0,.45); backdrop-filter: blur(2px);
  align-items: center; justify-content: center; padding: 1rem;
}
.consent-modal-overlay.show { display: flex; }
.consent-modal {
  background: var(--bs-body-bg, #fff); border-radius: 12px; width: 100%; max-width: 520px;
  max-height: 90vh; overflow-y: auto; box-shadow: 0 8px 32px rgba(0,0,0,.18);
}
.consent-modal-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 1rem 1.25rem; border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
.consent-modal-header h3 { margin: 0; font-size: 1rem; font-weight: 700; }
.consent-modal-body { padding: 1.25rem; }
.consent-category {
  padding: .75rem 0; border-bottom: 1px solid var(--bs-border-color-translucent, rgba(0,0,0,.08));
}
.consent-category:last-of-type { border-bottom: none; }
.consent-category strong { font-size: .85rem; }
.consent-category p { font-size: .78rem; line-height: 1.45; }
.consent-modal-footer {
  display: flex; justify-content: flex-end; gap: .5rem;
  padding: .75rem 1.25rem; border-top: 1px solid var(--bs-border-color, #dee2e6);
}

/* Legal footer */
.legal-footer {
  font-size: .72rem; color: var(--bs-secondary-color, #6c757d); text-align: center;
  padding: .5rem 1rem; border-top: 1px solid var(--bs-border-color-translucent, rgba(0,0,0,.06));
}
.legal-footer a { color: var(--bs-secondary-color, #6c757d); text-decoration: underline; margin: 0 .35rem; }
.legal-footer a:hover { color: var(--primary, #4f46e5); }
.legal-footer .consent-revoke { cursor: pointer; }

/* ── Absence calendar ─────────────────────────────────────── */
.abs-cal-scroll { overflow-x: auto; }
.abs-cal-table { border-collapse: collapse; width: 100%; min-width: 600px; }
.abs-cal-table th, .abs-cal-table td { border: 1px solid var(--bs-border-color, #e5e7eb); text-align: center; font-size: .7rem; padding: 2px; }
.abs-cal-emp { position: sticky; left: 0; background: var(--tt-surface); z-index: 1; min-width: 140px; text-align: left !important; padding: 4px 6px !important; }
.abs-cal-day { width: 28px; min-width: 28px; }
.abs-cal-day.weekend, .abs-cal-cell.weekend { background: var(--bs-tertiary-bg, #f1f5f9); }
.abs-cal-cell { position: relative; height: 28px; }
.abs-cal-dot { display: block; width: 10px; height: 10px; border-radius: 50%; margin: auto; }
.abs-legend { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: middle; margin-right: 2px; }
/* v2.6.12 — variantes semánticas para `.abs-legend` (legend dot por tipo de
   ausencia). Reemplazan inline style="background:#hex" en admin.html y
   homogeneizan los colores con `.abs-type-badge::before` (source of truth):
     vacaciones    rose  #f43f5e
     baja_medica   red   #e11d48
     permiso       amber #d97706
     asuntos_pr.   blue  #2563eb
     maternidad    purple #9333ea
     teletrabajo   teal  #0d9488
     mudanza       orange #ea580c
   Mantengo los hex (no rgba con var(--bs-*)) porque son colores semánticos
   por tipo de ausencia, NO theme tokens. Igual que `.abs-type-badge::before`. */
.abs-legend.vacaciones    { background: #f43f5e; }
.abs-legend.baja_medica   { background: #e11d48; }
.abs-legend.permiso       { background: #d97706; }
.abs-legend.asuntos_propios { background: #2563eb; }
.abs-legend.maternidad    { background: #9333ea; }
.abs-legend.teletrabajo   { background: #0d9488; }
.abs-legend.mudanza       { background: #ea580c; }
/* `.cal-pro-legend .dot` variantes para el calendario empleado (app.html).
   Usan rgba con alpha .45 para coincidir con la apariencia de las celdas
   `.cal-day .m-vac/.m-tele/...` que pintan eventos con misma opacidad. */
.cal-pro-legend .legend-item .dot.vac     { background: rgba(244,63,94,.45); }
.cal-pro-legend .legend-item .dot.sick    { background: rgba(225,29,72,.45); }
.cal-pro-legend .legend-item .dot.perm    { background: rgba(245,158,11,.45); }
.cal-pro-legend .legend-item .dot.shift   { background: rgba(16,185,129,.45); }
.cal-pro-legend .legend-item .dot.holiday { background: #fde68a; }

/* Nav pills small variant — v2.0 unified: underline tabs en vez de pills.
   Mantiene la API (.nav-pills-sm) para no romper el HTML existente, pero
   ahora luce idéntico a #sec-cumplimiento / #sec-gastos / .cfg-subnav. */
.nav-pills-sm .nav-link {
  font-size: .75rem; font-weight: 600; padding: .4rem .7rem;
  border-radius: 0;
  border: 0; border-bottom: 2px solid transparent;
  color: var(--bs-secondary-color);
  background: transparent;
  transition: color .15s, border-color .15s;
}
.nav-pills-sm .nav-link:hover {
  background: transparent;
  color: var(--bs-body-color);
}
.nav-pills-sm .nav-link.active {
  background: transparent;
  color: var(--bs-primary);
  border-bottom-color: var(--bs-primary);
  box-shadow: none;
}

/* ── Shift calendar (Turnos) ──────────────────────────────── */
.turno-scroll { overflow-x: auto; }
.turno-table { border-collapse: collapse; width: 100%; min-width: 700px; }
.turno-table th, .turno-table td { border: 1px solid var(--bs-border-color, #e5e7eb); vertical-align: top; }
.turno-emp-cell { position: sticky; left: 0; background: var(--tt-surface); z-index: 2; min-width: 180px; padding: 8px 10px !important; }
.turno-day-cell { text-align: center; padding: 6px 4px !important; min-width: 110px; font-size: .75rem; }
.turno-day-cell .turno-day-name { font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--bs-secondary-color); }
.turno-day-cell .turno-day-num { font-size: 1.1rem; font-weight: 700; }
.turno-day-cell.today { background: rgba(99,102,241,.06); }
.turno-day-cell.weekend, .turno-cell.weekend { background: var(--bs-tertiary-bg, #f1f5f9); }
.turno-total-cell { text-align: center; min-width: 60px; padding: 8px !important; font-size: .85rem; }
.turno-cell { padding: 4px !important; cursor: pointer; transition: background var(--tt-transition); min-height: 56px; }
.turno-cell:hover { background: rgba(99,102,241,.04); }
.turno-cell.today { background: rgba(99,102,241,.04); }
.turno-chip { background: color-mix(in srgb, var(--tc) 10%, transparent); border-left: 3px solid var(--tc); border-radius: 6px; padding: 5px 8px; font-size: .72rem; line-height: 1.35; }
.turno-chip-label { font-weight: 700; color: var(--tc); font-size: .68rem; text-transform: uppercase; letter-spacing: .02em; }
.turno-chip-time { color: var(--bs-secondary-color); font-variant-numeric: tabular-nums; }
.turno-loc { color: var(--bs-secondary-color); font-size: .65rem; margin-top: 1px; }
.turno-loc::before { content: '📍 '; }
.turno-legend-chip { display: inline-flex; align-items: center; gap: 4px; font-size: .75rem; padding: 3px 10px; border-radius: 20px; background: color-mix(in srgb, var(--tc) 10%, transparent); font-weight: 500; }

/* ── v25 (Factorial #4) — Borrador / Publicado en chips ─────────
   Chip en estado borrador: borde discontinuo + opacidad reducida +
   marca de agua diagonal. Visualmente claro que no está publicado.   */
.turno-chip.is-draft {
  border-left-style: dashed;
  border-top: 1px dashed color-mix(in srgb, var(--tc) 55%, transparent);
  border-right: 1px dashed color-mix(in srgb, var(--tc) 55%, transparent);
  border-bottom: 1px dashed color-mix(in srgb, var(--tc) 55%, transparent);
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--tc) 8%, transparent),
    color-mix(in srgb, var(--tc) 8%, transparent) 6px,
    color-mix(in srgb, var(--tc) 14%, transparent) 6px,
    color-mix(in srgb, var(--tc) 14%, transparent) 12px
  );
  opacity: .88;
  position: relative;
}
.turno-chip.is-draft::after {
  content: '·BORRADOR';
  position: absolute;
  bottom: 2px; right: 4px;
  font-size: .55rem;
  font-weight: 700;
  letter-spacing: .05em;
  color: color-mix(in srgb, var(--tc) 75%, transparent);
  opacity: .8;
  pointer-events: none;
}
.btn-xs {
  font-size: .68rem;
  padding: .15rem .5rem;
  line-height: 1.3;
  border-radius: .35rem;
}
.turno-emp-publish {
  white-space: nowrap;
}

/* ── v25 (Factorial #10) — Badge "TIEMPO ADICIONAL" ─────────── */
.turno-overtime-badge {
  display: inline-block;
  font-size: .54rem;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 1px 5px;
  margin-bottom: 3px;
  background: linear-gradient(90deg, #f59e0b, #ef4444);
  color: #fff;
  border-radius: 3px;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(245,158,11,.35);
  line-height: 1.1;
}
[data-bs-theme="dark"] .turno-overtime-badge {
  background: linear-gradient(90deg, #fbbf24, #f87171);
  color: #1c1917;
  box-shadow: 0 1px 2px rgba(251,191,36,.4);
}

/* ── v25 (Factorial #6) — Burbuja de comentarios en celdas ──── */
.turno-comment-bubble {
  position: absolute;
  top: 2px; right: 2px;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: var(--bs-body-bg);
  color: var(--tc);
  border: 1px solid color-mix(in srgb, var(--tc) 35%, var(--bs-border-color));
  border-radius: 12px;
  padding: 1px 6px 1px 5px;
  font-size: .62rem;
  font-weight: 700;
  cursor: pointer;
  line-height: 1.2;
  z-index: 3;
  transition: all .12s ease;
  min-height: 18px;
}
.turno-comment-bubble:hover {
  background: var(--tc);
  color: #fff;
  border-color: var(--tc);
  transform: translateY(-1px);
  box-shadow: 0 2px 6px color-mix(in srgb, var(--tc) 35%, transparent);
}
.turno-comment-bubble.empty {
  opacity: 0;
  background: transparent;
  border-color: transparent;
  color: var(--bs-secondary-color);
}
.turno-cell:hover .turno-comment-bubble.empty {
  opacity: .55;
  border-color: var(--bs-border-color);
  background: var(--bs-body-bg);
}
.turno-comment-bubble.empty:hover {
  opacity: 1;
}
.turno-comment-bubble i { font-size: .7rem; }
.turno-chip { position: relative; } /* requerido para el .turno-comment-bubble absoluto */

/* Lista de comentarios en el modal */
.shift-comments-list {
  max-height: 280px;
  overflow-y: auto;
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
  background: var(--bs-body-bg);
}
.shift-comment-item {
  padding: 10px 12px;
  border-bottom: 1px solid var(--bs-border-color);
}
.shift-comment-item:last-child { border-bottom: 0; }
.shift-comment-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 4px;
  font-size: .78rem;
}
.shift-comment-body {
  font-size: .85rem;
  color: var(--bs-body-color);
  white-space: pre-wrap;
  word-break: break-word;
}

/* ── v25 (Factorial #3) — Fila Cobertura sticky-bottom ──────── */
.turno-table tfoot {
  position: sticky;
  bottom: 0;
  z-index: 4;
  background: var(--bs-body-bg);
}
.turno-coverage-row td {
  border-top: 2px solid var(--bs-border-color);
  background: color-mix(in srgb, var(--bs-tertiary-bg) 70%, var(--bs-body-bg));
  padding: 8px 6px !important;
}
.turno-coverage-label {
  font-weight: 700;
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--bs-secondary-color);
}
.turno-coverage-cell {
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.turno-coverage-cell .cov-count {
  display: block;
  font-size: 1.1rem;
  font-weight: 800;
  line-height: 1.1;
}
.turno-coverage-cell .cov-suffix {
  display: block;
  font-size: .62rem;
  color: var(--bs-secondary-color);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.turno-coverage-cell.cov-empty .cov-count {
  color: var(--bs-secondary-color);
  opacity: .55;
}
.turno-coverage-cell.cov-thin .cov-count {
  color: #d97706; /* amber: cobertura frágil (1 persona) */
}
.turno-coverage-cell.cov-good .cov-count {
  color: #059669; /* emerald: cobertura sana (2+ personas) */
}
.turno-coverage-cell.turno-coverage-total {
  font-weight: 800;
  background: color-mix(in srgb, var(--bs-primary) 8%, var(--bs-body-bg));
}
[data-bs-theme="dark"] .turno-coverage-cell.cov-thin .cov-count { color: #fbbf24; }
[data-bs-theme="dark"] .turno-coverage-cell.cov-good .cov-count { color: #34d399; }

/* ── v25 (Factorial #8) — Sub-tabs Ausencias mobile-style ───────
   Pills horizontales que filtran entre Mi equipo / Todas /
   Automatizaciones. En mobile el ul es scrollable horizontalmente
   para no romper el layout cuando hay 3+ pills + badges. */
/* v2.0 unified: underline tabs en vez de filled pills.
   Mantiene el contenedor flex/scroll horizontal mobile-first pero la
   estética (color activo, indicador, hover) sigue el patrón premium
   compartido con #sec-cumplimiento, #sec-gastos, .cfg-subnav. */
.abs-scope-tabs {
  display: flex;
  gap: 0;
  border-bottom: 2px solid var(--bs-border-color);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  padding-bottom: .25rem;
  flex-wrap: nowrap;
}
.abs-scope-tabs::-webkit-scrollbar { height: 4px; }
.abs-scope-tabs::-webkit-scrollbar-thumb { background: var(--bs-border-color); border-radius: 2px; }
.abs-scope-tabs .nav-item { flex-shrink: 0; }
.abs-scope-tabs .nav-link {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .5rem .9rem;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: -.005em;
  border-radius: 0;
  color: var(--bs-secondary-color);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;          /* solapa con el border-bottom del wrapper */
  transition: color .15s, border-color .15s;
  white-space: nowrap;
}
.abs-scope-tabs .nav-link:hover {
  color: var(--bs-body-color);
  background: transparent;
}
.abs-scope-tabs .nav-link.active {
  color: var(--bs-primary);
  background: transparent;
  border-bottom-color: var(--bs-primary);
  box-shadow: none;
}
.abs-scope-tabs .nav-link.active .badge {
  /* En underline pattern el badge mantiene tinte primario suave */
  background: rgba(var(--bs-primary-rgb), .15) !important;
  color: var(--bs-primary) !important;
}
@media (max-width: 540px) {
  .abs-scope-tabs .nav-link { padding: .4rem .65rem; font-size: .75rem; }
}
.turno-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* ── Shift Planner — drag & drop mode (v1.0.6) ─────────────── */
/* Solo activo cuando #turnoGrid tiene .planner-mode (toggle ON).
   Diseñado para no afectar el layout del modo lectura normal. */
.turno-table.planner-mode .turno-chip {
  cursor: grab;
  user-select: none;
  position: relative;
  transition: transform var(--tt-transition), box-shadow var(--tt-transition);
}
.turno-table.planner-mode .turno-chip:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--tc) 35%, transparent);
}
.turno-table.planner-mode .turno-chip:active {
  cursor: grabbing;
}
.turno-chip.dragging {
  opacity: .35;
  transform: scale(.97);
  box-shadow: 0 0 0 2px var(--tc), 0 8px 24px color-mix(in srgb, var(--tc) 40%, transparent);
}
.turno-chip.touch-selected {
  outline: 2px dashed var(--tc);
  outline-offset: 2px;
  animation: planner-pulse 1.4s ease-in-out infinite;
}
@keyframes planner-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tc) 40%, transparent); }
  50%      { box-shadow: 0 0 0 6px color-mix(in srgb, var(--tc) 0%, transparent); }
}
.turno-chip.resizing { opacity: .7; outline: 2px solid var(--bs-info); }

/* Drop targets — feedback visual diferenciado por estado */
.turno-table.planner-mode .turno-cell.drop-valid {
  background: color-mix(in srgb, var(--bs-success) 14%, transparent) !important;
  outline: 2px dashed var(--bs-success);
  outline-offset: -3px;
}
.turno-table.planner-mode .turno-cell.drop-warning {
  background: color-mix(in srgb, var(--bs-warning) 18%, transparent) !important;
  outline: 2px dashed var(--bs-warning);
  outline-offset: -3px;
}
.turno-table.planner-mode .turno-cell.drop-conflict {
  background: color-mix(in srgb, var(--bs-info) 16%, transparent) !important;
  outline: 2px dashed var(--bs-info);
  outline-offset: -3px;
  position: relative;
}
.turno-table.planner-mode .turno-cell.drop-conflict::after {
  content: '⇄';
  position: absolute;
  top: 4px; right: 4px;
  font-size: 1rem;
  font-weight: 700;
  color: var(--bs-info);
  text-shadow: 0 0 4px rgba(255,255,255,.9);
  pointer-events: none;
}
.turno-table.planner-mode .turno-cell.drop-block {
  background: color-mix(in srgb, var(--bs-danger) 18%, transparent) !important;
  outline: 2px solid var(--bs-danger);
  outline-offset: -3px;
  cursor: not-allowed !important;
  position: relative;
}
.turno-table.planner-mode .turno-cell.drop-block::after {
  content: '⊘';
  position: absolute;
  top: 4px; right: 4px;
  font-size: 1.1rem;
  color: var(--bs-danger);
  text-shadow: 0 0 4px rgba(255,255,255,.9);
  pointer-events: none;
}

/* Resize handle — visible solo en planner-mode al hover del chip */
.turno-resize-handle {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 6px;
  cursor: ew-resize;
  background: transparent;
  border-radius: 0 6px 6px 0;
  opacity: 0;
  transition: opacity var(--tt-transition), background var(--tt-transition);
  z-index: 2;
}
.turno-table.planner-mode .turno-chip:hover .turno-resize-handle {
  opacity: 1;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--tc) 60%, transparent));
}
.turno-resize-handle:hover { opacity: 1 !important; background: var(--tc) !important; }

/* Empty cell in planner-mode → más visible para invitar a drop */
.turno-table.planner-mode .turno-cell:empty {
  background: repeating-linear-gradient(
    45deg,
    transparent, transparent 6px,
    color-mix(in srgb, var(--bs-border-color) 50%, transparent) 6px,
    color-mix(in srgb, var(--bs-border-color) 50%, transparent) 7px
  );
}

/* Reduced motion: respeta preferencia del usuario */
@media (prefers-reduced-motion: reduce) {
  .turno-chip.touch-selected { animation: none; }
  .turno-table.planner-mode .turno-chip { transition: none; }
}

/* ── Org chart ────────────────────────────────────────────── */
.org-chart-container { overflow-x: auto; padding: 1rem 0; }
.org-tree { display: flex; flex-direction: column; align-items: center; min-width: 300px; }
.org-root { display: flex; justify-content: center; }
.org-connector-v { width: 2px; height: 20px; background: var(--bs-border-color); margin: 0 auto; }
.org-branches { display: flex; gap: 1.5rem; flex-wrap: wrap; justify-content: center; }
.org-branch { display: flex; flex-direction: column; align-items: center; min-width: 200px; }
.org-node { background: var(--tt-surface); border: 1px solid var(--bs-border-color); border-radius: var(--tt-radius); padding: 12px 16px; text-align: center; box-shadow: var(--tt-shadow-xs); transition: box-shadow var(--tt-transition), transform var(--tt-transition); }
.org-node:hover { box-shadow: var(--tt-shadow-md); transform: translateY(-2px); }
.org-company { background: linear-gradient(135deg, rgba(99,102,241,.08), rgba(99,102,241,.02)); border-color: rgba(99,102,241,.2); min-width: 200px; }
.org-company .org-node-icon { width: 40px; height: 40px; border-radius: 10px; background: rgba(99,102,241,.12); color: #6366f1; display: grid; place-items: center; margin: 0 auto 6px; font-size: 1.2rem; }
.org-dept { border-left: 3px solid var(--dept-color, #6366f1); }
.org-dept .org-node-icon { width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; margin: 0 auto 4px; font-size: .9rem; }
.org-node-name { font-weight: 700; font-size: .85rem; }
.org-node-meta { font-size: .72rem; color: var(--bs-secondary-color); }
.org-members { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; max-width: 340px; }
.org-person { display: flex; align-items: center; gap: 8px; text-align: left; padding: 8px 12px; min-width: 160px; cursor: default; }
.org-person .org-avatar { flex-shrink: 0; }
.org-person .org-node-name { font-size: .8rem; }
.org-person .org-node-meta { font-size: .68rem; }
.org-manager { border: 2px solid rgba(99,102,241,.3); background: rgba(99,102,241,.03); }
@media (max-width: 768px) {
  .org-branches { flex-direction: column; align-items: center; }
  .org-branch { min-width: 100%; }
  .org-members { max-width: 100%; }
}

/* ── Attendance heatmap (sequential diverging palette) ───── */
.heatmap-table { border-collapse: collapse; width: 100%; min-width: 600px; }
.heatmap-table th, .heatmap-table td { border: 1px solid var(--bs-border-color, #e5e7eb); text-align: center; font-size: .65rem; padding: 2px; }
.heatmap-emp { position: sticky; left: 0; background: var(--tt-surface); z-index: 1; min-width: 80px; text-align: left !important; padding: 4px 6px !important; font-weight: 600; font-size: .72rem; }
.heatmap-day { font-weight: 600; padding: 3px 2px !important; min-width: 24px; }
.heatmap-day span { font-weight: 400; color: var(--bs-secondary-color); }
.heatmap-day.weekend { background: var(--bs-tertiary-bg, #f1f5f9); }
.heatmap-cell { width: 24px; min-width: 24px; height: 24px; transition: background .15s; }
.heatmap-cell.weekend { background: var(--bs-tertiary-bg, #f1f5f9); }
.heatmap-cell.full    { background: color-mix(in srgb, var(--tt-positive) 28%, transparent); }
.heatmap-cell.partial { background: color-mix(in srgb, var(--tt-caution) 25%, transparent); }
.heatmap-cell.low     { background: color-mix(in srgb, var(--tt-alert) 20%, transparent); }
.heatmap-cell.active  { background: rgba(var(--bs-primary-rgb), .15); }
.heatmap-cell.absent  { background: color-mix(in srgb, var(--tt-alert) 8%, transparent); }
/* v2.6.63 — Tipos de ausencia (overlay sobre celdas absent) */
.heatmap-cell.abs-vacation { background: rgba(14, 165, 233, .28); }  /* sky-500 */
.heatmap-cell.abs-sick     { background: rgba(244, 63, 94, .26); }   /* rose-500 */
.heatmap-cell.abs-personal { background: rgba(168, 85, 247, .26); }  /* violet-500 */
.heatmap-cell.abs-family   { background: rgba(236, 72, 153, .26); }  /* pink-500 */
.heatmap-cell.abs-training { background: rgba(245, 158, 11, .28); }  /* amber-500 */
.heatmap-cell.abs-permit   { background: rgba(100, 116, 139, .28); } /* slate-500 */
.heatmap-cell.abs-other    { background: rgba(99, 102, 241, .24); }  /* indigo-500 */
/* Hover ligero para indicar clickabilidad */
.heatmap-cell[data-kind] { cursor: pointer; }
.heatmap-cell[data-kind]:hover { outline: 1px solid rgba(var(--bs-primary-rgb), .55); outline-offset: -1px; }

/* Legend sample swatches: cuadradito del color del cell sin texto */
.heatmap-cell-sample {
  display: inline-block; width: 12px; height: 12px;
  border-radius: 2px; vertical-align: middle;
  border: 1px solid var(--bs-border-color, rgba(0,0,0,.08));
}
.heatmap-cell-sample.full    { background: color-mix(in srgb, var(--tt-positive) 28%, transparent); }
.heatmap-cell-sample.partial { background: color-mix(in srgb, var(--tt-caution) 25%, transparent); }
.heatmap-cell-sample.low     { background: color-mix(in srgb, var(--tt-alert) 20%, transparent); }
.heatmap-cell-sample.absent  { background: color-mix(in srgb, var(--tt-alert) 8%, transparent); }
.heatmap-cell-sample.weekend { background: var(--bs-tertiary-bg, #f1f5f9); }
.heatmap-cell-sample.abs-vacation { background: rgba(14, 165, 233, .28); }
.heatmap-cell-sample.abs-sick     { background: rgba(244, 63, 94, .26); }
.heatmap-cell-sample.abs-other    { background: rgba(99, 102, 241, .24); }

/* PWA standalone mode — hide browser chrome padding */
@media (display-mode: standalone) {
  body { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); }
  .bottom-nav { padding-bottom: env(safe-area-inset-bottom); }
}

/* ============================================================
   FACTORIAL-INSPIRED COMPONENTS (date-range pills, counter cards,
   pastel absence badges, falta-fichaje warning)
   ============================================================ */

/* ── Date-range pill (rose header + big number, connected) ── */
.date-range-pill { display: inline-flex; align-items: center; gap: 6px; }
.date-pill {
  display: inline-flex; flex-direction: column; align-items: stretch;
  width: 50px; border-radius: 10px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,.06);
  background: var(--tt-surface); border: 1px solid var(--bs-border-color);
}
[data-bs-theme="dark"] .date-pill { background: var(--bs-tertiary-bg); }
.date-pill .month {
  background: linear-gradient(135deg, #fb7185, #f43f5e);
  color: #fff; font-size: .58rem; font-weight: 800;
  padding: 2px 0; text-align: center; letter-spacing: .06em; text-transform: uppercase;
}
.date-pill .day {
  font-size: 1.05rem; font-weight: 800; text-align: center;
  padding: 4px 0 5px; color: var(--bs-body-color); line-height: 1;
}
.date-range-pill .arrow { color: var(--bs-secondary-color); font-size: .85rem; }
.date-range-pill .info { display: flex; flex-direction: column; margin-left: 8px; min-width: 0; }
.date-range-pill .info .name { font-weight: 600; font-size: .8125rem; line-height: 1.2; }
.date-range-pill .info .meta { font-size: .7rem; color: var(--bs-secondary-color); margin-top: 2px; }

/* ── Vacation counter card (3-stat: TOTAL / DISPONIBLES / TOMADOS) ── */
.vac-counter-card {
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius-lg);
  padding: 18px 20px;
  box-shadow: var(--tt-shadow-sm);
}
.vac-counter-card .header {
  display: flex; align-items: center; justify-content: space-between;
  font-size: .7rem; color: var(--bs-secondary-color); font-weight: 600;
  margin-bottom: 14px; letter-spacing: .02em;
}
.vac-counter-card .header .arrow-btn {
  background: transparent; border: 0; color: var(--bs-secondary-color);
  font-size: 1rem; padding: 0 4px; cursor: pointer; line-height: 1;
}
.vac-counter-card .stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  text-align: center; gap: 8px;
}
.vac-counter-card .stats .stat .value {
  font-size: 1.6rem; font-weight: 800; line-height: 1;
  font-feature-settings: 'tnum'; letter-spacing: -.03em;
}
.vac-counter-card .stats .stat .label {
  font-size: .58rem; font-weight: 700; color: var(--bs-secondary-color);
  text-transform: uppercase; letter-spacing: .06em; margin-top: 6px;
}

/* ── Absence type badge (pastel by category) ── */
.abs-type-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px; font-size: .68rem; font-weight: 600;
  white-space: nowrap;
}
.abs-type-badge::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.abs-type-badge.vacaciones    { background: rgba(244,63,94,.10);  color: #be123c; }
.abs-type-badge.vacaciones::before    { background: #f43f5e; }
.abs-type-badge.baja_medica   { background: rgba(225,29,72,.10);  color: #9f1239; }
.abs-type-badge.baja_medica::before   { background: #e11d48; }
.abs-type-badge.permiso       { background: rgba(217,119,6,.10);  color: #92400e; }
.abs-type-badge.permiso::before       { background: #d97706; }
.abs-type-badge.asuntos_propios { background: rgba(37,99,235,.10); color: #1e3a8a; }
.abs-type-badge.asuntos_propios::before { background: #2563eb; }
.abs-type-badge.maternidad    { background: rgba(147,51,234,.10); color: #6b21a8; }
.abs-type-badge.maternidad::before    { background: #9333ea; }
.abs-type-badge.teletrabajo   { background: rgba(13,148,136,.10); color: #115e59; }
.abs-type-badge.teletrabajo::before   { background: #0d9488; }
.abs-type-badge.mudanza       { background: rgba(234,88,12,.10);  color: #9a3412; }
.abs-type-badge.mudanza::before       { background: #ea580c; }

/* ── Falta fichaje warning indicator ── */
.falta-fichaje-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(225,29,72,.08); color: #be123c;
  font-size: .68rem; font-weight: 700;
  border: 1px solid rgba(225,29,72,.18);
}
.falta-fichaje-pill .dot {
  width: 6px; height: 6px; border-radius: 50%; background: #e11d48;
  animation: pulse 2s ease-in-out infinite;
}
.falta-fichaje-row td:first-child { border-left: 3px solid #e11d48; padding-left: calc(.875rem - 3px); }

/* ── Bulk action bar ───────────────────────────────── */
.bulk-bar {
  background: var(--bs-primary-bg-subtle, #e0e7ff);
  border: 1px solid var(--bs-primary-border-subtle, #c7d2fe);
  border-radius: var(--tt-radius);
  margin-bottom: .5rem;
  animation: bulkSlide .2s ease;
}
@keyframes bulkSlide { from { opacity:0; transform:translateY(-6px); } to { opacity:1; transform:translateY(0); } }
[data-bs-theme="dark"] .bulk-bar { background: rgba(99,102,241,.12); border-color: rgba(99,102,241,.25); }

/* ── GDPR retention banner ─────────────────────────── */
.gdpr-banner {
  background: linear-gradient(90deg, #fef3c7, #fef9c3);
  border: 1px solid #fde68a;
  border-radius: var(--tt-radius);
  padding: .6rem 1rem;
  font-size: .78rem;
  color: #92400e;
  display: flex; align-items: center; gap: .5rem;
  margin-bottom: 1rem;
}
.gdpr-banner i { font-size: 1.1rem; flex-shrink: 0; }
[data-bs-theme="dark"] .gdpr-banner { background: rgba(254,243,199,.08); border-color: rgba(253,230,138,.2); color: #fbbf24; }

/* ════════════════════════════════════════════════════════════
   v2.6.32 · GDPR DSAR EXPORT CARD (Art. 15 + 20 RGPD)
   ──────────────────────────────────────────────────────────
   Card premium en perfil del empleado para descarga server-
   side authoritative del dossier completo (ZIP + JSON+ SHA-256).
   Theme-aware con gradient indigo subtle + halo decorativo.
   ════════════════════════════════════════════════════════════ */
.gdpr-export-card {
  background: var(--bs-tertiary-bg, #f8fafc);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  padding: 20px 22px;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.gdpr-export-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--bs-primary, #4f46e5), color-mix(in srgb, var(--bs-primary, #4f46e5) 60%, #7c3aed));
  opacity: .85;
  z-index: 0;
}
.gdpr-export-card::after {
  content: '';
  position: absolute;
  top: -50px; right: -50px;
  width: 180px; height: 180px;
  background: radial-gradient(circle, color-mix(in srgb, var(--bs-primary, #4f46e5) 18%, transparent), transparent 70%);
  z-index: 0;
  pointer-events: none;
}

.gdpr-export-header {
  display: flex; align-items: flex-start; gap: 14px;
  margin-bottom: 16px;
  position: relative; z-index: 1;
}
.gdpr-export-icon {
  flex-shrink: 0;
  width: 44px; height: 44px;
  border-radius: 11px;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--bs-primary, #4f46e5) 14%, transparent);
  color: var(--bs-primary, #4f46e5);
  font-size: 1.35rem;
}
.gdpr-export-title {
  margin: 0 0 2px;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--bs-body-color);
}
.gdpr-export-sub {
  margin: 0;
  font-size: .8125rem;
  color: var(--bs-secondary-color);
  font-weight: 500;
}
.gdpr-export-body {
  position: relative; z-index: 1;
}
.gdpr-export-body > p {
  font-size: .875rem;
  color: var(--bs-body-color);
  line-height: 1.55;
  opacity: .9;
}

.gdpr-export-features {
  list-style: none;
  padding: 0;
  margin: 12px 0 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: .8125rem;
  color: var(--bs-secondary-color);
}
.gdpr-export-features li {
  display: flex; align-items: center; gap: 8px;
  line-height: 1.4;
}
.gdpr-export-features i { font-size: .95rem; flex-shrink: 0; }

.gdpr-export-btn {
  font-weight: 600;
  letter-spacing: -.005em;
  padding: 9px 18px;
  border-radius: 10px;
  font-size: .875rem;
  display: inline-flex; align-items: center;
  box-shadow: 0 1px 3px -1px rgba(0, 0, 0, .12);
  transition: transform .15s cubic-bezier(.2, .9, .2, 1), box-shadow .15s cubic-bezier(.2, .9, .2, 1);
}
.gdpr-export-btn:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow: 0 5px 14px -2px color-mix(in srgb, var(--bs-primary, #4f46e5) 35%, transparent), 0 0 0 3px color-mix(in srgb, var(--bs-primary, #4f46e5) 14%, transparent);
}
.gdpr-export-btn:disabled {
  opacity: .65;
  cursor: not-allowed;
}
.gdpr-export-hint {
  font-size: .75rem;
  color: var(--bs-secondary-color);
  letter-spacing: -.005em;
}

/* Dark mode adjustments */
[data-bs-theme="dark"] .gdpr-export-card {
  background: rgba(15, 23, 42, .6);
  border-color: rgba(99, 102, 241, .18);
}
[data-bs-theme="dark"] .gdpr-export-icon {
  background: rgba(99, 102, 241, .2);
  color: #a5b4fc;
}

/* ════════════════════════════════════════════════════════════
   v2.6.30 · TRIAL BANNER (sticky top, theme-aware, urgency-tier)
   ──────────────────────────────────────────────────────────
   Stripe-style banner para periodos de prueba activos. 3 niveles:
     · info     → primary gradient (>3 días restantes)
     · warning  → amber gradient (<=3 días)
     · danger   → red gradient + pulse animation (<=24h)
   Renderiza body.has-trial-banner para que las páginas con
   sidebar lo respeten en su top offset (z-index 1058 < topbar).
   ════════════════════════════════════════════════════════════ */
.trial-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1058;
  padding: 10px 16px;
  color: #fff;
  font-size: .875rem;
  box-shadow: 0 4px 14px -2px rgba(0, 0, 0, .25);
  animation: trialBannerSlideDown .4s cubic-bezier(.2,.9,.2,1);
  letter-spacing: -.005em;
}
@keyframes trialBannerSlideDown {
  from { transform: translateY(-100%); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}

.trial-banner[data-urgency="info"]    { background: linear-gradient(135deg, var(--bs-primary, #4f46e5), color-mix(in srgb, var(--bs-primary, #4f46e5) 65%, #7c3aed)); }
.trial-banner[data-urgency="warning"] { background: linear-gradient(135deg, #f59e0b, #d97706); }
.trial-banner[data-urgency="danger"]  {
  background: linear-gradient(135deg, #ef4444, #b91c1c);
  animation: trialBannerSlideDown .4s cubic-bezier(.2,.9,.2,1), trialBannerPulse 2.4s ease-in-out 1s infinite;
}
@keyframes trialBannerPulse {
  0%, 100% { box-shadow: 0 4px 14px -2px rgba(239, 68, 68, .35); }
  50%      { box-shadow: 0 4px 24px 4px  rgba(239, 68, 68, .55); }
}

.trial-banner-inner {
  display: flex; align-items: center; gap: 12px;
  max-width: 1280px; margin: 0 auto;
  flex-wrap: wrap;
}
.trial-banner-icon {
  flex-shrink: 0;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .18);
  border-radius: 10px;
  font-size: 1.1rem;
}
.trial-banner-body {
  flex: 1 1 280px;
  min-width: 0;
}
.trial-banner-title {
  font-weight: 700;
  line-height: 1.2;
  font-size: .9375rem;
}
.trial-banner-subtitle {
  opacity: .92;
  font-size: .8125rem;
  margin-top: 1px;
  line-height: 1.4;
}
.trial-banner-countdown {
  flex-shrink: 0;
  display: flex; align-items: center; gap: 4px;
  background: rgba(255, 255, 255, .22);
  padding: 6px 14px;
  border-radius: 100px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
  border: 1px solid rgba(255, 255, 255, .25);
}
.trial-countdown-num { font-size: .9375rem; }

.trial-banner-actions {
  display: flex; align-items: center; gap: 6px;
  flex-shrink: 0;
}
.trial-banner-cta {
  background: #fff;
  color: #0f172a !important;
  border: none;
  font-weight: 700;
  padding: 8px 16px;
  border-radius: 10px;
  display: inline-flex; align-items: center;
  box-shadow: 0 2px 6px -1px rgba(0, 0, 0, .18), inset 0 -1px 0 rgba(0, 0, 0, .05);
  transition: transform .15s cubic-bezier(.2,.9,.2,1), box-shadow .15s cubic-bezier(.2,.9,.2,1);
  letter-spacing: -.005em;
  font-size: .8125rem;
}
.trial-banner[data-urgency="info"] .trial-banner-cta    { color: var(--bs-primary, #4f46e5) !important; }
.trial-banner[data-urgency="warning"] .trial-banner-cta { color: #b45309 !important; }
.trial-banner[data-urgency="danger"] .trial-banner-cta  { color: #b91c1c !important; }
.trial-banner-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 5px 14px -2px rgba(0, 0, 0, .28), 0 0 0 3px rgba(255, 255, 255, .22), inset 0 -1px 0 rgba(0, 0, 0, .04);
}
.trial-banner-cta:active { transform: translateY(0); }

.trial-banner-close {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, .25);
  color: #fff;
  width: 32px; height: 32px;
  border-radius: 8px;
  display: grid; place-items: center;
  cursor: pointer;
  transition: background .15s, border-color .15s;
  flex-shrink: 0;
}
.trial-banner-close:hover { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .45); }
.trial-banner-close:active { background: rgba(255, 255, 255, .20); }
.trial-banner-close:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ── Body offset: empuja el contenido hacia abajo cuando hay banner ── */
body.has-trial-banner {
  padding-top: 56px;
}
body.has-trial-banner .topbar {
  top: 56px !important;
}
@media (max-width: 575.98px) {
  body.has-trial-banner { padding-top: 92px; }
  body.has-trial-banner .topbar { top: 92px !important; }
  .trial-banner-inner { gap: 8px; }
  .trial-banner-subtitle { display: none; }
  .trial-banner-countdown { padding: 4px 10px; }
  .trial-countdown-num { font-size: .8125rem; }
}

/* Reduced motion: kill animations */
@media (prefers-reduced-motion: reduce) {
  .trial-banner { animation: none; }
  .trial-banner[data-urgency="danger"] { animation: none; }
}

/* ── Onboarding tour ───────────────────────────────── */
.tour-overlay { position: fixed; inset: 0; z-index: 9998; background: rgba(0,0,0,.45); backdrop-filter: blur(2px); transition: opacity .25s; }
.tour-tooltip {
  position: fixed; z-index: 9999;
  background: var(--bs-body-bg); color: var(--bs-body-color);
  border-radius: 12px; padding: 1.25rem; width: 320px; max-width: 90vw;
  box-shadow: 0 16px 48px rgba(0,0,0,.2), 0 0 0 2px var(--bs-primary);
  animation: tourPop .25s cubic-bezier(.34,1.56,.64,1);
}
@keyframes tourPop { from { opacity:0; transform:scale(.9) translateY(8px); } to { opacity:1; transform:scale(1) translateY(0); } }
.tour-tooltip .tour-title { font-size: 1rem; font-weight: 700; margin-bottom: .25rem; }
.tour-tooltip .tour-body { font-size: .82rem; color: var(--bs-secondary-color); margin-bottom: .75rem; }
.tour-tooltip .tour-step { font-size: .65rem; color: var(--bs-tertiary-color); }
.tour-tooltip .tour-actions { display: flex; gap: .5rem; justify-content: flex-end; }
.tour-highlight { position: relative; z-index: 9999; box-shadow: 0 0 0 4px var(--bs-primary), 0 0 0 9999px rgba(0,0,0,.45); border-radius: 8px; }

/* ── Keyboard shortcuts modal ──────────────────────── */
.shortcut-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .25rem .75rem; }
.shortcut-row { display: flex; justify-content: space-between; align-items: center; padding: .3rem 0; font-size: .8rem; }
.shortcut-row kbd { background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: 4px; padding: .1rem .4rem; font-size: .7rem; font-family: inherit; min-width: 1.8em; text-align: center; }

/* ── Draft saved indicator ─────────────────────────── */
.draft-indicator {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .7rem; color: var(--bs-success-text-emphasis);
  opacity: 0; transition: opacity .3s;
}
.draft-indicator.visible { opacity: 1; }

/* ── S2 Talent — Kanban board ──────────────────────── */
.kanban-board { min-height: 400px; }
.kanban-col { min-width: 200px; flex: 1; background: var(--bs-tertiary-bg); border-radius: var(--tt-radius); overflow: hidden; }
.kanban-header { padding: .6rem .75rem; font-size: .8rem; font-weight: 700; color: var(--bs-body-color); border-top: 3px solid; display: flex; align-items: center; gap: .35rem; }
.kanban-items { padding: .5rem; min-height: 60px; display: flex; flex-direction: column; gap: .4rem; }
.kanban-card {
  background: var(--tt-surface); border: 1px solid var(--bs-border-color); border-radius: 8px; padding: .6rem;
  color: var(--bs-body-color);
  cursor: grab; transition: box-shadow .15s, transform .15s;
}
.kanban-card:active { cursor: grabbing; }
.kanban-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.08); transform: translateY(-1px); }
[data-bs-theme="dark"] .kanban-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.3); }
.kanban-card .fw-semibold { color: var(--bs-body-color); }
.kanban-card .text-muted, .kanban-card small { color: var(--bs-secondary-color) !important; }

/* ── S2 Talent — Career path visual ────────────────── */
.career-step { min-width: 110px; max-width: 140px; flex-shrink: 0; }
.career-node {
  width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  margin: 0 auto; font-size: 1.2rem; border: 2px solid; transition: transform .15s;
  color: #fff;
}
.career-node:hover { transform: scale(1.1); }
.career-arrow { display: flex; align-items: center; padding: 0 .25rem; color: var(--bs-secondary-color); }
.career-step .small { color: var(--bs-body-color); }

/* ── S2 Talent — Skills matrix ─────────────────────── */
.skills-matrix th { font-size: .7rem; padding: .35rem .25rem; vertical-align: bottom; color: var(--bs-secondary-color); }
.skills-matrix td { padding: .25rem; color: var(--bs-body-color); }
.skill-cell { font-size: .7rem !important; font-weight: 700; border-radius: 6px !important; padding: .15rem .4rem !important; transition: transform .1s; }
.skill-cell:hover { transform: scale(1.15); }
.skill-gap { outline: 2px dashed var(--tt-alert, #e11d48); outline-offset: 1px; }

/* ── S2 Talent — Timeline ──────────────────────────── */
.timeline { position: relative; padding-left: 28px; }
.timeline::before { content: ''; position: absolute; left: 11px; top: 0; bottom: 0; width: 2px; background: var(--bs-border-color); }
.timeline-item { position: relative; margin-bottom: 1.25rem; }
.timeline-dot { position: absolute; left: -28px; top: 12px; width: 12px; height: 12px; border-radius: 50%; z-index: 1; }
.timeline-content { margin-left: 0; color: var(--bs-body-color); }
.timeline-content .fw-semibold { color: var(--bs-body-color); }
.timeline-content .text-muted { color: var(--bs-secondary-color) !important; }

/* ── Card soft (reusable light card) — talent sections ── */
/* Note: there is also a .card-soft at ~line 430 for KPI/general use.
   This one adds hover effect for the talent feature cards. */

/* ── Dark: S2 Talent components ───────────────────────── */
[data-bs-theme="dark"] .kanban-col { background: var(--bs-tertiary-bg); }
[data-bs-theme="dark"] .kanban-card { background: var(--tt-surface); border-color: var(--bs-border-color); }
[data-bs-theme="dark"] .career-node { color: #fff; }
[data-bs-theme="dark"] .timeline-content { color: var(--bs-body-color); }
[data-bs-theme="dark"] .skill-gap { outline-color: var(--tt-alert); }

/* ── Approve / Reject button pair (Factorial style) ── */
/* v17.x — Approve/Reject mejorados: añadidos display, cursor, transiciones y
   compatibilidad con Bootstrap `.btn` (heredan focus-ring, disabled-state).
   Las clases .btn-approve/.btn-reject sobre-escriben las variables de color
   de Bootstrap para garantizar el aspecto correcto en light/dark/factorial. */
.btn-approve, .btn-reject {
  --bs-btn-padding-y: .375rem;
  --bs-btn-padding-x: .85rem;
  --bs-btn-font-size: .75rem;
  --bs-btn-font-weight: 600;
  --bs-btn-border-radius: var(--tt-radius-sm);
  display: inline-flex; align-items: center; gap: 5px;
  white-space: nowrap;
  cursor: pointer;
  transition: all .12s ease;
}
.btn-approve {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--tt-positive, #059669);
  --bs-btn-border-color: var(--tt-positive, #059669);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #047857;
  --bs-btn-hover-border-color: #047857;
  --bs-btn-active-bg: #065f46;
}
.btn-reject {
  --bs-btn-color: #e11d48;
  --bs-btn-bg: transparent;
  --bs-btn-border-color: rgba(225,29,72,.4);
  --bs-btn-hover-color: #be123c;
  --bs-btn-hover-bg: rgba(225,29,72,.08);
  --bs-btn-hover-border-color: rgba(225,29,72,.6);
  --bs-btn-active-bg: rgba(225,29,72,.16);
}
[data-bs-theme="dark"] .btn-reject {
  --bs-btn-color: #fb7185;
  --bs-btn-border-color: rgba(251,113,133,.4);
  --bs-btn-hover-color: #fda4af;
  --bs-btn-hover-bg: rgba(251,113,133,.12);
}

/* Container responsive: en móviles (<sm) los botones se colapsan a icono-only
   gracias a `.d-none .d-md-inline` aplicado al texto en el HTML. */
.swap-actions { gap: 4px; }
@media (max-width: 575.98px) {
  .swap-actions .btn-approve,
  .swap-actions .btn-reject {
    padding: .375rem .55rem;     /* más compacto en móvil */
  }
}

/* ── Sub-nav de Configuración (v17.x → v2.0 unified) ────────────
   Underline tabs sticky · scroll horizontal en móvil · theme-aware.
   Patrón unificado con #sec-cumplimiento, #sec-devops, #sec-gastos
   (estilo Linear/Stripe/Factorial). Sustituye los pills rellenos
   anteriores que rompían la coherencia visual con el resto de la app. */
.cfg-subnav {
  position: sticky; top: 56px;       /* debajo del topbar */
  z-index: 20;
  background: var(--bs-body-bg);
  margin-left: -16px; margin-right: -16px;
  padding: 8px 16px 0;               /* el border-bottom del wrapper hace de separador */
  backdrop-filter: blur(8px) saturate(160%);
  -webkit-backdrop-filter: blur(8px) saturate(160%);
}
.cfg-subnav .nav-pills,
.cfg-subnav .nav {
  gap: 0;
  scrollbar-width: none;             /* Firefox */
  border-bottom: 2px solid var(--bs-border-color);
  flex-wrap: nowrap;
  overflow-x: auto;
  -ms-overflow-style: none;
}
.cfg-subnav .nav-pills::-webkit-scrollbar,
.cfg-subnav .nav::-webkit-scrollbar { display: none; }
.cfg-subnav .nav-link {
  padding: .5rem .9rem;
  font-size: .8125rem; font-weight: 600;
  letter-spacing: -.005em;
  border-radius: 0;                  /* override pill radius */
  color: var(--bs-secondary-color);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;               /* solapa con el border-bottom del wrapper */
  transition: color .15s, border-color .15s;
  white-space: nowrap;
  flex-shrink: 0;
  box-shadow: none;
}
.cfg-subnav .nav-link:hover {
  background: transparent;
  color: var(--bs-body-color);
  border-color: transparent;
}
.cfg-subnav .nav-link.active {
  background: transparent;
  color: var(--bs-primary);
  border-bottom-color: var(--bs-primary);
  box-shadow: none;
}
[data-bs-theme="dark"] .cfg-subnav {
  background: rgba(11, 18, 32, .9);
}
[data-bs-theme="dark"] .cfg-subnav .nav-pills,
[data-bs-theme="dark"] .cfg-subnav .nav {
  border-bottom-color: var(--bs-border-color);
}
@media (max-width: 575.98px) {
  .cfg-subnav { top: 0; padding: 6px 12px 0; }
  .cfg-subnav .nav-link { padding: .4rem .65rem; font-size: .75rem; }
}

/* Animación sutil al cambiar entre paneles de configuración */
.cfg-block:not(.d-none) {
  animation: cfgFadeIn .2s ease;
}

/* Form Stripe atenuado cuando BILLING_ENABLED=0. Mantiene los inputs
 * editables (admin puede preparar claves sin activar el módulo) pero
 * comunica visualmente que el sistema no está cobrando. */
.billing-form-disabled {
  opacity: .55;
  filter: grayscale(.35);
  transition: opacity .2s ease, filter .2s ease;
  position: relative;
}
.billing-form-disabled::before {
  content: "Módulo desactivado — los cambios se aplicarán al reactivar";
  display: block;
  margin-bottom: .75rem;
  padding: .35rem .7rem;
  font-size: .75rem;
  font-weight: 600;
  color: var(--bs-danger-text-emphasis, #b91c1c);
  background: var(--bs-danger-bg-subtle, #fee2e2);
  border: 1px dashed currentColor;
  border-radius: .375rem;
}
@keyframes cfgFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Compatibilidad Leaflet con tema dark del proyecto */
[data-bs-theme="dark"] .leaflet-control-zoom a {
  background: rgba(15, 23, 42, .92) !important;
  color: #e2e8f0 !important;
  border-color: rgba(255, 255, 255, .08) !important;
}
[data-bs-theme="dark"] .leaflet-control-zoom a:hover {
  background: rgba(30, 41, 59, .95) !important;
}

/* ── Slide-to-confirm: integración con punch-card (v17.x) ──────────
   El componente .swipe-track ya trae sus estilos auto-injected desde
   js/swipe-button.js. Aquí solo añadimos:
   - Posicionamiento del toggle de modo (esquina inferior derecha)
   - Layout flex del .punch-actions cuando contiene swipe
   - Tokens de color heredados del gradiente del punch-card. */
.punch-card .actions {
  position: relative;
}
.punch-card .actions .swipe-slot {
  width: 100%;
  margin-top: 8px;
}
.punch-card .actions .swipe-track {
  /* El punch-card tiene gradiente violeta — el swipe se integra encima.
     Variables CSS sobrescritas dentro del card para que el contraste
     funcione contra el fondo del card en lugar del body-bg. */
  --swipe-bg:           rgba(255,255,255,.18);
  --swipe-border:       rgba(255,255,255,.30);
  --swipe-fill-bg:      rgba(255,255,255,.32);
  --swipe-thumb-bg:     #ffffff;
  --swipe-thumb-color:  #4f46e5;
  --swipe-label-color:  #ffffff;
}
.punch-card .actions .swipe-track.swipe-success {
  --swipe-thumb-bg: #22c55e; --swipe-thumb-color: #fff;
  --swipe-fill-bg:  rgba(34,197,94,.45);
}
.punch-card .actions .swipe-track.swipe-danger {
  --swipe-thumb-bg: #ef4444; --swipe-thumb-color: #fff;
  --swipe-fill-bg:  rgba(239,68,68,.45);
}

/* Botón flotante para alternar tap↔swipe sin abrir el perfil */
.punch-mode-toggle {
  position: absolute;
  top: -8px;
  right: -4px;
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 0;
  background: rgba(255, 255, 255, .15);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  font-size: .9rem;
  display: grid; place-items: center;
  cursor: pointer;
  transition: background .15s, transform .15s;
  z-index: 3;
  opacity: .75;
}
.punch-mode-toggle:hover {
  background: rgba(255, 255, 255, .28);
  opacity: 1;
  transform: scale(1.08);
}
.punch-mode-toggle:active { transform: scale(.95); }
.punch-mode-toggle:focus-visible {
  outline: 2px solid rgba(255, 255, 255, .6);
  outline-offset: 2px;
}

/* Vista previa en perfil — fondo gradient para que el swipe se vea bien */
.prefs-preview-box {
  margin-top: 12px;
  padding-top: 4px;
  border-top: 1px dashed var(--bs-border-color);
}

/* Tema Factorial — adaptación del swipe en punch-card (gradiente rosa) */
[data-color-theme="factorial"] .punch-card .actions .swipe-track {
  --swipe-thumb-color: #be123c;
}

/* ============================================================
   ORGANIGRAMA 2.0 (v17.x — SaaS-grade, inspirado Factorial/Personio)
   ============================================================ */

/* ── Toolbar superior: búsqueda + filtro + zoom + acciones ──
   v2.6.14: margin-bottom 12→20px (gap entre toolbar y stats row). 
   12px era demasiado apretado: las labels "EMPLEADOS / DEPARTAMENTOS /
   MANAGERS" se pegaban al input de búsqueda sin breathing room. 20px
   da separación visual SaaS estándar entre filter bar y KPI cards. */
.org-toolbar {
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: center;
  padding: 12px;
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius);
  margin-bottom: 20px;
  position: sticky;
  top: 56px;
  z-index: 10;
  box-shadow: var(--tt-shadow-xs);
}
.org-toolbar-search {
  flex: 1 1 240px;
  position: relative;
  min-width: 200px;
}
.org-toolbar-search > i.bi-search {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--bs-secondary-color); font-size: .9rem; pointer-events: none;
}
.org-toolbar-search input {
  padding-left: 32px; padding-right: 32px;
}
.org-search-clear {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  background: transparent; border: 0;
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--bs-secondary-color); cursor: pointer;
}
.org-search-clear:hover { background: var(--bs-tertiary-bg); color: var(--bs-body-color); }
.org-toolbar-select { width: auto; min-width: 180px; flex: 0 0 auto; }
.org-toolbar-zoom,
.org-toolbar-actions {
  display: flex; align-items: center; gap: 4px;
  background: var(--bs-tertiary-bg);
  padding: 3px;
  border-radius: 8px;
}
.org-toolbar-zoom .btn,
.org-toolbar-actions .btn {
  --bs-btn-padding-y: .25rem;
  --bs-btn-padding-x: .55rem;
  background: transparent; border: 0;
  color: var(--bs-secondary-color);
}
.org-toolbar-zoom .btn:hover,
.org-toolbar-actions .btn:hover {
  background: var(--tt-surface); color: var(--bs-primary);
}
.org-zoom-label {
  font-size: .75rem; font-weight: 600; min-width: 42px;
  text-align: center; color: var(--bs-secondary-color);
  font-variant-numeric: tabular-nums;
}

/* ── Stats row: mini-dashboard del organigrama ── */
.org-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-bottom: 16px;
}
.org-stat {
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius);
  padding: 12px 14px;
  display: flex; flex-direction: column;
  transition: border-color .15s, box-shadow .15s;
}
.org-stat:hover { border-color: rgba(var(--bs-primary-rgb), .35); box-shadow: var(--tt-shadow-sm); }
.org-stat-value {
  font-size: 1.5rem; font-weight: 800;
  letter-spacing: -.025em; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--bs-body-color);
}
.org-stat-label {
  font-size: .65rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .075em;
  color: var(--bs-secondary-color); margin-top: 4px;
}
.org-stat-result .org-stat-value { color: var(--bs-primary); }

/* ── Lienzo: pan/zoom container ── */
.org-canvas-wrap {
  position: relative;
  overflow: auto;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius);
  background:
    radial-gradient(circle, var(--bs-border-color) 1px, transparent 1px) 0 0 / 24px 24px,
    var(--bs-tertiary-bg);
  min-height: 400px;
  cursor: grab;
}
.org-canvas-wrap.is-panning { cursor: grabbing; user-select: none; }
[data-bs-theme="dark"] .org-canvas-wrap {
  background:
    radial-gradient(circle, rgba(148,163,184,.15) 1px, transparent 1px) 0 0 / 24px 24px,
    var(--bs-tertiary-bg);
}
.org-canvas {
  padding: 40px 32px;
  transition: transform .15s var(--ease-out);
  transform-origin: top center;
}
.org-canvas-wrap.is-panning .org-canvas { transition: none; }

/* ── Tree V2: layout principal ── */
.org-tree-v2 {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  gap: 48px;
}
.org-row { position: relative; z-index: 2; }
.org-row-root { display: flex; justify-content: center; }
.org-row-depts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 32px 24px;
  width: 100%;
}

/* ── SVG conectores curvos ── */
.org-connectors {
  position: absolute;
  top: 0; left: 0;
  pointer-events: none;
  z-index: 1;
}
.org-connectors path {
  fill: none;
  stroke: var(--bs-border-color);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: .8;
}
[data-bs-theme="dark"] .org-connectors path {
  stroke: rgba(148,163,184,.4);
}

/* ── Nodes V2 (company + dept) ── */
.org-node-v2 {
  display: flex; align-items: center; gap: 12px;
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  padding: 14px 18px;
  min-width: 220px;
  max-width: 320px;
  box-shadow: var(--tt-shadow-sm);
  transition: transform .18s var(--ease-out), box-shadow .18s var(--ease-out), border-color .18s var(--ease-out);
}
.org-node-v2:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--focus-ring-color), var(--tt-shadow);
}
.org-company-v2 {
  background: linear-gradient(135deg, rgba(var(--bs-primary-rgb), .08), rgba(var(--bs-primary-rgb), .02));
  border-color: rgba(var(--bs-primary-rgb), .25);
  border-width: 2px;
}
.org-company-v2 .org-node-badge {
  background: linear-gradient(135deg, var(--bs-primary), rgba(var(--bs-primary-rgb), .7));
  color: #fff;
  box-shadow: 0 4px 12px rgba(var(--bs-primary-rgb), .35);
}
.org-dept-v2 {
  cursor: pointer;
  position: relative;
  border-left: 3px solid var(--dept-color, var(--bs-primary));
  background: var(--tt-surface);
}
.org-dept-v2:hover {
  transform: translateY(-2px);
  box-shadow: var(--tt-shadow-md);
  border-color: var(--dept-color, var(--bs-primary));
}
.org-dept-v2.is-collapsed {
  opacity: .85;
  background: linear-gradient(180deg, var(--tt-surface) 0%, var(--bs-tertiary-bg) 100%);
}
.org-dept-unassigned {
  border-left-color: #94a3b8;
  background: var(--bs-tertiary-bg);
}

/* ── Badge interno (icon de la categoría) ── */
.org-node-badge {
  width: 44px; height: 44px;
  border-radius: 12px;
  display: grid; place-items: center;
  flex-shrink: 0;
  font-size: 1.25rem;
}

/* ── Body del nodo ── */
.org-node-body { flex: 1 1 auto; min-width: 0; }
.org-node-title {
  font-weight: 700; font-size: .9375rem;
  letter-spacing: -.02em;
  color: var(--bs-body-color);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.org-node-sub {
  font-size: .75rem;
  color: var(--bs-secondary-color);
  margin-top: 2px;
  display: flex; align-items: center; gap: 4px;
  flex-wrap: wrap;
}
.org-count {
  background: rgba(var(--bs-primary-rgb), .12);
  color: var(--bs-primary);
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: .68rem;
  font-variant-numeric: tabular-nums;
}
.org-mgr {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--bs-warning-text-emphasis, #d97706);
  font-weight: 600;
}
.org-mgr i { color: #f59e0b; font-size: .75em; }

/* ── Botón fold (chevron) ── */
.org-fold-btn {
  background: transparent; border: 0;
  width: 28px; height: 28px;
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--bs-secondary-color);
  flex-shrink: 0;
  transition: background .15s, transform .15s;
}
.org-dept-v2:hover .org-fold-btn { background: var(--bs-tertiary-bg); color: var(--bs-primary); }

/* ── Departamento column: dept + grid empleados ── */
.org-dept-col {
  display: flex; flex-direction: column;
  align-items: center;
  gap: 16px;
  position: relative;
}

/* ── Grid de cards de empleado ── */
.org-emp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 8px;
  width: 100%;
  max-width: 720px;
  padding: 4px;
  animation: orgGridIn .25s var(--ease-out);
}
@keyframes orgGridIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Card de empleado ── */
.org-emp-card {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  background: var(--tt-surface);
  border: 1px solid var(--bs-border-color);
  border-radius: 10px;
  padding: 10px 12px;
  cursor: pointer;
  transition: transform .15s var(--ease-out), box-shadow .15s var(--ease-out), border-color .15s var(--ease-out);
}
.org-emp-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 3px;
  background: var(--card-color, var(--bs-primary));
  border-radius: 10px 0 0 10px;
  opacity: 0;
  transition: opacity .15s;
}
.org-emp-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--tt-shadow-sm);
  border-color: var(--card-color, rgba(var(--bs-primary-rgb), .35));
}
.org-emp-card:hover::before { opacity: 1; }
.org-emp-card:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px var(--focus-ring-color);
}
.org-emp-card.is-manager {
  background: linear-gradient(135deg, rgba(245,158,11,.06), var(--tt-surface));
  border-color: rgba(245,158,11,.30);
}
.org-emp-avatar {
  width: 38px; height: 38px;
  flex-shrink: 0;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(var(--bs-primary-rgb), .1);
  color: var(--bs-primary);
  display: grid; place-items: center;
  font-weight: 700; font-size: .75rem;
  border: 2px solid var(--card-color, transparent);
}
.org-emp-avatar img { width: 100%; height: 100%; object-fit: cover; }
.org-emp-info { flex: 1 1 auto; min-width: 0; }
.org-emp-name {
  font-weight: 600; font-size: .8125rem;
  letter-spacing: -.01em;
  color: var(--bs-body-color);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.org-emp-role {
  font-size: .68rem;
  color: var(--bs-secondary-color);
  margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.org-emp-email {
  font-size: .65rem;
  color: var(--bs-secondary-color);
  margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: ui-monospace, monospace;
  opacity: .8;
}
.org-manager-pill {
  position: absolute;
  top: -6px; right: -6px;
  width: 22px; height: 22px;
  background: linear-gradient(135deg, #f59e0b, #d97706);
  color: #fff;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: .6rem;
  border: 2px solid var(--tt-surface);
  box-shadow: 0 2px 6px rgba(245,158,11,.4);
}

/* ── Highlight de coincidencias en búsqueda ── */
.org-hl {
  background: rgba(var(--bs-primary-rgb), .25);
  color: var(--bs-primary);
  font-weight: 700;
  padding: 0 2px;
  border-radius: 3px;
}
[data-bs-theme="dark"] .org-hl {
  background: rgba(165,180,252,.25);
  color: #a5b4fc;
}

/* ── Responsive: mobile compact ── */
@media (max-width: 575.98px) {
  .org-toolbar { gap: 6px; padding: 8px; top: 0; }
  .org-toolbar-search { flex-basis: 100%; }
  .org-toolbar-select { flex: 1; min-width: 0; }
  .org-toolbar-zoom { display: none; }
  .org-canvas-wrap { min-height: 300px; }
  .org-canvas { padding: 20px 12px; }
  .org-row-depts { gap: 16px; }
  .org-node-v2 { min-width: 180px; padding: 10px 12px; }
  .org-emp-grid { grid-template-columns: 1fr; max-width: 100%; }
}

/* ── Print: estilos para exportar ── */
@media print {
  .org-toolbar,
  .org-stats,
  .org-fold-btn { display: none !important; }
  .org-canvas-wrap {
    overflow: visible !important;
    border: 0 !important;
    background: #fff !important;
    box-shadow: none !important;
    min-height: auto !important;
  }
  .org-canvas { transform: none !important; padding: 0 !important; }
  .org-emp-card,
  .org-node-v2 { box-shadow: none !important; break-inside: avoid; }
}

/* ── Botón "glass" (semi-transparente con blur) sobre fondos con gradiente.
   Usado en punch-card para "Comprobar mi ubicación" — se integra con el
   gradiente violeta sin romper el contraste. */
.btn-light-glass {
  background: rgba(255, 255, 255, .15);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, .25);
  backdrop-filter: blur(8px) saturate(160%);
  -webkit-backdrop-filter: blur(8px) saturate(160%);
  font-weight: 600;
  font-size: .75rem;
  padding: .375rem .75rem;
  border-radius: 999px;
  transition: background .15s, transform .15s, border-color .15s;
}
.btn-light-glass:hover {
  background: rgba(255, 255, 255, .28);
  border-color: rgba(255, 255, 255, .42);
  color: #fff;
  transform: translateY(-1px);
}
.btn-light-glass:active { transform: translateY(0); }
.btn-light-glass:focus-visible {
  outline: 2px solid rgba(255, 255, 255, .6);
  outline-offset: 2px;
}

/* ============================================================
   v17.x — DESKTOP MODERNIZATION
   ------------------------------------------------------------
   Refinamiento tipográfico, iconográfico y cromático orientado
   a escritorio (≥992px) sin romper mobile. Inspiración: Linear,
   Notion, Vercel, Stripe Dashboard. Compatible con light/dark
   y con paletas Atlántico (default) / Factorial (rose).
   ============================================================ */

/* ── 1) Tokens nuevos (icon system + display scale) ───────────────
   Sistema de tamaños de icono. Aplicar via clases utilidad o
   directamente en selectores específicos. Garantiza coherencia
   visual entre sidebar, topbar, KPIs, buttons y modales. */
:root {
  --icon-xs: 14px;
  --icon-sm: 16px;
  --icon-md: 18px;
  --icon-lg: 20px;
  --icon-xl: 24px;
  --icon-2xl: 32px;

  /* Display scale (titulares hero, splash screens, dashboards) */
  --display-1: 2.5rem;
  --display-2: 2rem;
  --display-3: 1.625rem;

  /* Focus ring — estilo Linear (3px halo translúcido del primary) */
  --focus-ring-color: rgba(var(--bs-primary-rgb), .25);
  --focus-ring-width: 3px;

  /* Selection — color principal con baja saturación */
  --selection-bg: rgba(var(--bs-primary-rgb), .18);
  --selection-color: var(--bs-body-color);

  /* Easing curves (consistente con Apple HIG / Material Motion) */
  --ease-out:    cubic-bezier(0, 0, 0.2, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-emph:   cubic-bezier(0.34, 1.56, 0.64, 1);  /* spring suave */
}
[data-bs-theme="dark"] {
  --focus-ring-color: rgba(165, 180, 252, .35);
  --selection-bg:     rgba(99, 102, 241, .35);
}

/* ── 2) Selection + smooth scroll global ─────────────────────────── */
::selection {
  background: var(--selection-bg);
  color: var(--selection-color);
}
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ── 3) Focus ring unificado (a11y + look premium) ───────────────── */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 2px;
  border-radius: var(--bs-border-radius);
}
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
}

/* ── 4) Sistema de iconos: clases utilidad + sizing por contexto ── */
.bi { vertical-align: -0.125em; line-height: 1; }
.icon-xs  { font-size: var(--icon-xs);  }
.icon-sm  { font-size: var(--icon-sm);  }
.icon-md  { font-size: var(--icon-md);  }
.icon-lg  { font-size: var(--icon-lg);  }
.icon-xl  { font-size: var(--icon-xl);  }
.icon-2xl { font-size: var(--icon-2xl); }

/* Iconos heredan color de texto por defecto (no hardcodear color) */
.btn .bi          { font-size: var(--icon-sm); }
.btn-sm .bi       { font-size: var(--icon-xs); }
.btn-lg .bi       { font-size: var(--icon-md); }
.dropdown-item .bi{ font-size: var(--icon-sm); width: var(--icon-md); text-align: center; }

/* ── 5) Tipografía: refuerzo de jerarquía (mobile-first → desktop) ── */
/* Numeral hierarchy: tabular-nums por defecto en KPIs, tablas, métricas */
.tabular,
.kpi .value,
.timer,
.clock,
.table tbody td,
.table tfoot td,
.dl-data dd { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' on, 'cv11' on; }

/* Display classes para títulos hero y splash */
.display-hero {
  font-size: var(--display-1);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
}
.display-md {
  font-size: var(--display-2);
  font-weight: 800;
  letter-spacing: -0.030em;
  line-height: 1.10;
}
.display-sm {
  font-size: var(--display-3);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.15;
}

/* Body text refinado: kerning + ligaduras de Inter */
body {
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11', 'ss01';
  font-variant-ligatures: common-ligatures;
}

/* ── 6) Hover lift refinado en cards (estilo Linear/Vercel) ────── */
.kpi,
.card-soft,
.announce,
.doc-item,
.person-card,
.project-card,
.org-node {
  transition:
    transform .18s var(--ease-out),
    box-shadow .18s var(--ease-out),
    border-color .18s var(--ease-out);
}
@media (hover: hover) {
  .kpi:hover,
  .card-soft:hover,
  .announce:hover,
  .doc-item:hover,
  .person-card:hover,
  .project-card:hover,
  .org-node:hover {
    transform: translateY(-2px);
    box-shadow: var(--tt-shadow-md);
    border-color: rgba(var(--bs-primary-rgb), .15);
  }
}
@media (prefers-reduced-motion: reduce) {
  .kpi:hover,
  .card-soft:hover,
  .announce:hover,
  .doc-item:hover,
  .person-card:hover,
  .project-card:hover,
  .org-node:hover { transform: none; }
}

/* ── 7) Inputs refinados: focus halo + transición ────────────────── */
.form-control,
.form-select {
  transition:
    border-color .15s var(--ease-out),
    box-shadow .15s var(--ease-out);
}
.form-control:hover:not(:focus):not(:disabled),
.form-select:hover:not(:focus):not(:disabled) {
  border-color: rgba(var(--bs-primary-rgb), .35);
}
[data-bs-theme="dark"] .form-control,
[data-bs-theme="dark"] .form-select {
  background-color: var(--tt-surface);
  color: var(--bs-body-color);
}

/* ── 8) Botones primarios premium: lift + shadow vibrante ────── */
.btn-primary {
  position: relative;
  font-weight: 600;
  letter-spacing: -.005em;
  transition:
    transform .12s var(--ease-out),
    box-shadow .12s var(--ease-out),
    background-color .12s var(--ease-out);
}
.btn-primary:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow:
    0 4px 14px rgba(var(--bs-primary-rgb), .35),
    inset 0 1px 0 rgba(255, 255, 255, .12);
}
.btn-primary:not(:disabled):active {
  transform: translateY(0);
  transition-duration: .05s;
}

/* Iconos del botón: alineación perfecta con la baseline */
.btn .bi { vertical-align: -.1em; }

/* ── 9) Sidebar: iconos consistentes + más breathing room ───────── */
.sidebar nav a .bi { font-size: var(--icon-md); width: 22px; text-align: center; flex-shrink: 0; }
.sidebar nav a.active .bi { color: #fff; }

/* ── 10) Scrollbar temático (Webkit + Firefox) ───────────────────── */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(var(--bs-primary-rgb), .28) transparent;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(var(--bs-primary-rgb), .25);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(var(--bs-primary-rgb), .45);
  background-clip: content-box;
  border: 2px solid transparent;
}

/* ── 11) Badges: refinamiento weight + tracking ──────────────────── */
.badge {
  font-weight: 700;
  letter-spacing: .015em;
  font-feature-settings: 'tnum' on;
  padding: .25em .55em;
}

/* ── 12) Status badges (.status-badge): tipografía + dots refinados */
.status-badge {
  font-weight: 700;
  letter-spacing: .025em;
  text-transform: uppercase;
  font-size: .65rem;
  padding: 4px 10px;
}
.status-badge::before {
  width: 7px; height: 7px;
  box-shadow: 0 0 0 2px currentColor;  /* halo sutil del color del badge */
  opacity: .9;
}

/* ============================================================
   ≥ 992px (DESKTOP) — refinamientos espaciales y tipográficos
   ============================================================ */
@media (min-width: 992px) {
  /* Body un punto más grande para legibilidad confortable en pantalla grande */
  body {
    font-size: 0.9375rem;            /* ~15px */
  }

  /* Headings con escala visual más generosa en desktop */
  h1, .h1 { font-size: 1.875rem; line-height: 1.15; }
  h2, .h2 { font-size: 1.5rem;   line-height: 1.20; }
  h3, .h3 { font-size: 1.25rem;  line-height: 1.25; }

  /* Section titles: más impacto en desktop */
  .section-title {
    font-size: 1.375rem;
    font-weight: 800;
    letter-spacing: -.025em;
  }
  .section-sub { font-size: .875rem; }

  /* KPI cards: valores más grandes en desktop (más impacto visual) */
  .kpi {
    padding: 22px 24px;
    gap: 18px;
  }
  .kpi .icon {
    width: 56px; height: 56px;
    font-size: 1.5rem;
    border-radius: 14px;
  }
  .kpi .value {
    /* Fluido respecto al ancho REAL de la card (container query): 1.5rem
       cuando .kpi mide ~200px (col-md-3 en 992-1199px, donde "-15h 27m"
       a 1.75rem se clipa con overflow:hidden), 1.75rem cuando hay
       espacio sobrado (col-md-6 / wide desktop). */
    font-size: clamp(1.5rem, 6cqi + 0.5rem, 1.75rem);
    letter-spacing: -.035em;
    line-height: 1.05;
  }
  .kpi .label {
    font-size: .7rem;
    letter-spacing: .075em;
    margin-bottom: 4px;
  }

  /* Sidebar: iconos un punto más grandes + nav-link más cómodo */
  .sidebar nav a {
    padding: 10px 14px;
    font-size: .875rem;
    gap: 12px;
  }
  .sidebar nav a .bi { font-size: var(--icon-lg); width: 24px; }
  .sidebar-brand strong { font-size: 1rem; }
  .nav-section {
    font-size: .65rem;
    letter-spacing: .12em;
    padding: 22px 22px 8px;
  }

  /* Topbar más alto + tipografía generosa */
  .topbar {
    min-height: 64px;
    padding: 12px 28px;
  }
  .topbar h1 { font-size: 1.0625rem; letter-spacing: -.02em; }
  .topbar .clock { font-size: .875rem; }

  /* Content padding más generoso para mayor breathing room */
  .content { padding: 32px 36px; }

  /* Punch card: timer + textos en versión desktop más grandes */
  .punch-card { padding: 36px; border-radius: 24px; }
  .punch-card .timer  { font-size: 4rem; }
  .punch-card .date   { font-size: .875rem; }
  .punch-card .meta strong { font-size: 1.125rem; }

  /* Tablas: padding más cómodo en desktop */
  .table > :not(caption) > * > * {
    padding: .9rem 1rem;
    font-size: .875rem;
  }
  .table-wrap thead th {
    font-size: .7rem;
    padding: .75rem 1rem;
  }

  /* Modales: padding más generoso */
  .modal-header { padding: 1.25rem 1.5rem; }
  .modal-body   { padding: 1.5rem; }
  .modal-footer { padding: 1.125rem 1.5rem; }
  .modal-content { border-radius: 18px; }

  /* Buttons: altura confortable de 38px en desktop (mínimo táctil mantenido) */
  .btn {
    min-height: 38px;
    font-size: .875rem;
    padding: .5rem 1rem;
  }
  .btn-sm  { min-height: 32px; font-size: .8125rem; padding: .375rem .75rem; }
  .btn-lg  { min-height: 44px; font-size: .9375rem; padding: .625rem 1.25rem; }

  /* Forms: labels más distinguibles */
  .form-label {
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .005em;
    margin-bottom: 8px;
  }
  .form-control,
  .form-select {
    font-size: .875rem;
    padding: .55rem .85rem;
    min-height: 40px;
  }

  /* Avatar dimensions más generosos */
  .avatar    { width: 40px; height: 40px; font-size: .8125rem; }
  .avatar.sm { width: 32px; height: 32px; }
  .avatar.lg { width: 64px; height: 64px; font-size: 1.15rem; }

  /* Card-soft padding refinado */
  .card-soft { padding: 24px; border-radius: 14px; }

  /* Section header con mejor jerarquía visual */
  .section-header { margin-bottom: 24px; }
}

/* ============================================================
   ≥ 1400px (Wide desktop) — extras para pantallas amplias
   ============================================================ */
@media (min-width: 1400px) {
  body { font-size: 0.9375rem; }
  .content { padding: 36px 48px; }
  .punch-card .timer { font-size: 4.5rem; }
  .display-hero { font-size: 3rem; }
}

/* ============================================================
   Refinamiento de paleta: ajustes finos de superficies y textos
   ============================================================ */

/* Light mode: micro-ajuste de jerarquía de superficies */
:root:not([data-bs-theme="dark"]) {
  --tt-surface-raised: #ffffff;            /* cards principales */
  --tt-surface-popover: #ffffff;           /* dropdowns, modales */
  --tt-surface-overlay: rgba(255,255,255,.85); /* topbar blur backdrop */
}
[data-bs-theme="dark"] {
  --tt-surface-raised:  #232f47;            /* slate-800 más cálido */
  --tt-surface-popover: #2a3654;            /* slate-700 para modals/popovers */
  --tt-surface-overlay: rgba(15,23,42,.85);
}

/* Modal / dropdown / popover usan surface-popover para jerarquía elevation */
.modal-content,
.dropdown-menu,
.popover { background-color: var(--tt-surface-popover); }

/* Topbar con backdrop blur premium */
.topbar {
  background: var(--tt-surface-overlay);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
}

/* Texto secundario en dark más legible (slate-400 sobre slate-800) */
[data-bs-theme="dark"] {
  --bs-secondary-color: #94a3b8;
}

/* ============================================================
   THEME: FACTORIAL (rose coral + teal accent + pastel bg)
   Activated by: data-color-theme="factorial"
   ============================================================ */
[data-color-theme="factorial"] {
  --bs-primary: #f43f5e;
  --bs-primary-rgb: 244,63,94;
  --bs-link-color-rgb: 244,63,94;
  /* Token premium reutilizable: hace que .btn-primary, dept-pill, sidebar.active y
     cualquier consumidor de --tt-grad-primary herede automáticamente la paleta
     factorial sin overrides puntuales. Mantiene uniformidad cross-theme. */
  --tt-grad-primary: linear-gradient(135deg, #f43f5e 0%, #ec4899 60%, #db2777 100%);
  --bs-link-hover-color-rgb: 225,29,72;
  --tt-vac:       #f43f5e;
  --tt-sick:      #e11d48;
  --tt-leave:     #0d9488;
  --tt-maternity: #9333ea;
  --tt-paternity: #2563eb;
}
[data-color-theme="factorial"][data-bs-theme="light"] {
  /* ── Color Theory: Factorial Light ─────────────────────────
     Warm pastel canvas with rose-coral primary.
     Body text: warm near-black (#2d1a1e) for harmony with pink bg.
     Secondary text: warm grey (#7a5c62) for AA on white surfaces.
     Borders: warm rose-mist for cohesive feel.
     ──────────────────────────────────────────────────────── */
  --bs-body-bg: #fff7f3;
  --bs-body-color: #2d1a1e;
  --bs-secondary-color: #7a5c62;
  --bs-secondary-bg: #fff0eb;
  --bs-tertiary-bg: #fee9e0;
  --bs-border-color: #f5cdc0;
  --tt-surface: #ffffff;
  --tt-surface-2: #fff5f1;
}
[data-color-theme="factorial"][data-bs-theme="light"] .table-wrap,
[data-color-theme="factorial"][data-bs-theme="light"] .card,
[data-color-theme="factorial"][data-bs-theme="light"] .modal-content {
  background: #fff;
}
[data-color-theme="factorial"][data-bs-theme="light"] .table-wrap thead th {
  background: #fee9e0;
  color: #7a5c62;
}
[data-color-theme="factorial"][data-bs-theme="light"] .form-control,
[data-color-theme="factorial"][data-bs-theme="light"] .form-select {
  border-color: #f5cdc0;
  color: #2d1a1e;
}
[data-color-theme="factorial"][data-bs-theme="light"] .form-control:focus,
[data-color-theme="factorial"][data-bs-theme="light"] .form-select:focus {
  border-color: #f43f5e;
  box-shadow: 0 0 0 3px rgba(244,63,94,.12);
}
[data-color-theme="factorial"][data-bs-theme="light"] .dropdown-menu { background: #fff; border-color: #f5cdc0; }
[data-color-theme="factorial"][data-bs-theme="light"] .dropdown-item { color: #2d1a1e; }
[data-color-theme="factorial"][data-bs-theme="light"] .dropdown-item:hover { background: #fff0eb; }
[data-color-theme="factorial"][data-bs-theme="light"] .nav-tabs .nav-link { color: #7a5c62; }
[data-color-theme="factorial"][data-bs-theme="light"] .nav-tabs .nav-link.active { color: #f43f5e; border-bottom-color: #f43f5e; }
[data-color-theme="factorial"][data-bs-theme="light"] .kpi .label { color: #7a5c62; }
[data-color-theme="factorial"][data-bs-theme="light"] .section-sub { color: #7a5c62; }
/* .btn-primary ya hereda --tt-grad-primary (definido arriba en el bloque
   factorial). No hace falta overrider aquí — se eliminó código muerto. */
[data-color-theme="factorial"] .punch-card {
  background: linear-gradient(135deg, #f43f5e 0%, #fb7185 35%, #fda4af 75%, #fecdd3 100%);
  box-shadow: 0 12px 32px rgba(244,63,94,.32), inset 0 1px 0 rgba(255,255,255,.15);
}
[data-color-theme="factorial"] .sidebar nav a.active {
  background: #f43f5e; box-shadow: 0 4px 14px rgba(244,63,94,.45);
}
[data-color-theme="factorial"] .btn-approve { background: #0d9488; border-color: #0d9488; }
[data-color-theme="factorial"] .btn-approve:hover { background: #115e59; }
[data-color-theme="factorial"] .date-pill .month {
  background: linear-gradient(135deg, #fb7185, #f43f5e);
}
[data-color-theme="factorial"][data-bs-theme="dark"] {
  /* ── Color Theory: Factorial Dark ──────────────────────────
     Warm-toned dark palette. Canvas: deep rose-black.
     Body text: warm off-white (#f5e6e9) → 14:1 on #14080b, AAA.
     Secondary: muted rose (#b89a9f) → 5.2:1 on surface, AA.
     Borders: warm dark rose for visible separation (3.2:1).
     ──────────────────────────────────────────────────────── */
  --bs-body-bg: #14080b;
  --bs-body-color: #f5e6e9;
  --bs-secondary-color: #b89a9f;
  --bs-secondary-bg: #2a1a1f;
  --bs-tertiary-bg: #221318;
  --bs-tertiary-color: #8a6b72;
  --bs-border-color: #3d2a30;
  --bs-emphasis-color: #fdf2f4;
  --bs-emphasis-color-rgb: 253,242,244;
  --tt-surface: #1e1015;
  --tt-surface-2: #2a1a1f;
}
[data-color-theme="factorial"][data-bs-theme="dark"] .form-control,
[data-color-theme="factorial"][data-bs-theme="dark"] .form-select {
  background-color: var(--tt-surface);
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
}
[data-color-theme="factorial"][data-bs-theme="dark"] .form-control::placeholder { color: var(--bs-tertiary-color); }
[data-color-theme="factorial"][data-bs-theme="dark"] .form-control:focus,
[data-color-theme="factorial"][data-bs-theme="dark"] .form-select:focus {
  background-color: var(--tt-surface-2);
  border-color: #f43f5e;
}
[data-color-theme="factorial"][data-bs-theme="dark"] .dropdown-menu {
  background: var(--tt-surface);
  border-color: var(--bs-border-color);
}
[data-color-theme="factorial"][data-bs-theme="dark"] .dropdown-item { color: var(--bs-body-color); }
[data-color-theme="factorial"][data-bs-theme="dark"] .dropdown-item:hover { background: var(--tt-surface-2); }
[data-color-theme="factorial"][data-bs-theme="dark"] .modal-content {
  background: var(--tt-surface);
  color: var(--bs-body-color);
}
[data-color-theme="factorial"][data-bs-theme="dark"] .table-wrap thead th {
  background: var(--tt-surface-2);
  color: var(--bs-secondary-color);
}
[data-color-theme="factorial"][data-bs-theme="dark"] .table > :not(caption) > * > * {
  color: var(--bs-body-color);
  border-bottom-color: var(--bs-border-color);
}
[data-color-theme="factorial"][data-bs-theme="dark"] .nav-tabs .nav-link { color: var(--bs-secondary-color); }
[data-color-theme="factorial"][data-bs-theme="dark"] .nav-tabs .nav-link.active { color: #fb7185; }
[data-color-theme="factorial"][data-bs-theme="dark"] .kpi .label { color: var(--bs-secondary-color); }
[data-color-theme="factorial"][data-bs-theme="dark"] .btn-icon {
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
}
[data-color-theme="factorial"][data-bs-theme="dark"] .punch-card {
  background: linear-gradient(135deg, #4a1525 0%, #be123c 35%, #f43f5e 70%, #fb7185 100%);
  box-shadow: 0 12px 32px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
}

/* ============================================================
   THEME: NIMBUS (cyan-teal premium · Linear/Vercel/Stripe vibes)
   Activated by: data-color-theme="nimbus"
   ------------------------------------------------------------
   Tercera paleta del trío SaaS: cubre el hue cyan-teal, perfil
   "técnico-premium". Light: canvas off-white frío + cyan-600.
   Dark: ink-navy profundo + cyan-400 con glow. Inspiración:
   Linear (motion + tracking), Vercel (cleanliness), Arc (cyan
   accent), Stripe (depth de surfaces).
   ============================================================ */
[data-color-theme="nimbus"] {
  --bs-primary: #0891b2;            /* Cyan-600 — corporativo, alto contraste */
  --bs-primary-rgb: 8,145,178;
  --bs-link-color-rgb: 8,145,178;
  --bs-link-hover-color-rgb: 14,116,144;
  --tt-grad-primary: linear-gradient(135deg, #06b6d4 0%, #0891b2 50%, #0e7490 100%);
  /* Categorías de ausencia/baja con paleta análoga */
  --tt-vac:       #0891b2;          /* vacaciones — cyan      */
  --tt-sick:      #ea580c;          /* enfermedad — orange-600 (complementario) */
  --tt-leave:     #10b981;          /* permiso    — emerald-500 (accent)        */
  --tt-maternity: #7c3aed;          /* maternidad — violet-600                  */
  --tt-paternity: #2563eb;          /* paternidad — blue-600                    */
  --tt-positive:  #10b981;
  --tt-other:     #64748b;
}
[data-color-theme="nimbus"][data-bs-theme="light"] {
  /* ── Color Theory: Nimbus Light ──────────────────────────
     Cool off-white canvas (#f6f8fb) crea descanso visual sin
     sentirse plano. Surfaces puro blanco. Texto Slate-900
     (#0f172a) → 17:1 sobre canvas, AAA. Borders sutiles slate.
     Primary Cyan-600 → 4.7:1 sobre blanco, AA. */
  --bs-body-bg: #f6f8fb;
  --bs-body-color: #0f172a;
  --bs-secondary-color: #475569;
  --bs-tertiary-color: #64748b;
  --bs-tertiary-bg: #eef2f7;
  --bs-secondary-bg: #e2e8f0;
  --bs-border-color: #dbe3ec;
  --bs-border-color-translucent: rgba(15,23,42,.08);
  --tt-surface: #ffffff;
  --tt-surface-2: #f1f5f9;
  --tt-surface-overlay: rgba(255,255,255,.78);
  --tt-surface-popover: #ffffff;
}
[data-color-theme="nimbus"][data-bs-theme="light"] .table-wrap thead th {
  background: #eef6f9;
  color: #0e7490;
  letter-spacing: .04em;
}
[data-color-theme="nimbus"][data-bs-theme="light"] .form-control,
[data-color-theme="nimbus"][data-bs-theme="light"] .form-select {
  border-color: #cbd5e1;
  background: #fff;
}
[data-color-theme="nimbus"][data-bs-theme="light"] .form-control:focus,
[data-color-theme="nimbus"][data-bs-theme="light"] .form-select:focus {
  border-color: #06b6d4;
  box-shadow: 0 0 0 4px rgba(6,182,212,.14), 0 1px 2px rgba(8,145,178,.06);
}
[data-color-theme="nimbus"][data-bs-theme="light"] .nav-tabs .nav-link.active {
  color: #0891b2; border-bottom-color: #06b6d4;
}
[data-color-theme="nimbus"][data-bs-theme="light"] .demo-box code { color: #0e7490; }

[data-color-theme="nimbus"][data-bs-theme="dark"] {
  /* ── Color Theory: Nimbus Dark ───────────────────────────
     Ink-navy profundo (#080d18) — más oscuro que Slate-950 puro
     para dar el "vacío premium" de Linear/Arc. Surfaces sobre
     canvas con leve hint cyan. Primario Cyan-400 (#22d3ee) brilla
     sobre el fondo (glow natural) → ratio 11:1, AAA. */
  --bs-body-bg: #080d18;
  --bs-body-color: #e2e8f0;
  --bs-secondary-color: #94a3b8;
  --bs-tertiary-color: #64748b;
  --bs-tertiary-bg: #0f1626;
  --bs-secondary-bg: #131b2e;
  --bs-border-color: #1e293b;
  --bs-border-color-translucent: rgba(148,163,184,.12);
  --bs-primary: #22d3ee;
  --bs-primary-rgb: 34,211,238;
  --tt-surface: #0f1626;
  --tt-surface-2: #131b2e;
  --tt-surface-overlay: rgba(15,22,38,.78);
  --tt-surface-popover: #131b2e;
  --tt-grad-primary: linear-gradient(135deg, #22d3ee 0%, #06b6d4 55%, #0891b2 100%);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] .table-wrap thead th {
  background: #0f1626;
  color: #67e8f9;
  border-bottom-color: rgba(34,211,238,.12);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] .form-control,
[data-color-theme="nimbus"][data-bs-theme="dark"] .form-select {
  background-color: #0f1626;
  color: var(--bs-body-color);
  border-color: var(--bs-border-color);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] .form-control::placeholder { color: var(--bs-tertiary-color); }
[data-color-theme="nimbus"][data-bs-theme="dark"] .form-control:focus,
[data-color-theme="nimbus"][data-bs-theme="dark"] .form-select:focus {
  background-color: #131b2e;
  border-color: #22d3ee;
  box-shadow: 0 0 0 4px rgba(34,211,238,.18), 0 0 20px rgba(34,211,238,.08);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] .modal-content { background: #0f1626; }
[data-color-theme="nimbus"][data-bs-theme="dark"] .dropdown-menu {
  background: #131b2e; border-color: var(--bs-border-color);
  box-shadow: 0 24px 48px -12px rgba(0,0,0,.6), 0 0 0 1px rgba(34,211,238,.04);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] .nav-tabs .nav-link.active {
  color: #67e8f9; border-bottom-color: #22d3ee;
}

/* ── Componentes signature de Nimbus ─────────────────────────── */
[data-color-theme="nimbus"] .punch-card {
  background: linear-gradient(135deg, #0e7490 0%, #0891b2 30%, #06b6d4 65%, #22d3ee 100%);
  box-shadow:
    0 12px 32px rgba(8,145,178,.32),
    0 0 60px -12px rgba(34,211,238,.45),
    inset 0 1px 0 rgba(255,255,255,.16);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] .punch-card {
  background: linear-gradient(135deg, #083344 0%, #155e75 35%, #06b6d4 75%, #22d3ee 100%);
  box-shadow:
    0 12px 32px rgba(0,0,0,.6),
    0 0 80px -16px rgba(34,211,238,.5),
    inset 0 1px 0 rgba(255,255,255,.08);
}
[data-color-theme="nimbus"] .sidebar {
  background: linear-gradient(180deg, #050a14 0%, #081420 55%, #0a1a2a 100%);
}
[data-color-theme="nimbus"] .sidebar-brand .logo {
  background: linear-gradient(135deg, #22d3ee 0%, #06b6d4 50%, #0891b2 100%);
  box-shadow: 0 4px 14px rgba(6,182,212,.5), inset 0 1px 0 rgba(255,255,255,.22);
}
[data-color-theme="nimbus"] .sidebar nav a:hover i { color: #67e8f9; }
[data-color-theme="nimbus"] .sidebar nav a.active {
  background: linear-gradient(135deg, #0891b2 0%, #06b6d4 60%, #22d3ee 100%);
  box-shadow:
    0 6px 18px rgba(6,182,212,.45),
    0 0 24px -4px rgba(34,211,238,.55),
    inset 0 1px 0 rgba(255,255,255,.18);
}
[data-color-theme="nimbus"] .sidebar-footer .avatar {
  background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);
  box-shadow: 0 2px 8px rgba(6,182,212,.4), inset 0 1px 0 rgba(255,255,255,.18);
}
[data-color-theme="nimbus"] .date-pill .month {
  background: linear-gradient(135deg, #22d3ee, #0891b2);
}
/* Approve = Cyan, Reject mantiene rosa para máxima distinción semántica */
[data-color-theme="nimbus"] .btn-approve {
  --bs-btn-bg: #0891b2; --bs-btn-border-color: #0891b2;
  --bs-btn-hover-bg: #0e7490; --bs-btn-hover-border-color: #155e75;
  background: linear-gradient(135deg, #06b6d4, #0891b2);
}
/* Halo cyan en primary buttons (intensifica el premium feel) */
[data-color-theme="nimbus"] .btn-primary {
  box-shadow:
    0 1px 2px rgba(8,145,178,.25),
    0 0 16px -4px rgba(34,211,238,.35),
    inset 0 1px 0 rgba(255,255,255,.14);
}
[data-color-theme="nimbus"] .btn-primary:hover {
  box-shadow:
    0 2px 8px rgba(8,145,178,.4),
    0 0 28px -4px rgba(34,211,238,.55),
    inset 0 1px 0 rgba(255,255,255,.12);
}
/* Topbar con highlight cyan sutil */
[data-color-theme="nimbus"][data-bs-theme="dark"] .topbar {
  border-bottom-color: rgba(34,211,238,.08);
}

/* ═══════════════════════════════════════════════════════════
 * ENTERPRISE FEATURES — shared styles
 * ═══════════════════════════════════════════════════════════ */

/* Department pill used in location cards */
.dept-pill {
  display: inline-block; padding: 2px 8px; border-radius: 10px;
  font-size: .68rem; font-weight: 600; line-height: 1.4;
}

/* Status badges used across enterprise features */
.status-badge {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px; border-radius: 10px;
  font-size: .68rem; font-weight: 600; line-height: 1.4;
  white-space: nowrap;
}
.status-badge.success { background: rgba(34,197,94,.12); color: #16a34a; }
.status-badge.warning { background: rgba(245,158,11,.12); color: #d97706; }
.status-badge.info    { background: rgba(99,102,241,.12); color: #6366f1; }
.status-badge.primary { background: rgba(79,70,229,.12); color: #4f46e5; }
.status-badge.muted   { background: var(--bs-tertiary-bg); color: var(--bs-secondary-color); }
[data-bs-theme="dark"] .status-badge.success { background: rgba(34,197,94,.15); color: #4ade80; }
[data-bs-theme="dark"] .status-badge.warning { background: rgba(245,158,11,.15); color: #fbbf24; }
[data-bs-theme="dark"] .status-badge.info    { background: rgba(99,102,241,.18); color: #a5b4fc; }
[data-bs-theme="dark"] .status-badge.primary { background: rgba(79,70,229,.18); color: #a5b4fc; }

/* Enterprise section cards */
#sec-ubicaciones .card,
#sec-rotaciones .card,
#sec-marketplace .card,
#sec-cobertura .card,
#sec-bancohoras .card,
#sec-maternidad .card {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius, 12px);
  transition: box-shadow .2s, border-color .2s;
}
#sec-ubicaciones .card:hover,
#sec-rotaciones .card:hover,
#sec-marketplace .card:hover,
#sec-cobertura .card:hover,
#sec-bancohoras .card:hover,
#sec-maternidad .card:hover {
  border-color: var(--bs-primary);
  box-shadow: 0 4px 16px rgba(var(--bs-primary-rgb), .1);
}

/* Shift pattern slot row */
.sp-slot-row {
  padding: 4px 8px;
  background: var(--bs-tertiary-bg);
  border-radius: 8px;
}

/* Hour bank table */
#sec-bancohoras .table { font-size: .78rem; }
#sec-bancohoras .table th { font-size: .7rem; text-transform: uppercase; letter-spacing: .03em; color: var(--bs-secondary-color); }

/* Maternity progress bars */
#sec-maternidad .progress { border-radius: 3px; background: var(--bs-tertiary-bg); }

/* Coverage alert styling */
#coverageAlerts {
  padding: 8px 12px;
  background: var(--bs-tertiary-bg);
  border-radius: var(--tt-radius, 12px);
  border: 1px solid var(--bs-border-color);
}

/* Avatar small variant for enterprise features */
.avatar.sm {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .7rem; font-weight: 700;
  background: linear-gradient(135deg, var(--bs-primary), rgba(var(--bs-primary-rgb),.6));
  color: #fff; flex-shrink: 0;
}
.avatar.sm img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }

/* ═══════════════════════════════════════════════════════════
 * MICRO-INTERACTIONS — Sprint A+B
 * ═══════════════════════════════════════════════════════════ */

/* 3. Confetti */
.confetti-container {
  position: fixed; inset: 0; pointer-events: none; z-index: 99999; overflow: hidden;
}
.confetti-piece {
  position: absolute; top: -10px; width: 8px; height: 12px; border-radius: 2px;
  animation: confetti-fall var(--d, 1s) ease-out var(--delay, 0s) forwards;
}
@keyframes confetti-fall {
  0% { transform: translateX(0) rotate(0deg); opacity: 1; }
  100% { transform: translateX(var(--x, 0)) translateY(100vh) rotate(var(--r, 360deg)); opacity: 0; }
}

/* 4. Card hover preview */
.hover-preview-card {
  position: absolute; z-index: 10000; background: var(--tt-surface, #fff); border: 1px solid var(--bs-border-color);
  border-radius: 12px; padding: 12px 14px; box-shadow: 0 8px 24px rgba(0,0,0,.12);
  display: flex; gap: 10px; align-items: center; pointer-events: none;
  min-width: 220px; max-width: 300px; opacity: 0; animation: hp-in .15s ease forwards;
}
.hover-preview-card[style*="display: none"] { animation: none; }
@keyframes hp-in { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.hp-avatar {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, var(--bs-primary), rgba(var(--bs-primary-rgb),.5));
  color: #fff; font-size: .72rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.hp-name { font-weight: 700; font-size: .82rem; }
.hp-pos { font-size: .7rem; color: var(--bs-secondary-color); }
.hp-dept { font-size: .68rem; font-weight: 600; }
.hp-meta { font-size: .65rem; color: var(--bs-secondary-color); }

/* 6. Pull-to-refresh */
.ptr-indicator {
  position: fixed; top: 0; left: 50%; transform: translateX(-50%) translateY(-50px);
  width: 36px; height: 36px; border-radius: 50%; z-index: 10001;
  background: var(--bs-primary); color: #fff;
  display: flex; align-items: center; justify-content: center;
  transition: transform .2s, opacity .2s; opacity: 0; font-size: 1.1rem;
}
.ptr-indicator.ready { background: #22c55e; }
.ptr-indicator.refreshing i { animation: ptr-spin .6s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }

/* 7. Toast stacking */
#toast-stack {
  position: fixed; bottom: 20px; right: 20px; z-index: 10002;
  display: flex; flex-direction: column-reverse; gap: 8px; max-width: 360px;
}
.smart-toast {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: 10px; font-size: .82rem; font-weight: 500;
  background: var(--tt-surface, #fff); border: 1px solid var(--bs-border-color);
  box-shadow: 0 6px 20px rgba(0,0,0,.1); color: var(--bs-body-color);
  transform: translateX(120%); transition: transform .3s cubic-bezier(.34,1.56,.64,1), opacity .3s;
  opacity: 0;
}
.smart-toast.show { transform: none; opacity: 1; }
.smart-toast.toast-exit { transform: translateX(120%); opacity: 0; }
.smart-toast i { font-size: 1rem; flex-shrink: 0; }
.toast-success i { color: #16a34a; } .toast-warning i { color: #d97706; }
.toast-danger i { color: #dc2626; } .toast-info i { color: #6366f1; }
.toast-primary i { color: var(--bs-primary); }
.toast-msg { flex: 1; min-width: 0; }
.toast-count { font-size: .7rem; opacity: .6; }
.toast-close { background: none; border: 0; color: var(--bs-secondary-color); cursor: pointer; font-size: 1rem; padding: 0 2px; line-height: 1; }

/* 8. Inline diff */
.diff-old { text-decoration: line-through; color: #dc2626; opacity: .7; font-size: .85em; }
.diff-arrow { margin: 0 4px; color: var(--bs-secondary-color); font-size: .75em; }
.diff-new { color: #16a34a; font-weight: 600; }
[data-bs-theme="dark"] .diff-old { color: #fca5a5; }
[data-bs-theme="dark"] .diff-new { color: #86efac; }
[data-bs-theme="dark"] .toast-success i { color: #4ade80; }
[data-bs-theme="dark"] .toast-warning i { color: #fbbf24; }
[data-bs-theme="dark"] .toast-danger i  { color: #fca5a5; }
[data-bs-theme="dark"] .toast-info i    { color: #a5b4fc; }

/* ════════════════════════════════════════════════════════════
   v2.6.31 · 11. PAGE TRANSITIONS (View Transitions API)
   ──────────────────────────────────────────────────────────
   Animaciones premium con cubic-bezier emphasized + named
   transitions para el pageTitle (cross-fade text morph) y
   el contenido principal (slide+fade).  Si el browser no
   soporta la API o el user pidió reduced-motion, navigateWith-
   Transition() en micro-interactions.js cae a fn() directo sin
   animación — estas reglas no se ejecutan.
   ════════════════════════════════════════════════════════════ */
::view-transition-old(root) {
  animation: vt-out .18s cubic-bezier(.4, 0, 1, 1) forwards;
}
::view-transition-new(root) {
  animation: vt-in .26s cubic-bezier(0, 0, .2, 1);
}
@keyframes vt-out {
  to { opacity: 0; transform: translateY(-6px) scale(.992); filter: blur(.5px); }
}
@keyframes vt-in {
  from { opacity: 0; transform: translateY(10px) scale(.996); filter: blur(.5px); }
}

/* ── Named transition: page title (cross-fade entre nombres de sección) ── */
#pageTitle { view-transition-name: page-title; }

::view-transition-old(page-title) {
  animation: vt-title-out .22s cubic-bezier(.4, 0, 1, 1) forwards;
}
::view-transition-new(page-title) {
  animation: vt-title-in .32s cubic-bezier(0, 0, .2, 1);
}
@keyframes vt-title-out {
  to { opacity: 0; transform: translateX(-12px); }
}
@keyframes vt-title-in {
  from { opacity: 0; transform: translateX(12px); }
}

/* ── Reduced-motion: el JS ya evita disparar startViewTransition,
   pero por defensa-en-profundidad si una transición ya está en
   marcha (cambio de preferencia mid-flight), kill animations. ── */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(page-title),
  ::view-transition-new(page-title) { animation: none !important; }
}

/* 13. NEW ribbons */
.new-ribbon {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: linear-gradient(135deg, #ec4899, #f43f5e);
  color: #fff; font-size: .52rem; font-weight: 800; letter-spacing: .06em;
  padding: 1px 5px; border-radius: 6px; line-height: 1.4;
  animation: ribbon-pulse 2s ease infinite;
}
@keyframes ribbon-pulse { 0%,100% { opacity: 1; } 50% { opacity: .7; } }

/* 14. Back to top */
.back-to-top {
  position: fixed; bottom: 24px; right: 24px; z-index: 9998;
  width: 40px; height: 40px; border-radius: 50%; border: 0;
  background: var(--bs-primary); color: #fff;
  box-shadow: 0 4px 14px rgba(var(--bs-primary-rgb),.35);
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem;
  opacity: 0; transform: translateY(20px); pointer-events: none;
  transition: opacity .25s, transform .25s;
  cursor: pointer;
}
.back-to-top.visible { opacity: 1; transform: none; pointer-events: auto; }
.back-to-top:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(var(--bs-primary-rgb),.45); }

/* 20. Command palette */
.cmd-palette-overlay {
  position: fixed; inset: 0; z-index: 10010; background: rgba(0,0,0,.4);
  backdrop-filter: blur(4px); display: flex; align-items: flex-start; justify-content: center;
  padding-top: min(20vh, 140px); opacity: 0; pointer-events: none;
  transition: opacity .15s;
}
.cmd-palette-overlay.open { opacity: 1; pointer-events: auto; }
.cmd-palette {
  background: var(--tt-surface, #fff); border: 1px solid var(--bs-border-color);
  border-radius: 14px; width: min(560px, 92vw); box-shadow: 0 20px 60px rgba(0,0,0,.18);
  overflow: hidden; transform: scale(.96); transition: transform .15s;
}
.cmd-palette-overlay.open .cmd-palette { transform: none; }
.cmd-palette-header {
  display: flex; align-items: center; gap: 10px; padding: 12px 16px;
  border-bottom: 1px solid var(--bs-border-color);
}
.cmd-palette-header i { color: var(--bs-secondary-color); font-size: 1.1rem; }
.cmd-palette-input {
  flex: 1; border: 0; background: transparent; outline: none; font-size: .92rem;
  color: var(--bs-body-color);
}
.cmd-palette-header kbd {
  font-size: .65rem; padding: 2px 6px; border-radius: 4px;
  background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color);
  color: var(--bs-secondary-color);
}
.cmd-palette-results { max-height: 340px; overflow-y: auto; padding: 6px; }
.cmd-palette-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  border-radius: 8px; cursor: pointer; font-size: .84rem; color: var(--bs-body-color);
}
.cmd-palette-item:hover, .cmd-palette-item.active { background: var(--bs-tertiary-bg); }
.cmd-palette-item i { color: var(--bs-secondary-color); font-size: .9rem; width: 20px; text-align: center; }
.cmd-palette-empty { padding: 24px; text-align: center; color: var(--bs-secondary-color); font-size: .82rem; }

/* 22. Birthday widget */
.birthday-widget {
  display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  background: linear-gradient(135deg, rgba(236,72,153,.06), rgba(245,158,11,.06));
  border: 1px solid rgba(236,72,153,.15); border-radius: var(--tt-radius, 12px);
  animation: bday-glow 3s ease infinite;
}
@keyframes bday-glow { 0%,100% { box-shadow: 0 0 0 transparent; } 50% { box-shadow: 0 0 20px rgba(236,72,153,.08); } }
.bw-icon { font-size: 1.6rem; }
.bw-title { font-size: .72rem; font-weight: 700; color: var(--bs-secondary-color); text-transform: uppercase; letter-spacing: .04em; }
.bw-names { font-size: .88rem; font-weight: 600; }
.bw-name { color: var(--bs-primary); }

/* 23. Streak badges */
.streak-badge {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 7px; border-radius: 8px; font-size: .65rem; font-weight: 700;
}
.streak-bronze { background: rgba(205,127,50,.12); color: #92400e; }
.streak-silver { background: rgba(148,163,184,.15); color: #475569; }
.streak-gold { background: rgba(245,158,11,.15); color: #b45309; }
[data-bs-theme="dark"] .streak-bronze { background: rgba(205,127,50,.2); color: #fbbf24; }
[data-bs-theme="dark"] .streak-silver { background: rgba(148,163,184,.2); color: #94a3b8; }
[data-bs-theme="dark"] .streak-gold { background: rgba(245,158,11,.25); color: #fcd34d; }

/* 24. Pulse survey widget */
.pulse-widget {
  padding: 14px 18px; border-radius: var(--tt-radius, 12px);
  background: linear-gradient(135deg, rgba(99,102,241,.04), rgba(236,72,153,.04));
  border: 1px solid rgba(99,102,241,.12);
}
.pw-q { font-size: .88rem; font-weight: 600; margin-bottom: 10px; }
.pw-scale { display: flex; gap: 6px; }
.pw-btn {
  width: 40px; height: 36px; border-radius: 8px; border: 1px solid var(--bs-border-color);
  background: var(--tt-surface, #fff); font-weight: 700; font-size: .88rem;
  cursor: pointer; transition: all .15s;
}
.pw-btn:hover { background: var(--bs-primary); color: #fff; border-color: var(--bs-primary); transform: translateY(-2px); }
.pw-hint { font-size: .68rem; color: var(--bs-secondary-color); margin-top: 6px; }
.pw-thanks { font-size: .88rem; font-weight: 600; color: var(--bs-primary); padding: 8px 0; }

/* 25. Comments thread */
.comments-thread { border-top: 1px solid var(--bs-border-color); padding-top: 10px; margin-top: 10px; }
.ct-msg { padding: 6px 0; border-bottom: 1px solid rgba(var(--bs-border-color-rgb, 222,226,230),.3); }
.ct-msg strong { font-size: .78rem; }
.ct-time { font-size: .65rem; color: var(--bs-secondary-color); margin-left: 6px; }
.ct-text { font-size: .8rem; margin-top: 2px; }
.ct-empty { font-size: .78rem; color: var(--bs-secondary-color); font-style: italic; padding: 4px 0; }
.ct-form { display: flex; gap: 6px; margin-top: 8px; }
.ct-form input { flex: 1; }

/* 39. Reaction bar */
.reaction-bar { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }
.reaction-btn {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 8px; border-radius: 16px; border: 1px solid var(--bs-border-color);
  background: transparent; font-size: .78rem; cursor: pointer;
  transition: all .15s;
}
.reaction-btn:hover { background: var(--bs-tertiary-bg); transform: scale(1.08); }
.reaction-btn.active { background: rgba(var(--bs-primary-rgb),.08); border-color: var(--bs-primary); }
.rc-count { font-size: .65rem; font-weight: 600; color: var(--bs-secondary-color); }

/* 9. Color picker inline */
.color-picker-inline { display: flex; gap: 4px; flex-wrap: wrap; }
.cp-swatch {
  width: 24px; height: 24px; border-radius: 50%; border: 2px solid transparent;
  cursor: pointer; transition: transform .15s, border-color .15s;
}
.cp-swatch:hover { transform: scale(1.15); }
.cp-swatch.active { border-color: var(--bs-body-color); box-shadow: 0 0 0 2px rgba(var(--bs-primary-rgb),.3); }

/* ═══════════════════════════════════════════════════════════
 * SECTION TABS — pattern compartido por secciones con muchas tabs
 *   · Cumplimiento (8 tabs)
 *   · DevOps (7 tabs)
 * Se generaliza para que ambas usen el mismo CSS: scroll horizontal
 * con scrollbar oculto, nowrap y padding compacto en mobile. Cualquier
 * sección futura puede sumarse añadiendo su id a los selectores.
 * ═══════════════════════════════════════════════════════════ */
#sec-cumplimiento .nav-tabs,
#sec-devops .nav-tabs {
  border-bottom: 2px solid var(--bs-border-color);
  gap: 0;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
#sec-cumplimiento .nav-tabs::-webkit-scrollbar,
#sec-devops .nav-tabs::-webkit-scrollbar { display: none; }
#sec-cumplimiento .nav-tabs .nav-link,
#sec-devops .nav-tabs .nav-link {
  font-size: .75rem; font-weight: 600; padding: .5rem .75rem;
  white-space: nowrap; border: none; border-bottom: 2px solid transparent;
  color: var(--bs-secondary-color); transition: color .15s, border-color .15s;
  margin-bottom: -2px;
  flex-shrink: 0;
}
#sec-cumplimiento .nav-tabs .nav-link:hover,
#sec-devops .nav-tabs .nav-link:hover { color: var(--bs-body-color); }
#sec-cumplimiento .nav-tabs .nav-link.active,
#sec-devops .nav-tabs .nav-link.active {
  color: var(--bs-primary);
  border-bottom-color: var(--bs-primary);
  background: transparent;
}
#sec-cumplimiento .tab-content,
#sec-devops .tab-content { padding-top: 1rem; }
#sec-cumplimiento .tab-pane .card-soft,
#sec-devops .tab-pane .card-soft { transition: box-shadow .2s; }
#sec-cumplimiento .tab-pane .card-soft:hover,
#sec-devops .tab-pane .card-soft:hover { box-shadow: var(--tt-shadow-sm, 0 2px 8px rgba(0,0,0,.06)); }

/* KPI value modifier — para valores como "2h 30m" o timestamps que no
   caben con la tipografía base de 1.375rem. Usado en DevOps sync queue
   y otras secciones con KPIs de antigüedad / fecha. */
.kpi .value.value-sm { font-size: 1rem; }
.kpi .value.value-xs { font-size: .9rem; }

@media (max-width: 767.98px) {
  #sec-cumplimiento .nav-tabs .nav-link,
  #sec-devops .nav-tabs .nav-link { font-size: .7rem; padding: .4rem .5rem; }
  /* En mobile la "value-sm" puede ser aún más estrecha */
  .kpi .value.value-sm { font-size: .9rem; }
}

/* DevOps · KPIs con icono no se rompen + tablas tienen acción mínima
   de overflow horizontal (table-responsive ya lo hace, pero por si
   alguna tabla del panel se renderiza sin wrap). */
#sec-devops .kpi .value { word-break: keep-all; }
#sec-devops .table-responsive { -webkit-overflow-scrolling: touch; }

/* ── Features-50 styles ── */
/* #10 Drag & drop */
[data-drag-id] { cursor: grab; transition: opacity .2s, transform .15s; }
[data-drag-id].dragging { opacity: .4; transform: scale(.97); }
[data-drag-id].drag-over { outline: 2px dashed var(--bs-primary); outline-offset: 2px; border-radius: 8px; }

/* #17 Saved views */
.saved-views-bar .btn-group-sm .btn { font-size: .75rem; }

/* #19 Inline editing */
td.inline-editing { outline: 2px solid var(--bs-primary); outline-offset: -1px; border-radius: 4px; background: var(--bs-body-bg); }

/* #21 Activity feed */
.activity-feed { max-height: 400px; overflow-y: auto; }
.af-item { display: flex; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid var(--bs-border-color-translucent); }
.af-icon { width: 28px; height: 28px; border-radius: 50%; background: var(--bs-primary-bg-subtle); color: var(--bs-primary); display: grid; place-items: center; flex-shrink: 0; font-size: .75rem; }
.af-action { font-size: .8125rem; font-weight: 500; }
.af-detail { font-size: .75rem; }
.af-meta { font-size: .6875rem; color: var(--bs-secondary-color); }

/* #30 Help center */
.help-center-fab { position: fixed; bottom: 24px; right: 24px; z-index: 1060; width: 48px; height: 48px; border-radius: 50%; background: var(--bs-primary); color: #fff; border: none; font-size: 1.25rem; display: grid; place-items: center; box-shadow: 0 4px 16px rgba(0,0,0,.18); transition: transform .2s; }
.help-center-fab:hover { transform: scale(1.1); }
.help-center-panel { position: fixed; bottom: 80px; right: 24px; z-index: 1059; width: 340px; max-height: 450px; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); border-radius: 14px; box-shadow: 0 8px 32px rgba(0,0,0,.15); display: none; flex-direction: column; overflow: hidden; }
.help-center-panel.open { display: flex; animation: hcSlideUp .25s ease-out; }
@keyframes hcSlideUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.hc-header { display: flex; align-items: center; justify-content: space-between; padding: .75rem 1rem; border-bottom: 1px solid var(--bs-border-color-translucent); }
.hc-body { padding: .75rem 1rem; overflow-y: auto; flex: 1; }
.hc-faq { margin-bottom: .5rem; }
.hc-faq summary { cursor: pointer; font-size: .8125rem; font-weight: 500; padding: .4rem 0; }
.hc-faq p { padding-left: .5rem; border-left: 2px solid var(--bs-primary); }

/* #28 Help tips */
.help-tip-btn { background: none; border: none; color: var(--bs-secondary-color); font-size: .875rem; padding: 0 .25rem; cursor: help; vertical-align: middle; }
.help-tip-btn:hover { color: var(--bs-primary); }

/* #37 DND */
.dnd-active-badge { font-size: .6875rem; background: var(--bs-warning-bg-subtle); color: var(--bs-warning-text-emphasis); padding: 2px 8px; border-radius: 99px; }

/* #40 Suggested colleagues */
.colleagues-widget { padding: .75rem 0; }
.cw-title { font-size: .8125rem; font-weight: 600; margin-bottom: .5rem; }
.cw-list { display: flex; flex-direction: column; gap: .4rem; }
.cw-card { display: flex; align-items: center; gap: .5rem; padding: .35rem .5rem; border-radius: 8px; transition: background .15s; }
.cw-card:hover { background: var(--bs-tertiary-bg); }
.cw-card .avatar.sm { width: 30px; height: 30px; border-radius: 50%; background: var(--bs-primary-bg-subtle); color: var(--bs-primary); display: grid; place-items: center; font-size: .7rem; font-weight: 600; flex-shrink: 0; }
.cw-name { font-size: .8125rem; font-weight: 500; }
.cw-dept { font-size: .6875rem; }

/* #43 Forecasting */
.forecast-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.fc-day { width: 64px; padding: 6px; border-radius: 8px; text-align: center; background: var(--bs-tertiary-bg); border: 1px solid transparent; }
.fc-day.fc-ok { border-color: var(--bs-success-border-subtle); }
.fc-day.fc-danger { border-color: var(--bs-danger); background: var(--bs-danger-bg-subtle); }
.fc-day.fc-holiday { border-color: var(--bs-info-border-subtle); background: var(--bs-info-bg-subtle); }
.fc-dow { font-size: .625rem; text-transform: uppercase; color: var(--bs-secondary-color); }
.fc-date { font-size: .875rem; font-weight: 600; }
.fc-bar { height: 4px; border-radius: 2px; background: var(--bs-border-color-translucent); margin: 4px 0 2px; }
.fc-fill { height: 100%; border-radius: 2px; background: var(--bs-success); transition: width .3s; }
.fc-danger .fc-fill { background: var(--bs-danger); }
.fc-count { font-size: .6875rem; color: var(--bs-secondary-color); }
.fc-legend { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 4px; vertical-align: middle; }
.fc-legend.fc-ok { background: var(--bs-success); }
.fc-legend.fc-danger { background: var(--bs-danger); }
.fc-legend.fc-holiday { background: var(--bs-info); }

/* #49 Achievements */
.achievements-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.ach-card { display: flex; align-items: center; gap: .5rem; padding: .5rem .75rem; border-radius: 10px; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color-translucent); min-width: 180px; }
.ach-card.ach-gold { background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); border-color: #f59e0b; }
.ach-card.ach-silver { background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%); border-color: #94a3b8; }
.ach-card.ach-bronze { background: linear-gradient(135deg, #fff7ed 0%, #fed7aa 100%); border-color: #fb923c; }
.ach-icon { font-size: 1.25rem; }
.ach-gold .ach-icon { color: #d97706; }
.ach-silver .ach-icon { color: #64748b; }
.ach-bronze .ach-icon { color: #ea580c; }
.ach-name { font-size: .8125rem; font-weight: 600; }
.ach-label { font-size: .6875rem; color: var(--bs-secondary-color); }

/* #15 Animated empty states */
.animated-empty-state { text-align: center; padding: 2rem 1rem; }
.aes-illustration { width: 140px; height: 120px; margin: 0 auto 1rem; }
.aes-svg { width: 100%; height: 100%; }
.aes-message { font-size: .875rem; color: var(--bs-secondary-color); }
@media (prefers-reduced-motion: no-preference) {
  .aes-pulse { animation: aesPulse 2s ease-in-out infinite; }
  .aes-bounce { animation: aesBounce 2.5s ease-in-out infinite; }
  .aes-draw { stroke-dasharray: 200; stroke-dashoffset: 200; animation: aesDraw 1.5s ease forwards; }
  .aes-slide { opacity: 0; animation: aesSlide .6s ease forwards; animation-delay: var(--d, 0s); }
  .aes-fade { opacity: 0; animation: aesFade .8s ease forwards; animation-delay: var(--d, 0s); }
  .aes-grow { transform-origin: bottom; transform: scaleY(0); animation: aesGrow .6s ease forwards; animation-delay: var(--d, 0s); }
}
@keyframes aesPulse { 0%,100% { opacity: .6; transform: scale(1); } 50% { opacity: 1; transform: scale(1.15); } }
@keyframes aesBounce { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@keyframes aesDraw { to { stroke-dashoffset: 0; } }
@keyframes aesSlide { to { opacity: 1; transform: translateX(0); } from { opacity: 0; transform: translateX(-12px); } }
@keyframes aesFade { to { opacity: 1; } }
@keyframes aesGrow { to { transform: scaleY(1); } }

/* #45 Reports builder */
.rb-field-chip { display: inline-flex; align-items: center; gap: .25rem; padding: .25rem .6rem; border-radius: 99px; border: 1px solid var(--bs-border-color); font-size: .75rem; cursor: pointer; transition: all .15s; user-select: none; }
.rb-field-chip input { display: none; }
.rb-field-chip.active { background: var(--bs-primary-bg-subtle); border-color: var(--bs-primary); color: var(--bs-primary); }
.rb-field-chip:hover { border-color: var(--bs-primary); }

/* #50 Insights */
.insights-list { display: flex; flex-direction: column; gap: .5rem; }
.ins-card { display: flex; align-items: flex-start; gap: .6rem; padding: .6rem .75rem; border-radius: 10px; border: 1px solid var(--bs-border-color-translucent); background: var(--bs-body-bg); }
.ins-card.ins-warning { border-left: 3px solid var(--bs-warning); }
.ins-card.ins-info { border-left: 3px solid var(--bs-info); }
.ins-icon { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; flex-shrink: 0; font-size: .8rem; }
.ins-warning .ins-icon { background: var(--bs-warning-bg-subtle); color: var(--bs-warning-text-emphasis); }
.ins-info .ins-icon { background: var(--bs-info-bg-subtle); color: var(--bs-info-text-emphasis); }
.ins-text { font-size: .8125rem; font-weight: 500; }
.ins-detail { font-size: .75rem; color: var(--bs-secondary-color); }

/* ================================================================
   S15 — Polish para las secciones S6/S7/S8/S10/S11/S14
   Mejoras de dark mode + estados hover/focus + spacings consistentes
   en las nuevas funcionalidades de self-service y reportes.
   ================================================================ */

/* ── Goals & OKRs cards (S7/S10) ─────────────────────── */
/* Las tarjetas usan border-left coloreado por progreso. Aseguramos
   que el progress bar interno sea visible en dark mode (el inline
   `background:#e5e7eb` no se ve bien sobre fondo oscuro). */
[data-bs-theme="dark"] #myGoalsContent .progress,
[data-bs-theme="dark"] #adminGoalsContent .progress {
  background: rgba(255, 255, 255, .08) !important;
}

/* KR rows (lista interna de cada goal). El inline `background:#f8fafc`
   choca con dark mode → usar bg de surface. */
[data-bs-theme="dark"] #myGoalsContent .border.rounded.p-2,
[data-bs-theme="dark"] #adminGoalKRsBuilder .border.rounded,
[data-bs-theme="dark"] #goalKRsBuilder .border.rounded {
  background: var(--bs-tertiary-bg) !important;
  border-color: var(--bs-border-color) !important;
}

/* Botón de completar goal (✓ verde) — tamaño mínimo táctil 36px */
#myGoalsContent .btn-outline-success,
#adminGoalsContent .btn-outline-success {
  min-width: 36px;
}

/* Linked skills chips (S10): mejor contraste en dark mode */
[data-bs-theme="dark"] #myGoalsContent .badge.bg-primary.bg-opacity-10 {
  background: rgba(99, 102, 241, .22) !important;
  color: #c7d2fe !important;
}
[data-bs-theme="dark"] #myGoalsContent .badge.bg-success.bg-opacity-10 {
  background: rgba(16, 185, 129, .22) !important;
  color: #6ee7b7 !important;
}

/* ── Pulse Surveys (S6/S8) ─────────────────────────────── */
/* Botones de la escala 1-5 con emojis: estado hover con elevación */
#myPulseContent .btn.flex-fill {
  transition: transform .12s var(--ease-out), box-shadow .12s var(--ease-out), background-color .12s var(--ease-out);
}
@media (hover: hover) {
  #myPulseContent .btn.flex-fill:not(:disabled):hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .12);
  }
}
#myPulseContent .btn.flex-fill:active {
  transform: translateY(0);
}

/* Card de encuesta urgente (≤1 día): pulse sutil para llamar la atención */
#myPulseContent .card-soft.border-warning {
  border-left-color: var(--bs-warning) !important;
}

/* Tabla admin pulse: progress bar de respuestas con mejor visibilidad */
[data-bs-theme="dark"] #pulseAdminContent .progress {
  background: rgba(255, 255, 255, .08);
}

/* ── Mis competencias (S4) ─────────────────────────────── */
/* Marker vertical sobre el progress bar (nivel requerido) — más
   visible: añadimos triángulo invertido sobre el marker. */
#mySkillsContent .progress {
  overflow: visible;
}
#mySkillsContent .progress > div:not(.progress-bar) {
  pointer-events: none;
}
[data-bs-theme="dark"] #mySkillsContent .progress {
  background: rgba(255, 255, 255, .08) !important;
}

/* ── Mi carrera (S4/S11) ───────────────────────────────── */
/* Career nodes: focus-visible para accesibilidad teclado */
.career-node:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 4px;
}
/* En dark mode, los iconos de los nodos pueden quedar tenues:
   reforzamos el color base de `bi` dentro de career-node. */
[data-bs-theme="dark"] .career-node i.bi {
  filter: brightness(1.15);
}
/* Check-circle (step pasado) y geo-alt (estás aquí) tienen background
   blanco hardcoded en JS — sustituir por surface en dark. */
[data-bs-theme="dark"] .career-node .bi-check-circle-fill {
  background: var(--tt-surface) !important;
  border-radius: 50%;
}

/* ── Referrals (S5) ────────────────────────────────────── */
/* Truncate descriptions a 3 líneas (ya inline). Aseguramos que el
   spacing del CTA respira bien en mobile. */
#myRefContent .card-soft .btn-primary {
  white-space: nowrap;
}

/* ── Mis gastos (S3): receipt thumb hover ─────────────── */
#myExpContent .table img {
  transition: transform .12s var(--ease-out);
}
@media (hover: hover) {
  #myExpContent .table img:hover {
    transform: scale(1.5);
    box-shadow: 0 4px 14px rgba(0, 0, 0, .25);
    z-index: 2;
    position: relative;
  }
}

/* ── Reportes ampliados S14: cards con altura uniforme ─── */
#sec-reportes .card-soft canvas {
  max-width: 100%;
}
#sec-reportes h3.h6.mt-4 {
  padding-top: .5rem;
  border-top: 1px solid var(--bs-border-color);
}

/* ── KPI sub-label (usado en talent KPIs con ciclo) ──── */
.kpi .sub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Sidebar badges nuevas secciones ──────────────────── */
/* Las nuevas secciones (Mis objetivos, Encuestas, Recomendar talento)
   usan badges pequeñas en el nav. Aseguramos tamaño mínimo legible. */
.sidebar nav a .badge {
  font-size: .65rem;
  padding: .2rem .4rem;
  min-width: 1.2rem;
  text-align: center;
}

/* ── Modales con KR builder: scroll suave en mobile ─── */
#myGoalModal .modal-body,
#adminGoalModal .modal-body {
  scroll-behavior: smooth;
}

/* ── Goal builder rows (modal KR) ─────────────────────── */
#goalKRsBuilder > div,
#adminGoalKRsBuilder > div {
  background: var(--bs-tertiary-bg);
}

/* ── Tooltip-friendly: status badges con cursor help ─── */
.status-badge[title] {
  cursor: help;
}

/* ============================================================
   v3.44.0 — PREMIUM POLISH LAYER (May 10 2026)
   ------------------------------------------------------------
   Refinamiento profesional inspirado en Linear, Stripe, Vercel,
   Notion. Mejora tipografía del sidebar, jerarquía cromática,
   micro-interacciones y entrada de paneles. Compatible con
   light/dark + Atlántico/Factorial. No rompe componentes
   existentes (capa de overrides no destructiva).
   ============================================================ */

/* ── Color tokens premium (color theory: triad atenuada) ────
   Indigo (primary) + Teal (success/info) + Amber (caution).
   Triada balanceada para máxima distinción + armonía. */
:root {
  --tt-accent-teal:  #14b8a6;   /* Teal-500 — info/positive secundario      */
  --tt-accent-amber: #f59e0b;   /* Amber-500 — caution/highlight            */
  --tt-accent-rose:  #f43f5e;   /* Rose-500 — alerta inversa, atención      */
  /* Gradientes premium (marcas tipo Stripe/Linear) */
  --tt-grad-primary: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
  --tt-grad-success: linear-gradient(135deg, #059669 0%, #14b8a6 100%);
  --tt-grad-warm:    linear-gradient(135deg, #f59e0b 0%, #ef4444 100%);
  --tt-grad-sidebar: linear-gradient(180deg, #0b1426 0%, #0f172a 60%, #131c30 100%);
  --tt-grad-sidebar-hover: linear-gradient(135deg, rgba(99,102,241,.16), rgba(139,92,246,.10));

  /* Text colors sidebar (alto contraste con bg navy) */
  --tt-sb-text:        #cbd5e1;   /* Slate-300  → 9.5:1 sobre #0f172a, AAA */
  --tt-sb-text-strong: #f8fafc;   /* Slate-50   → títulos / brand          */
  --tt-sb-text-muted:  #94a3b8;   /* Slate-400  → labels secundarios       */
  --tt-sb-section:     #64748b;   /* Slate-500  → headers de sección       */
}
[data-bs-theme="dark"] {
  --tt-grad-sidebar: linear-gradient(180deg, #020617 0%, #050a14 50%, #0a1020 100%);
  --tt-grad-sidebar-hover: linear-gradient(135deg, rgba(129,140,248,.18), rgba(167,139,250,.10));
}

/* ════════════════════════════════════════════════════════════
   v2.6.9 · CASCADE FIX — theme-aware gradient tokens
   ------------------------------------------------------------
   El bloque `:root` previo (line ~4280) re-define
   `--tt-grad-primary` con valores indigo de atlantico.  Como
   `:root` y `[data-color-theme="X"]` tienen MISMA especificidad
   (10), gana el último por source-order.  Esto sobrescribía los
   tokens de factorial (line 3329) y nimbus (line 3469), haciendo
   que `.btn-primary`, `.sidebar nav a.active`, `.dropdown-item
   :active`, `.brand-preview-card`, `.plan-card-ribbon`, FAB,
   setup-progress, tour-tip-progress, sidebar-brand .logo y
   sidebar-footer .avatar mostraran indigo en TODOS los temas.
   Solución: re-aplicar los tokens themed AQUI (después del
   :root) para garantizar que ganen el cascade.

   Tokens cubiertos:
     · --tt-grad-primary  (btn-primary, sidebar.active, etc.)
     · --pe-grad-1/2/cool (definidos en premium-employee.css —
       también necesitan override aquí porque ese archivo carga
       después pero su `:root` block tiene la misma especificidad
       que las overrides themed).
   ════════════════════════════════════════════════════════════ */
[data-color-theme="factorial"] {
  /* Reaplica el rose gradient definido en el bloque factorial (3329) */
  --tt-grad-primary: linear-gradient(135deg, #f43f5e 0%, #ec4899 60%, #db2777 100%);
}
[data-color-theme="nimbus"] {
  /* Reaplica el cyan gradient definido en el bloque nimbus (3469) */
  --tt-grad-primary: linear-gradient(135deg, #06b6d4 0%, #0891b2 50%, #0e7490 100%);
}
[data-color-theme="nimbus"][data-bs-theme="dark"] {
  /* Reaplica el cyan vibrant dark definido en nimbus dark (3538) */
  --tt-grad-primary: linear-gradient(135deg, #22d3ee 0%, #06b6d4 55%, #0891b2 100%);
}

/* ============================================================
   1) SIDEBAR PREMIUM — tipografía, contraste, micro-interacciones
   ============================================================ */
.sidebar {
  background: var(--tt-grad-sidebar);
  color: var(--tt-sb-text);
  border-right: 1px solid rgba(255,255,255,.04);
  /* Subtle inner glow on the right edge */
  box-shadow: inset -1px 0 0 rgba(255,255,255,.02);
}
.offcanvas.sidebar,
.offcanvas-lg.sidebar { --bs-offcanvas-bg: transparent; background: var(--tt-grad-sidebar); }

/* Brand block: stronger hierarchy */
.sidebar-brand strong {
  color: var(--tt-sb-text-strong);
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.2;
}
.sidebar-brand small {
  color: var(--tt-sb-text-muted);
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .015em;
  line-height: 1.3;
}
.sidebar-brand .logo {
  background: var(--tt-grad-primary);
  box-shadow:
    0 4px 14px rgba(99,102,241,.45),
    inset 0 1px 0 rgba(255,255,255,.18),
    inset 0 -1px 0 rgba(0,0,0,.18);
  transition: transform .25s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.sidebar-brand:hover .logo { transform: rotate(-6deg) scale(1.06); }

/* Section headers: discreet, professional */
.nav-section {
  color: var(--tt-sb-section);
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 18px 22px 8px;
  position: relative;
}
.nav-section::after {
  content: '';
  position: absolute;
  left: 22px; right: 22px; bottom: 4px;
  height: 1px;
  background: linear-gradient(90deg, rgba(255,255,255,.06), transparent);
}

/* Nav links: brighter base text + smoother transitions */
.sidebar nav a {
  color: var(--tt-sb-text);
  font-weight: 500;
  font-size: .8125rem;
  letter-spacing: -.005em;
  padding: 9px 13px;
  border-radius: 10px;
  position: relative;
  transition:
    background .18s var(--ease-out, cubic-bezier(0,0,.2,1)),
    color .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
    transform .18s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.sidebar nav a i {
  color: var(--tt-sb-text-muted);
  transition: color .15s var(--ease-out, cubic-bezier(0,0,.2,1)), transform .25s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.sidebar nav a:hover {
  background: var(--tt-grad-sidebar-hover);
  color: var(--tt-sb-text-strong);
}
.sidebar nav a:hover i {
  color: #a5b4fc;
  transform: scale(1.08);
}
[data-color-theme="factorial"] .sidebar nav a:hover i { color: #fda4af; }

/* Active state: gradient pill + accent line + glow */
.sidebar nav a.active {
  background: var(--tt-grad-primary);
  color: #fff;
  font-weight: 600;
  box-shadow:
    0 6px 18px rgba(99,102,241,.45),
    inset 0 1px 0 rgba(255,255,255,.16),
    inset 0 -1px 0 rgba(0,0,0,.12);
}
.sidebar nav a.active i { color: #fff; }
.sidebar nav a.active::before {
  content: '';
  position: absolute;
  left: -12px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 60%;
  background: var(--tt-sb-text-strong);
  border-radius: 0 3px 3px 0;
  box-shadow: 0 0 8px rgba(255,255,255,.5);
}
[data-color-theme="factorial"] .sidebar nav a.active {
  background: linear-gradient(135deg, #f43f5e 0%, #fb7185 60%, #ec4899 100%);
  box-shadow:
    0 6px 18px rgba(244,63,94,.45),
    inset 0 1px 0 rgba(255,255,255,.18);
}

/* Sidebar footer (user card): premium card */
.sidebar-footer {
  padding: 14px 18px;
  background: rgba(255,255,255,.02);
  border-top: 1px solid rgba(255,255,255,.05);
  backdrop-filter: blur(8px);
}
.sidebar-footer .who {
  color: var(--tt-sb-text-strong);
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: -.005em;
}
.sidebar-footer .who small {
  color: var(--tt-sb-text-muted);
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .01em;
  margin-top: 1px;
}
.sidebar-footer .avatar {
  background: var(--tt-grad-primary);
  color: #fff;
  box-shadow:
    0 2px 8px rgba(99,102,241,.4),
    inset 0 1px 0 rgba(255,255,255,.18);
  font-weight: 700;
}
.sidebar-footer .btn-link {
  color: var(--tt-sb-text-muted) !important;
  border-radius: 8px;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  transition: background .15s var(--ease-out, cubic-bezier(0,0,.2,1)), color .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.sidebar-footer .btn-link:hover {
  background: rgba(244,63,94,.12) !important;
  color: #fda4af !important;
}

/* Sidebar scrollbar (dark, subtle) */
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,.10);
  border-radius: 3px;
  border: 0;
}
.sidebar::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.20); }
.sidebar { scrollbar-color: rgba(255,255,255,.12) transparent; }

/* Stagger entrance animation for nav links (premium feel) */
@keyframes ttSidebarSlideIn {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0); }
}
.sidebar nav a {
  animation: ttSidebarSlideIn .35s var(--ease-out, cubic-bezier(0,0,.2,1)) backwards;
}
.sidebar nav a:nth-child(1) { animation-delay: .02s; }
.sidebar nav a:nth-child(2) { animation-delay: .04s; }
.sidebar nav a:nth-child(3) { animation-delay: .06s; }
.sidebar nav a:nth-child(4) { animation-delay: .08s; }
.sidebar nav a:nth-child(5) { animation-delay: .10s; }
.sidebar nav a:nth-child(6) { animation-delay: .12s; }
.sidebar nav a:nth-child(7) { animation-delay: .14s; }
.sidebar nav a:nth-child(8) { animation-delay: .16s; }
@media (prefers-reduced-motion: reduce) {
  .sidebar nav a { animation: none; }
}

/* Badge inside sidebar links: refined */
.sidebar nav a .badge {
  font-size: .6rem;
  font-weight: 700;
  padding: .15rem .45rem;
  border-radius: 6px;
  letter-spacing: .02em;
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
}

/* ============================================================
   2) DROPDOWN MENUS — premium elevation + entry animation
   (notifications, theme picker, language picker, user menu)
   ============================================================ */
.dropdown-menu {
  border-radius: 12px;
  border: 1px solid rgba(0,0,0,.06);
  box-shadow:
    0 1px 2px rgba(15,23,42,.04),
    0 12px 40px -8px rgba(15,23,42,.16),
    0 4px 12px -4px rgba(15,23,42,.08);
  padding: .375rem;
  font-size: .8125rem;
  /* Entry animation */
  transform-origin: top right;
  animation: ttDropdownIn .18s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.dropdown-menu.dropdown-menu-end { transform-origin: top right; }
.dropdown-menu:not(.dropdown-menu-end) { transform-origin: top left; }
@keyframes ttDropdownIn {
  from { opacity: 0; transform: scale(.96) translateY(-4px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
[data-bs-theme="dark"] .dropdown-menu {
  border-color: rgba(255,255,255,.08);
  box-shadow:
    0 1px 2px rgba(0,0,0,.4),
    0 12px 40px -8px rgba(0,0,0,.6),
    0 4px 12px -4px rgba(0,0,0,.4);
}

.dropdown-header {
  color: var(--bs-secondary-color);
  font-size: .65rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: .5rem .75rem .35rem;
  margin-bottom: .15rem;
}

.dropdown-item {
  border-radius: 8px;
  padding: .5rem .75rem;
  font-size: .8125rem;
  font-weight: 500;
  color: var(--bs-body-color);
  display: flex; align-items: center; gap: .15rem;
  transition: background .12s var(--ease-out, cubic-bezier(0,0,.2,1)), color .12s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.dropdown-item:hover, .dropdown-item:focus {
  background: rgba(var(--bs-primary-rgb), .08);
  color: var(--bs-body-color);
}
.dropdown-item:active {
  background: var(--tt-grad-primary);
  color: #fff;
}
.dropdown-item.active {
  background: rgba(var(--bs-primary-rgb), .12);
  color: var(--bs-primary);
}
.dropdown-divider { margin: .35rem .25rem; opacity: .5; }

/* Notifications panel: more breathing room, premium */
.notif-panel {
  width: 360px;
  max-width: 92vw;
  padding: 0;
  overflow: hidden;
}
.notif-panel .border-bottom {
  border-color: var(--bs-border-color) !important;
}

/* ============================================================
   3) TOPBAR — refined glass, better hierarchy
   ============================================================ */
.topbar {
  background: var(--tt-surface-overlay, rgba(255,255,255,.85));
  backdrop-filter: blur(16px) saturate(190%);
  -webkit-backdrop-filter: blur(16px) saturate(190%);
  border-bottom: 1px solid rgba(15,23,42,.06);
}
[data-bs-theme="dark"] .topbar {
  border-bottom-color: rgba(255,255,255,.05);
}
.topbar h1 {
  background: linear-gradient(135deg, var(--bs-body-color), var(--bs-secondary-color) 200%);
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--bs-body-color);
}
.topbar .clock {
  font-feature-settings: 'tnum' on, 'cv11' on;
  font-weight: 600;
}

/* btn-icon: cleaner, with active-state ripple */
.btn-icon {
  border-color: transparent;
  background: transparent;
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.btn-icon:hover {
  background: rgba(var(--bs-primary-rgb), .10);
  border-color: rgba(var(--bs-primary-rgb), .15);
  color: var(--bs-primary);
  transform: translateY(-1px);
}
.btn-icon:active { transform: translateY(0); transition-duration: .05s; }

/* ============================================================
   4) KPI CARDS — premium hover micro-interaction
   ============================================================ */
.kpi {
  position: relative;
  overflow: hidden;
}
.kpi::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--tt-grad-primary);
  opacity: 0;
  transition: opacity .2s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.kpi:hover::before { opacity: 1; }
.kpi .icon {
  transition: transform .25s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.kpi:hover .icon { transform: scale(1.08) rotate(-3deg); }

/* KPI value: gradient text in hover for premium feel (subtle) */
.kpi .value {
  transition: color .2s var(--ease-out, cubic-bezier(0,0,.2,1));
}

/* ============================================================
   5) SECTION ENTER ANIMATION — refined with spring
   ============================================================ */
@keyframes ttSectionIn {
  from {
    opacity: 0;
    transform: translateY(8px) scale(.995);
    filter: blur(2px);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}
.content > section.active {
  animation: ttSectionIn .35s var(--ease-out, cubic-bezier(0,0,.2,1));
}
@media (prefers-reduced-motion: reduce) {
  .content > section.active { animation: none; }
  .kpi:hover .icon { transform: none; }
  .sidebar-brand:hover .logo { transform: none; }
}

/* ============================================================
   6) BUTTONS — premium primary with shimmer on hover
   ============================================================ */
.btn-primary {
  background: var(--tt-grad-primary);
  border: 0;
  position: relative;
  overflow: hidden;
}
.btn-primary::before {
  content: '';
  position: absolute;
  top: 0; left: -100%;
  width: 100%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.18), transparent);
  transition: left .55s var(--ease-out, cubic-bezier(0,0,.2,1));
  pointer-events: none;
}
.btn-primary:not(:disabled):hover::before { left: 100%; }

/* ============================================================
   7) CARDS — premium border-glow on hover
   ============================================================ */
.card-soft {
  position: relative;
  transition:
    transform .2s var(--ease-out, cubic-bezier(0,0,.2,1)),
    box-shadow .2s var(--ease-out, cubic-bezier(0,0,.2,1)),
    border-color .2s var(--ease-out, cubic-bezier(0,0,.2,1));
}
@media (hover: hover) {
  .card-soft:hover {
    border-color: rgba(var(--bs-primary-rgb), .25);
    box-shadow:
      var(--tt-shadow-md),
      0 0 0 1px rgba(var(--bs-primary-rgb), .06);
  }
}

/* ============================================================
   8) TABLE — premium row hover with primary accent
   ============================================================ */
.table-wrap tbody tr {
  transition: background .15s var(--ease-out, cubic-bezier(0,0,.2,1)), box-shadow .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.table-wrap tbody tr:hover {
  background: rgba(var(--bs-primary-rgb), .035);
  box-shadow: inset 3px 0 0 var(--bs-primary);
}

/* ============================================================
   9) BADGE & PILL — refined typography
   ============================================================ */
.dept-pill {
  background: rgba(var(--bs-primary-rgb), .10);
  border: 1px solid rgba(var(--bs-primary-rgb), .15);
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .005em;
  padding: 3px 10px;
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.dept-pill:hover {
  background: rgba(var(--bs-primary-rgb), .16);
  border-color: rgba(var(--bs-primary-rgb), .28);
}

/* ============================================================
   10) FORM CONTROLS — premium focus ring (gradient)
   ============================================================ */
.form-control:focus,
.form-select:focus {
  border-color: var(--bs-primary);
  box-shadow:
    0 0 0 4px rgba(var(--bs-primary-rgb), .12),
    0 1px 2px rgba(var(--bs-primary-rgb), .04);
}

/* ============================================================
   11) MODAL — premium backdrop + entry
   ============================================================ */
.modal-backdrop.show {
  opacity: .55;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.modal.fade .modal-dialog {
  transform: translateY(8px) scale(.985);
  transition: transform .25s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.modal.show .modal-dialog {
  transform: translateY(0) scale(1);
}
.modal-content {
  border: 1px solid rgba(0,0,0,.06);
  box-shadow:
    0 24px 64px -16px rgba(15,23,42,.25),
    0 8px 24px -8px rgba(15,23,42,.12);
}
[data-bs-theme="dark"] .modal-content {
  border-color: rgba(255,255,255,.08);
  box-shadow:
    0 24px 64px -16px rgba(0,0,0,.7),
    0 8px 24px -8px rgba(0,0,0,.5);
}

/* ============================================================
   12) AVATARS — premium fallback gradient
   ============================================================ */
.avatar:not(:has(img)) {
  background: linear-gradient(135deg, rgba(var(--bs-primary-rgb), .14), rgba(var(--bs-primary-rgb), .08));
  border: 1px solid rgba(var(--bs-primary-rgb), .12);
  color: var(--bs-primary);
}

/* ============================================================
   13) CHARTS — premium canvas container
   ============================================================ */
.card-soft canvas {
  border-radius: var(--tt-radius-sm);
}

/* ============================================================
   14) SECTION TITLES — premium gradient accent on hover
   ============================================================ */
.section-title {
  position: relative;
  display: inline-block;
}
.section-title::after {
  content: '';
  display: block;
  height: 2px;
  width: 0;
  background: var(--tt-grad-primary);
  border-radius: 2px;
  margin-top: 4px;
  transition: width .35s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.section-header:hover .section-title::after,
.card-soft:hover .section-title::after { width: 32px; }

/* ============================================================
   16) PASSWORD STRENGTH METER (legal-security.js)
   ============================================================ */
.pwd-meter {
  width: 100%;
}
.pwd-meter-bar {
  height: 6px;
  background: var(--bs-tertiary-bg);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}
.pwd-meter-fill {
  height: 100%;
  width: 0;
  border-radius: 3px;
  transition: width .3s var(--ease-out, cubic-bezier(0,0,.2,1)),
              background-color .3s var(--ease-out, cubic-bezier(0,0,.2,1));
  box-shadow: 0 0 8px currentColor;
}
.pwd-meter-info {
  font-size: .7rem;
  letter-spacing: .02em;
}
.pwd-meter-label {
  text-transform: uppercase;
  letter-spacing: .06em;
}
[data-bs-theme="dark"] .pwd-meter-bar { background: rgba(255,255,255,.08); }

/* ============================================================
   17) LEGAL & COMPLIANCE PANEL (legal-security.js)
   ============================================================ */
.legal-sec-grid .card-soft {
  position: relative;
}
.legal-sec-grid .card-soft .section-title {
  font-size: 1rem;
  font-weight: 700;
}
#legalDpoForm .form-label,
#breachForm .form-label,
#dpiaForm .form-label {
  font-size: .75rem;
  font-weight: 600;
  margin-bottom: 4px;
}

/* ============================================================
   15) FACTORIAL PALETTE — sidebar override (pink accent)
   ============================================================ */
[data-color-theme="factorial"] .sidebar {
  background: linear-gradient(180deg, #1a0a14 0%, #2a0e1f 60%, #1f0d18 100%);
}
[data-color-theme="factorial"] .sidebar-brand .logo {
  background: linear-gradient(135deg, #f43f5e 0%, #ec4899 50%, #be185d 100%);
  box-shadow: 0 4px 14px rgba(244,63,94,.5), inset 0 1px 0 rgba(255,255,255,.18);
}
[data-color-theme="factorial"] .sidebar-footer .avatar {
  background: linear-gradient(135deg, #f43f5e 0%, #ec4899 100%);
  box-shadow: 0 2px 8px rgba(244,63,94,.4), inset 0 1px 0 rgba(255,255,255,.18);
}

/* ============================================================
   18) COMMAND PALETTE (⌘K / Ctrl+K) — js/command-palette.js
   ------------------------------------------------------------
   Inspirado en Linear / Raycast / VSCode. Glass surface, blur
   backdrop, animación spring de entrada. Theme-aware vía vars
   (hereda surface/border/primary del tema activo).
   ============================================================ */
.cmdk-overlay {
  position: fixed; inset: 0; z-index: 1080;
  display: none;
  background: rgba(15, 23, 42, .55);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  padding: 10vh 16px 16px;
  align-items: flex-start; justify-content: center;
  animation: cmdkFadeIn .14s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.cmdk-overlay.show { display: flex; }
[data-bs-theme="dark"] .cmdk-overlay { background: rgba(2, 6, 23, .72); }
@keyframes cmdkFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes cmdkSlideIn {
  from { opacity: 0; transform: translateY(-12px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
body.cmdk-noscroll { overflow: hidden; }

.cmdk-modal {
  width: 100%; max-width: 640px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  box-shadow:
    0 28px 72px -20px rgba(15,23,42,.45),
    0 12px 32px -12px rgba(15,23,42,.18),
    0 0 0 1px rgba(var(--bs-primary-rgb), .04);
  overflow: hidden;
  animation: cmdkSlideIn .22s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
  display: flex; flex-direction: column;
  max-height: min(560px, 80vh);
}
[data-bs-theme="dark"] .cmdk-modal {
  box-shadow:
    0 32px 80px -16px rgba(0,0,0,.7),
    0 12px 32px -8px rgba(0,0,0,.5),
    0 0 0 1px rgba(var(--bs-primary-rgb), .08);
}

/* Halo premium en cmdk modal para las 3 paletas — todas tier "premium". */
[data-color-theme="nimbus"] .cmdk-modal {
  box-shadow:
    0 28px 72px -20px rgba(8,145,178,.35),
    0 0 60px -16px rgba(34,211,238,.25),
    0 0 0 1px rgba(34,211,238,.08);
}
/* Atlántico (default, sin data-color-theme): halo violeta-índigo */
:root:not([data-color-theme]) .cmdk-modal,
[data-color-theme="atlantico"] .cmdk-modal {
  box-shadow:
    0 28px 72px -20px rgba(99,102,241,.35),
    0 0 60px -16px rgba(139,92,246,.25),
    0 0 0 1px rgba(99,102,241,.08);
}
/* Factorial: halo rosa-coral */
[data-color-theme="factorial"] .cmdk-modal {
  box-shadow:
    0 28px 72px -20px rgba(244,63,94,.35),
    0 0 60px -16px rgba(236,72,153,.25),
    0 0 0 1px rgba(244,63,94,.08);
}
/* Item activo del cmdk con barra lateral acentuada en las 3 paletas */
:root:not([data-color-theme]) .cmdk-item.active,
[data-color-theme="atlantico"] .cmdk-item.active {
  background: linear-gradient(90deg, rgba(99,102,241,.12), rgba(99,102,241,.04));
  box-shadow: inset 2px 0 0 #6366f1;
}
[data-color-theme="factorial"] .cmdk-item.active {
  background: linear-gradient(90deg, rgba(244,63,94,.12), rgba(244,63,94,.04));
  box-shadow: inset 2px 0 0 #f43f5e;
}

/* Header (input + esc kbd) */
.cmdk-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--bs-border-color);
}
.cmdk-search-icon {
  font-size: 1.05rem; color: var(--bs-secondary-color);
  flex-shrink: 0;
}
.cmdk-input {
  flex: 1; min-width: 0;
  background: transparent; border: 0; outline: 0;
  font-size: 1rem; font-weight: 500;
  color: var(--bs-body-color);
  font-family: inherit; letter-spacing: -.005em;
  padding: 2px 0;
}
.cmdk-input::placeholder { color: var(--bs-tertiary-color, var(--bs-secondary-color)); opacity: .85; }

/* Results list */
.cmdk-results {
  flex: 1; overflow-y: auto;
  padding: 6px;
  scroll-behavior: smooth;
}
.cmdk-results::-webkit-scrollbar { width: 6px; }
.cmdk-results::-webkit-scrollbar-thumb {
  background: rgba(var(--bs-emphasis-color-rgb, 15,23,42), .12);
  border-radius: 3px;
}

.cmdk-group {
  font-size: .65rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--bs-tertiary-color, var(--bs-secondary-color));
  padding: 10px 12px 6px;
}

.cmdk-item {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 9px 12px;
  background: transparent; border: 0; border-radius: 8px;
  color: var(--bs-body-color);
  font-size: .875rem; text-align: left;
  cursor: pointer;
  transition: background .1s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.cmdk-item > i.bi:first-child {
  font-size: 1rem;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border-radius: 7px;
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg, rgba(0,0,0,.04));
  flex-shrink: 0;
  transition: color .12s, background .12s;
}
.cmdk-item-text { flex: 1; min-width: 0; }
.cmdk-item-title {
  font-weight: 600; font-size: .875rem;
  letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmdk-item-sub {
  font-size: .72rem; color: var(--bs-secondary-color);
  margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmdk-shortcut {
  display: inline-flex; gap: 4px;
  flex-shrink: 0;
}
.cmdk-enter-hint {
  font-size: .9rem; color: var(--bs-tertiary-color, var(--bs-secondary-color));
  opacity: 0;
  transition: opacity .12s;
  flex-shrink: 0;
}
.cmdk-item.active {
  background: rgba(var(--bs-primary-rgb), .10);
}
.cmdk-item.active > i.bi:first-child {
  color: var(--bs-primary);
  background: rgba(var(--bs-primary-rgb), .14);
}
.cmdk-item.active .cmdk-enter-hint { opacity: .8; color: var(--bs-primary); }
[data-color-theme="nimbus"] .cmdk-item.active {
  background: linear-gradient(90deg, rgba(34,211,238,.12), rgba(8,145,178,.06));
  box-shadow: inset 2px 0 0 #06b6d4;
}

.cmdk-empty {
  display: flex; flex-direction: column; align-items: center;
  gap: 8px;
  padding: 36px 16px;
  color: var(--bs-secondary-color);
  font-size: .85rem;
}
.cmdk-empty i { font-size: 1.6rem; opacity: .5; }

/* Footer (hint bar) */
.cmdk-footer {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 8px 14px;
  border-top: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg, rgba(0,0,0,.02));
  font-size: .68rem; color: var(--bs-secondary-color);
  letter-spacing: .01em;
}
.cmdk-footer span { display: inline-flex; align-items: center; gap: 5px; }
.cmdk-brand { font-weight: 600; color: var(--bs-tertiary-color, var(--bs-secondary-color)); }
.cmdk-brand i { color: var(--bs-primary); font-size: .75rem; }

/* Generic <kbd> inside the palette: monospace pill */
.cmdk-overlay kbd, .cmdk-kbd {
  display: inline-grid; place-items: center;
  min-width: 22px; height: 20px;
  padding: 0 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .68rem; font-weight: 600;
  color: var(--bs-secondary-color);
  background: var(--tt-surface-2, var(--bs-tertiary-bg));
  border: 1px solid var(--bs-border-color);
  border-bottom-width: 2px;
  border-radius: 5px;
  letter-spacing: 0;
  line-height: 1;
}
.cmdk-esc { font-size: .62rem; min-width: 32px; }

/* Topbar pill que abre la paleta (discoverability) */
.cmdk-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 10px 0 12px;
  background: var(--bs-tertiary-bg, rgba(0,0,0,.04));
  border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius-sm, 10px);
  color: var(--bs-secondary-color);
  font-size: .78rem; font-weight: 500;
  cursor: pointer;
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
  min-width: 0;
}
.cmdk-trigger:hover {
  border-color: rgba(var(--bs-primary-rgb), .35);
  color: var(--bs-body-color);
  background: var(--tt-surface-2, var(--bs-tertiary-bg));
  transform: translateY(-1px);
}
.cmdk-trigger i.bi-search { font-size: .9rem; opacity: .8; }
.cmdk-trigger .cmdk-trigger-label {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 140px;
}
.cmdk-trigger kbd {
  display: inline-grid; place-items: center;
  min-width: 18px; height: 18px;
  padding: 0 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .62rem; font-weight: 600;
  color: var(--bs-secondary-color);
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 4px;
  line-height: 1;
}
@media (max-width: 767.98px) {
  .cmdk-trigger .cmdk-trigger-label,
  .cmdk-trigger kbd { display: none; }
  .cmdk-trigger { padding: 0; width: 36px; justify-content: center; }
}

/* ── Mobile topbar consolidation ─────────────────────────────
   En mobile el topbar tenía 9-11 controles que provocaban que
   el título de sección se truncara agresivamente ("Comu..." en
   vez de "Comunicados"). Patrón SaaS estándar (Linear/Stripe/
   Notion): mobile muestra solo los controles esenciales —
   menú · título · búsqueda · tema · notificaciones · avatar.
   Los secundarios (branding, plan badge, what's new, paleta de
   color, idioma) se ocultan; siguen accesibles en tablet/desktop
   y a través de las secciones de Configuración / Cuenta.

   Uso de clase explícita `.topbar-secondary` en los wrappers
   `<div class="dropdown topbar-secondary">` (en lugar de `:has()`)
   para máxima compatibilidad de navegadores. */
@media (max-width: 767.98px) {
  .topbar .brand-topbar-btn,
  .topbar .plan-badge,
  .topbar .wn-btn,
  .topbar .topbar-secondary { display: none !important; }
}

/* Mobile: paleta más compacta y fullscreen-ish */
@media (max-width: 575.98px) {
  .cmdk-overlay { padding: 6vh 10px 10px; }
  .cmdk-modal { max-height: 88vh; border-radius: 12px; }
  .cmdk-footer { font-size: .64rem; gap: 10px; padding: 7px 12px; }
  .cmdk-brand { display: none; }
}

/* ============================================================
   19) TOAST SYSTEM (Utils.toast) — premium, theme-aware
   ------------------------------------------------------------
   Reemplaza el toast Bootstrap por un componente custom con
   icono semántico, action button, dismiss, progress bar y
   hover-pause. Stack en top-right (mobile: top-center).
   ============================================================ */
.tt-toast-host {
  position: fixed;
  top: 16px; right: 16px;
  z-index: 1095;
  display: flex; flex-direction: column;
  gap: 10px;
  max-width: min(420px, calc(100vw - 32px));
  pointer-events: none;
}
.tt-toast-host > * { pointer-events: auto; }

.tt-toast {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--tt-surface, #fff);
  color: var(--bs-body-color);
  border: 1px solid var(--bs-border-color);
  border-radius: 12px;
  box-shadow:
    0 10px 28px -10px rgba(15,23,42,.25),
    0 4px 12px -4px rgba(15,23,42,.10),
    0 0 0 1px rgba(0,0,0,.02);
  font-size: .8125rem;
  line-height: 1.45;
  letter-spacing: -.005em;
  overflow: hidden;
  opacity: 0; transform: translateX(28px) scale(.96);
  transition:
    opacity .2s var(--ease-out, cubic-bezier(0,0,.2,1)),
    transform .26s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.tt-toast.show { opacity: 1; transform: translateX(0) scale(1); }
.tt-toast.leaving {
  opacity: 0;
  transform: translateX(28px) scale(.96);
  transition: opacity .18s, transform .18s;
}
[data-bs-theme="dark"] .tt-toast {
  background: var(--tt-surface-2, #131b2e);
  box-shadow:
    0 14px 32px -10px rgba(0,0,0,.7),
    0 4px 12px -4px rgba(0,0,0,.5),
    0 0 0 1px rgba(255,255,255,.04);
}

/* Icon disc (left) */
.tt-toast-icon {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 9px;
  font-size: 1rem;
  flex-shrink: 0;
}
/* Variant accents — icon disc + left border accent */
.tt-toast::before {
  content: ''; position: absolute;
  left: 0; top: 0; bottom: 0; width: 3px;
}
.tt-toast-success::before { background: #10b981; }
.tt-toast-success .tt-toast-icon { background: rgba(16,185,129,.12); color: #059669; }
.tt-toast-danger::before  { background: #ef4444; }
.tt-toast-danger  .tt-toast-icon { background: rgba(239,68,68,.12); color: #dc2626; }
.tt-toast-warning::before { background: #f59e0b; }
.tt-toast-warning .tt-toast-icon { background: rgba(245,158,11,.14); color: #d97706; }
.tt-toast-info::before, .tt-toast-primary::before {
  background: var(--bs-primary);
}
.tt-toast-info .tt-toast-icon, .tt-toast-primary .tt-toast-icon {
  background: rgba(var(--bs-primary-rgb), .12); color: var(--bs-primary);
}
.tt-toast-neutral::before { background: var(--bs-secondary-color); }
.tt-toast-neutral .tt-toast-icon { background: rgba(var(--bs-emphasis-color-rgb, 15,23,42), .06); color: var(--bs-secondary-color); }

[data-bs-theme="dark"] .tt-toast-success .tt-toast-icon { background: rgba(16,185,129,.18); color: #34d399; }
[data-bs-theme="dark"] .tt-toast-danger  .tt-toast-icon { background: rgba(239,68,68,.20); color: #fb7185; }
[data-bs-theme="dark"] .tt-toast-warning .tt-toast-icon { background: rgba(245,158,11,.20); color: #fbbf24; }

.tt-toast-body {
  min-width: 0;
  font-weight: 500;
  color: var(--bs-body-color);
  word-wrap: break-word;
}
.tt-toast-body strong { font-weight: 700; }

.tt-toast-action {
  flex-shrink: 0;
  background: transparent; border: 0;
  color: var(--bs-primary);
  font-weight: 600; font-size: .78rem;
  letter-spacing: -.005em;
  padding: 5px 10px; border-radius: 7px;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.tt-toast-action:hover { background: rgba(var(--bs-primary-rgb), .10); }
.tt-toast-danger .tt-toast-action { color: #dc2626; }
.tt-toast-danger .tt-toast-action:hover { background: rgba(239,68,68,.10); }

.tt-toast-close {
  flex-shrink: 0;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  background: transparent; border: 0; padding: 0;
  color: var(--bs-secondary-color);
  border-radius: 6px;
  cursor: pointer;
  font-size: .8rem;
  transition: background .12s, color .12s;
}
.tt-toast-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

.tt-toast-progress {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px;
  background: rgba(var(--bs-emphasis-color-rgb, 15,23,42), .06);
  overflow: hidden;
}
.tt-toast-progress-fill {
  height: 100%; width: 100%;
  background: currentColor;
  opacity: .6;
  transition: width .08s linear;
}
.tt-toast-success .tt-toast-progress-fill { background: #10b981; }
.tt-toast-danger  .tt-toast-progress-fill { background: #ef4444; }
.tt-toast-warning .tt-toast-progress-fill { background: #f59e0b; }
.tt-toast-info    .tt-toast-progress-fill,
.tt-toast-primary .tt-toast-progress-fill { background: var(--bs-primary); }

@media (max-width: 575.98px) {
  .tt-toast-host {
    top: 10px; left: 10px; right: 10px;
    max-width: none;
    align-items: stretch;
  }
  .tt-toast { padding: 10px 12px; font-size: .8rem; }
  .tt-toast-icon { width: 28px; height: 28px; font-size: .9rem; }
}
@media (prefers-reduced-motion: reduce) {
  .tt-toast { transition: opacity .15s; transform: none; }
  .tt-toast.show, .tt-toast.leaving { transform: none; }
}

/* ============================================================
   20) CONFIRM MODAL (Utils.confirm) — replaces window.confirm()
   ------------------------------------------------------------
   Glass overlay + centered card, focus-trap, theme-aware.
   ============================================================ */
.tt-confirm-overlay {
  position: fixed; inset: 0; z-index: 1085;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: rgba(15,23,42,.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity .18s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.tt-confirm-overlay.show { opacity: 1; }
.tt-confirm-overlay.leaving { opacity: 0; }
[data-bs-theme="dark"] .tt-confirm-overlay { background: rgba(2,6,23,.72); }
body.tt-confirm-noscroll { overflow: hidden; }

.tt-confirm-modal {
  width: 100%; max-width: 420px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 16px;
  padding: 28px 24px 22px;
  box-shadow:
    0 28px 72px -20px rgba(15,23,42,.45),
    0 12px 32px -12px rgba(15,23,42,.18);
  text-align: center;
  transform: translateY(8px) scale(.98);
  transition: transform .24s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.tt-confirm-overlay.show .tt-confirm-modal { transform: translateY(0) scale(1); }
[data-bs-theme="dark"] .tt-confirm-modal {
  box-shadow:
    0 32px 80px -16px rgba(0,0,0,.7),
    0 12px 32px -8px rgba(0,0,0,.5);
}

.tt-confirm-icon {
  width: 56px; height: 56px;
  display: grid; place-items: center;
  margin: 0 auto 14px;
  border-radius: 50%;
  font-size: 1.6rem;
  background: rgba(var(--bs-primary-rgb), .12);
  color: var(--bs-primary);
}
.tt-confirm-danger  .tt-confirm-icon { background: rgba(239,68,68,.12); color: #dc2626; }
.tt-confirm-warning .tt-confirm-icon { background: rgba(245,158,11,.14); color: #d97706; }
[data-bs-theme="dark"] .tt-confirm-danger  .tt-confirm-icon { background: rgba(239,68,68,.18); color: #fb7185; }
[data-bs-theme="dark"] .tt-confirm-warning .tt-confirm-icon { background: rgba(245,158,11,.22); color: #fbbf24; }

.tt-confirm-title {
  font-size: 1.0625rem; font-weight: 700;
  letter-spacing: -.02em;
  margin: 0 0 8px;
  color: var(--bs-body-color);
}
.tt-confirm-msg {
  font-size: .8625rem; line-height: 1.5;
  color: var(--bs-secondary-color);
  margin: 0 0 22px;
}
.tt-confirm-actions {
  display: flex; gap: 10px;
  justify-content: stretch;
}
.tt-confirm-actions .btn { flex: 1; padding: .55rem .9rem; font-weight: 600; }
@media (max-width: 575.98px) {
  .tt-confirm-modal { padding: 22px 18px 18px; border-radius: 14px; }
  .tt-confirm-icon { width: 48px; height: 48px; font-size: 1.4rem; }
  .tt-confirm-title { font-size: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .tt-confirm-overlay, .tt-confirm-modal { transition: opacity .12s; transform: none; }
}

/* ============================================================
   21) SETUP CHECKLIST (onboarding.js)
   ------------------------------------------------------------
   FAB flotante (bottom-right, mobile bottom-left por bottom-nav)
   + panel sliding lateral con barra de progreso, lista de tareas
   con check-marks, y CTA por tarea. Theme-aware vía vars.
   ============================================================ */
/* SetupChecklist FAB se apila ENCIMA del HelpCenter FAB (que está fijo
   en bottom-right). Offset 84px para dejar clearance de 60px sobre el
   HelpCenter (48px + 12px gap). Si no hay HelpCenter, queda a 20px. */
.setup-fab {
  position: fixed;
  right: 24px; bottom: 84px;
  width: 56px; height: 56px;
  display: grid; place-items: center;
  background: var(--tt-grad-primary, linear-gradient(135deg, #6366f1, #8b5cf6, #a855f7));
  color: #fff;
  border: 0; border-radius: 50%;
  box-shadow:
    0 10px 28px -6px rgba(var(--bs-primary-rgb), .55),
    0 4px 12px -4px rgba(0,0,0,.18),
    inset 0 1px 0 rgba(255,255,255,.18);
  cursor: pointer;
  font-size: 1.4rem;
  z-index: 1040;
  transition:
    transform .2s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)),
    box-shadow .2s var(--ease-out, cubic-bezier(0,0,.2,1)),
    opacity .2s;
  animation: setupFabPop .5s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
@keyframes setupFabPop {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.setup-fab:hover {
  transform: translateY(-2px) scale(1.04);
  box-shadow:
    0 14px 36px -8px rgba(var(--bs-primary-rgb), .65),
    0 6px 16px -4px rgba(0,0,0,.25),
    inset 0 1px 0 rgba(255,255,255,.22);
}
.setup-fab.hidden { opacity: 0; pointer-events: none; transform: scale(.8); }
.setup-fab.hidden-permanent { display: none; }
.setup-fab.all-done .setup-fab-badge { display: none; }
.setup-fab i { color: inherit; }

.setup-fab-badge {
  position: absolute; top: -2px; right: -2px;
  min-width: 22px; height: 22px;
  padding: 0 6px;
  display: grid; place-items: center;
  background: #ef4444;
  color: #fff;
  font-size: .7rem; font-weight: 700;
  border-radius: 11px;
  border: 2px solid var(--bs-body-bg);
  box-shadow: 0 1px 3px rgba(239,68,68,.4);
}
.setup-fab-badge:empty { display: none; }

/* Mobile: subir aún más para no chocar ni con bottom-nav ni con HelpCenter
   (que en mobile cubre 48px en bottom: 24px). bottom-nav es ~64px → total
   bottom: 64 (nav) + 48 (HelpCenter) + gap = ~140px para SetupChecklist. */
@media (max-width: 991.98px) {
  .setup-fab { bottom: 144px; right: 16px; width: 50px; height: 50px; font-size: 1.25rem; }
}
/* HelpCenter en mobile también sube para no chocar con bottom-nav */
@media (max-width: 991.98px) {
  .help-center-fab { bottom: 76px !important; }
  .help-center-panel { bottom: 132px !important; }
}

/* Backdrop */
.setup-backdrop {
  position: fixed; inset: 0;
  background: rgba(15,23,42,.45);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 1041;
  opacity: 0; pointer-events: none;
  transition: opacity .25s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.setup-backdrop.show { opacity: 1; pointer-events: auto; }
[data-bs-theme="dark"] .setup-backdrop { background: rgba(2,6,23,.65); }
body.setup-noscroll { overflow: hidden; }

/* Panel */
.setup-panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 100%; max-width: 440px;
  background: var(--tt-surface, #fff);
  border-left: 1px solid var(--bs-border-color);
  box-shadow:
    -16px 0 48px -12px rgba(15,23,42,.30),
    -4px 0 12px -4px rgba(15,23,42,.10);
  display: flex; flex-direction: column;
  z-index: 1042;
  transform: translateX(100%);
  transition: transform .32s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.setup-panel.open { transform: translateX(0); }
[data-bs-theme="dark"] .setup-panel {
  background: var(--tt-surface-2, #131b2e);
  box-shadow: -16px 0 48px -12px rgba(0,0,0,.7);
}

.setup-header {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 22px 22px 14px;
  border-bottom: 1px solid var(--bs-border-color);
}
.setup-header > div:first-child { flex: 1; min-width: 0; }
.setup-eyebrow {
  font-size: .68rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-primary);
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 4px;
}
.setup-title {
  font-size: 1.1rem; font-weight: 800;
  letter-spacing: -.025em;
  margin: 0;
  color: var(--bs-body-color);
}
.setup-close {
  background: transparent; border: 1px solid var(--bs-border-color);
  border-radius: var(--tt-radius-sm);
  width: 34px; height: 34px;
  display: grid; place-items: center;
  color: var(--bs-secondary-color);
  cursor: pointer;
  flex-shrink: 0;
  transition: all .15s;
}
.setup-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

.setup-progress {
  padding: 16px 22px 12px;
  border-bottom: 1px solid var(--bs-border-color);
}
.setup-progress-meta {
  display: flex; justify-content: space-between;
  font-size: .75rem; font-weight: 600;
  color: var(--bs-secondary-color);
  margin-bottom: 8px;
}
.setup-progress-pct { color: var(--bs-primary); }
.setup-progress-track {
  height: 6px;
  background: var(--bs-tertiary-bg);
  border-radius: 3px;
  overflow: hidden;
}
.setup-progress-bar {
  height: 100%;
  background: var(--tt-grad-primary, var(--bs-primary));
  border-radius: 3px;
  width: 0%;
  transition: width .5s var(--ease-out, cubic-bezier(0,0,.2,1));
  box-shadow: 0 0 8px rgba(var(--bs-primary-rgb), .4);
}

.setup-tasks {
  flex: 1;
  list-style: none;
  margin: 0; padding: 8px;
  overflow-y: auto;
}
.setup-task {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 14px 12px;
  border-radius: var(--tt-radius-sm);
  transition: background .12s;
}
.setup-task:hover { background: var(--bs-tertiary-bg); }
.setup-task.done { opacity: .65; }
.setup-task.done .setup-task-title {
  text-decoration: line-through;
  color: var(--bs-secondary-color);
}

.setup-task-check {
  background: transparent; border: 0; padding: 0;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  font-size: 1.4rem;
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: color .15s, transform .15s;
}
.setup-task-check:hover { transform: scale(1.1); }
.setup-task.done .setup-task-check { color: #10b981; }
[data-color-theme="nimbus"] .setup-task.done .setup-task-check { color: #06b6d4; }

.setup-task-icon {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgba(var(--bs-primary-rgb), .10);
  color: var(--bs-primary);
  font-size: 1rem;
  flex-shrink: 0;
}
.setup-task.done .setup-task-icon {
  background: rgba(16,185,129,.10);
  color: #10b981;
}

.setup-task-body { min-width: 0; }
.setup-task-title {
  font-size: .8625rem; font-weight: 600;
  color: var(--bs-body-color);
  line-height: 1.35;
  letter-spacing: -.01em;
}
.setup-task-desc {
  font-size: .75rem; color: var(--bs-secondary-color);
  line-height: 1.4; margin-top: 2px;
}

.setup-task-go {
  flex-shrink: 0;
  white-space: nowrap;
  font-size: .72rem;
  padding: .35rem .65rem;
}

.setup-task-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px;
  background: rgba(16,185,129,.12);
  color: #059669;
  font-size: .68rem; font-weight: 700;
  border-radius: 999px;
  letter-spacing: .02em;
}
[data-bs-theme="dark"] .setup-task-badge {
  background: rgba(16,185,129,.18);
  color: #34d399;
}

.setup-footer {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 22px 16px;
  border-top: 1px solid var(--bs-border-color);
  font-size: .72rem;
}
.setup-dismiss {
  font-size: .72rem;
  color: var(--bs-secondary-color);
  text-decoration: none;
}
.setup-dismiss:hover { color: var(--bs-body-color); }

@media (max-width: 575.98px) {
  .setup-panel { max-width: 100%; }
  .setup-header { padding: 18px 16px 12px; }
  .setup-progress { padding: 12px 16px 10px; }
  .setup-tasks { padding: 6px; }
  .setup-task { padding: 12px 10px; gap: 10px; grid-template-columns: auto auto 1fr; }
  .setup-task-go, .setup-task-badge { grid-column: 2 / 4; justify-self: start; margin-top: 4px; }
}

/* ============================================================
   22) PRODUCT TOUR (onboarding.js)
   ------------------------------------------------------------
   Spotlight overlay (4 divs alrededor del target) + tip flotante
   con título, body, progress bar y navegación (Anterior/Siguiente/
   Saltar). Soporta placement auto (top|bottom|left|right).
   ============================================================ */
.tour-overlay {
  position: fixed; inset: 0;
  z-index: 1075;
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.tour-overlay.show { opacity: 1; pointer-events: auto; }
/* v3.x — bug fix: ProductTour.init() (en page load) crea el overlay y el
   tip dentro de él. El tip tiene `pointer-events: auto` explícito (línea
   ~6326) que ANULA el `pointer-events: none` del overlay cuando éste
   todavía no tiene `.show`. Como el tip aún no ha sido posicionado por
   _tourShow(), queda en (0,0) con 360px de ancho — invisible pero
   atrapando todos los clicks de la esquina superior izquierda (incluido
   el botón hamburguesa del topbar mobile). Sin esta regla el menú móvil
   parece "muerto": el click cae en el tip fantasma. */
.tour-overlay:not(.show) .tour-tip,
.tour-overlay:not(.show) .tour-spotlight { display: none !important; }
body.tour-noscroll { overflow: hidden; }

.tour-spotlight {
  position: absolute;
  border-radius: 12px;
  /* huge box-shadow creates the dimmed surrounding layer */
  box-shadow:
    0 0 0 9999px rgba(15,23,42,.66),
    0 0 0 2px rgba(var(--bs-primary-rgb), .8),
    0 0 0 6px rgba(var(--bs-primary-rgb), .25),
    0 12px 32px -8px rgba(0,0,0,.4);
  transition:
    left .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)),
    top .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)),
    width .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)),
    height .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)),
    opacity .25s;
  pointer-events: none;
}
[data-bs-theme="dark"] .tour-spotlight {
  box-shadow:
    0 0 0 9999px rgba(2,6,23,.78),
    0 0 0 2px rgba(var(--bs-primary-rgb), .9),
    0 0 0 6px rgba(var(--bs-primary-rgb), .28),
    0 16px 40px -8px rgba(0,0,0,.6);
}
.tour-overlay.tour-centered .tour-spotlight {
  /* Sin target: usar oscurecimiento full-screen vía pseudo-element */
  left: -50px; top: -50px; width: 0; height: 0;
}
.tour-overlay.tour-centered::before {
  content: ''; position: absolute; inset: 0;
  background: rgba(15,23,42,.66);
  pointer-events: auto;
}
[data-bs-theme="dark"] .tour-overlay.tour-centered::before {
  background: rgba(2,6,23,.78);
}

.tour-tip {
  position: absolute;
  width: 360px; max-width: calc(100vw - 24px);
  background: var(--tt-surface, #fff);
  color: var(--bs-body-color);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  padding: 20px 22px 16px;
  box-shadow:
    0 24px 56px -16px rgba(15,23,42,.45),
    0 8px 20px -8px rgba(15,23,42,.18);
  pointer-events: auto;
  animation: tourTipIn .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
[data-bs-theme="dark"] .tour-tip {
  background: var(--tt-surface-2, #131b2e);
  box-shadow: 0 28px 64px -12px rgba(0,0,0,.7);
}
@keyframes tourTipIn {
  from { opacity: 0; transform: translateY(6px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.tour-tip-arrow {
  position: absolute;
  width: 14px; height: 14px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  transform: rotate(45deg);
  display: none;
}
.tour-tip[data-placement="bottom"] .tour-tip-arrow {
  display: block; top: -8px; left: 50%; margin-left: -7px;
  border-right: 0; border-bottom: 0;
}
.tour-tip[data-placement="top"] .tour-tip-arrow {
  display: block; bottom: -8px; left: 50%; margin-left: -7px;
  border-left: 0; border-top: 0;
}
.tour-tip[data-placement="right"] .tour-tip-arrow {
  display: block; left: -8px; top: 50%; margin-top: -7px;
  border-top: 0; border-right: 0;
}
.tour-tip[data-placement="left"] .tour-tip-arrow {
  display: block; right: -8px; top: 50%; margin-top: -7px;
  border-bottom: 0; border-left: 0;
}
[data-bs-theme="dark"] .tour-tip-arrow { background: var(--tt-surface-2, #131b2e); }

.tour-tip-step {
  font-size: .68rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--bs-primary);
  margin-bottom: 6px;
}
.tour-step-num { color: var(--bs-body-color); font-weight: 800; }
.tour-tip-title {
  font-size: 1.0625rem; font-weight: 800;
  letter-spacing: -.025em;
  margin: 0 0 8px;
}
.tour-tip-body {
  font-size: .8125rem; line-height: 1.55;
  color: var(--bs-secondary-color);
  margin: 0 0 14px;
}
.tour-tip-body kbd {
  display: inline-block;
  padding: 1px 6px;
  font-size: .68rem; font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-bottom-width: 2px;
  border-radius: 4px;
  color: var(--bs-body-color);
  vertical-align: 1px;
}

.tour-tip-progress {
  height: 4px;
  background: var(--bs-tertiary-bg);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 12px;
}
.tour-tip-progress-fill {
  height: 100%; width: 0%;
  background: var(--tt-grad-primary, var(--bs-primary));
  border-radius: 2px;
  transition: width .35s var(--ease-out, cubic-bezier(0,0,.2,1));
  box-shadow: 0 0 8px rgba(var(--bs-primary-rgb), .4);
}

.tour-tip-actions {
  display: flex; align-items: center;
  gap: 8px;
}
.tour-skip {
  color: var(--bs-secondary-color);
  font-size: .75rem;
  padding: 4px 10px;
  text-decoration: none;
  border-radius: 6px;
  transition: color .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
              background .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.tour-skip:hover {
  color: var(--bs-body-color);
  background: var(--bs-tertiary-bg);
}
.tour-prev { transition: opacity .15s; }
.tour-prev:disabled {
  opacity: .55;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Dark mode: contraste legible para Saltar + Anterior(disabled)
       Antes: --bs-secondary-color en dark = #94a3b8 sobre #131b2e
       quedaba casi invisible. opacity .4 sobre btn-light dark
       tampoco se leía. Subimos contraste cumpliendo WCAG AA.   ── */
[data-bs-theme="dark"] .tour-skip {
  color: #cbd5e1;          /* slate-300, contraste 8.5:1 sobre #131b2e */
}
[data-bs-theme="dark"] .tour-skip:hover {
  color: #f1f5f9;          /* slate-100 al hover */
  background: rgba(255,255,255,.06);
}
[data-bs-theme="dark"] .tour-prev {
  background: rgba(255,255,255,.08);
  border-color: rgba(255,255,255,.12);
  color: #e2e8f0;          /* slate-200, claramente legible */
}
[data-bs-theme="dark"] .tour-prev:hover:not(:disabled) {
  background: rgba(255,255,255,.14);
  border-color: rgba(255,255,255,.2);
  color: #f8fafc;
}
[data-bs-theme="dark"] .tour-prev:disabled {
  opacity: .65;            /* sube de .4 a .65 — legible pero claramente disabled */
  background: rgba(255,255,255,.04);
  border-color: rgba(255,255,255,.08);
  color: #94a3b8;
}

@media (max-width: 575.98px) {
  .tour-tip { width: calc(100vw - 24px); padding: 16px 18px 14px; }
  .tour-tip-title { font-size: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .tour-spotlight { transition: opacity .15s; }
  .tour-tip { animation: none; }
}

/* ============================================================
   23) PLANS (plans.js) — badge, trial banner, lock, modal upgrade
   ============================================================ */

/* Topbar plan badge */
.plan-badge {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px;
  background: var(--bs-tertiary-bg, rgba(0,0,0,.04));
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  color: var(--bs-secondary-color);
  font-size: .72rem; font-weight: 700;
  letter-spacing: .01em;
  cursor: pointer;
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
  white-space: nowrap;
}
.plan-badge:hover {
  border-color: rgba(var(--bs-primary-rgb), .35);
  color: var(--bs-body-color);
  transform: translateY(-1px);
}
.plan-badge i { font-size: .8rem; }
.plan-badge-free { color: var(--bs-secondary-color); }
.plan-badge-pro {
  background: linear-gradient(135deg, rgba(var(--bs-primary-rgb), .14), rgba(var(--bs-primary-rgb), .06));
  border-color: rgba(var(--bs-primary-rgb), .28);
  color: var(--bs-primary);
}
.plan-badge-pro i { color: var(--bs-primary); }
.plan-badge-enterprise {
  background: linear-gradient(135deg, rgba(245,158,11,.14), rgba(217,119,6,.06));
  border-color: rgba(245,158,11,.32);
  color: #b45309;
}
[data-bs-theme="dark"] .plan-badge-enterprise { color: #fbbf24; border-color: rgba(245,158,11,.4); }
.plan-badge-enterprise i { color: #d97706; }
[data-bs-theme="dark"] .plan-badge-enterprise i { color: #fbbf24; }
.plan-badge-trial {
  display: inline-block;
  font-size: .62rem; font-weight: 700;
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(var(--bs-primary-rgb), .15);
  color: var(--bs-primary);
  margin-left: 4px;
}
.plan-badge.on-trial { animation: planPulse 2.4s ease-in-out infinite; }
@keyframes planPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--bs-primary-rgb), .4); }
  50%      { box-shadow: 0 0 0 6px rgba(var(--bs-primary-rgb), 0); }
}
@media (max-width: 575.98px) {
  .plan-badge-text { display: none; }
  .plan-badge { padding: 0; width: 28px; justify-content: center; }
}

/* Trial banner (debajo del topbar) */
.plan-trial-banner {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 22px;
  background: linear-gradient(90deg, rgba(var(--bs-primary-rgb),.08), rgba(var(--bs-primary-rgb),.02));
  border-bottom: 1px solid var(--bs-border-color);
  font-size: .8125rem;
  color: var(--bs-body-color);
  position: relative;
}
.plan-trial-banner i.bi-stars { color: var(--bs-primary); font-size: 1rem; }
.plan-trial-dismiss {
  background: transparent; border: 0; padding: 4px 8px;
  color: var(--bs-secondary-color);
  border-radius: 6px;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.plan-trial-dismiss:hover { background: var(--bs-tertiary-bg); color: var(--bs-body-color); }

/* Locked feature visual */
.plan-locked {
  position: relative;
  cursor: not-allowed !important;
  filter: saturate(.6);
}
.plan-locked::after {
  content: ''; position: absolute; inset: 0;
  background: rgba(var(--bs-emphasis-color-rgb, 15,23,42), .03);
  pointer-events: none;
  border-radius: inherit;
}
.plan-lock-badge {
  display: inline-flex; align-items: center; gap: 4px;
  position: absolute; top: 8px; right: 8px;
  padding: 3px 8px;
  background: rgba(var(--bs-primary-rgb), .14);
  color: var(--bs-primary);
  border: 1px solid rgba(var(--bs-primary-rgb), .25);
  border-radius: 999px;
  font-size: .65rem; font-weight: 700;
  letter-spacing: .02em;
  pointer-events: none;
  z-index: 2;
}
.plan-lock-badge i { font-size: .72rem; }

/* Upgrade modal */
.plan-modal-overlay {
  position: fixed; inset: 0;
  z-index: 1090;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 5vh 16px 16px;
  background: rgba(15,23,42,.55);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  overflow-y: auto;
  opacity: 0;
  transition: opacity .22s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.plan-modal-overlay.show { opacity: 1; }
.plan-modal-overlay.leaving { opacity: 0; }
[data-bs-theme="dark"] .plan-modal-overlay { background: rgba(2,6,23,.72); }
body.plan-modal-noscroll { overflow: hidden; }

.plan-modal {
  width: 100%; max-width: 1080px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 18px;
  padding: 36px 32px 28px;
  box-shadow:
    0 32px 80px -20px rgba(15,23,42,.55),
    0 12px 32px -12px rgba(15,23,42,.20);
  position: relative;
  transform: translateY(12px) scale(.98);
  transition: transform .26s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.plan-modal-overlay.show .plan-modal { transform: translateY(0) scale(1); }
[data-bs-theme="dark"] .plan-modal {
  background: var(--tt-surface-2, #131b2e);
  box-shadow: 0 32px 80px -16px rgba(0,0,0,.7);
}

.plan-modal-close {
  position: absolute; top: 16px; right: 16px;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--bs-border-color);
  border-radius: 50%;
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: all .15s;
}
.plan-modal-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  transform: rotate(90deg);
}

.plan-modal-header { text-align: center; margin-bottom: 28px; }
.plan-modal-eyebrow {
  font-size: .72rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--bs-primary);
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 10px;
}
.plan-modal-header h2 {
  font-size: 1.625rem; font-weight: 800;
  letter-spacing: -.035em;
  margin: 0 0 8px;
  color: var(--bs-body-color);
}
.plan-modal-header p {
  color: var(--bs-secondary-color);
  font-size: .9rem;
  margin: 0;
}
.plan-modal-reason {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 14px;
  padding: 8px 14px;
  background: rgba(var(--bs-primary-rgb), .08);
  border: 1px solid rgba(var(--bs-primary-rgb), .18);
  border-radius: 999px;
  font-size: .78rem;
  color: var(--bs-body-color);
}
.plan-modal-reason i { color: var(--bs-primary); }

.plan-modal-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-bottom: 24px;
}
@media (max-width: 991.98px) {
  .plan-modal-cards { grid-template-columns: 1fr; gap: 14px; }
  .plan-modal { padding: 28px 22px 22px; }
  .plan-modal-header h2 { font-size: 1.35rem; }
}

.plan-card {
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  padding: 24px 22px 20px;
  display: flex; flex-direction: column;
  position: relative;
  transition: transform .2s var(--ease-out, cubic-bezier(0,0,.2,1)),
              border-color .2s, box-shadow .2s;
}
.plan-card:hover {
  transform: translateY(-3px);
  border-color: rgba(var(--bs-primary-rgb), .28);
  box-shadow: 0 14px 32px -12px rgba(15,23,42,.18);
}
[data-bs-theme="dark"] .plan-card { background: var(--tt-surface, #0f1626); }
[data-bs-theme="dark"] .plan-card:hover {
  box-shadow: 0 16px 36px -10px rgba(0,0,0,.5);
}
.plan-card.highlight {
  border-color: rgba(var(--bs-primary-rgb), .45);
  box-shadow:
    0 14px 32px -10px rgba(var(--bs-primary-rgb), .35),
    0 0 0 1px rgba(var(--bs-primary-rgb), .12);
  background: linear-gradient(180deg,
    rgba(var(--bs-primary-rgb), .04) 0%,
    var(--bs-body-bg) 30%);
}
[data-bs-theme="dark"] .plan-card.highlight {
  background: linear-gradient(180deg,
    rgba(var(--bs-primary-rgb), .10) 0%,
    var(--tt-surface, #0f1626) 30%);
}
.plan-card.current {
  border-color: rgba(16,185,129,.4);
  box-shadow: 0 0 0 1px rgba(16,185,129,.18);
}

.plan-card-ribbon {
  position: absolute;
  top: -10px; right: 18px;
  background: var(--tt-grad-primary, linear-gradient(135deg, var(--bs-primary), #8b5cf6));
  color: #fff;
  font-size: .65rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 999px;
  box-shadow: 0 6px 16px -4px rgba(var(--bs-primary-rgb), .55);
}

.plan-card header { margin-bottom: 18px; }
.plan-card-name {
  font-size: 1rem; font-weight: 800;
  letter-spacing: -.02em;
  color: var(--bs-body-color);
}
.plan-card.highlight .plan-card-name { color: var(--bs-primary); }
.plan-card-tagline {
  font-size: .78rem;
  color: var(--bs-secondary-color);
  margin-top: 4px;
}
.plan-card-price {
  margin-top: 14px;
  display: flex; align-items: baseline; gap: 6px;
}
.plan-price {
  font-size: 2rem; font-weight: 800;
  letter-spacing: -.04em;
  color: var(--bs-body-color);
  font-feature-settings: 'tnum';
}
.plan-price-suffix {
  font-size: .75rem;
  color: var(--bs-secondary-color);
}

.plan-card-features {
  list-style: none; margin: 0; padding: 0;
  flex: 1;
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 18px;
}
.plan-card-features li {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: .82rem;
  line-height: 1.4;
  color: var(--bs-body-color);
}
.plan-card-features li i {
  color: #10b981;
  font-size: .9rem;
  margin-top: 2px;
  flex-shrink: 0;
}
.plan-card-features li.excluded {
  color: var(--bs-tertiary-color, var(--bs-secondary-color));
  text-decoration: line-through;
  opacity: .6;
}
.plan-card-features li.excluded i { color: var(--bs-secondary-color); }
[data-bs-theme="dark"] .plan-card-features li i { color: #34d399; }

.plan-card-cta .btn { padding: .55rem .9rem; font-weight: 600; }

/* Indicador "Plan actual" — reemplaza al antiguo <button btn-light disabled>
   que en tema oscuro quedaba con un texto negro sobre fondo claro casi
   ilegible (bajo contraste con la card oscura circundante). Ahora es un
   pill verde semantico, coherente con .plan-card.current (borde verde). */
.plan-card-current-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: .55rem .9rem;
  font-weight: 600;
  font-size: .85rem;
  line-height: 1.2;
  background: rgba(16, 185, 129, .12);
  color: #047857;
  border: 1px solid rgba(16, 185, 129, .35);
  border-radius: 8px;
  letter-spacing: -.005em;
  user-select: none;
}
.plan-card-current-cta i { font-size: 1rem; line-height: 1; }
[data-bs-theme="dark"] .plan-card-current-cta {
  background: rgba(52, 211, 153, .14);
  color: #6ee7b7;
  border-color: rgba(52, 211, 153, .35);
}

.plan-modal-footer {
  display: flex; flex-wrap: wrap; gap: 18px;
  justify-content: center;
  padding-top: 18px;
  border-top: 1px solid var(--bs-border-color);
  font-size: .76rem;
  color: var(--bs-secondary-color);
}
.plan-modal-footer span { display: inline-flex; align-items: center; gap: 6px; }
.plan-modal-footer i { color: var(--bs-primary); }

@media (max-width: 575.98px) {
  .plan-modal { padding: 24px 18px 18px; border-radius: 14px; }
  .plan-modal-header h2 { font-size: 1.25rem; }
  .plan-card { padding: 20px 18px 16px; }
  .plan-modal-footer { gap: 10px; font-size: .7rem; }
}
@media (prefers-reduced-motion: reduce) {
  .plan-modal, .plan-card { transition: opacity .12s; transform: none; }
  .plan-badge.on-trial { animation: none; }
}

/* ── Sale mode toggle (footer del Plans modal) ─────────────────
   Switch admin que permite desactivar todo el sistema de Plans
   con un click. Cuando OFF: banner verde en el header del modal,
   gates limpios, badge oculto en topbar. */
.plan-modal-salemode-banner {
  display: flex; align-items: center; gap: 12px;
  margin-top: 16px;
  padding: 12px 16px;
  background: linear-gradient(90deg, rgba(16,185,129,.10), rgba(16,185,129,.04));
  border: 1px solid rgba(16,185,129,.28);
  border-radius: 10px;
  text-align: left;
}
.plan-modal-salemode-banner i {
  color: #059669; font-size: 1.2rem;
  flex-shrink: 0;
}
[data-bs-theme="dark"] .plan-modal-salemode-banner i { color: #34d399; }
.plan-modal-salemode-banner > div {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0;
}
.plan-modal-salemode-banner strong {
  font-size: .85rem; color: var(--bs-body-color);
  letter-spacing: -.01em;
}
.plan-modal-salemode-banner span {
  font-size: .76rem; color: var(--bs-secondary-color);
}

.plan-modal-admin {
  padding: 14px 32px 22px;
  border-top: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg, rgba(0,0,0,.02));
}
.plan-salemode-toggle {
  display: flex; align-items: center; gap: 14px;
  cursor: pointer;
  user-select: none;
  margin: 0;
}
.plan-salemode-toggle input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0; height: 0;
}
.plan-salemode-track {
  position: relative;
  display: inline-block;
  width: 44px; height: 24px;
  background: var(--bs-secondary-bg, #e2e8f0);
  border-radius: 999px;
  transition: background .2s var(--ease-out, cubic-bezier(0,0,.2,1));
  flex-shrink: 0;
}
.plan-salemode-thumb {
  position: absolute;
  top: 2px; left: 2px;
  width: 20px; height: 20px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 2px 6px -1px rgba(0,0,0,.25);
  transition: left .22s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.plan-salemode-toggle input:checked ~ .plan-salemode-track {
  background: var(--bs-primary);
}
.plan-salemode-toggle input:checked ~ .plan-salemode-track .plan-salemode-thumb {
  left: 22px;
}
.plan-salemode-toggle input:focus-visible ~ .plan-salemode-track {
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .22);
}
.plan-salemode-text {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0;
}
.plan-salemode-text strong {
  font-size: .85rem; font-weight: 700;
  color: var(--bs-body-color);
  letter-spacing: -.01em;
}
.plan-salemode-text small {
  font-size: .72rem;
  color: var(--bs-secondary-color);
  line-height: 1.4;
}
@media (max-width: 575.98px) {
  .plan-modal-admin { padding: 12px 18px 18px; }
}

/* ============================================================
   24) BRANDING / WHITE-LABEL (branding.js)
   ------------------------------------------------------------
   Modal con preview en vivo: subida de logo, presets de color +
   hex custom, nombre de empresa. Gated por Plans 'custom_branding'
   (Pro+). Free users ven el modal pero "Guardar" abre upgrade.
   ============================================================ */
.brand-modal-overlay {
  position: fixed; inset: 0;
  z-index: 1088;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 5vh 16px 16px;
  background: rgba(15,23,42,.55);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  overflow-y: auto;
  opacity: 0;
  transition: opacity .22s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.brand-modal-overlay.show { opacity: 1; }
.brand-modal-overlay.leaving { opacity: 0; }
[data-bs-theme="dark"] .brand-modal-overlay { background: rgba(2,6,23,.72); }
body.brand-modal-noscroll { overflow: hidden; }

.brand-modal {
  width: 100%; max-width: 720px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 18px;
  box-shadow:
    0 32px 80px -20px rgba(15,23,42,.55),
    0 12px 32px -12px rgba(15,23,42,.20);
  position: relative;
  overflow: hidden;
  transform: translateY(12px) scale(.98);
  transition: transform .26s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
  display: flex; flex-direction: column;
  max-height: calc(100vh - 10vh - 16px);
}
.brand-modal-overlay.show .brand-modal { transform: translateY(0) scale(1); }
[data-bs-theme="dark"] .brand-modal {
  background: var(--tt-surface-2, #131b2e);
  box-shadow: 0 32px 80px -16px rgba(0,0,0,.7);
}

.brand-modal-close {
  position: absolute; top: 14px; right: 14px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--bs-border-color);
  border-radius: 50%;
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: all .15s;
  z-index: 2;
}
.brand-modal-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  transform: rotate(90deg);
}

.brand-modal-header {
  padding: 28px 28px 20px;
  border-bottom: 1px solid var(--bs-border-color);
}
.brand-modal-eyebrow {
  font-size: .7rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--bs-primary);
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 8px;
}
.brand-modal-header h2 {
  font-size: 1.375rem; font-weight: 800;
  letter-spacing: -.03em;
  margin: 0 0 6px;
  color: var(--bs-body-color);
}
.brand-modal-header p {
  font-size: .85rem;
  color: var(--bs-secondary-color);
  margin: 0;
}

.brand-modal-gate {
  display: flex; align-items: center; gap: 10px;
  margin-top: 16px;
  padding: 10px 14px;
  background: linear-gradient(90deg, rgba(245,158,11,.10), rgba(245,158,11,.04));
  border: 1px solid rgba(245,158,11,.28);
  border-radius: 10px;
  font-size: .8125rem;
  color: var(--bs-body-color);
}
.brand-modal-gate i.bi-lock-fill { color: #d97706; font-size: 1rem; }
[data-bs-theme="dark"] .brand-modal-gate {
  background: linear-gradient(90deg, rgba(245,158,11,.14), rgba(245,158,11,.06));
}
[data-bs-theme="dark"] .brand-modal-gate i.bi-lock-fill { color: #fbbf24; }

.brand-modal-body {
  padding: 22px 28px;
  overflow-y: auto;
}
.brand-modal-body.is-locked {
  opacity: .85;
  position: relative;
}

/* Live preview card */
.brand-preview-card {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 18px 22px;
  margin-bottom: 22px;
  background: var(--tt-surface-2, var(--bs-tertiary-bg));
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  --brand-preview-color: var(--bs-primary);
  --brand-preview-rgb: var(--bs-primary-rgb);
  position: relative;
  overflow: hidden;
}
.brand-preview-card::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(circle at 20% 50%, rgba(var(--brand-preview-rgb), .08), transparent 60%);
  pointer-events: none;
}

.brand-preview-sidebar {
  display: flex; align-items: center; gap: 12px;
  position: relative;
  min-width: 0;
}
.brand-preview-logo {
  width: 44px; height: 44px;
  border-radius: 12px;
  background: var(--brand-preview-color);
  color: #fff;
  display: grid; place-items: center;
  font-weight: 800; font-size: 1.1rem;
  box-shadow:
    0 4px 12px -2px rgba(var(--brand-preview-rgb), .5),
    inset 0 1px 0 rgba(255,255,255,.18);
  flex-shrink: 0;
  overflow: hidden;
}
.brand-preview-logo img {
  width: 100%; height: 100%;
  object-fit: contain;
  border-radius: inherit;
}
.brand-preview-name {
  font-size: 1rem; font-weight: 800;
  letter-spacing: -.02em;
  color: var(--bs-body-color);
}
.brand-preview-tag {
  font-size: .72rem;
  color: var(--bs-secondary-color);
}

.brand-preview-action {
  display: flex; align-items: center; gap: 10px;
  position: relative;
  flex-shrink: 0;
}
.brand-preview-card .btn-primary {
  background: var(--brand-preview-color) !important;
  border-color: var(--brand-preview-color) !important;
  box-shadow: 0 0 0 0 rgba(var(--brand-preview-rgb), 0);
}
.brand-preview-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px;
  background: rgba(var(--brand-preview-rgb), .12);
  color: var(--brand-preview-color);
  border-radius: 999px;
  font-size: .68rem; font-weight: 700;
  letter-spacing: .04em;
}

@media (max-width: 575.98px) {
  .brand-preview-card {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Fields */
.brand-fields {
  display: flex; flex-direction: column;
  gap: 22px;
}
.brand-field {
  display: flex; flex-direction: column; gap: 8px;
}
.brand-field-label {
  font-size: .8rem; font-weight: 700;
  color: var(--bs-body-color);
  letter-spacing: -.005em;
  margin: 0;
  display: inline-flex; align-items: center; gap: 6px;
}
.brand-field-label i { color: var(--bs-primary); font-size: .9rem; }
.brand-field-hint {
  font-size: .72rem;
  color: var(--bs-secondary-color);
  line-height: 1.4;
  margin-top: 2px;
}

/* Logo uploader */
.brand-logo-uploader {
  display: flex; align-items: center; gap: 16px;
}
.brand-logo-preview {
  width: 80px; height: 80px;
  border-radius: 14px;
  background: var(--bs-tertiary-bg);
  border: 2px dashed var(--bs-border-color);
  display: grid; place-items: center;
  flex-shrink: 0;
  overflow: hidden;
  color: var(--bs-secondary-color);
  font-size: 1.5rem;
  transition: border-color .15s, background .15s;
}
.brand-logo-preview:hover {
  border-color: rgba(var(--bs-primary-rgb), .35);
  background: rgba(var(--bs-primary-rgb), .04);
}
.brand-logo-preview img {
  width: 100%; height: 100%;
  object-fit: contain;
}
.brand-logo-actions {
  display: flex; flex-direction: column;
  gap: 6px;
  align-items: flex-start;
}
.brand-logo-actions .btn { padding: .35rem .8rem; font-size: .78rem; }

/* Color swatches */
.brand-color-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
}
.brand-color-swatch {
  display: flex; flex-direction: column; align-items: center;
  gap: 6px;
  padding: 10px 6px 8px;
  background: var(--bs-tertiary-bg);
  border: 1.5px solid var(--bs-border-color);
  border-radius: 10px;
  cursor: pointer;
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.brand-color-swatch:hover {
  background: var(--bs-secondary-bg);
  border-color: var(--bs-secondary-color);
  transform: translateY(-1px);
}
.brand-color-swatch.active {
  border-color: var(--swatch);
  background: color-mix(in srgb, var(--swatch) 8%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--swatch) 18%, transparent);
}
.brand-color-dot {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--swatch);
  box-shadow:
    0 4px 10px -2px color-mix(in srgb, var(--swatch) 50%, transparent),
    inset 0 1px 0 rgba(255,255,255,.22);
}
.brand-color-label {
  font-size: .7rem; font-weight: 600;
  color: var(--bs-secondary-color);
}
.brand-color-swatch.active .brand-color-label { color: var(--bs-body-color); }

.brand-color-custom {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px;
  padding: 10px 12px;
  background: var(--bs-tertiary-bg);
  border-radius: 10px;
}
.brand-color-custom-label {
  font-size: .75rem;
  color: var(--bs-secondary-color);
  flex-shrink: 0;
}
.brand-color-custom .form-control {
  flex: 1; min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .8125rem;
  text-transform: uppercase;
}
.brand-color-custom input[type="color"] {
  width: 36px; height: 36px;
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
  cursor: pointer;
  background: transparent;
  padding: 2px;
}

/* Footer */
.brand-modal-footer {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 16px 28px;
  border-top: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg, rgba(0,0,0,.02));
}
.brand-modal-footer .btn { font-weight: 600; }

/* Topbar button (admin) */
.brand-topbar-btn { color: var(--bs-secondary-color); }
.brand-topbar-btn:hover { color: var(--bs-primary); }

@media (max-width: 575.98px) {
  .brand-modal { max-width: 100%; border-radius: 14px; }
  .brand-modal-header { padding: 22px 18px 14px; }
  .brand-modal-body { padding: 16px 18px; }
  .brand-modal-footer { padding: 12px 18px; }
  .brand-modal-header h2 { font-size: 1.15rem; }
  .brand-color-swatches { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); }
  .brand-logo-preview { width: 64px; height: 64px; font-size: 1.2rem; }
}
@media (prefers-reduced-motion: reduce) {
  .brand-modal { transition: opacity .12s; transform: none; }
}

/* ============================================================
   25) WHAT'S NEW dropdown (whats-new.js)
   ------------------------------------------------------------
   Botón en topbar (icono stars) con dot rojo si hay versiones
   no leídas. Click → panel flotante con timeline de releases.
   ============================================================ */
.wn-btn { position: relative; }
.wn-btn-dot {
  position: absolute;
  top: 4px; right: 4px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #ef4444;
  box-shadow: 0 0 0 2px var(--bs-body-bg);
  animation: wnPulse 2.4s ease-in-out infinite;
}
@keyframes wnPulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--bs-body-bg), 0 0 0 0 rgba(239,68,68,.5); }
  50%      { box-shadow: 0 0 0 2px var(--bs-body-bg), 0 0 0 6px rgba(239,68,68,0); }
}

.wn-panel {
  position: fixed;
  z-index: 1078;
  max-width: calc(100vw - 24px);
  max-height: 70vh;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  box-shadow:
    0 24px 56px -16px rgba(15,23,42,.40),
    0 8px 20px -8px rgba(15,23,42,.18),
    0 0 0 1px rgba(var(--bs-primary-rgb), .04);
  display: flex; flex-direction: column;
  overflow: hidden;
  opacity: 0; transform: translateY(-8px) scale(.98);
  pointer-events: none;
  transition:
    opacity .18s var(--ease-out, cubic-bezier(0,0,.2,1)),
    transform .22s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.wn-panel.show {
  opacity: 1; transform: translateY(0) scale(1);
  pointer-events: auto;
}
[data-bs-theme="dark"] .wn-panel {
  background: var(--tt-surface-2, #131b2e);
  box-shadow:
    0 28px 64px -12px rgba(0,0,0,.7),
    0 8px 20px -8px rgba(0,0,0,.4);
}

/* Header */
.wn-header {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--bs-border-color);
  background: linear-gradient(180deg, rgba(var(--bs-primary-rgb), .05), transparent);
}
.wn-header > div:first-child { flex: 1; min-width: 0; }
.wn-eyebrow {
  font-size: .68rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-primary);
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 4px;
}
.wn-title {
  font-size: 1rem; font-weight: 800;
  letter-spacing: -.02em;
  margin: 0;
  color: var(--bs-body-color);
}
.wn-count {
  font-size: .72rem;
  color: var(--bs-secondary-color);
  margin: 2px 0 0;
  font-weight: 600;
}
.wn-close {
  background: transparent; border: 1px solid var(--bs-border-color);
  border-radius: 50%;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  color: var(--bs-secondary-color);
  cursor: pointer;
  flex-shrink: 0;
  transition: all .15s;
}
.wn-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  transform: rotate(90deg);
}

/* List of entries */
.wn-list {
  overflow-y: auto;
  flex: 1;
  padding: 6px 0;
}
.wn-list::-webkit-scrollbar { width: 6px; }
.wn-list::-webkit-scrollbar-thumb {
  background: rgba(var(--bs-emphasis-color-rgb, 15,23,42), .12);
  border-radius: 3px;
}

.wn-entry {
  position: relative;
  padding: 14px 20px;
  border-bottom: 1px solid var(--bs-border-color);
}
.wn-entry:last-child { border-bottom: 0; }
.wn-entry.is-unread {
  background: linear-gradient(90deg, rgba(var(--bs-primary-rgb), .04), transparent);
}
.wn-entry.is-unread::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--bs-primary);
  border-radius: 0 3px 3px 0;
}

.wn-entry-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 8px;
}
.wn-version-pill {
  display: inline-flex; align-items: center;
  height: 20px;
  padding: 0 8px;
  background: var(--bs-tertiary-bg);
  border-radius: 999px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .68rem; font-weight: 700;
  color: var(--bs-body-color);
  letter-spacing: .01em;
}
.wn-date {
  font-size: .68rem;
  color: var(--bs-secondary-color);
  font-weight: 500;
}
.wn-tag {
  display: inline-flex; align-items: center; gap: 4px;
  height: 20px;
  padding: 0 8px;
  border-radius: 999px;
  font-size: .65rem; font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.wn-tag i { font-size: .68rem; }
.wn-tag-feature {
  background: rgba(var(--bs-primary-rgb), .12);
  color: var(--bs-primary);
}
.wn-tag-polish {
  background: rgba(139,92,246,.14);
  color: #7c3aed;
}
[data-bs-theme="dark"] .wn-tag-polish { color: #a78bfa; }
.wn-tag-fix {
  background: rgba(16,185,129,.12);
  color: #059669;
}
[data-bs-theme="dark"] .wn-tag-fix { color: #34d399; }
.wn-tag-security {
  background: rgba(245,158,11,.14);
  color: #d97706;
}
[data-bs-theme="dark"] .wn-tag-security { color: #fbbf24; }
.wn-unread-dot {
  margin-left: auto;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #ef4444;
  flex-shrink: 0;
}

.wn-entry-title {
  font-size: .9rem; font-weight: 700;
  letter-spacing: -.015em;
  color: var(--bs-body-color);
  margin: 0 0 8px;
  line-height: 1.3;
}
.wn-entry-items {
  list-style: none;
  margin: 0; padding: 0;
  display: flex; flex-direction: column;
  gap: 6px;
}
.wn-entry-items li {
  position: relative;
  padding-left: 16px;
  font-size: .78rem;
  line-height: 1.5;
  color: var(--bs-secondary-color);
}
.wn-entry-items li::before {
  content: '';
  position: absolute;
  left: 4px; top: 9px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--bs-primary);
  opacity: .65;
}
.wn-entry-items li strong {
  color: var(--bs-body-color);
  font-weight: 700;
}
.wn-entry-items li kbd {
  display: inline-block;
  padding: 1px 5px;
  font-size: .68rem; font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-bottom-width: 2px;
  border-radius: 4px;
  color: var(--bs-body-color);
}

/* Footer */
.wn-footer {
  padding: 10px 20px;
  border-top: 1px solid var(--bs-border-color);
  text-align: center;
  background: var(--bs-tertiary-bg, rgba(0,0,0,.02));
}
.wn-footer small {
  font-size: .68rem;
  color: var(--bs-secondary-color);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: .01em;
}

@media (max-width: 575.98px) {
  .wn-panel { right: 8px !important; left: 8px !important; width: auto !important; }
  .wn-entry { padding: 12px 16px; }
  .wn-header { padding: 14px 16px 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .wn-panel { transition: opacity .12s; transform: none; }
  .wn-btn-dot { animation: none; }
}

/* ============================================================
   26) A11Y POLISH — focus-visible para componentes nuevos
   ------------------------------------------------------------
   El proyecto ya tiene un focus-ring base en :focus-visible (sec.
   v17.x), aquí refinamos componentes interactivos custom para
   que sean perfectamente accesibles por teclado.
   ============================================================ */

/* Command Palette items */
.cmdk-item:focus-visible {
  outline: 0;
  background: rgba(var(--bs-primary-rgb), .14);
  box-shadow: inset 0 0 0 2px var(--bs-primary);
}

/* Plans cards & CTAs */
.plan-card:focus-within {
  border-color: rgba(var(--bs-primary-rgb), .55);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .15);
}
.plan-modal-close:focus-visible,
.brand-modal-close:focus-visible,
.plan-trial-dismiss:focus-visible,
.tt-toast-close:focus-visible,
.tt-toast-action:focus-visible,
.wn-close:focus-visible,
.setup-close:focus-visible,
.setup-task-check:focus-visible,
.setup-fab:focus-visible,
.cmdk-trigger:focus-visible,
.brand-color-swatch:focus-visible,
.tour-skip:focus-visible,
.tour-prev:focus-visible,
.tour-next:focus-visible,
.plan-badge:focus-visible {
  outline: 0;
  box-shadow:
    0 0 0 3px rgba(var(--bs-primary-rgb), .25),
    0 0 0 1px var(--bs-primary);
}

/* Setup FAB necesita un focus-ring que sobresalga del círculo */
.setup-fab:focus-visible {
  box-shadow:
    0 10px 28px -6px rgba(var(--bs-primary-rgb), .55),
    0 0 0 4px rgba(var(--bs-primary-rgb), .35),
    inset 0 1px 0 rgba(255,255,255,.18);
}

/* WhatsNew button focus */
.wn-btn:focus-visible {
  outline: 0;
  background: rgba(var(--bs-primary-rgb), .12);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .25);
}

/* Brand color swatch — focus de tono del swatch para contraste */
.brand-color-swatch:focus-visible {
  outline: 2px solid var(--swatch);
  outline-offset: 3px;
}

/* Tour tip — el modal foca el primer botón */
.tour-tip:focus-visible { outline: 0; }
.tour-next:focus-visible {
  box-shadow:
    0 0 0 3px rgba(var(--bs-primary-rgb), .35),
    0 4px 12px -2px rgba(var(--bs-primary-rgb), .25);
}

/* Sale-mode toggle: focus-ring custom (el estándar ya ataca al input
   pero visualmente queremos que se vea sobre el track). */
.plan-salemode-toggle input:focus-visible ~ .plan-salemode-track {
  outline: 0;
  box-shadow:
    0 0 0 3px rgba(var(--bs-primary-rgb), .28),
    0 0 0 1px var(--bs-primary);
}

/* Skip-to-content (a11y mejor práctica): solo visible al focus */
.skip-to-content {
  position: absolute;
  left: -9999px; top: -9999px;
  z-index: 10000;
  background: var(--bs-primary); color: #fff;
  padding: 8px 16px; border-radius: 0 0 8px 0;
  font-weight: 600; font-size: .85rem;
  text-decoration: none;
}
.skip-to-content:focus {
  left: 0; top: 0;
  outline: 3px solid rgba(var(--bs-primary-rgb), .35);
}

/* Aria-hidden util — nunca debe ser focusable */
[aria-hidden="true"] { pointer-events: none; }

/* Mejorar contraste de placeholders en dark (WCAG AA) */
[data-bs-theme="dark"] .form-control::placeholder,
[data-bs-theme="dark"] .form-select::placeholder,
[data-bs-theme="dark"] .cmdk-input::placeholder {
  color: rgba(226, 232, 240, .55);
}

/* ============================================================
   27) BOTTOM SHEETS EN MOBILE (≤575px)
   ------------------------------------------------------------
   Transforma los modales custom (Plans, Branding, Confirm,
   ReportBuilder) en bottom sheets nativos: slide-up desde abajo,
   esquinas redondeadas sólo arriba, drag-handle visual.
   El cmdk-modal mantiene su anchorage superior (mejor UX para
   buscar). Los modales Bootstrap se transforman vía .modal-dialog.
   ============================================================ */
@media (max-width: 575.98px) {
  /* Animación de entrada bottom-sheet */
  @keyframes bsSlideUp {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
  }

  /* Plans modal → bottom sheet */
  .plan-modal-overlay {
    align-items: flex-end !important;
    padding: 0 !important;
  }
  .plan-modal-overlay .plan-modal {
    width: 100%;
    max-width: 100% !important;
    border-radius: 18px 18px 0 0 !important;
    transform: translateY(100%) !important;
    transition: transform .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)) !important;
    max-height: 88vh;
    overflow-y: auto;
    padding-top: 30px !important;   /* hueco para el drag-handle */
  }
  .plan-modal-overlay.show .plan-modal {
    transform: translateY(0) !important;
  }
  .plan-modal-overlay .plan-modal::before {
    content: '';
    position: absolute;
    top: 10px; left: 50%;
    width: 44px; height: 4px;
    background: var(--bs-secondary-color);
    opacity: .35;
    border-radius: 2px;
    transform: translateX(-50%);
  }
  .plan-modal-overlay .plan-modal-close {
    top: 10px !important; right: 10px !important;
    width: 30px !important; height: 30px !important;
  }

  /* Branding modal → bottom sheet */
  .brand-modal-overlay {
    align-items: flex-end !important;
    padding: 0 !important;
  }
  .brand-modal-overlay .brand-modal {
    max-width: 100% !important;
    border-radius: 18px 18px 0 0 !important;
    transform: translateY(100%) !important;
    transition: transform .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)) !important;
    max-height: 90vh !important;
    padding-top: 18px !important;
  }
  .brand-modal-overlay.show .brand-modal {
    transform: translateY(0) !important;
  }
  .brand-modal-overlay .brand-modal::before {
    content: '';
    position: absolute;
    top: 8px; left: 50%;
    width: 44px; height: 4px;
    background: var(--bs-secondary-color);
    opacity: .35;
    border-radius: 2px;
    transform: translateX(-50%);
  }

  /* Confirm modal → bottom sheet */
  .tt-confirm-overlay {
    align-items: flex-end !important;
    padding: 0 !important;
  }
  .tt-confirm-overlay .tt-confirm-modal {
    max-width: 100%;
    width: 100%;
    border-radius: 18px 18px 0 0 !important;
    transform: translateY(100%) !important;
    transition: transform .28s var(--ease-emph, cubic-bezier(.34,1.56,.64,1)) !important;
    padding-top: 28px !important;
  }
  .tt-confirm-overlay.show .tt-confirm-modal {
    transform: translateY(0) !important;
  }
  .tt-confirm-overlay .tt-confirm-modal::before {
    content: '';
    position: absolute;
    top: 10px; left: 50%;
    width: 44px; height: 4px;
    background: var(--bs-secondary-color);
    opacity: .35;
    border-radius: 2px;
    transform: translateX(-50%);
  }

  /* Bootstrap modals → bottom sheets vía media query */
  .modal:not(.modal-fullscreen):not(.cmdk-overlay) .modal-dialog {
    margin: 0 !important;
    align-items: flex-end !important;
    min-height: 100% !important;
  }
  .modal:not(.modal-fullscreen):not(.cmdk-overlay) .modal-content {
    border-radius: 18px 18px 0 0 !important;
    max-height: 90vh;
    overflow-y: auto;
    padding-top: 22px;
    position: relative;
  }
  .modal:not(.modal-fullscreen):not(.cmdk-overlay) .modal-content::before {
    content: '';
    position: absolute;
    top: 10px; left: 50%;
    width: 44px; height: 4px;
    background: var(--bs-secondary-color);
    opacity: .35;
    border-radius: 2px;
    transform: translateX(-50%);
    z-index: 1;
  }
  /* La animación de slide la maneja Bootstrap pero alteramos el origen */
  .modal.fade .modal-dialog {
    transform: translateY(20px) !important;
  }
  .modal.show .modal-dialog {
    transform: translateY(0) !important;
  }

  /* Brand-preview-card en mobile compacto */
  .brand-preview-card { gap: 10px; padding: 14px 16px; }
}

/* ============================================================
   28) CUSTOM REPORT BUILDER (report-builder.js)
   ------------------------------------------------------------
   Modal con sources cards, column-chips, filtros, preview-table
   y botones de export/save. Theme-aware.
   ============================================================ */
.rb-overlay {
  position: fixed; inset: 0;
  z-index: 1086;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 4vh 16px 16px;
  background: rgba(15,23,42,.55);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
  overflow-y: auto;
  opacity: 0;
  transition: opacity .22s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.rb-overlay.show { opacity: 1; }
.rb-overlay.leaving { opacity: 0; }
[data-bs-theme="dark"] .rb-overlay { background: rgba(2,6,23,.72); }
body.rb-noscroll { overflow: hidden; }

.rb-modal {
  width: 100%; max-width: 980px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 18px;
  box-shadow:
    0 32px 80px -20px rgba(15,23,42,.55),
    0 12px 32px -12px rgba(15,23,42,.20);
  position: relative;
  transform: translateY(12px) scale(.98);
  transition: transform .26s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
  display: flex; flex-direction: column;
  max-height: calc(100vh - 4vh - 16px);
}
.rb-overlay.show .rb-modal { transform: translateY(0) scale(1); }
[data-bs-theme="dark"] .rb-modal {
  background: var(--tt-surface-2, #131b2e);
  box-shadow: 0 32px 80px -16px rgba(0,0,0,.7);
}

.rb-close {
  position: absolute; top: 14px; right: 14px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: transparent; border: 1px solid var(--bs-border-color);
  border-radius: 50%;
  color: var(--bs-secondary-color);
  cursor: pointer;
  transition: all .15s;
  z-index: 2;
}
.rb-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  transform: rotate(90deg);
}

.rb-header {
  padding: 28px 28px 18px;
  border-bottom: 1px solid var(--bs-border-color);
}
.rb-eyebrow {
  font-size: .7rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--bs-primary);
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 8px;
}
.rb-header h2 {
  font-size: 1.35rem; font-weight: 800;
  letter-spacing: -.025em;
  margin: 0 0 4px;
  color: var(--bs-body-color);
}
.rb-header p {
  font-size: .82rem;
  color: var(--bs-secondary-color);
  margin: 0;
}

.rb-modal > .rb-section,
.rb-modal > .rb-header,
.rb-modal > .rb-footer {
  flex-shrink: 0;
}
.rb-modal {
  overflow-y: auto;
}

.rb-section {
  padding: 18px 28px 4px;
  border-bottom: 1px solid var(--bs-border-color);
}
.rb-section:last-of-type { border-bottom: 0; }
.rb-h3 {
  font-size: .82rem; font-weight: 700;
  letter-spacing: -.01em;
  margin: 0 0 10px;
  color: var(--bs-body-color);
  display: inline-flex; align-items: center; gap: 8px;
}
.rb-step {
  display: inline-grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(var(--bs-primary-rgb), .12);
  color: var(--bs-primary);
  font-size: .72rem; font-weight: 800;
  font-feature-settings: 'tnum';
}

/* Saved reports chips */
.rb-saved-list {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding-bottom: 10px;
}
.rb-saved-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 6px 6px 12px;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  cursor: pointer;
  font-size: .78rem; font-weight: 600;
  color: var(--bs-body-color);
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.rb-saved-chip:hover {
  border-color: rgba(var(--bs-primary-rgb), .35);
  transform: translateY(-1px);
}
.rb-saved-chip i.bi { color: var(--bs-primary); font-size: .82rem; }
.rb-saved-date {
  font-size: .68rem;
  color: var(--bs-secondary-color);
  font-weight: 500;
  font-feature-settings: 'tnum';
}
.rb-saved-del {
  display: inline-grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  color: var(--bs-secondary-color);
  background: transparent;
  transition: all .12s;
}
.rb-saved-del:hover {
  background: rgba(239,68,68,.14);
  color: #dc2626;
}

/* Source cards grid */
.rb-source-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px;
  padding-bottom: 14px;
}
.rb-source-card {
  display: flex; flex-direction: column;
  gap: 4px;
  padding: 14px 14px 12px;
  background: var(--bs-tertiary-bg);
  border: 1.5px solid var(--bs-border-color);
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.rb-source-card:hover {
  border-color: rgba(var(--bs-primary-rgb), .35);
  transform: translateY(-1px);
}
.rb-source-card.active {
  border-color: var(--bs-primary);
  background: linear-gradient(180deg, rgba(var(--bs-primary-rgb), .10), rgba(var(--bs-primary-rgb), .02));
  box-shadow: 0 4px 12px -4px rgba(var(--bs-primary-rgb), .25);
}
.rb-source-card i.bi {
  font-size: 1.2rem;
  color: var(--bs-primary);
  margin-bottom: 4px;
}
.rb-source-label {
  font-size: .88rem; font-weight: 700;
  color: var(--bs-body-color);
  letter-spacing: -.01em;
}
.rb-source-desc {
  font-size: .72rem;
  color: var(--bs-secondary-color);
  line-height: 1.4;
}

/* Column chips */
.rb-columns {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding-bottom: 14px;
}
.rb-col-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
  cursor: pointer;
  font-size: .78rem; font-weight: 500;
  color: var(--bs-body-color);
  transition: all .12s;
}
.rb-col-chip input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0; height: 0;
}
.rb-col-chip::before {
  content: '';
  width: 14px; height: 14px;
  border-radius: 4px;
  border: 1.5px solid var(--bs-border-color);
  background: var(--tt-surface, #fff);
  transition: all .12s;
  flex-shrink: 0;
}
.rb-col-chip.active {
  background: rgba(var(--bs-primary-rgb), .10);
  border-color: rgba(var(--bs-primary-rgb), .35);
  color: var(--bs-primary);
  font-weight: 600;
}
.rb-col-chip.active::before {
  background: var(--bs-primary);
  border-color: var(--bs-primary);
  box-shadow: inset 0 0 0 2px var(--tt-surface, #fff), inset 0 0 0 4px var(--bs-primary);
}
.rb-col-chip:hover {
  border-color: var(--bs-secondary-color);
}

/* Filters grid */
.rb-filters-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  padding-bottom: 14px;
}
.rb-filter-field { display: flex; flex-direction: column; gap: 4px; }
.rb-filter-field label {
  font-size: .7rem; font-weight: 700;
  color: var(--bs-secondary-color);
  letter-spacing: .04em; text-transform: uppercase;
  margin: 0;
}
.rb-filter-field input,
.rb-filter-field select {
  padding: 6px 10px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
  font-size: .82rem;
  color: var(--bs-body-color);
  font-family: inherit;
}
.rb-filter-field input:focus,
.rb-filter-field select:focus {
  outline: 0;
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .15);
}

/* Preview */
.rb-preview-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.rb-preview-meta {
  font-size: .72rem;
  color: var(--bs-secondary-color);
  font-feature-settings: 'tnum';
  font-weight: 600;
  padding: 3px 8px;
  background: var(--bs-tertiary-bg);
  border-radius: 999px;
}
.rb-preview {
  padding-bottom: 14px;
}
.rb-preview-table-wrap {
  border: 1px solid var(--bs-border-color);
  border-radius: 10px;
  overflow: auto;
  max-height: 320px;
  background: var(--tt-surface, #fff);
}
.rb-preview-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .78rem;
}
.rb-preview-table thead th {
  position: sticky; top: 0;
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  font-size: .68rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 8px 10px;
  border-bottom: 1px solid var(--bs-border-color);
  text-align: left;
  z-index: 1;
}
.rb-preview-table tbody td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--bs-border-color);
  color: var(--bs-body-color);
  white-space: nowrap;
}
.rb-preview-table tbody tr:last-child td { border-bottom: 0; }
.rb-preview-table tbody tr:hover { background: rgba(var(--bs-primary-rgb), .04); }
.rb-preview-more {
  margin-top: 6px;
  font-size: .7rem;
  color: var(--bs-secondary-color);
  font-style: italic;
}
.rb-empty {
  padding: 28px 16px;
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: .82rem;
  background: var(--bs-tertiary-bg);
  border: 1px dashed var(--bs-border-color);
  border-radius: 10px;
}
.rb-empty i {
  display: block;
  font-size: 2rem;
  opacity: .4;
  margin-bottom: 6px;
}

/* Footer */
.rb-footer {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 16px 28px;
  border-top: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg, rgba(0,0,0,.02));
  position: sticky; bottom: 0;
}
.rb-name-input {
  flex: 1; min-width: 200px;
  font-size: .85rem;
}
.rb-footer-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.rb-footer-actions .btn { font-weight: 600; }

@media (max-width: 575.98px) {
  .rb-overlay { padding: 0 !important; align-items: flex-end !important; }
  .rb-modal {
    max-width: 100%; max-height: 95vh;
    border-radius: 18px 18px 0 0;
    transform: translateY(100%);
    padding-top: 24px;
  }
  .rb-overlay.show .rb-modal { transform: translateY(0); }
  .rb-modal::before {
    content: '';
    position: absolute;
    top: 10px; left: 50%;
    width: 44px; height: 4px;
    background: var(--bs-secondary-color);
    opacity: .35;
    border-radius: 2px;
    transform: translateX(-50%);
  }
  .rb-header { padding: 18px 18px 14px; }
  .rb-section { padding: 14px 18px 4px; }
  .rb-footer { padding: 12px 18px; }
  .rb-source-grid { grid-template-columns: 1fr 1fr; }
  .rb-name-input { min-width: 0; }
  .rb-footer-actions { width: 100%; justify-content: stretch; }
  .rb-footer-actions .btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .rb-modal { transition: opacity .12s; transform: none; }
}

/* ============================================================
   29) NPS WIDGET (nps.js) — feedback no-intrusivo bottom-right
   ------------------------------------------------------------
   Card flotante con 3 etapas (score 0-10 / comment / thanks).
   Posicionada por encima del HelpCenter+SetupChecklist FABs.
   Theme-aware via vars del tema activo.
   ============================================================ */
.nps-card {
  position: fixed;
  right: 24px; bottom: 24px;
  width: 360px; max-width: calc(100vw - 32px);
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 14px;
  box-shadow:
    0 24px 56px -16px rgba(15,23,42,.40),
    0 8px 20px -8px rgba(15,23,42,.18),
    0 0 0 1px rgba(var(--bs-primary-rgb), .04);
  padding: 22px 22px 18px;
  z-index: 1059;
  opacity: 0; transform: translateY(20px) scale(.96);
  transition:
    opacity .25s var(--ease-out, cubic-bezier(0,0,.2,1)),
    transform .3s var(--ease-emph, cubic-bezier(.34,1.56,.64,1));
}
.nps-card.show { opacity: 1; transform: translateY(0) scale(1); }
.nps-card.leaving { opacity: 0; transform: translateY(20px) scale(.96); }
[data-bs-theme="dark"] .nps-card {
  background: var(--tt-surface-2, #131b2e);
  box-shadow:
    0 28px 64px -12px rgba(0,0,0,.7),
    0 8px 20px -8px rgba(0,0,0,.4);
}

.nps-close {
  position: absolute; top: 10px; right: 10px;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  background: transparent; border: 0;
  color: var(--bs-secondary-color);
  border-radius: 50%;
  cursor: pointer;
  font-size: .85rem;
  transition: all .12s;
}
.nps-close:hover {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
}

.nps-eyebrow {
  font-size: .68rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--bs-primary);
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: 6px;
}
.nps-title {
  font-size: .95rem; font-weight: 700;
  letter-spacing: -.015em;
  margin: 0 0 14px;
  color: var(--bs-body-color);
  line-height: 1.35;
  padding-right: 24px;
}

/* Score grid 0-10 */
.nps-score-grid {
  display: grid;
  grid-template-columns: repeat(11, 1fr);
  gap: 4px;
  margin-bottom: 6px;
}
.nps-score-btn {
  height: 32px;
  padding: 0;
  border: 1.5px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg);
  border-radius: 6px;
  font-size: .8rem; font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--bs-body-color);
  cursor: pointer;
  transition: all .12s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.nps-score-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px -2px rgba(0,0,0,.18);
}
.nps-score-btn.nps-score-detractor:hover {
  background: rgba(239,68,68,.14);
  border-color: #ef4444;
  color: #dc2626;
}
.nps-score-btn.nps-score-passive:hover {
  background: rgba(245,158,11,.14);
  border-color: #f59e0b;
  color: #d97706;
}
.nps-score-btn.nps-score-promoter:hover {
  background: rgba(16,185,129,.14);
  border-color: #10b981;
  color: #059669;
}
[data-bs-theme="dark"] .nps-score-btn.nps-score-detractor:hover { color: #fb7185; }
[data-bs-theme="dark"] .nps-score-btn.nps-score-passive:hover { color: #fbbf24; }
[data-bs-theme="dark"] .nps-score-btn.nps-score-promoter:hover { color: #34d399; }

.nps-score-legend {
  display: flex; justify-content: space-between;
  font-size: .68rem;
  color: var(--bs-secondary-color);
  font-weight: 500;
  margin-bottom: 14px;
  padding: 0 2px;
}

.nps-permanent-dismiss {
  display: block;
  margin: 0 auto;
  background: transparent;
  border: 0;
  color: var(--bs-secondary-color);
  font-size: .72rem;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  padding: 4px 8px;
}
.nps-permanent-dismiss:hover { color: var(--bs-body-color); }

/* Stage 2: comment */
.nps-selected-score {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 12px;
  padding: 8px 12px;
  background: var(--bs-tertiary-bg);
  border-radius: 8px;
}
.nps-selected-num {
  display: inline-grid; place-items: center;
  width: 36px; height: 36px;
  border-radius: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1rem; font-weight: 800;
}
.nps-selected-num.nps-score-detractor {
  background: rgba(239,68,68,.16); color: #dc2626;
}
.nps-selected-num.nps-score-passive {
  background: rgba(245,158,11,.16); color: #d97706;
}
.nps-selected-num.nps-score-promoter {
  background: rgba(16,185,129,.16); color: #059669;
}
[data-bs-theme="dark"] .nps-selected-num.nps-score-detractor { color: #fb7185; }
[data-bs-theme="dark"] .nps-selected-num.nps-score-passive { color: #fbbf24; }
[data-bs-theme="dark"] .nps-selected-num.nps-score-promoter { color: #34d399; }
.nps-selected-label {
  font-size: .82rem; font-weight: 700;
  color: var(--bs-body-color);
  letter-spacing: -.005em;
}

.nps-comment-title {
  margin-bottom: 10px;
  padding-right: 0;
  font-size: .9rem;
}
.nps-comment {
  width: 100%;
  padding: 10px 12px;
  background: var(--tt-surface, #fff);
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
  font-size: .82rem;
  font-family: inherit;
  color: var(--bs-body-color);
  resize: vertical;
  min-height: 70px;
  margin-bottom: 12px;
}
.nps-comment:focus {
  outline: 0;
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .15);
}
[data-bs-theme="dark"] .nps-comment {
  background: var(--tt-surface-2, #131b2e);
}

.nps-comment-actions {
  display: flex; justify-content: space-between; gap: 8px;
}
.nps-comment-actions .btn { font-size: .78rem; padding: .35rem .8rem; font-weight: 600; }

/* Stage 3: thanks */
.nps-stage-thanks {
  text-align: center;
  padding: 12px 0 6px;
}
.nps-thanks-icon {
  font-size: 2.4rem;
  color: #ef4444;
  margin-bottom: 8px;
  animation: npsHeartBeat 1.2s ease-in-out 1;
}
@keyframes npsHeartBeat {
  0%, 100% { transform: scale(1); }
  20%, 60% { transform: scale(1.18); }
  40%, 80% { transform: scale(.94); }
}
.nps-thanks-msg {
  font-size: .82rem;
  color: var(--bs-secondary-color);
  margin: 0;
  line-height: 1.5;
}

/* Mobile: card full-width inferior */
@media (max-width: 575.98px) {
  .nps-card {
    right: 12px; left: 12px; bottom: 12px;
    width: auto; max-width: none;
    padding: 18px 18px 14px;
  }
  .nps-score-btn { height: 28px; font-size: .72rem; }
  .nps-score-grid { gap: 3px; }
}
@media (max-width: 991.98px) {
  /* Subir el NPS card por encima del bottom-nav y del HelpCenter mobile */
  .nps-card { bottom: 132px; }
}

/* Focus-visible para accesibilidad */
.nps-score-btn:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .35);
  border-color: var(--bs-primary);
}
.nps-close:focus-visible,
.nps-permanent-dismiss:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .25);
}
@media (prefers-reduced-motion: reduce) {
  .nps-card { transition: opacity .15s; transform: none; }
  .nps-thanks-icon { animation: none; }
}

/* ============================================================
   PREMIUM POLISH v1.0 — Refinamiento final de la UI
   ============================================================
   Bloque añadido en la primera versión estable. Aplica polish
   sutil sobre el sistema de diseño existente para conseguir
   "premium SaaS feel" sin reescribir lo anterior.

   Se anexa AL FINAL del archivo para sobrescribir defaults
   solo donde queremos refinar (cascade order natural).
   ============================================================ */

/* ── Sombras refinadas (más sutiles, más elegantes) ────────── */
:root {
  --tt-shadow-glass: 0 8px 32px -4px rgba(15, 23, 42, .08), 0 2px 8px -2px rgba(15, 23, 42, .04);
  --tt-shadow-elevation-1: 0 1px 2px rgba(15, 23, 42, .05), 0 1px 1px rgba(15, 23, 42, .03);
  --tt-shadow-elevation-2: 0 4px 8px -2px rgba(15, 23, 42, .06), 0 2px 4px -2px rgba(15, 23, 42, .04);
  --tt-shadow-elevation-3: 0 12px 24px -8px rgba(15, 23, 42, .12), 0 4px 8px -4px rgba(15, 23, 42, .04);
  --tt-shadow-glow-primary: 0 0 0 4px rgba(99, 102, 241, .12);
  --tt-blur-glass: saturate(180%) blur(12px);
}

[data-bs-theme="dark"] {
  --tt-shadow-glass: 0 8px 32px -4px rgba(0, 0, 0, .4), 0 2px 8px -2px rgba(0, 0, 0, .25);
  --tt-shadow-elevation-1: 0 1px 2px rgba(0, 0, 0, .3);
  --tt-shadow-elevation-2: 0 4px 8px -2px rgba(0, 0, 0, .35);
  --tt-shadow-elevation-3: 0 12px 24px -8px rgba(0, 0, 0, .5);
  --tt-shadow-glow-primary: 0 0 0 4px rgba(129, 140, 248, .18);
}

/* ── Cards con elevación premium en hover ──────────────────── */
.card-soft,
.card.card-soft,
.kpi {
  transition: transform .2s cubic-bezier(.4,0,.2,1),
              box-shadow .2s cubic-bezier(.4,0,.2,1),
              border-color .2s ease;
}
.card-soft:hover,
.card.card-soft:hover {
  box-shadow: var(--tt-shadow-elevation-2);
  border-color: rgba(var(--bs-primary-rgb), .15);
}

/* ── Botones primarios con micro-interaction ───────────────── */
.btn-primary {
  position: relative;
  transition: transform .12s cubic-bezier(.4,0,.2,1),
              box-shadow .15s ease;
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: var(--tt-shadow-elevation-2);
}
.btn-primary:active {
  transform: translateY(0);
  box-shadow: var(--tt-shadow-elevation-1);
}

/* ── Focus ring premium accesible (WCAG AA) ────────────────── */
button:focus-visible,
a:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--tt-shadow-glow-primary);
  border-color: var(--bs-primary);
  z-index: 2;
}

/* ── Glass effect en elementos flotantes (dropdowns, toasts) ─ */
.dropdown-menu.show,
.tt-toast,
.command-palette,
.help-center-panel.open {
  backdrop-filter: var(--tt-blur-glass);
  -webkit-backdrop-filter: var(--tt-blur-glass);
}

/* ── Toast premium con animación elástica ──────────────────── */
.tt-toast {
  box-shadow: var(--tt-shadow-elevation-3);
  border: 1px solid rgba(var(--bs-primary-rgb), .08);
  transform: translateX(120%) scale(.96);
  opacity: 0;
  transition: transform .35s cubic-bezier(.34, 1.56, .64, 1),
              opacity .25s ease;
}
.tt-toast.show {
  transform: translateX(0) scale(1);
  opacity: 1;
}
.tt-toast.leaving {
  transform: translateX(120%) scale(.96);
  opacity: 0;
}

/* ── Skeleton loading premium (en vez de spinner básico) ───── */
.skeleton {
  background: linear-gradient(90deg,
    rgba(var(--bs-secondary-rgb, 100, 116, 139), .08) 0%,
    rgba(var(--bs-secondary-rgb, 100, 116, 139), .15) 50%,
    rgba(var(--bs-secondary-rgb, 100, 116, 139), .08) 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
  border-radius: var(--tt-radius-sm);
}
@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Sidebar links con animación de subrayado ──────────────── */
.sidebar nav a {
  position: relative;
  transition: background .2s ease, color .2s ease;
}
.sidebar nav a::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%) scaleY(0);
  width: 3px;
  height: 24px;
  background: var(--bs-primary);
  border-radius: 0 3px 3px 0;
  transition: transform .2s cubic-bezier(.4,0,.2,1);
}
.sidebar nav a.active::before,
.sidebar nav a:hover::before {
  transform: translateY(-50%) scaleY(1);
}

/* ── Inputs premium con focus suave ────────────────────────── */
.form-control,
.form-select {
  transition: border-color .15s ease, box-shadow .15s ease;
}

/* ── KPI cards: contraste mejorado del valor ───────────────── */
.kpi .value {
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}

/* ── Empty states premium (sin gráficos pesados) ───────────── */
.empty-state {
  padding: 2.5rem 1.5rem;
  text-align: center;
  color: var(--bs-secondary-color);
}
.empty-state .empty-icon {
  font-size: 3rem;
  opacity: .3;
  margin-bottom: 1rem;
  color: var(--bs-secondary-color);
}
.empty-state .empty-title {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--bs-body-color);
  margin-bottom: .25rem;
}
.empty-state .empty-desc {
  font-size: .875rem;
  max-width: 320px;
  margin: 0 auto;
}

/* ── Mejor contraste en dark mode para placeholders ────────── */
[data-bs-theme="dark"] ::placeholder { opacity: .55; }

/* ── Selección de texto premium ────────────────────────────── */
::selection {
  background: rgba(var(--bs-primary-rgb), .25);
  color: var(--bs-body-color);
}

/* ── Scrollbar premium consistente light/dark ──────────────── */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(100, 116, 139, .25) transparent;
}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: rgba(100, 116, 139, .25);
  border-radius: 8px;
  transition: background .2s ease;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(100, 116, 139, .45); }

/* ── Modal premium: header sin border, sombra suave ────────── */
.modal-content {
  box-shadow: var(--tt-shadow-elevation-3);
}
.modal-header.border-0 + .modal-body { padding-top: 0; }

/* ── Reduce motion: respeta preferencia del usuario ────────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Print: ocultar elementos UI no relevantes ─────────────── */
@media print {
  .sidebar, .bottom-nav, .help-center-fab, .help-center-panel,
  .tt-toast-host, .setup-fab, .nps-widget, .command-palette,
  .btn, .dropdown { display: none !important; }
  body { background: #fff !important; }
  .content { padding: 0 !important; }
}

/* ============================================================
   DESKTOP REDESIGN v1.0.8 — modern SaaS, professional UI/UX
   Aplicable principalmente a >=1200px (sin afectar mobile/tablet).
   Incluye fix global del badge .plan-lock-badge en btn-sm.
   ============================================================ */

/* ── A) Fix universal: .plan-lock-badge no debe desbordar
       botones pequeños (btn-sm o dentro de btn-group-sm).
       Root cause del PDF squished que reportaste.            ── */
.btn-sm.plan-locked .plan-lock-badge,
.btn-group-sm > .plan-locked .plan-lock-badge,
.btn-group-sm .btn.plan-locked .plan-lock-badge {
  /* Reemplaza badge "Pro + lock" gordo por punto-candado compacto */
  top: -5px;
  right: -5px;
  width: 16px;
  height: 16px;
  padding: 0;
  gap: 0;
  font-size: 0;          /* oculta texto "Pro"/"Enterprise" */
  letter-spacing: 0;
  border: 2px solid var(--bs-body-bg, #fff);
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
  color: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.2);
  border-radius: 50%;
}
.btn-sm.plan-locked .plan-lock-badge i,
.btn-group-sm > .plan-locked .plan-lock-badge i,
.btn-group-sm .btn.plan-locked .plan-lock-badge i {
  font-size: .58rem;
  line-height: 1;
  margin: 0;
}
/* En contextos compactos, .plan-locked filter desatura demasiado */
.btn-sm.plan-locked,
.btn-group-sm > .plan-locked,
.btn-group-sm .btn.plan-locked {
  filter: opacity(.88);
}
/* Dark theme: borde del badge */
[data-bs-theme="dark"] .btn-sm.plan-locked .plan-lock-badge,
[data-bs-theme="dark"] .btn-group-sm > .plan-locked .plan-lock-badge,
[data-bs-theme="dark"] .btn-group-sm .btn.plan-locked .plan-lock-badge {
  border-color: var(--tt-surface, #131b2e);
}

/* ── B) Fix universal: btn-group con icono+texto en section-header
       — evita squish horizontal cuando el viewport es justo.    ── */
.section-header .actions .btn-group .btn {
  min-width: 56px;
  white-space: nowrap;
}
.section-header .actions .btn-group .btn > .bi {
  flex-shrink: 0;
}

/* ============================================================
   DESKTOP ONLY (>=1200px) — premium SaaS polish
   ============================================================ */
@media (min-width: 1200px) {

  /* ── 1) Section header: jerarquía visual + breathing room ── */
  .content .section-header {
    align-items: flex-end;
    gap: 24px;
    margin-bottom: 24px;
    padding-bottom: 2px;
  }
  .content .section-title {
    font-size: 1.5rem;
    letter-spacing: -.025em;
    line-height: 1.2;
  }
  .content .section-sub {
    font-size: .9375rem;
    margin-top: 4px;
    color: var(--bs-secondary-color);
  }
  .content .section-header .actions { gap: 10px; }
  .content .section-header .actions .btn {
    font-size: .875rem;
    padding: .5rem .9rem;
  }
  .content .section-header .actions .btn-sm {
    padding: .45rem .8rem;
    font-size: .8125rem;
    border-radius: 8px;
  }
  /* btn-group dentro de actions: cada botón con respiración */
  .content .section-header .actions .btn-group .btn {
    padding: .45rem .75rem;
    font-size: .8125rem;
  }
  .content .section-header .actions .btn-group .btn .bi {
    margin-right: 2px;
  }

  /* ── 2) Filtros (toolbar) tipo "filter chip bar" ─────── */
  /* Match cualquier sección con un flex de filtros .d-flex.gap-2.mb-3 */
  .content > section > .d-flex.flex-wrap.mb-3,
  .content > section > .d-flex.gap-2.mb-3 {
    background: var(--tt-surface, var(--bs-body-bg));
    border: 1px solid var(--bs-border-color);
    border-radius: var(--tt-radius, 12px);
    padding: 12px 16px;
    margin-bottom: 16px !important;
    box-shadow: var(--tt-shadow-xs, 0 1px 2px rgba(0,0,0,.04));
    gap: 12px !important;
    align-items: center;
  }
  .content > section > .d-flex.flex-wrap.mb-3 > .form-control-sm,
  .content > section > .d-flex.flex-wrap.mb-3 > .form-select-sm,
  .content > section > .d-flex.gap-2.mb-3 > .form-control-sm,
  .content > section > .d-flex.gap-2.mb-3 > .form-select-sm {
    height: 38px;
    font-size: .875rem;
    border-color: transparent;
    background: var(--bs-tertiary-bg);
    transition: all .15s var(--ease-out, cubic-bezier(0,0,.2,1));
  }
  .content > section > .d-flex.flex-wrap.mb-3 > .form-control-sm:focus,
  .content > section > .d-flex.flex-wrap.mb-3 > .form-select-sm:focus,
  .content > section > .d-flex.gap-2.mb-3 > .form-control-sm:focus,
  .content > section > .d-flex.gap-2.mb-3 > .form-select-sm:focus {
    background: var(--bs-body-bg);
    border-color: rgba(var(--bs-primary-rgb), .4);
    box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .12);
    outline: 0;
  }

  /* ── 3) Tablas: padding cómodo, sticky head, hover sutil ── */
  .content .table-wrap {
    border-radius: 12px;
    box-shadow: var(--tt-shadow-xs, 0 1px 2px rgba(0,0,0,.04));
  }
  .content .table-wrap thead th {
    padding: .875rem 1rem;
    font-size: .7rem;
    letter-spacing: .06em;
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bs-tertiary-bg);
  }
  .content .table-wrap tbody td {
    padding: .875rem 1rem;
    font-size: .875rem;
    vertical-align: middle;
  }
  /* Acciones de fila: botones cuadrados pill-style */
  .content .table-wrap tbody .btn-light,
  .content .table-wrap tbody .btn-outline-secondary {
    width: 32px;
    height: 32px;
    padding: 0;
    display: inline-grid;
    place-items: center;
    border-radius: 8px;
    margin-left: 4px;
    transition:
      background .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
      transform .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
      box-shadow .15s var(--ease-out, cubic-bezier(0,0,.2,1));
  }
  .content .table-wrap tbody .btn-light:hover {
    background: rgba(var(--bs-primary-rgb), .1);
    color: var(--bs-primary);
    transform: translateY(-1px);
    box-shadow: 0 2px 6px rgba(0,0,0,.08);
  }
  .content .table-wrap tbody .btn-light.text-danger:hover {
    background: rgba(239,68,68,.1);
    color: #dc2626 !important;
  }

  /* ── 4) Sección EMPLEADOS específica ─────────────────── */
  #sec-empleados #empSearch {
    max-width: 360px !important;
  }
  #sec-empleados #empDept,
  #sec-empleados #empActive {
    max-width: 240px !important;
  }
  /* Avatar+name column: más espacio */
  #sec-empleados .table-wrap tbody td:nth-child(2) {
    min-width: 260px;
    padding-left: 1rem;
  }
  #sec-empleados .table-wrap tbody td:nth-child(2) .avatar {
    width: 36px;
    height: 36px;
    font-size: .85rem;
    flex-shrink: 0;
  }
  #sec-empleados .table-wrap tbody td:nth-child(2) .fw-semibold {
    font-size: .9rem;
    color: var(--bs-body-color);
  }
  #sec-empleados .table-wrap tbody td:nth-child(2) .text-muted.small {
    font-size: .75rem;
    margin-top: 1px;
  }
  /* Status badges: pill más limpio en desktop */
  #sec-empleados .status-badge {
    font-size: .7rem;
    padding: 3px 10px;
    font-weight: 600;
  }
  /* Última columna (acciones): alineada y separada */
  #sec-empleados .table-wrap tbody td:last-child {
    padding-right: 1rem;
    white-space: nowrap;
  }

  /* ── 5) Sección JORNADAS: actions con btn-group sin squish ── */
  #sec-jornadas .section-header .actions {
    flex-wrap: wrap;
    gap: 10px;
  }
  #sec-jornadas .section-header .actions > .form-control-sm,
  #sec-jornadas .section-header .actions > .form-select-sm {
    height: 38px;
    font-size: .875rem;
    background: var(--bs-tertiary-bg);
    border-color: transparent;
    border-radius: 8px;
  }
  #sec-jornadas .section-header .actions > .btn-group .btn {
    min-width: 72px;
    padding: .5rem .85rem;
    font-size: .8125rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: 8px;
  }
  /* En grupo, mantiene radius solo en los extremos */
  #sec-jornadas .section-header .actions > .btn-group .btn:not(:first-child):not(:last-child) {
    border-radius: 0;
  }
  #sec-jornadas .section-header .actions > .btn-group .btn:first-child {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
  }
  #sec-jornadas .section-header .actions > .btn-group .btn:last-child {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
  }

  /* ── 6) Bulk bar: alineado al estilo filtros ──────────── */
  .content .bulk-bar {
    border-radius: 10px;
    margin-bottom: 12px;
    box-shadow: var(--tt-shadow-xs, 0 1px 2px rgba(0,0,0,.04));
  }

  /* ── 7) Form controls focus ring premium ──────────────── */
  .content .form-control:focus,
  .content .form-select:focus {
    border-color: rgba(var(--bs-primary-rgb), .4);
    box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .12);
  }

  /* ── 8) Cards & contenedores: radius consistente ─────── */
  .content .card,
  .content .card-soft {
    border-radius: 12px;
  }

  /* ── 9) Status badges (global): font tabular para legibilidad ── */
  .content .status-badge {
    font-variant-numeric: tabular-nums;
  }

  /* ── 10) Empty state: más generoso en desktop ─────────── */
  .content .empty {
    padding: 64px 24px;
    gap: 8px;
  }
  .content .empty > .bi,
  .content .empty > i.bi {
    font-size: 3rem;
    color: var(--bs-secondary-color);
    opacity: .5;
  }
}

/* ============================================================
   ULTRA-WIDE (>=1400px) — mega breathing room
   ============================================================ */
@media (min-width: 1400px) {
  .content { padding: 32px 40px; }
  .content .section-header { gap: 32px; margin-bottom: 28px; }
  .content .section-title { font-size: 1.625rem; }
  #sec-empleados .table-wrap tbody td { padding: 1rem 1.125rem; }
  #sec-empleados .table-wrap tbody td:nth-child(2) { min-width: 300px; }
}

/* ============================================================
   END PREMIUM POLISH v1.0.8 (Desktop SaaS redesign)
   ============================================================ */

/* ════════════════════════════════════════════════════════════════
   UNIFICATION LAYER v2.0 — Premium SaaS Consistency (May 15 2026)
   ----------------------------------------------------------------
   Pase final del cascade que armoniza el lenguaje visual entre TODAS
   las secciones (Dashboard, Empleados, Jornadas, Ausencias, Reportes,
   Compliance, DevOps, Configuración, Talent, Marketplace, etc.). Se
   carga después de las capas anteriores (v3.44.0 Premium + v1.0.8
   Desktop SaaS) por lo que gana el cascade donde aplica.

   Filosofía: refuerza tokens compartidos (radius, shadow, surface,
   focus ring, hover lift) sin redefinir variantes específicas. Cada
   sección puede seguir teniendo overrides locales — esta capa solo
   garantiza el "tronco común" del sistema de diseño.

   No remueve nada. Todas las reglas aquí son ADITIVAS.
   ════════════════════════════════════════════════════════════════ */

/* ── 1) Surfaces · jerarquía de elevación uniforme ─────────────
   Cards de contenido (card-soft, .card, .kpi) viven en superficie
   plana con border. Modales y dropdowns suben de tier (shadow-md/lg).
   Asegura que NO haya backgrounds que coincidan con el body bg. */
.card-soft,
.card,
.kpi,
.modal-content,
.dropdown-menu,
.popover {
  background-color: var(--tt-surface);
  border-color: var(--bs-border-color);
}

/* ── 2) Border-radius scale uniforme (tier system) ─────────────
   inputs/buttons → sm (10px); cards/KPIs/tables → md (14px);
   modals/dropdowns → lg (18px). Esto evita los radius "random" que
   van apareciendo en componentes nuevos. */
.kpi,
.card-soft,
.table-wrap,
.list-group,
.alert {
  border-radius: var(--tt-radius);
}
.modal-content {
  border-radius: var(--tt-radius-lg);
}
.dropdown-menu,
.popover,
.tooltip-inner {
  border-radius: var(--tt-radius);
}
.btn,
.form-control,
.form-select,
.input-group > .form-control,
.input-group > .form-select {
  border-radius: var(--tt-radius-sm);
}

/* ── 3) Section header · spacing & tipografía consistente ──────
   Todas las secciones admin usan .section-header como contenedor.
   Aquí garantizamos breathing room uniforme y jerarquía tipográfica
   alineada con la escala premium (h6→title→sub). */
.content .section-header {
  margin-bottom: 20px;
  gap: 16px;
}
@media (min-width: 992px) {
  .content .section-header { margin-bottom: 24px; gap: 20px; }
}
.content .section-title {
  font-weight: 700;
  letter-spacing: -.025em;
  line-height: 1.25;
}
.content .section-sub {
  font-weight: 500;
  line-height: 1.5;
  color: var(--bs-secondary-color);
  font-size: .8125rem;
}
@media (min-width: 768px) {
  .content .section-sub { font-size: .875rem; }
}

/* ── 4) KPI · proporciones idénticas en todas las secciones ────
   El sistema KPI ya está bien definido, pero hay secciones que aplican
   inline styles. Aquí re-aseguramos las invariantes:
     · label en uppercase + tracking
     · value en tabular-nums + nowrap
     · icon flex-shrink:0 para no deformarse */
.kpi {
  transition: transform .15s var(--ease-out, cubic-bezier(0,0,.2,1)),
              box-shadow .15s var(--ease-out, cubic-bezier(0,0,.2,1));
}
.kpi .icon {
  flex-shrink: 0;
}
.kpi .label {
  text-transform: uppercase;
  letter-spacing: .04em;
  font-weight: 600;
  color: var(--bs-secondary-color);
}
.kpi .value {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  letter-spacing: -.025em;
}

/* ── 5) Sub-navigation · UNDERLINE TABS uniformes en TODA la app ───
   Decisión de diseño (May 15 2026): el patrón "underline tabs" (Linear,
   Stripe, Factorial, Personio) es el premium SaaS estándar. Se aplica
   globalmente a:
     · .nav-tabs (Compliance, DevOps, Gastos, Talent…) — ya usaban underline
     · .cfg-subnav (Configuración) — refactorizado de filled-pills
     · .nav-pills-sm (Jornadas) — refactorizado de filled-pills
     · .abs-scope-tabs (Ausencias) — refactorizado de filled-pills
     · cualquier .nav-pills genérico de app.html/admin.html
       (myExpTabs, mySwapsTabs, myEvalsTabs, myRefTabs, myGoalsTabs,
        myPulseTabs, atsTabs) — sustituye el filled-pill por defecto
        de Bootstrap.

   Características compartidas:
     · sin background-fill en activo (solo texto primary + border-bottom 2px)
     · hover sutil sin fondo (cambia color a body-color)
     · padding consistente .5rem .9rem en desktop, .4rem .65rem en mobile
     · letter-spacing -.005em + font-weight 600 + font-size .8125rem
     · transición .15s en color + border-color (no transform, no shadow)
     · border-radius: 0 (sustituye el pill 999px de Bootstrap)
     · margin-bottom: -2px para que el underline solape el border del wrapper
*/
.nav-tabs {
  border-bottom: 1px solid var(--bs-border-color);
}

/* GLOBAL OVERRIDE: convertir cualquier .nav-pills NO marcado explícitamente
   como filter-chip al patrón underline. Esto cubre todos los sub-tabs de
   app.html/admin.html sin tener que tocar el HTML. Si alguna vez se
   necesita un filter-pill real, añadir clase .nav-pills-filled como
   opt-in y excluirla con :not(.nav-pills-filled). */
.nav-pills:not(.nav-pills-filled) {
  gap: 0;
  border-bottom: 2px solid var(--bs-border-color);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.nav-pills:not(.nav-pills-filled)::-webkit-scrollbar {
  display: none;
}
.nav-pills:not(.nav-pills-filled) .nav-link {
  border-radius: 0;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--bs-secondary-color);
  font-weight: 600;
  font-size: .8125rem;
  letter-spacing: -.005em;
  padding: .5rem .9rem;
  margin-bottom: -2px;
  white-space: nowrap;
  flex-shrink: 0;
  box-shadow: none;
  transition: color .15s, border-color .15s;
}
.nav-pills:not(.nav-pills-filled) .nav-link:hover {
  background: transparent;
  color: var(--bs-body-color);
  border-color: transparent;
}
.nav-pills:not(.nav-pills-filled) .nav-link.active,
.nav-pills:not(.nav-pills-filled) .show > .nav-link {
  background: transparent !important;     /* sobrescribe filled-pill default de Bootstrap */
  color: var(--bs-primary) !important;
  border-bottom-color: var(--bs-primary);
  box-shadow: none;
}
.nav-pills:not(.nav-pills-filled) .nav-link.active .badge,
.nav-pills:not(.nav-pills-filled) .show > .nav-link .badge {
  /* Badges en tab activo mantienen tinte primario suave para legibilidad */
  background: rgba(var(--bs-primary-rgb), .15) !important;
  color: var(--bs-primary) !important;
}
@media (max-width: 575.98px) {
  .nav-pills:not(.nav-pills-filled) .nav-link { padding: .4rem .65rem; font-size: .75rem; }
}

/* Tema oscuro: border-bottom usa el border-color sutil propio del tema */
[data-bs-theme="dark"] .nav-pills:not(.nav-pills-filled) {
  border-bottom-color: var(--bs-border-color);
}

/* ── 6) Forms · focus ring premium uniforme ────────────────────
   Reemplaza el focus ring default de Bootstrap por uno consistente
   en TODO input (no solo dentro de .content). Mismo halo en modales,
   dropdowns con inputs, sub-navs con searchbox, etc. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: rgba(var(--bs-primary-rgb), .5);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .12);
  outline: 0;
}
.form-check-input:checked {
  background-color: var(--bs-primary);
  border-color: var(--bs-primary);
}

/* ── 7) Buttons · hover lift uniforme + focus visible ──────────
   Cualquier .btn no disabled obtiene el sutil "translateY(-1px)" en
   hover (excepto .btn-link y .btn-icon que tienen su propio sistema).
   Garantiza que el feel táctil sea consistente entre Dashboard,
   Configuración, Compliance, etc. */
.btn:not(:disabled):not(.btn-link):not(.btn-icon):hover {
  transform: translateY(-1px);
}
.btn:not(:disabled):not(.btn-link):not(.btn-icon):active {
  transform: translateY(0);
  transition-duration: .05s;
}
.btn:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 2px;
}

/* ── 8) Modals · elevación máxima + animación de entrada ───────
   Todos los modales (legacy y nuevos) comparten misma elevación,
   borde, animación. Evita que ciertos modales se vean "planos" o
   "sin sombra" en algunas secciones. */
.modal-content {
  border: 1px solid var(--bs-border-color);
  box-shadow: var(--tt-shadow-lg);
}
.modal-backdrop.show {
  opacity: .55;
}

/* ── 9) Dropdowns · elevación tier-2 ───────────────────────────
   Por debajo de modal-content pero por encima de cards/tables. */
.dropdown-menu {
  border: 1px solid var(--bs-border-color);
  box-shadow: var(--tt-shadow-md);
  padding: .375rem;
}
.dropdown-item {
  border-radius: var(--tt-radius-sm);
  padding: .5rem .75rem;
  font-size: .8125rem;
  font-weight: 500;
  transition: background-color var(--tt-transition);
}
.dropdown-item:hover {
  background-color: rgba(var(--bs-primary-rgb), .08);
  color: var(--bs-primary);
}
.dropdown-divider {
  margin: .375rem 0;
  border-top-color: var(--bs-border-color);
}

/* ── 10) Empty states · consolidar .empty y .empty-state ──────
   Históricamente hay dos clases para "no hay datos": `.empty` (legacy)
   y `.empty-state` (premium). Aquí se aseguran proporciones y tono
   visual idénticos para que el usuario no perciba dos sistemas. */
.empty,
.empty-state {
  text-align: center;
  color: var(--bs-secondary-color);
  padding: 3rem 1.5rem;
}
@media (min-width: 992px) {
  .empty,
  .empty-state { padding: 4rem 2rem; }
}
.empty .title,
.empty-state .empty-title {
  font-weight: 700;
  color: var(--bs-body-color);
  margin-bottom: 4px;
  font-size: .9375rem;
}
.empty .subtitle,
.empty-state .empty-desc {
  font-size: .8125rem;
  max-width: 320px;
  margin: 0 auto;
  line-height: 1.5;
}

/* ── 11) Badges · tipografía + padding consistente ────────────
   Pill badges (.rounded-pill) usadas en headers y status badges.
   Mismo peso, mismo tracking, mismo padding horizontal. */
.badge {
  font-weight: 600;
  font-size: .6875rem;
  letter-spacing: .02em;
  padding: .35em .6em;
  font-feature-settings: 'tnum' on;
}
.badge.rounded-pill {
  padding: .35em .8em;
}
.badge.bg-primary-subtle,
.badge.bg-success-subtle,
.badge.bg-warning-subtle,
.badge.bg-danger-subtle,
.badge.bg-info-subtle,
.badge.bg-secondary-subtle {
  font-weight: 700;
}

/* ── 12) Form labels · tipografía consistente ─────────────────
   Todos los <label class="form-label"> usan misma jerarquía. */
.form-label {
  font-weight: 600;
  font-size: .75rem;
  color: var(--bs-body-color);
  margin-bottom: 6px;
  letter-spacing: .01em;
}
.form-text {
  font-size: .75rem;
  color: var(--bs-secondary-color);
  line-height: 1.45;
}

/* ── 13) Alerts · tipografía + radius consistente ─────────────
   Las alertas dentro de cards (config, settings, modales) deben tener
   el mismo tamaño + radius que el resto de la UI. */
.alert {
  font-size: .8125rem;
  line-height: 1.5;
  padding: .75rem 1rem;
  border-radius: var(--tt-radius);
  border: 1px solid transparent;
}
.alert.py-2 { padding-top: .5rem !important; padding-bottom: .5rem !important; }

/* ── 14) Tooltips · misma tipografía + radius ────────────────── */
.tooltip-inner {
  font-size: .75rem;
  padding: .4rem .65rem;
  font-weight: 500;
  letter-spacing: -.005em;
  box-shadow: var(--tt-shadow-md);
  max-width: 280px;
}

/* ── 15) Tables · refinamiento final ──────────────────────────
   Todas las tablas dentro de .table-wrap o table-responsive comparten
   espaciado de celdas, color de header y zebra hover. */
.table-wrap {
  box-shadow: var(--tt-shadow-xs);
}
.table thead th {
  font-weight: 600;
  font-size: .6875rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
}
.table tbody td {
  vertical-align: middle;
}

/* ── 16) Sticky topbar · backdrop blur premium ───────────────
   Topbar y headers de modal usan blur consistente. */
.topbar,
.modal-header {
  backdrop-filter: saturate(180%) blur(8px);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
}

/* ── 17) Container padding consistency ───────────────────────
   Asegura que main content area tiene padding uniforme en todos los
   breakpoints, incluso si una sección lo intenta sobrescribir. */
.content {
  padding: 16px;
}
@media (min-width: 768px) { .content { padding: 24px 28px; } }
@media (min-width: 1200px) { .content { padding: 28px 32px; } }
@media (min-width: 1400px) { .content { padding: 32px 40px; } }

/* ── 18) FAB / floating action button · consistent placement ──
   Help center, what's new, etc. siempre flotan en bottom-right con
   margen consistente. La regla `.content { padding-bottom: 88px }`
   en desktop (definida arriba) garantiza que no tapan contenido. */
.fab-stack,
.help-center-fab,
.whats-new-fab {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1040;
}
@media (max-width: 991.98px) {
  .fab-stack,
  .help-center-fab,
  .whats-new-fab {
    bottom: 80px; /* sobre la bottom-nav móvil */
  }
}

/* ── 19) Dark mode reforzamientos ─────────────────────────────
   En dark, las superficies deben tener border más visible para
   mantener jerarquía sin shadows fuertes (que se pierden en oscuro). */
[data-bs-theme="dark"] .card-soft,
[data-bs-theme="dark"] .card,
[data-bs-theme="dark"] .kpi,
[data-bs-theme="dark"] .modal-content,
[data-bs-theme="dark"] .dropdown-menu {
  border-color: rgba(255, 255, 255, .08);
}
[data-bs-theme="dark"] .table thead th {
  color: var(--bs-secondary-color);
}

/* ── 20) Reduced motion · respeto a preferencias del usuario ──
   Cualquier transform/animation se desactiva cuando el usuario tiene
   prefers-reduced-motion: reduce. Las propiedades de color/border se
   mantienen para que el feedback visual no desaparezca. */
@media (prefers-reduced-motion: reduce) {
  .kpi:hover,
  .card-soft:hover,
  .btn:hover {
    transform: none !important;
  }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ════════════════════════════════════════════════════════════════
   END UNIFICATION LAYER v2.0
   ════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════
   v2.6.7 · FAB CLEARANCE (revisión 2 · 15-may-2026)
   ----------------------------------------------------------------
   Historial:
     v2.5.2 → padding-right: 88px en TODO `.content`  → franja
       vacía visible en desktop.  Demasiado agresivo.
     v2.6.1 → margin-right: 72px en `.table-wrap`     → cortaba la
       última columna ESTADO de tablas anchas (pill CERRADA / ACTIVO
       truncada al borde).  Demasiado.
     v2.6.7 → ESTRATEGIA FINAL: clearance vertical sólo.

   Vertical clearance (`padding-bottom: 88px`) ya existe en
   `.content` (rules previas) y es suficiente: si una tabla larga
   scrollea hasta abajo, las últimas filas quedan ABAJO de donde
   está el FAB (right:24px; bottom:84px).  Para tablas cortas
   (que no llegan al fondo), el FAB no las solapa porque está
   mucho más abajo.

   Trade-off aceptado: si una tabla acaba justo a la altura del
   FAB y a la derecha, el FAB podría tapar el botón Editar de la
   última fila visible.  Pero ese caso es raro Y el botón sigue
   siendo clickable via teclado/atajos.  Recuperamos el ancho
   horizontal completo para todas las tablas.
   ════════════════════════════════════════════════════════════════ */
/* (Sin reglas adicionales aquí — el `padding-bottom: 88px` en
   `.content` que vive en las reglas base es suficiente para
   evitar que el FAB tape contenido al hacer scroll al final.) */

/* ── Mobile (<992px): tablas anchas con scroll-x suave ────────
   La mayoría de tablas tienen 7+ columnas con white-space:nowrap.
   En narrow viewports Bootstrap `.table-responsive` añade scroll-x,
   pero faltaba:
     · momentum scroll iOS (`-webkit-overflow-scrolling: touch`)
     · indicación visual de “hay más → desliza”
     · evitar que las columnas con nowrap se aprieten cuando el
       contenedor es <max-content (Safari/iOS) */
@media (max-width: 991.98px) {
  .table-wrap > .table-responsive {
    -webkit-overflow-scrolling: touch;
    overflow-x: auto;
    /* Fade-shadow lateral derecho indicando scroll disponible.
       `local` background-attachment hace que la sombra se mueva
       con el scroll, desapareciendo al llegar al final. */
    background:
      linear-gradient(90deg,  var(--tt-surface) 30%, transparent) left center / 12px 100% no-repeat local,
      linear-gradient(-90deg, var(--tt-surface) 30%, transparent) right center / 12px 100% no-repeat local,
      radial-gradient(ellipse at 0%   50%, rgba(0,0,0,.10), transparent 70%) left center / 14px 100% no-repeat,
      radial-gradient(ellipse at 100% 50%, rgba(0,0,0,.10), transparent 70%) right center / 14px 100% no-repeat;
  }
  .table-wrap table {
    /* En viewports estrechos, deja que la tabla mida su contenido
       natural (max-content) en vez de comprimir columnas nowrap. */
    width: max-content;
    min-width: 100%;
  }
}
/* Dark theme: fade más sutil */
[data-bs-theme="dark"] .table-wrap > .table-responsive {
  background:
    linear-gradient(90deg,  var(--tt-surface) 30%, transparent) left center / 12px 100% no-repeat local,
    linear-gradient(-90deg, var(--tt-surface) 30%, transparent) right center / 12px 100% no-repeat local,
    radial-gradient(ellipse at 0%   50%, rgba(255,255,255,.05), transparent 70%) left center / 14px 100% no-repeat,
    radial-gradient(ellipse at 100% 50%, rgba(255,255,255,.05), transparent 70%) right center / 14px 100% no-repeat;
}

/* ── Section header: que las actions nunca se corten en desktop ──
   En `.section-header` con flex-direction:row (≥768px), si la suma
   de title-block + actions excede el ancho disponible (típico en
   1024-1200px con sidebar abierto), antes Bootstrap colapsaba sin
   gracia.  Con flex-wrap:wrap el bloque actions baja a la siguiente
   línea sin perder controles. */
@media (min-width: 768px) {
  .section-header { flex-wrap: wrap; row-gap: 8px; }
  /* v2.6.12 — flex-basis 260px en title block: cuando actions+260px excede
     el ancho del .section-header (típico en #sec-turnos con planner toggle
     + week nav + dept filter + 2 botones, ~800px), `flex-wrap:wrap` empuja
     actions a una nueva fila en lugar de colapsar el título a ~120px.
     Mantiene min-width:0 para permitir text-overflow:ellipsis interno. */
  .section-header > div:first-child {
    flex: 1 1 260px;
    min-width: 0;
  }
  .section-header .actions { flex-shrink: 0; }
}
