/* ============================================================
   AUTO TUNING SHOP CRM — Sistema de diseño
   Inspirado en los patrones de producto de los CRM SaaS modernos
   (sidebar clara, tarjetas con aire, tablas limpias, pipelines
   tipo tablero) con marca propia: grafito de taller + acento cobre.
   Tipografía: Oswald (títulos/cifras destacadas, estilo rotulado)
               Inter (cuerpo, legibilidad en tablas densas)
               JetBrains Mono (folios, montos, placas)
   Firma visual: "línea de corte" — regla con marcas tipo cinta
   métrica, referencia directa al oficio de medir/cortar vinil.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@500;600&display=swap');

:root {
  /* Color — neutros fríos, marca cálida (cobre) como único acento */
  --ats-ink: #1A1C1F;
  --ats-ink-soft: #5B6069;
  --ats-ink-faint: #8B9099;
  --ats-graphite-900: #1E2023;
  --ats-graphite-800: #26292E;
  --ats-graphite-700: #34383F;
  --ats-surface: #F5F6F8;
  --ats-card: #FFFFFF;
  --ats-border: #E3E5EA;
  --ats-border-soft: #EEEFF2;
  --ats-copper: #B5592B;
  --ats-copper-dark: #973F1A;
  --ats-copper-tint: #F2E1D6;
  --ats-copper-tint-soft: #FBF2EC;
  --ats-green: #256B47;
  --ats-green-tint: #DFF0E6;
  --ats-amber: #8F6015;
  --ats-amber-tint: #F6E9D2;
  --ats-red: #B23A3A;
  --ats-red-tint: #F5DEDE;
  --ats-blue: #33618E;
  --ats-blue-tint: #DCE7F0;
  --ats-teal: #1E6E64;
  --ats-teal-dark: #17554D;
  --ats-teal-tint: #DCEEEA;
  --ats-violet: #5B4B8A;
  --ats-violet-tint: #E7E2F2;
  --ats-green-ink: #1E5138;
  --ats-red-ink: #7A2626;
  --ats-blue-ink: #1F3E5C;
  --ats-amber-ink: #6B4A10;

  /* Tipografía */
  --font-display: 'Oswald', 'Arial Narrow', sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;

  /* Layout */
  --sidebar-width: 244px;
  --topbar-height: 64px;
  --test-banner-height: 0px; /* banner de prueba quitado para producción (VPS real) */
  /* Offset compartido para cualquier barra sticky que deba pegarse justo
   * debajo del topbar (que ya de por sí está corrido hacia abajo por la
   * franja de "versión de prueba") — evita que cada barra sticky nueva
   * repita el mismo calc() y se le olvide sumar test-banner-height, como
   * ya le pasó a .ats-settings-nav (bug real, corregido 2026-09-08: seguía
   * con top: var(--topbar-height) de antes de que existiera la franja, así
   * que la barra de navegación de Configuración quedaba tapada 38px por el
   * topbar en vez de pegarse justo debajo). */
  --content-top-offset: calc(var(--test-banner-height) + var(--topbar-height));
  --radius: 10px;
  --radius-sm: 7px;
  --radius-lg: 14px;
  --shadow-card: 0 1px 2px rgba(16,24,32,0.04), 0 1px 4px rgba(16,24,32,0.05);
  --shadow-hover: 0 6px 20px rgba(16,24,32,0.10);
  --shadow-pop: 0 16px 40px rgba(16,24,32,0.18);
}

/* Modo oscuro real (Etapa 5 del plan VPS, 2026-09-06) — preferencia guardada
   por usuario en users.theme_preference (ver toggle_theme.php), no solo en
   este navegador. Redefine únicamente los tokens de color de arriba — cada
   componente del sistema ya lee color exclusivamente a través de var(--ats-*),
   así que ningún otro selector necesita tocarse para que el modo oscuro
   funcione en toda la app. Las dos excepciones deliberadas que NO cambian
   aquí: el fondo grafito del login (.ats-auth-screen) y del nav inferior
   móvil (.ats-bottom-nav) — ya son oscuros por diseño en ambos temas, son
   parte de la identidad de marca, no del contenido que el toggle controla. */
