/**
 * tokens.css — Design Tokens Globales
 * distrib-v482 | "Hoja de Ruta" — identidad propia basada en el rubro real
 * (remitos, guías de despacho, manifiestos de carga, señalética de depósito)
 * en vez de la estética SaaS genérica (Electric Blue #2563EB heredada de
 * Stripe/Linear, sobre Gentelella+AdminLTE). Ver /DESIGN_SYSTEM_HOJA_DE_RUTA.md
 * en la raíz del repo para la dirección completa y la metodología de migración.
 */

@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500;600;700&family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root {

  /* ─── Paleta — alineada a la landing (frontend/index.html): papel +
     verde/navy, en vez del amarillo señalética "Hoja de Ruta" anterior.
     Ver /DESIGN_SYSTEM_HOJA_DE_RUTA.md — la dirección tipográfica/de
     radios/sombras de ese documento se mantiene, solo cambia el color. */
  --color-bg:           #F6F7F5; /* --paper de la landing */
  --color-surface:      #FFFFFF;
  --color-surface-2:    #ECEEEA; /* --paper-deep de la landing */
  --color-border:       #DDE1DC; /* --line de la landing */
  --color-border-soft:  #E7E9E4;

  --color-text:         #111A17; /* --ink de la landing */
  --color-text-muted:   #5B6660; /* --muted de la landing */
  --color-text-light:   #7A857E;

  /* Acento: verde de la landing (reemplaza el amarillo señalética de depósito) */
  --color-primary:      #6A9873; /* --green de la landing */
  --color-primary-bg:   rgba(106,152,115,.14);
  --color-primary-dark: #487050; /* --green-deep de la landing */

  --color-success:      #487050;  --color-success-bg: #E2F0E5;  --color-success-mid: #75A37D; /* --green-deep / --green-light */
  --color-warning:      #8A5F13;  --color-warning-bg: #FBE8C9;  --color-warning-mid: #E0A53E; /* --amber de la landing */
  --color-danger:       #7A2820;  --color-danger-bg:  #F5DDD8;  --color-danger-mid:  #D1594A; /* --red de la landing */
  --color-info:         #1F3555;  --color-info-bg:    #DDE6EE;  --color-info-mid:    #33507A; /* --navy / --navy-light de la landing */

  /* Pills/badges categóricos — para etiquetas de tipo/categoría (ej. tipo de
     entidad en búsqueda global, tipo de movimiento) que no encajan en el set
     success/warning/danger/info de arriba. Los badges que sí son semánticos
     (ok/alerta/error/info) reusan los tokens de arriba en vez de duplicarse acá. */
  --pill-neutral-bg: #EAE4D6;  --pill-neutral-text: #4B4A45;
  --pill-purple-bg:  #EDE4F5;  --pill-purple-text:  #5B4A8F;
  --pill-pink-bg:    #F5E4EC;  --pill-pink-text:    #8F3A5C;
  --pill-orange-bg:  #FBE8C9;  --pill-orange-text:  #8A5F13;

  /* Violeta de migración — 3 tonos para el badge/sección de "origen de
     migración" (migracion-badge.js), que traía un violeta Tailwind crudo
     (#a855f7/#7c3aed/#6d28d9) sin relación con la marca. Recalibrado sobre
     el único violeta que ya existe en el sistema (--nav-facturacion,
     #5B4A8F) como tono medio, con una versión más clara para texto sobre
     fondo tenue y una más oscura para texto que necesita más contraste
     (ej. encabezados de tabla sobre fondo casi blanco). --violeta-rgb es
     el mismo RGB de --nav-facturacion, para los fondos/bordes con alpha
     variable que ese archivo arma vía rgba(). */
  --violeta-light: #7A639F;
  --violeta-mid:   #5B4A8F; /* = --nav-facturacion */
  --violeta-dark:  #453A70;
  --violeta-rgb:   91,74,143;

  /* Tonos de fondo sólido con texto blanco encima (botones/sellos), AA 4.5:1+ */
  --color-box-primary:  #6A9873;
  --color-box-success:  #487050;
  --color-box-warning:  #8A5F13;
  --color-box-danger:   #B8402E;
  --color-box-info:     #33507A;

  /* ─── Nav — riel oscuro, paleta dark de la landing (--bg-900/850/800) ─── */
  --nav-dark-bg:        #0A1119;
  --nav-dark-rail:      #0E1826;
  --nav-dark-text:      #C9CCD3;
  --nav-dark-text-sub:  #8890A0;
  --nav-dark-border:    #122132;
  --nav-dark-hover:     rgba(106,152,115,.10);
  --nav-dark-active:    rgba(106,152,115,.16);

  /* Workspaces — colores de acento por sección, tomados de la landing */
  --nav-hoy:          #6A9873;   --nav-hoy-bg:          rgba(106,152,115,.14);
  --nav-ventas:       #487050;   --nav-ventas-bg:       rgba(72,112,80,.12);
  --nav-deposito:     #1F3555;   --nav-deposito-bg:     rgba(31,53,85,.12);
  --nav-cobros:       #3A9C96;   --nav-cobros-bg:       rgba(58,156,150,.12);
  --nav-facturacion:  #5B4A8F;   --nav-facturacion-bg:  rgba(91,74,143,.12);
  --nav-fidelizacion: #8F3A5C;   --nav-fidelizacion-bg: rgba(143,58,92,.12);
  --nav-reportes:     #33507A;   --nav-reportes-bg:     rgba(51,80,122,.12);
  --nav-config:       #5B6660;   --nav-config-bg:       rgba(91,102,96,.12);
  /* v961 — "Asistente IA": único grupo del menú que no es una sección más
     (ver destacado:true en nav-data.js) — dorado/ámbar, el único tono
     cálido de la rueda de acentos (el resto son verdes/navy/teal/violeta/
     rosa), elegido justamente para no confundirse con ningún workspace
     existente y saltar a la vista dentro del panel. */
  --nav-ia:           #8A5F13;   --nav-ia-bg:           rgba(138,95,19,.16);

  /* ─── Tipografía — condensada industrial + utilitaria + mono para datos ─── */
  --font-family-display:  'Oswald', 'Arial Narrow', sans-serif; /* títulos, KPIs — estarcido de depósito */
  --font-family:          'IBM Plex Sans', -apple-system, 'Segoe UI', sans-serif; /* UI, tablas, cuerpo */
  --font-mono:            'IBM Plex Mono', 'SFMono-Regular', 'Consolas', monospace; /* remitos, CUIT, montos, códigos */
  --font-size-xs:         0.75rem;
  --font-size-sm:         0.875rem;
  --font-size-base:       1rem;
  --font-size-md:         1.0625rem;
  --font-size-lg:         1.125rem;
  --font-size-xl:         1.25rem;
  --font-size-2xl:        1.5rem;
  --font-weight-normal:   400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;
  --font-weight-bold:     700;
  --line-height-tight:    1.25;
  --line-height-base:     1.5;
  --line-height-relaxed:  1.75;
  --letter-spacing-tight: -0.015em;
  --letter-spacing-normal: 0em;
  --letter-spacing-wide:  0.05em;

  /* ─── Espaciado ─── */
  --space-1:0.25rem; --space-2:0.5rem;  --space-3:0.75rem;
  --space-4:1rem;    --space-5:1.25rem; --space-6:1.5rem;
  --space-8:2rem;    --space-10:2.5rem; --space-12:3rem;

  /* ─── Radios — más cerrados que el SaaS de siempre: documento impreso, no pill soft ─── */
  --radius-sm:   2px;
  --radius-md:   4px;
  --radius-lg:   6px;
  --radius-xl:   8px;
  --radius-xxl:  10px;
  --radius-full: 9999px;
  --radius-pill: 9999px;

  /* ─── Sombras — planas, casi sin difuminado: hoja apoyada sobre hoja, no elevación SaaS ─── */
  --shadow-outline:       0 0 0 1px var(--color-border-soft);
  --shadow-outline-dark:  0 0 0 1px rgba(106,152,115,.20);
  --shadow-fluffy:
    0 1px 0 rgba(22,24,29,.06),
    2px 3px 0 rgba(22,24,29,.05);
  --shadow-big:
    0 1px 0 rgba(22,24,29,.05),
    3px 5px 0 rgba(22,24,29,.07);
  --shadow-xs:  0 1px 0 rgba(22,24,29,.05);
  --shadow-sm:  var(--shadow-outline);
  --shadow-md:  var(--shadow-fluffy);
  --shadow-lg:  var(--shadow-big);
  --shadow-xl:  4px 6px 0 rgba(22,24,29,.08), 0 0 0 1px var(--color-border-soft);
  --card-shadow:       var(--shadow-fluffy);
  --card-shadow-hover: var(--shadow-big);
  --card-header-bg:    transparent;
  --card-header-border: 1px solid var(--color-border-soft);

  /* ─── Sin glassmorphism — superficie plana tipo papel ─── */
  --glass-bg:    var(--color-surface);
  --glass-border: 1px solid var(--color-border-soft);
  --glass-blur:  none;
  --glass-modal: var(--color-surface);
  --shadow-glow: 0 0 0 4px rgba(106,152,115,.20);
  --shadow-big-dark: 0 1px 0 rgba(22,24,29,.05), 3px 5px 0 rgba(22,24,29,.07);

  /* ─── Gradientes — acento amarillo/ink, ya no azul corporativo ─── */
  --gradient-primary: linear-gradient(135deg, #6A9873 0%, #487050 100%);
  --gradient-primary-text: linear-gradient(180deg, #6A9873 0%, #487050 100%);

  /* ─── Transiciones ─── */
  --transition-fast: 120ms ease;
  --transition-base: 200ms ease;
  --transition-slow: 350ms ease;
  --marquee-duration: 25s;

  /* ─── Z-index ───
     AUDITORIA-RESPONSIVE FASE1 (2026-08-22): la escala original se
     cortaba en --z-tooltip:800, pero en producción hay overlays reales
     que necesitan estar por encima de TODO (modal de producto con
     sub-modales anidados: vincular-celular, Receta/BOM; chat widget;
     toasts inyectados por JS en runtime). Al no existir un nivel para
     eso, cada archivo nuevo inventaba su propio número grande (9999,
     10000, 10001...) sin coordinarse entre sí — de ahí la fragmentación
     del hallazgo 1.9. Se agregan acá los niveles que ya existen hoy en
     el código como números sueltos, para que el próximo componente use
     una var() en vez de otro número mágico más. Los valores hardcodeados
     que ya existían (productos-modal-fix.css, skeletons.css, etc.) SÍ
     fueron migrados a estas variables — ver el segundo bloque de abajo
     y el CHANGELOG de la auditoría responsive Fase 1 (2026-08-22). */
  --z-base:0; --z-raised:10; --z-dropdown:100;
  --z-sticky:200; --z-modal:400; --z-toast:600; --z-tooltip:800;
  --z-overlay-critical:9000;   /* "por encima de todo lo normal" (reemplaza al 9999 usado a mano) */
  --z-modal-anidado-1:9100;    /* 1er nivel de modal dentro de otro modal */
  --z-modal-anidado-2:9200;    /* 2do nivel anidado */
  --z-modal-anidado-3:9300;    /* 3er nivel anidado (caso productos.css) */

  /* ─── Z-index — migración hallazgo 1.9 (2026-08-22) ───
     Cada valor de acá es EXACTAMENTE el número que ya estaba hardcodeado
     en el archivo indicado — no se re-numeró nada. El objetivo es solo
     centralizar los números mágicos en variables con nombre, sin tocar
     el orden de stacking real (cero riesgo visual). Migración hecha
     archivo por archivo con verificación de que ningún valor compartido
     tapara a otro dentro de la misma página. */
  --z-popover:40;              /* dropdowns/tooltips locales (compras, productos, catalogo) */
  --z-panel:50;                /* panel/FAB local elevado (clientes, compras, finanzas, productos,
                                   stock, remito, carrito, catalogo, login) */
  --z-panel-2:60;               /* mismo rol que --z-panel, un escalón por encima (cliente/pedidos) */
  --z-modal-backdrop:300;      /* fondo oscuro de modal, por debajo de --z-modal (clientes, facturacion,
                                   gastos-generales, login, pedidos, productos, reglas-precio, stock) */
  --z-nav-panel:401;           /* panel del menú de usuario, admin/nav.css (justo sobre --z-modal) */
  --z-flyout:500;              /* modal-overlay "legacy" de finanzas.css/rutas.css/pedidos.css */
  --z-chat-widget:590;         /* burbuja + panel del asistente de chat (shared/chat-widget.css) */
  --z-mnav-overlay:690;        /* fondo del drawer de navegación mobile (admin/nav.css) */
  --z-mnav-panel:691;          /* panel del drawer de navegación mobile (admin/nav.css) */
  --z-mnav-toggle:700;         /* botón que abre/cierra el drawer mobile (admin/nav.css) */
  --z-confirm-dialog:750;      /* diálogo global window.confirmar()/confirmarConTexto() (ui-utils.js).
                                   Dedicado y fijo: antes reutilizaba --z-modal (400) y algunas páginas
                                   (notas, cheques, cobranzas, productos) subían --z-modal a 10100 a nivel
                                   :root para que este diálogo superara a su modal local (--z-flyout:500) —
                                   pero --z-modal también lo usa el backdrop del "Menú principal" global
                                   (admin/nav.css), así que esa página entera quedaba tapada por el fondo
                                   oscuro del menú por encima de su propio panel. Con un token propio, ya
                                   por encima de --z-flyout sin tocar --z-modal, esas cuatro sobreescrituras
                                   dejan de hacer falta. */
  --z-cobranzas-overlay:999;   /* overlay fullscreen puntual de cobranzas-gentelella.css */
  --z-modal-stack-1:1000;      /* backdrop de modal en cascada (automatizacion, devoluciones) */
  --z-modal-stack-2:1001;      /* contenido de modal en cascada, sobre --z-modal-stack-1 */
  --z-modal-stack-3:1002;      /* feedback/confirm por encima del stack anterior (devoluciones) */
  --z-rutas-toggle:10000;      /* botón flotante compacto de rutas-professional.css */
  --z-super-overlay:10500;     /* overlay crítico puntual (productos.css / stock-overview.css) */
  --z-super-overlay-content:10501; /* contenido sobre --z-super-overlay */
}

/* ─── Reset ─── */
*, *::before, *::after { box-sizing: border-box; }

/* Neutraliza el resaltado celeste/amarillo nativo que pone el navegador
   en inputs autocompletados (usuario/contraseña guardados), para que se
   vean iguales al resto — sin este override, Chrome fuerza su propio
   fondo y no hay forma de anularlo solo con `background`. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--color-surface) inset !important;
  box-shadow: 0 0 0 1000px var(--color-surface) inset !important;
  -webkit-text-fill-color: var(--color-text) !important;
  caret-color: var(--color-text);
  transition: background-color 5000s ease-in-out 0s;
}

body {
  font-family:    var(--font-family);
  font-size:      var(--font-size-base);
  color:          var(--color-text);
  background:     var(--color-bg);
  line-height:    var(--line-height-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ─── Tipografía display — títulos de sección y KPIs, estarcido de depósito ─── */
h1, h2, h3, .titulo-seccion, .kpi-valor, .display {
  font-family: var(--font-family-display);
  font-weight: 600;
  letter-spacing: .01em;
  text-transform: none;
}
/* Todo dato — montos, CUIT, remitos, códigos — en mono con cifras tabulares */
.dato-mono, .tabla-base td.num, .cifra, code {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ─── Toast ─── */
/* [Fix — recuadro vacío que quedaba pegado abajo en TODAS las páginas]
   El estado "oculto" dependía solo de `translateY(120%)`, un porcentaje
   relativo a la altura PROPIA del toast (~40px para un mensaje de una
   línea). Eso lo corre apenas ~48px hacia abajo — muy por debajo de los
   96px (+ su propia altura) que haría falta para sacarlo del viewport
   dado el `bottom: 96px`. En la práctica el toast "oculto" NUNCA salía
   de la pantalla: solo bajaba un poco y quedaba flotando como un
   recuadro vacío pegado al borde inferior, en cualquier página que
   dispare al menos un toast (o sea, casi todas).
   Ahora "oculto" también apaga opacity/visibility, así queda realmente
   invisible sin importar cuánto mida el mensaje. El transform se deja
   solo como detalle visual (un leve deslizamiento), ya no como el
   mecanismo que decide si se ve o no. */
.toast {
  position: fixed; bottom: 96px; left: 50%;
  transform: translateX(-50%) translateY(8px);
  opacity: 0; visibility: hidden;
  background: var(--color-surface);
  /* [Fix — aviso "Seleccioná un chofer" pasaba desapercibido] El tono neutro
     (--color-text) + font-size-sm hacía que los avisos de validación (falta
     elegir chofer, falta un dato obligatorio, etc.) quedaran casi ilegibles.
     El tipo "default" es el que usan ~90% de esos avisos en toda la app
     (rutas.js, clientes.js, facturacion.js, etc.), así que se sube acá,
     en el componente global, para que impacte en todas las páginas y
     secciones sin tener que tocar cada llamado a toast() una por una. */
  color: var(--color-danger);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-danger-mid);
  padding: 10px 18px; border-radius: var(--radius-md);
  font-size: var(--font-size-md); font-weight: var(--font-weight-bold);
  box-shadow: var(--shadow-big); z-index: var(--z-toast);
  transition: transform var(--transition-slow), opacity var(--transition-slow),
              visibility 0s linear var(--transition-slow);
  pointer-events: none; max-width: min(90vw,380px);
  text-align: center; letter-spacing: .01em;
  overflow: hidden; /* recorta la barra de progreso a las esquinas redondeadas */
}
.toast--visible, .toast.show, .toast.visible {
  transform: translateX(-50%) translateY(0);
  opacity: 1; visibility: visible;
  transition: transform var(--transition-slow), opacity var(--transition-slow), visibility 0s;
}
.toast--success, .toast.exito {
  border-left-color: var(--color-success-mid);
  color: var(--color-success);
}
.toast--danger,  .toast.error {
  border-left-color: var(--color-danger-mid);
  color: var(--color-danger);
}
.toast--warning {
  border-left-color: var(--color-warning-mid);
  color: var(--color-warning);
}
/* Barra de progreso: muestra visualmente el tiempo que le queda al mensaje
   antes de auto-ocultarse, para que quede claro que no está "trabado". La
   duración real la fija ui-utils.js vía animation-duration inline (ver
   `_toastBarEl.style.animation` en la función toast()). */
.toast-progress {
  position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
  background: currentColor; opacity: .35;
  transform-origin: left center;
  transform: scaleX(1);
}
@keyframes toast-progress {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

/* ─── Sello de estado (elemento firma "Hoja de Ruta") ───
   Reemplaza el badge-pill genérico por un sello tipo troquelado/estampado:
   mayúsculas condensadas, borde doble, esquina recortada casi cuadrada —
   evoca el sello de recepción de mercadería sobre un remito, en vez del
   badge redondeado de cualquier dashboard SaaS.
   `.badge` se mantiene como alias (compatibilidad con ~24 archivos que ya
   lo consumen) — mismo resultado visual, cero cambios de marcado en HTML/JS. */
.badge, .sello {
  display: inline-flex; align-items: center; gap: var(--space-1);
  padding: 1px var(--space-2); border-radius: var(--radius-sm);
  font-family: var(--font-family-display);
  font-size: 10.5px; font-weight: 600;
  line-height: 1.6; white-space: nowrap;
  text-transform: uppercase; letter-spacing: .04em;
  border-width: 3px; border-style: double; border-color: currentColor;
  background: var(--color-surface);
}
.badge--primary, .sello--primary { color: var(--color-primary-dark); background: var(--color-primary-bg); }
.badge--success, .sello--exito   { color: var(--color-success);      background: var(--color-success-bg); }
.badge--warning, .sello--alerta  { color: var(--color-warning);      background: var(--color-warning-bg); }
.badge--danger,  .sello--anulado { color: var(--color-danger);       background: var(--color-danger-bg); }
.badge--info,    .sello--info    { color: var(--color-info);         background: var(--color-info-bg); }

/* ─── Botones ─── */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 8px 18px; border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold);
  font-family: inherit; cursor: pointer;
  transition: all var(--transition-base);
  text-decoration: none; white-space: nowrap; user-select: none;
  line-height: 1.4; letter-spacing: -.01em;
}
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn--primary {
  background: var(--color-box-primary); color: #fff;
  border-color: var(--color-box-primary);
  box-shadow: 0 1px 2px rgba(106,152,115,.25);
}
.btn--primary:hover:not(:disabled) {
  background: var(--color-primary-dark); border-color: var(--color-primary-dark);
  box-shadow: var(--shadow-glow), 0 4px 12px rgba(106,152,115,.22);
}
.btn--success  { background: var(--color-box-success); color: #fff; border-color: var(--color-box-success); }
.btn--danger   { background: var(--color-box-danger);  color: #fff; border-color: var(--color-box-danger); }
.btn--warning  { background: var(--color-box-warning); color: #fff; border-color: var(--color-box-warning); }
.btn--info     { background: var(--color-box-info);    color: #fff; border-color: var(--color-box-info); }
.btn--secondary{ background: var(--color-surface); color: var(--color-text-muted); border-color: var(--color-border); }
.btn--ghost {
  background: transparent; color: var(--color-text-muted);
  border-color: var(--color-border); box-shadow: none;
}
.btn--ghost:hover:not(:disabled) { background: var(--color-surface-2); color: var(--color-text); }
.btn--outline-primary {
  background: transparent; color: var(--color-primary);
  border-color: var(--color-primary);
}
.btn--outline-primary:hover:not(:disabled) { background: var(--color-primary); color: #fff; }
.btn--sm  { padding: 5px 12px; font-size: var(--font-size-xs); }
.btn--lg  { padding: 11px 22px; font-size: var(--font-size-md); }
.btn--icon { padding: 7px 9px; }
.btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.btn--danger:focus-visible  { outline-color: var(--color-danger-mid); }
.btn--success:focus-visible { outline-color: var(--color-success-mid); }

/* ─── Loading btn ─── */
.btn--loading { position: relative; color: transparent !important; pointer-events: none; cursor: wait; }
.btn--loading::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
  border-radius: 50%; animation: btn-spin .65s linear infinite;
}
.btn--ghost.btn--loading::after, .btn--outline-primary.btn--loading::after {
  border-color: rgba(106,152,115,.28); border-top-color: var(--color-primary);
}
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* ─── Botones legacy ─── */
.btn-primario {
  background: var(--color-box-primary); color: #fff; border: 1px solid var(--color-box-primary);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 8px 18px; border-radius: var(--radius-md);
  font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold);
  font-family: inherit; cursor: pointer; transition: all var(--transition-base);
  white-space: nowrap; user-select: none; line-height: 1.4; letter-spacing: -.01em;
}
.btn-primario:hover:not(:disabled) {
  background: var(--color-primary-dark); border-color: var(--color-primary-dark);
  box-shadow: var(--shadow-glow);
}
.btn-primario:disabled { opacity: .55; cursor: not-allowed; }
.btn-primario:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.btn-secundario {
  background: var(--color-surface); color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 8px 18px; border-radius: var(--radius-md);
  font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold);
  font-family: inherit; cursor: pointer; transition: all var(--transition-base);
  white-space: nowrap; user-select: none; line-height: 1.4;
}
.btn-secundario:hover:not(:disabled) { background: var(--color-surface-2); color: var(--color-text); }
.btn-secundario:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.btn-peligro {
  background: transparent; color: var(--color-danger);
  border: 1px solid rgba(220,38,38,.25);
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 8px 18px; border-radius: var(--radius-md);
  font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold);
  font-family: inherit; cursor: pointer; transition: all var(--transition-base);
  white-space: nowrap; user-select: none; line-height: 1.4;
}
.btn-peligro:hover:not(:disabled) { background: var(--color-danger-bg); }
.btn-peligro:focus-visible { outline: 2px solid var(--color-danger-mid); outline-offset: 2px; }

/* ─── Tabla base ─── */
.tabla-base { width: 100%; border-collapse: collapse; font-size: var(--font-size-sm); }
.tabla-base th {
  padding: 10px 14px; text-align: left;
  font-weight: var(--font-weight-semibold); font-size: 11px;
  color: var(--color-text-muted); border-bottom: 1px solid var(--color-border);
  white-space: nowrap; background: var(--color-surface-2);
  text-transform: uppercase; letter-spacing: var(--letter-spacing-wide);
}
.tabla-base td {
  padding: 12px 14px; border-bottom: 1px solid var(--color-border-soft);
  color: var(--color-text); vertical-align: middle;
}
.tabla-base tbody tr:hover td { background: var(--color-primary-bg); }
.tabla-base tr:last-child td { border-bottom: none; }
.tabla-empty { text-align: center; color: var(--color-text-light); padding: var(--space-10); font-size: var(--font-size-sm); }

/* ─── Input base ─── */
.input-base {
  width: 100%; padding: 8px 12px;
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  font-size: var(--font-size-sm); font-family: inherit;
  color: var(--color-text); background: var(--color-surface);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
  line-height: 1.5;
}
.input-base:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(106,152,115,.16); }
.input-base::placeholder { color: var(--color-text-light); }
.input-base:disabled { opacity: .55; cursor: not-allowed; background: var(--color-surface-2); }

/* ─── Animaciones ─── */
@keyframes shimmer { 0% { transform: translateX(-100%); } to { transform: translateX(100%); } }
.shimmer-effect { position: relative; overflow: hidden; }
.shimmer-effect::after {
  content: ''; animation: shimmer 1.5s linear infinite;
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.6), transparent);
  pointer-events: none;
}