:root[data-theme="dark"] {
  --ats-ink: #EDEAE5;
  --ats-ink-soft: #B5AFA6;
  --ats-ink-faint: #837C72;
  --ats-surface: #16140F;
  --ats-card: #201D19;
  --ats-border: #37322B;
  --ats-border-soft: #2A2622;
  --ats-copper: #E0824F;
  --ats-copper-dark: #C96B3C;
  --ats-copper-tint: #4A2E1E;
  --ats-copper-tint-soft: #3A2519;
  --ats-green: #7FCBA0;
  --ats-green-tint: #1E3A2C;
  --ats-amber: #E0B563;
  --ats-amber-tint: #3D2F14;
  --ats-red: #E08585;
  --ats-red-tint: #3A1F1F;
  --ats-blue: #7EB3E8;
  --ats-blue-tint: #1E2E3F;
  --ats-teal: #5FBFB2;
  --ats-teal-dark: #7FD1C6;
  --ats-teal-tint: #16332F;
  --ats-violet: #A695D6;
  --ats-violet-tint: #2A2440;
  --ats-green-ink: #BFE8D3;
  --ats-red-ink: #F2C6C6;
  --ats-blue-ink: #C9E0F5;
  --ats-amber-ink: #F2DBA3;
  --shadow-card: 0 1px 2px rgba(0,0,0,0.3), 0 1px 4px rgba(0,0,0,0.25);
  --shadow-hover: 0 6px 20px rgba(0,0,0,0.4);
  --shadow-pop: 0 16px 40px rgba(0,0,0,0.55);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html {
  /* Flujo de la orden de trabajo, rediseño de navegación (2026-09-06) — un
     salto instantáneo de #anchor a #anchor se sentía brusco justo en el
     escenario que más importa aquí (después de cada acción, la página
     redirige al siguiente paso); un desplazamiento suave se siente cuidado
     en vez de un "salto" — mejora global, no solo de esta página. */
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--ats-surface);
  color: var(--ats-ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Transición de entrada del armazón completo (rediseño visual, Fase 2) — el
   objetivo puntual es que abrir la app instalada (PWA) no se sienta como un
   "parpadeo" entre la pantalla de carga nativa del sistema operativo (armada
   sola por el navegador a partir de background_color/theme_color/ícono de
   manifest.json, no hay nada que tocar ahí) y el contenido real ya cargado
   — un fundido breve de toda la app, no solo del contenido principal
   (.ats-main ya tenía su propia entrada, ver más abajo), cierra ese salto. */
@keyframes ats-app-fade-in { from { opacity: 0; } to { opacity: 1; } }
.ats-app { animation: ats-app-fade-in 0.22s ease both; }
@media (prefers-reduced-motion: reduce) {
  .ats-app { animation: none; }
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  margin: 0 0 4px;
  color: var(--ats-ink);
}
h1 { font-size: 1.5rem; letter-spacing: 0.005em; }
h2 { font-size: 1.15rem; }
h3 {
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 700;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ats-ink);
}

.ats-muted { color: var(--ats-ink-soft); }
.ats-mono { font-family: var(--font-mono); }

/* --- Firma visual: regla de corte (tick ruler), más discreta --- */
.cut-rule {
  position: relative;
  height: 7px;
  margin: 4px 0 16px;
  background-image: repeating-linear-gradient(
    to right,
    var(--ats-border) 0, var(--ats-border) 1px,
    transparent 1px, transparent 12px
  );
  background-position: bottom left;
  background-size: 100% 6px;
  background-repeat: repeat-x;
  border-bottom: 1.5px solid var(--ats-copper);
  opacity: 0.85;
}
.cut-rule.short { width: 56px; }

/* --- Layout general --- */
.ats-app { display: flex; min-height: 100vh; }

/* --- Sidebar clara --- */
.ats-sidebar {
  width: var(--sidebar-width);
  background: var(--ats-card);
  color: var(--ats-ink);
  border-right: 1px solid var(--ats-border);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  position: fixed;
  top: var(--test-banner-height); bottom: 0; left: 0;
  z-index: 40;
  transition: transform 0.2s ease;
}

.ats-sidebar-brand {
  display: block;
  padding: 18px 20px 16px;
  border-bottom: 1px solid var(--ats-border);
  text-decoration: none;
}
.ats-sidebar-logo {
  max-width: 100%;
  height: auto;
  display: block;
  margin-bottom: 4px;
}
.ats-sidebar-brand .name {
  font-family: var(--font-display);
  font-size: 1.02rem;
  letter-spacing: 0.01em;
  color: var(--ats-ink);
}
.ats-sidebar-brand .name span { color: var(--ats-copper); }
.ats-sidebar-brand .tag {
  font-size: 0.72rem;
  color: var(--ats-ink-faint);
  letter-spacing: 0.03em;
}

.ats-nav { flex: 1; overflow-y: auto; padding: 10px 0 20px; }
.ats-nav-group { margin-top: 14px; }
.ats-nav-group-label {
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ats-ink-faint);
  padding: 4px 20px;
}
.ats-nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 18px;
  margin: 1px 8px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--ats-ink-soft);
  border-left: 3px solid transparent;
}
.ats-nav-icon { display: inline-flex; flex-shrink: 0; opacity: 0.75; }
.ats-nav a:hover { background: var(--ats-surface); color: var(--ats-ink); }
.ats-nav a:hover .ats-nav-icon, .ats-nav a.active .ats-nav-icon { opacity: 1; }
.ats-nav a.active {
  background: var(--ats-copper-tint-soft);
  color: var(--ats-copper-dark);
  font-weight: 600;
  border-left-color: var(--ats-copper);
}

.ats-sidebar-footer {
  padding: 14px 20px;
  border-top: 1px solid var(--ats-border);
  font-size: 0.8rem;
  color: var(--ats-ink-faint);
}

/* --- Contenido --- */
.ats-content {
  margin-left: var(--sidebar-width);
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.ats-topbar {
  height: var(--topbar-height);
  background: var(--ats-card);
  border-bottom: 1px solid var(--ats-border);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 24px;
  position: sticky;
  top: var(--test-banner-height);
  z-index: 30;
}

/* Aviso "VERSIÓN DE PRUEBA" — solo existe en esta copia (ats-crm-vps), la de
   práctica/desarrollo, nunca en la copia real. Pedido explícito del usuario,
   2026-09-07: confundía esta copia con la real que usa en local en vivo, y
   pidió que fuera más llamativa en un segundo pedido el mismo día. Rayas
   diagonales tipo "cinta de precaución" en TODO el ancho (no solo a los
   lados) — es la señal visual más reconocible de "cuidado/no es lo real"
   que existe, y un color (ámbar/negro) que no aparece en ningún otro lugar
   de la app (el acento normal es cobre). El texto va sobre una placa oscura
   con borde ámbar y un resplandor pulsante suave — separa el texto de las
   rayas para que sea legible sin perder el efecto de "cinta de advertencia".
   Pegajosa arriba de todo (z-index por encima del topbar y de cualquier
   menú desplegable) para que sea imposible de perder sin importar cuánto se
   haya bajado la página.

   Bug real corregido junto con este ajuste: el service worker (sw.js) sirve
   assets/css/app.css con "stale-while-revalidate" — la primera carga
   después de cualquier cambio a este archivo sigue mostrando la versión
   vieja en caché (se actualiza apenas en segundo plano, para la SIGUIENTE
   carga). Por eso el ajuste anterior del sidebar no se vio de inmediato y
   la franja tapó el logo. CACHE_NAME se subió a v3 para forzar la
   invalidación — cualquier cambio futuro a app.css/app.js necesita el mismo
   bump o el navegador seguirá sirviendo la versión vieja indefinidamente. */
.ats-test-banner {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--test-banner-height);
  display: flex;
  align-items: center;
  justify-content: center;
  background: repeating-linear-gradient(135deg, #F5B942, #F5B942 18px, #1A1400 18px, #1A1400 36px);
  box-shadow: 0 2px 12px rgba(245, 185, 66, 0.55);
}
.ats-test-banner .label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #1A1400;
  color: #F5B942;
  padding: 6px 18px;
  border-radius: 999px;
  border: 1.5px solid #F5B942;
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  animation: ats-test-banner-glow 2.2s ease-in-out infinite;
}
@keyframes ats-test-banner-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 185, 66, 0.55); }
  50% { box-shadow: 0 0 0 5px rgba(245, 185, 66, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .ats-test-banner .label { animation: none; }
}

.ats-search {
  flex: 1;
  max-width: 420px;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--ats-surface);
  border: 1px solid var(--ats-border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  color: var(--ats-ink-soft);
}
.ats-search:focus-within { border-color: var(--ats-copper); }
.ats-search input {
  border: none;
  background: transparent;
  outline: none;
  font-size: 0.9rem;
  width: 100%;
  color: var(--ats-ink);
}

.ats-menu-toggle {
  display: none;
  background: none;
  border: none;
  font-size: 1.3rem;
  cursor: pointer;
  color: var(--ats-ink);
}

.ats-user-chip {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.85rem;
}
.ats-user-chip .avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--ats-copper);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.85rem;
}

.ats-main { padding: 26px 30px 60px; }

/* Movimiento con propósito (rediseño visual, Fase 2) — el contenido entra con
   un fundido/deslizamiento breve en vez de aparecer de golpe. Respeta
   prefers-reduced-motion (abajo) para quien lo tenga activado a propósito. */
@keyframes ats-fade-in-up {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
.ats-main > * { animation: ats-fade-in-up 0.32s ease both; }
.ats-main > *:nth-child(2) { animation-delay: 0.03s; }
.ats-main > *:nth-child(3) { animation-delay: 0.06s; }
.ats-main > *:nth-child(4) { animation-delay: 0.09s; }
.ats-main > *:nth-child(n+5) { animation-delay: 0.11s; }
/* Bug real, 2026-09-08: un elemento con `animation` (aunque ya haya
   terminado — animation-fill-mode:both deja la propiedad animation-name
   activa para siempre, no solo mientras se reproduce) queda promovido a su
   propio contexto de apilamiento. Eso aislaba el z-index:40 del menú
   "Documentos y enlaces" (adentro de .ats-page-header, el primer hijo de
   .ats-main) — no podía competir contra el contenido de CUALQUIER sección
   posterior de la página (ej. la rejilla de Precio/Anticipo/Saldo), sin
   importar el número, porque el z-index solo compite dentro del mismo
   contexto. Se quita la animación solo del encabezado (donde vive el único
   menú desplegable que necesita salirse de su propia sección) — el resto de
   secciones se quedan con su entrada normal. */
.ats-main > .ats-page-header { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .ats-main > * { animation: none; }
}

.ats-section-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ats-copper);
  margin-bottom: 6px;
}
.ats-breadcrumbs {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ats-copper);
  margin-bottom: 10px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
}
.ats-breadcrumbs a { color: var(--ats-copper); text-decoration: none; }
.ats-breadcrumbs a:hover { text-decoration: underline; }
.ats-breadcrumbs .sep { color: var(--ats-ink-faint); font-weight: 400; }
.ats-breadcrumbs .current { color: var(--ats-ink-soft); font-weight: 400; }

.ats-page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 4px;
}

/* Menú "Documentos" del encabezado de orden — auditoría de saturación de
   pantalla, 2026-09-07: el encabezado llegó a tener hasta 6 botones, 3 de
   ellos con el mismo texto "Enviar por WhatsApp" (seguimiento, comprobante de
   cita, comprobante de liquidación) — indistinguibles entre sí hasta hacer
   clic. Se agrupan en un solo menú desplegable con opciones ya diferenciadas
   por su propio texto. Es un <details> nativo (mismo patrón que el resto del
   proyecto usa para colapsables), no un componente JS nuevo — solo se le
   agrega el cierre al hacer clic afuera (assets/js/app.js). */