@keyframes ping { 75%, 100% { transform: scale(2); opacity: 0; } }

/* ─── Status dot ─── */
.status-dot {
  position: relative; display: inline-flex;
  width: 10px; height: 10px; flex-shrink: 0;
}
.status-dot::before {
  content: ''; position: absolute; inset: 0;
  border-radius: var(--radius-full); background: currentColor;
  opacity: .3; animation: ping 1.5s cubic-bezier(0,0,.2,1) infinite;
}
.status-dot::after {
  content: ''; position: relative; z-index: 1;
  width: 100%; height: 100%; border-radius: var(--radius-full);
  background: currentColor; display: block;
}
.status-dot--active  { color: var(--color-box-success); }
.status-dot--warning { color: var(--color-box-warning); }
.status-dot--danger  { color: var(--color-box-danger); }
.status-dot--muted   { color: var(--color-text-light); }
.status-dot--muted::before { animation: none; }

/* ─── Gradient text ─── */
.text-gradient-primary {
  background: linear-gradient(180deg, var(--color-text) 0%, #555 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.text-gradient-green {
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ─── Accessibility ─── */
[aria-disabled="true"] { opacity: .55; cursor: not-allowed; pointer-events: none; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.empty-state-cell { padding: 0 !important; border: none !important; }
.empty-state, .empty-row, .tabla-empty, .vacio, .grilla-empty, .tabla-loading {
  padding: 40px 20px; text-align: center; color: var(--color-text-light); font-size: 14px; line-height: 1.5;
}

/* ─── Tabs ARIA ─── */
[role="tablist"] { display: flex; gap: 2px; border-bottom: 1px solid var(--color-border); flex-wrap: wrap; }
[role="tab"] {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: 8px 16px; font-size: var(--font-size-sm); font-weight: var(--font-weight-medium);
  font-family: inherit; color: var(--color-text-muted); cursor: pointer;
  transition: color var(--transition-base), border-color var(--transition-base);
  margin-bottom: -1px; white-space: nowrap;
}
[role="tab"]:hover { color: var(--color-text); }
[role="tab"][aria-selected="true"] {
  color: var(--color-primary); border-bottom-color: var(--color-primary);
  font-weight: var(--font-weight-semibold);
}
[role="tab"]:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; border-radius: 4px 4px 0 0; }

/* ─── Modal close legacy ─── */
.modal-close, .modal-box-close, .modal-cerrar {
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer;
  color: var(--color-text-muted); border-radius: var(--radius-sm);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.modal-close:hover, .modal-box-close:hover, .modal-cerrar:hover {
  background: var(--color-surface-2); color: var(--color-text);
}
.modal-close:focus-visible, .modal-box-close:focus-visible, .modal-cerrar:focus-visible {
  outline: 2px solid var(--color-primary); outline-offset: 2px;
}

button.kpi-card { all: unset; cursor: pointer; display: block; width: 100%; box-sizing: border-box; }
button.kpi-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: var(--radius-xl); }
.foto-upload-area { display: block; cursor: pointer; }
.foto-upload-area:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: var(--radius-md); }

/* Utilidades (hallazgo 4.1 auditoría v254) — reemplazo de style="" inline */
.texto-chico  { font-size: var(--font-size-sm); }
.texto-mini   { font-size: 11px; }
.oculto       { display: none; }

/* ── Pulso suave para elementos esenciales/urgentes (auditoría UX) ──
   Reemplaza la idea de "parpadeo" por un halo que crece y se desvanece
   en un ciclo lento (1.6s), sin apagar ni bajar la opacidad del elemento.
   Usar SOLO cuando una condición de datos real lo amerite (stock en 0,
   alerta crítica activa, cheque por vencer hoy, etc.) y sacarla apenas
   esa condición deja de cumplirse — nunca de forma decorativa/permanente,
   y nunca más de 1-2 elementos pulsando a la vez en la misma pantalla.
   Mismo patrón que .ct-kpi--pulse (dashboard-control-tower.css), pensado
   para reutilizarse en el resto del panel admin. */
.urgente--pulso {
  animation: urgente-pulso-danger 1.6s ease-out infinite;
}
.urgente--pulso.urgente--pulso-ambar {
  animation-name: urgente-pulso-ambar;
}
@keyframes urgente-pulso-danger {
  0%   { box-shadow: 0 0 0 0 rgba(220, 38, 38, .45); }
  100% { box-shadow: 0 0 0 12px rgba(220, 38, 38, 0); }
}
@keyframes urgente-pulso-ambar {
  0%   { box-shadow: 0 0 0 0 rgba(180, 83, 9, .45); }
  100% { box-shadow: 0 0 0 12px rgba(180, 83, 9, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .urgente--pulso { animation: none; }
}