.ats-dropdown { position: relative; display: inline-block; }
.ats-dropdown > summary {
  list-style: none;
  cursor: pointer;
}
.ats-dropdown > summary::-webkit-details-marker { display: none; }
.ats-dropdown > summary::after { content: ' ▾'; }
.ats-dropdown[open] > summary::after { content: ' ▴'; }
.ats-dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 260px;
  background: var(--ats-card);
  border: 1px solid var(--ats-border);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  padding: 6px;
  z-index: 40;
}
.ats-dropdown-menu a {
  display: block;
  padding: 9px 12px;
  border-radius: 6px;
  color: var(--ats-ink);
  text-decoration: none;
  font-size: 0.85rem;
  white-space: nowrap;
}
.ats-dropdown-menu a:hover { background: var(--ats-surface); }
.ats-dropdown-menu .ats-dropdown-divider { height: 1px; background: var(--ats-border); margin: 6px 4px; }

/* --- Navegación interna de página larga (ej. Configuración) ---
   Auditoría visual, 2026-08-31: Configuración tenía 7+ secciones apiladas en
   una sola columna de miles de px, sin ninguna forma de saltar directo a una —
   solo scroll a ciegas. Pegajosa justo debajo del topbar para que siga siendo
   útil aunque ya se haya bajado varias pantallas. Cualquier tarjeta que quiera
   ser un destino de esta nav necesita scroll-margin-top para no quedar tapada
   por el topbar + esta barra al saltar. */
.ats-settings-nav {
  position: sticky;
  top: var(--content-top-offset);
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  background: var(--ats-surface);
  padding: 10px 0;
  margin-bottom: 4px;
}
.ats-settings-nav a {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 100px;
  background: var(--ats-card);
  border: 1px solid var(--ats-border);
  color: var(--ats-ink-soft);
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.ats-settings-nav a:hover { border-color: var(--ats-copper); color: var(--ats-copper-dark); background: var(--ats-copper-tint-soft); }
.ats-settings-nav ~ .ats-card[id] { scroll-margin-top: calc(var(--content-top-offset) + 56px); }

/* Pestañas de periodo rápido (Día/Semana/Mes/Año — gráfica de Ventas del Dashboard) */
.ats-period-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.ats-period-tabs button {
  font-size: 0.74rem;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: 100px;
  background: var(--ats-card);
  border: 1px solid var(--ats-border);
  color: var(--ats-ink-soft);
  cursor: pointer;
  transition: border-color 0.12s ease, color 0.12s ease, background 0.12s ease;
}
.ats-period-tabs button:hover:not(.active) { border-color: var(--ats-copper); color: var(--ats-copper-dark); }
.ats-period-tabs button.active { background: var(--ats-copper); border-color: var(--ats-copper); color: #fff; }

/* Banner "Siguiente paso" (rediseño del flujo de la orden, 2026-09-06) — ver
   la función nextStepFor() en modules/work_order_view.php. Resuelve el
   problema real encontrado: casi ninguna transición de la orden redirigía a
   un ancla, así que después de cada acción la página aterrizaba hasta arriba
   y había que buscar a mano qué seguía. Este banner siempre dice qué sigue,
   sin importar dónde aterrice la página — combinado con que ahora cada
   acción SÍ redirige al ancla correcta, cubre tanto "acabo de llegar a esta
   orden desde otro lado" como "acabo de completar un paso". */
.ats-next-step {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 20px;
  border-radius: var(--radius);
  margin-bottom: 18px;
  border: 1px solid;
}
.ats-next-step .icon { font-size: 1.3rem; flex-shrink: 0; }
.ats-next-step .text { flex: 1; }
.ats-next-step .text .label { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.75; }
.ats-next-step .text .action { font-size: 1rem; font-weight: 600; margin-top: 2px; }
.ats-next-step.action { background: var(--ats-copper-tint-soft); border-color: var(--ats-copper-tint); color: var(--ats-copper-dark); }
.ats-next-step.waiting { background: var(--ats-border-soft); border-color: var(--ats-border); color: var(--ats-ink-soft); }
.ats-next-step.done { background: var(--ats-green-tint); border-color: var(--ats-green-tint); color: var(--ats-green-ink, var(--ats-green)); }
/* Rediseño 2026-09-08: reemplaza al riel horizontal sticky (quitado, ver
   nextStepFor() en work_order_view.php) como el único elemento pegado
   arriba de la orden mientras se hace scroll — ya trae su propio fondo
   opaco por severidad (arriba), así que no necesita uno extra para no
   transparentarse sobre el contenido. */
.ats-next-step-sticky { position: sticky; top: var(--content-top-offset); z-index: 15; }

/* Estado vacío con carácter (rediseño visual, Fase 2) — ver emptyStateHtml() en includes/functions.php */
.ats-empty-state {
  text-align: center;
  padding: 36px 20px;
  color: var(--ats-ink-faint);
}
.ats-empty-state svg { color: var(--ats-border); margin-bottom: 12px; }
.ats-empty-state p { margin: 0; font-size: 0.9rem; color: var(--ats-ink-soft); }

/* --- Tarjetas --- */
.ats-card {
  background: var(--ats-card);
  border: 1px solid var(--ats-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 22px;
  margin-bottom: 18px;
  transition: box-shadow 0.18s ease;
}

/* Línea de tiempo vertical de la orden de trabajo — rediseño 2026-09-08,
   real-usage report: "todos los botones los siento complejos... lo quiero
   todo más visual, un orden cronológico" — investigado contra Ant/Material
   Design steppers, rastreadores de envío y el "accordion checkout" de
   Baymard: el patrón real es UNA sola línea continua con el contenido de
   cada paso anidado junto a su punto, nunca un riel resumen + tarjetas
   sueltas por separado (que es justo lo que tenía esta página antes).
   Implementado 100% en CSS (::before + contador nativo) envolviendo la
   secuencia de tarjetas ya existente en work_order_view.php SIN mover ni
   modificar ninguna — cada tarjeta ya trae su propia clase .ats-card-done
   (o no) calculada por su propia lógica de negocio, así que el punto de
   cada una nunca puede quedar desincronizado del estado real de esa
   tarjeta (no hay una segunda fuente de verdad que mantener al día, a
   diferencia del riel horizontal que sí la necesitaba). Una tarjeta que
   solo existe mientras aplica y luego desaparece del todo (ej. "Iniciar
   trabajo") simplemente dejará de tener punto/línea en cuanto deje de
   renderizarse — la línea de cada tarjeta solo llega hasta su propio final
   (no hay una línea global de posición fija), así que esto nunca deja un
   hueco visual cuando una tarjeta va y viene. */
.ats-order-timeline {
  position: relative;
  counter-reset: ats-timeline;
}
.ats-order-timeline::before {
  content: '';
  position: absolute;
  left: 13px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--ats-border);
  z-index: 1;
}
/* #finanzas queda técnicamente adentro del contenedor por cómo anidan las
   condiciones de rol en work_order_view.php (ver el comentario ahí), pero
   no es un paso cronológico — se excluye del punto/línea a propósito. */
.ats-order-timeline > .ats-card:not(#finanzas) {
  position: relative;
  margin-left: 38px;
}
.ats-order-timeline > .ats-card:not(#finanzas)::before {
  counter-increment: ats-timeline;
  content: counter(ats-timeline);
  position: absolute;
  left: -38px;
  top: 20px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 0.76rem;
  font-weight: 700;
  background: var(--ats-card);
  border: 2px solid var(--ats-copper);
  color: var(--ats-copper-dark);
  z-index: 2;
}
.ats-order-timeline > .ats-card.ats-card-done::before {
  content: '✓';
  background: var(--ats-green-tint);
  border-color: var(--ats-green);
  color: var(--ats-green);
}

/* Spinner del botón "Procesando..." (rediseño visual, Fase 2) — se inyecta
   por JS (assets/js/app.js) junto al cambio de texto ya existente, nunca
   reemplaza esa lógica (el bug real documentado ahí sobre deshabilitar de
   forma síncrona sigue aplicando exactamente igual). */
@keyframes ats-spin { to { transform: rotate(360deg); } }
.ats-btn-spinner {
  display: inline-block;
  width: 13px; height: 13px;
  border: 2px solid rgba(255,255,255,0.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: ats-spin 0.6s linear infinite;
  margin-right: 7px;
  vertical-align: -2px;
}
.btn-secondary .ats-btn-spinner { border-color: var(--ats-border); border-top-color: var(--ats-ink-soft); }
@media (prefers-reduced-motion: reduce) {
  .ats-btn-spinner { animation-duration: 1.4s; }
}

.ats-grid { display: grid; gap: 16px; }
.ats-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.ats-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.ats-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }

.ats-stat {
  padding: 16px 18px;
  border-radius: var(--radius);
  background: var(--ats-card);
  border: 1px solid var(--ats-border);
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.ats-stat:hover { box-shadow: var(--shadow-hover); transform: translateY(-1px); }
.ats-stat .label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ats-ink-faint);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.ats-stat .value {
  font-family: var(--font-display);
  font-size: 1.9rem;
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.ats-stat.accent { border-left: 3px solid var(--ats-copper); }
.ats-stat.accent-teal { border-left: 3px solid var(--ats-teal); }
.ats-stat.accent-violet { border-left: 3px solid var(--ats-violet); }

/* Indicador de tendencia (rediseño visual, Fase 2) — comparación real contra
   el periodo anterior, no decorativo: dashboard.php calcula el % de verdad. */
.ats-trend {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 0.68rem;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
  text-transform: none;
  letter-spacing: 0;
}
.ats-trend.up { background: var(--ats-green-tint); color: var(--ats-green-ink, var(--ats-green)); }
.ats-trend.down { background: var(--ats-red-tint); color: var(--ats-red-ink, var(--ats-red)); }
.ats-trend.flat { background: var(--ats-border); color: var(--ats-ink-soft); }

/* --- Folio chip (placa tipo decal) --- */
.ats-folio {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 4px;
  background: var(--ats-graphite-900);
  color: #fff;
  border-left: 3px solid var(--ats-copper);
}

/* --- Badges de estado (pill) --- */
.ats-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 100px;
  letter-spacing: 0.01em;
}
.ats-badge.green { background: var(--ats-green-tint); color: var(--ats-green); }
.ats-badge.amber { background: var(--ats-amber-tint); color: var(--ats-amber); }
.ats-badge.red { background: var(--ats-red-tint); color: var(--ats-red); }
.ats-badge.blue { background: var(--ats-blue-tint); color: var(--ats-blue); }
.ats-badge.copper { background: var(--ats-copper-tint); color: var(--ats-copper-dark); }
.ats-badge.gray { background: var(--ats-border); color: var(--ats-ink-soft); }

/* --- Formularios --- */
.ats-field { margin-bottom: 16px; }
.ats-field label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--ats-ink);
}
.ats-field .hint { font-size: 0.76rem; color: var(--ats-ink-soft); margin-top: 4px; }

/* Campo específico marcado en rojo tras un error de validación — rediseño
   2026-09-08, punto 5: antes solo se veía el resumen de errores hasta arriba
   de la página ($errors[]); para un formulario largo (6-7 fotos en
   Recepción/Entrega) tocaba adivinar cuál campo era el que faltaba. Ver
   $errorFields en work_order_view.php — mismo patrón reutilizable para
   cualquier campo futuro que necesite esto, no solo fotos. */
.ats-field-error {
  border: 1px solid var(--ats-red);
  background: var(--ats-red-tint);
  border-radius: var(--radius-sm);
  padding: 10px 12px 12px;
  margin-left: -12px;
  margin-right: -12px;
}
.ats-field-error label { color: var(--ats-red-ink); }
.ats-field-error-text { font-weight: 600; }
.ats-field input[type="text"],
.ats-field input[type="email"],
.ats-field input[type="password"],
.ats-field input[type="number"],
.ats-field input[type="date"],
.ats-field input[type="datetime-local"],
.ats-field select,
.ats-field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--ats-border);
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  font-family: inherit;
  background: var(--ats-card);
  color: var(--ats-ink);
}
.ats-field input:focus,
.ats-field select:focus,
.ats-field textarea:focus {
  outline: none;
  border-color: var(--ats-copper);
  box-shadow: 0 0 0 3px var(--ats-copper-tint);
}

/* --- Checkboxes / radios nativos: teñidos de marca en vez de gris de sistema ---
   Auditoría visual, 2026-08-31: se veían "de fábrica" junto a inputs ya
   personalizados. accent-color es soporte nativo del navegador, sin necesidad
   de reconstruir el control (ni JS, ni markup adicional). */
input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--ats-copper);
  width: 16px;
  height: 16px;
  cursor: pointer;
}

/* --- Input de archivo nativo, con el mismo look que .btn-secondary ---
   ::file-selector-button tiene soporte amplio (Chrome/Edge/Firefox/Safari 15.4+)
   y no requiere envolver el <input> en markup adicional en ninguna de las
   pantallas que ya lo usan (compras, recepción, entrega, diseños, comprobantes). */
input[type="file"] {
  font-size: 0.85rem;
  color: var(--ats-ink-soft);
}
input[type="file"]::file-selector-button {
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 8px 14px;
  margin-right: 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--ats-border);
  background: var(--ats-card);
  color: var(--ats-ink);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
input[type="file"]::file-selector-button:hover {
  border-color: var(--ats-ink-faint);
  background: var(--ats-surface);
}

/* --- Columnas numéricas/monetarias en tablas: alineadas a la derecha ---
   Auditoría visual, 2026-08-31: los montos se alineaban como texto normal,
   dificultando comparar cifras de un vistazo. Aplicar esta clase al <th>/<td>
   de cualquier columna de dinero o cantidad. */
.ats-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --- Botones --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
}
.btn-primary { background: var(--ats-copper); color: #fff; }
.btn-primary:hover { background: var(--ats-copper-dark); }
.btn-secondary { background: var(--ats-card); color: var(--ats-ink); border-color: var(--ats-border); }
.btn-secondary:hover { border-color: var(--ats-ink-faint); background: var(--ats-surface); }
.btn-danger { background: var(--ats-red); color: #fff; }
.btn-danger:hover { background: #8E2E2E; }
.btn-block { width: 100%; }

/* --- Acción secundaria compacta en tarjetas (Kanban, etc.) ---
   Auditoría visual, 2026-08-31: antes eran links de texto subrayado sueltos
   ("Archivar", "Marcar perdido") — se leían como enlaces de documento, no como
   acciones de un producto. Mismo espíritu que .btn-secondary pero más chico,
   pensado para vivir varias juntas dentro de una tarjeta angosta. */
.ats-chip-action {
  display: inline-flex;
  align-items: center;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 100px;
  background: var(--ats-surface);
  border: 1px solid var(--ats-border);
  color: var(--ats-ink-soft);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.ats-chip-action:hover { background: var(--ats-card); border-color: var(--ats-ink-faint); color: var(--ats-ink); }
.btn-lg { padding: 14px 20px; font-size: 1rem; }

/* --- Tablas --- */
.ats-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.ats-table th {
  text-align: left;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ats-ink-faint);
  padding: 10px 12px;
  border-bottom: 1px solid var(--ats-border);
}
.ats-table td {
  padding: 13px 12px;
  border-bottom: 1px solid var(--ats-border-soft);
  vertical-align: middle;
}
.ats-table tr:hover td { background: var(--ats-surface); }
.ats-table .row-actions { opacity: 0; transition: opacity 0.1s ease; }
.ats-table tr:hover .row-actions { opacity: 1; }
.ats-table tr.ats-row-link { cursor: pointer; }
.ats-row-chevron { width: 24px; text-align: right; color: var(--ats-ink-faint); }
.ats-table tr.ats-row-link:hover .ats-row-chevron { color: var(--ats-copper); }

/* --- Alertas / flash messages --- */
.ats-alert {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  margin-bottom: 14px;
  font-size: 0.88rem;
  border-left: 3px solid;
}
.ats-alert.success { background: var(--ats-green-tint); border-color: var(--ats-green); color: var(--ats-green-ink); }
.ats-alert.error { background: var(--ats-red-tint); border-color: var(--ats-red); color: var(--ats-red-ink); }
.ats-alert.info { background: var(--ats-blue-tint); border-color: var(--ats-blue); color: var(--ats-blue-ink); }
/* Auditoría visual, 2026-08-31: faltaba un nivel "aviso" entre info y error —
   las alertas del dashboard usaban rojo para todo, sin distinguir lo bloqueante
   (saldo vencido, capacidad excedida) de lo que solo hay que tener en la mira
   (material que aún no vence, diseño esperando aprobación). */
.ats-alert.warning { background: var(--ats-amber-tint); border-color: var(--ats-amber); color: var(--ats-amber-ink); }

/* --- Login / instalador --- */
.ats-auth-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ats-graphite-900);
  background-image:
    repeating-linear-gradient(45deg, rgba(255,255,255,0.02) 0, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 14px);
  padding: 20px;
}
.ats-auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--ats-card);
  border-radius: var(--radius-lg);
  padding: 32px 30px;
  box-shadow: var(--shadow-pop);
}
.ats-auth-brand {
  text-align: center;
  margin-bottom: 22px;
}
.ats-auth-logo {
  max-width: 220px;
  width: 100%;
  height: auto;
  margin: 0 auto 6px;
  display: block;
}
.ats-auth-brand .name {
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: 0.01em;
}
.ats-auth-brand .name span { color: var(--ats-copper); }

/* --- Pipeline / tablero tipo Deals --- */
.ats-pipeline-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
/* --- Máscara de desvanecido para contenedores con scroll horizontal ---
   Auditoría visual, 2026-08-31: el tablero Kanban y el riel de etapas no daban
   ninguna pista de que había más contenido a los lados. Envolver el elemento
   con overflow-x:auto en un .ats-scroll-fade (position:relative) agrega un
   degradado en el borde derecho — puramente decorativo, no reemplaza barras de
   scroll ni cambia el comportamiento de arrastrar tarjetas. */
.ats-scroll-fade { position: relative; }
.ats-scroll-fade::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 12px;
  width: 40px;
  background: linear-gradient(to right, transparent, var(--ats-surface) 80%);
  pointer-events: none;
}
.ats-kanban { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 12px; align-items: flex-start; }
.ats-kanban-col {
  flex: 0 0 272px;
  background: var(--ats-surface);
  border-radius: var(--radius);
  padding: 4px;
  transition: background 0.12s ease, box-shadow 0.12s ease;
}
.ats-kanban-col.drag-over { background: var(--ats-copper-tint-soft); box-shadow: inset 0 0 0 2px var(--ats-copper); }
.ats-kanban-col-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 10px 6px;
  border-top: 3px solid var(--stage-color, var(--ats-copper));
  border-radius: 4px 4px 0 0;
}
.ats-kanban-col-header .title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--ats-ink);
}
.ats-kanban-col-header .count { font-size: 0.72rem; color: var(--ats-ink-faint); }
.ats-kanban-col-value {
  padding: 0 10px 8px;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ats-ink-soft);
}
/* Auditoría visual, 2026-08-31: una columna con muchas tarjetas hacía crecer
   toda la página mientras las columnas vecinas quedaban vacías arriba — altura
   máxima + scroll propio mantiene el tablero parejo sin importar cuántas
   tarjetas tenga una sola columna. */
.ats-kanban-body { padding: 4px 8px 8px; min-height: 40px; max-height: 600px; overflow-y: auto; }
.ats-kanban-card {
  background: var(--ats-card);
  border: 1px solid var(--ats-border);
  border-left: 3px solid var(--stage-color, var(--ats-copper));
  border-radius: var(--radius-sm);
  padding: 11px 12px;
  margin-bottom: 8px;
  font-size: 0.84rem;
  cursor: grab;
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.12s ease, transform 0.12s ease, opacity 0.12s ease;
}
.ats-kanban-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-1px); }
.ats-kanban-card.dragging { opacity: 0.4; }
.ats-kanban-card .deal-value {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--ats-ink);
  margin-top: 4px;
}
/* Tarjetas Kanban más ricas (rediseño visual, Fase 2) — iniciales del cliente
   como avatar (mismo look que .ats-user-chip .avatar de la barra superior,
   solo más pequeño) y una etiqueta de "cuánto lleva aquí" para distinguir de
   un vistazo una tarjeta recién movida de una que lleva semanas estancada. */
.ats-kanban-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 2px; }
.ats-kanban-avatar {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  background: var(--ats-copper-tint); color: var(--ats-copper-dark);
  font-family: var(--font-display); font-size: 0.72rem; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
}
.ats-kanban-days {
  font-size: 0.68rem; color: var(--ats-ink-faint); font-weight: 500;
  margin-left: auto; white-space: nowrap;
}
.ats-kanban-empty { font-size: 0.78rem; color: var(--ats-ink-faint); padding: 10px 6px; text-align: center; }

/* --- Pasos ya completados que se colapsan (Preparación, Recepción, etc.) ---
   Fondo/borde distintos a propósito: dos tarjetas blancas consecutivas (una
   colapsada a una línea, la otra expandida justo debajo) se veían como un solo
   bloque continuo — real feedback de uso, se confundía con que el contenido de
   la siguiente tarjeta "seguía siendo parte" de la colapsada. */
.ats-card summary { list-style-position: outside; }
.ats-card summary::marker { color: var(--ats-copper); }
.ats-card summary:hover { color: var(--ats-copper); }
.ats-card details[open] summary { margin-bottom: 4px; }
.ats-card.ats-card-done {
  padding-top: 14px;
  padding-bottom: 14px;
  border-left: 3px solid var(--ats-green);
  background: var(--ats-green-tint);
}
.ats-card.ats-card-done details[open] {
  padding-bottom: 4px;
}

/* Riel pegado (sticky) al hacer scroll — rediseño 2026-09-08, punto 3 de la
   propuesta: al bajar a una tarjeta como Recepción, el riel de arriba ya no
   se veía, así que se perdía de vista en qué paso iba la orden. Se probó
   deliberadamente NO construir una segunda versión "compacta" separada del
   riel — ya es una sola fila razonablemente compacta, y una segunda copia
   sería exactamente la clase de "dos lugares derivando la misma cosa" que ya
   mordió a este archivo antes ($stageRail vs. $prepDone). Mismo patrón que
   .ats-settings-nav (Configuración): position:sticky, fondo sólido para que
   no se transparente el contenido al desplazarse debajo, pegado justo abajo
   del topbar (--content-top-offset ya incluye la franja de "versión de
   prueba" de esta copia de práctica). */
.ats-stage-rail-sticky {
  position: sticky;
  top: var(--content-top-offset);
  z-index: 15;
  background: var(--ats-surface);
}

/* --- Riel de etapas de una orden de trabajo (work_order_view.php) --- */
.ats-stage-rail {
  display: flex;
  overflow-x: auto;
  gap: 0;
  padding: 4px 2px 14px;
  margin-bottom: 4px;
}
.ats-stage-rail-item { display: flex; align-items: center; flex: none; }
.ats-stage-rail-item:last-child .ats-stage-rail-connector { display: none; }
.ats-stage-rail-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 96px;
  text-align: center;
  text-decoration: none;
  color: inherit;
}
.ats-stage-rail-dot {
  width: 26px; height: 26px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  border: 2px solid var(--ats-border);
  color: var(--ats-ink-faint);
  background: var(--ats-surface);
  flex: none;
}
.ats-stage-rail-label { font-size: 0.72rem; color: var(--ats-ink-faint); line-height: 1.25; }
.ats-stage-rail-item.done .ats-stage-rail-dot { background: var(--ats-green-tint); border-color: var(--ats-green); color: var(--ats-green); }
.ats-stage-rail-item.done .ats-stage-rail-label { color: var(--ats-ink-soft); }
.ats-stage-rail-item.current .ats-stage-rail-dot { background: var(--ats-copper); border-color: var(--ats-copper); color: #fff; box-shadow: 0 0 0 3px var(--ats-copper-tint); }
.ats-stage-rail-item.current .ats-stage-rail-label { color: var(--ats-ink); font-weight: 700; }
.ats-stage-rail-connector { width: 22px; height: 2px; background: var(--ats-border); flex: none; }
.ats-stage-rail-item.done .ats-stage-rail-connector { background: var(--ats-green); }

/* --- Responsive: móvil --- */
@media (max-width: 900px) {
  .ats-sidebar { transform: translateX(-100%); }
  .ats-sidebar.open { transform: translateX(0); }
  .ats-content { margin-left: 0; }
  .ats-menu-toggle { display: block; }
  .ats-main { padding: 16px 14px 90px; }
  .ats-grid.cols-2, .ats-grid.cols-3, .ats-grid.cols-4 { grid-template-columns: 1fr 1fr; }
  .ats-search { max-width: none; }
  h1 { font-size: 1.25rem; }

  /* Barra inferior compacta para instaladores en campo */
  .ats-bottom-nav {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--ats-graphite-900);
    display: flex;
    justify-content: space-around;
    padding: 8px 4px calc(8px + env(safe-area-inset-bottom));
    z-index: 45;
  }
  .ats-bottom-nav a {
    color: #C7C7C2;
    font-size: 0.68rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
  }
  .ats-bottom-nav a.active { color: var(--ats-copper); }
}

@media (max-width: 560px) {
  .ats-grid.cols-2, .ats-grid.cols-3, .ats-grid.cols-4 { grid-template-columns: 1fr; }
}

.ats-sidebar-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(16,18,20,0.4);
  z-index: 35;
}
.ats-sidebar-overlay.open { display: block; }

/* Foco visible para accesibilidad de teclado */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--ats-copper);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
