/*! 360-design-system v0.3.0 — generado por scripts/construir.py, no editar a mano: los cambios van en src/ */

/* ════ tokens.css ════ */
/* Tokens del sistema de diseño: la única fuente de verdad de colores,
   superficies y medidas de tabla del ecosistema.

   WHY: dos familias de color a propósito. `--corp-*` es el contenido (claro:
   tarjetas, tablas, formularios) y `--corp-chrome-*` es el "chrome" oscuro
   (barra de estado, panel de marca del login). Los valores nacieron en
   Posventa (pitstopIA) y Ventas los calcó en ago 2026; desde la v0.1.0 viven
   aquí y cada aplicativo los toma de este archivo.

   NOTE: cambiar un valor aquí cambia TODOS los aplicativos en su próxima
   sincronización. Un color nuevo se agrega como token, nunca como valor
   suelto en un componente. */
:root {
  --corp-dark: #ffffff;
  --corp-darker: #eceef1;
  --corp-gray: #5b6167;
  --corp-gray-dim: #6b7280;
  --corp-light: #f4f5f6;
  --corp-surface: #f1f3f5;
  --corp-border: rgba(120, 125, 130, 0.15);
  --corp-border-strong: rgba(120, 125, 130, 0.3);
  --corp-accent: #3b82f6;
  --corp-accent-hover: #2563eb;
  --corp-accent-dim: rgba(59, 130, 246, 0.15);
  --corp-success: #10b981;
  --corp-warning: #f59e0b;
  --corp-danger: #ef4444;
  --corp-info: #6366f1;
  --corp-text: #1a1d1f;
  /* WHY: "chrome" oscuro deliberado — taskbar/start-menu y panel de marca
     del login, ver comentario de arriba. Valores calcados de pitstopIA
     (.xp-taskbar/.xp-start-menu en su index.css: #2A2E32→#16181A y
     #202426 respectivamente). */
  --corp-chrome: #202426;
  --corp-chrome-2: #16181a;
  --corp-chrome-border: rgba(164, 165, 166, 0.15);
  --corp-chrome-muted: rgba(255, 255, 255, 0.65);
  --corp-chrome-dim: rgba(255, 255, 255, 0.45);

  /* WHY: estándar de padding de celda para el sistema de tablas (§5.5,
     `.table-dark`) — antes cada tabla tenía un padding horizontal
     asimétrico (0.85rem izquierda / 1.25rem derecha) copiado de tabla en
     tabla sin una fuente única, lo que dejaba columnas visualmente
     desalineadas entre sí (pedido explícito del cliente, ago 2026: "las
     columnas se ven apretadas, desalineadas y con espaciados
     inconsistentes"). Estos dos tokens son ahora la única fuente de
     verdad — cualquier tabla nueva debe usarlos en vez de un valor
     suelto. `--table-cell-px` se redefine más angosto bajo el breakpoint
     móvil (ver `@media (max-width: 640px)` más abajo). */
  --table-cell-py: 0.65rem;
  --table-cell-px: 1rem;

  /* WHY: medidas de la navegación vertical (`.app-shell-vertical`, ver
     chrome.css). `--app-header-alto` es el alto de `.app-header-top` con el
     logo de 60px: la barra lateral arranca justo debajo. */
  --app-nav-ancho: 220px;
  --app-header-alto: 80px;
}

/* WHY: mismo breakpoint de 640px que el resto de la app — celdas más
   angostas en móvil para que quepa más contenido antes de que
   `.tabla-wrap` empiece a hacer scroll horizontal (pedido explícito del
   cliente, ago 2026: espaciado consistente también en responsive). */
@media (max-width: 640px) {
  :root {
    --table-cell-px: 0.65rem;
  }
}

/* ════ fuentes.css ════ */
/* Tipografía: Inter (variable, subset "latin" — cubre á/é/í/ó/ú/ñ/ü).

   WHY: el archivo viaja con el sistema de diseño (fuentes/, licencia OFL en
   fuentes/OFL-Inter.txt), sin CDN en runtime. La ruta es relativa a este
   CSS, así funciona igual servida como estático (Ventas) o importada por Vite
   (Posventa). `font-weight: 400 800` es un rango porque es una fuente
   variable: un solo archivo para todos los pesos. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fuentes/Inter-Variable-latin.woff2") format("woff2");
}

/* ════ base.css ════ */
/* Base: caja, cuerpo de página, encabezados, barras de scroll y utilidades (.mono, .meta, .sr-only). */

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  overflow-x: hidden;
  background-color: var(--corp-darker);
  color: var(--corp-text);
  /* WHY: "Inter" ahora sí está cargada (ver @font-face arriba) — la pila de
     sistema queda como fallback real (si el woff2 tarda o falla) en vez de
     ser la única fuente, como pasaba antes de vendorizarla. */
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

html {
  scroll-behavior: smooth;
}

* {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--corp-darker); }
::-webkit-scrollbar-thumb { background: rgba(120, 125, 130, 0.35); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(120, 125, 130, 0.55); }

h1, h2, h3 {
  margin: 0;
  font-weight: 600;
  color: var(--corp-text);
  text-wrap: balance;
}

a {
  color: inherit;
}

/* WHY: números de orden/chasis/motor/valores — fuente monoespaciada para
   que los dígitos se alineen en columna (docs/UI_DESIGN_SYSTEM.md §4). */
.mono {
  /* WHY: mismo problema que el font-family de arriba — "JetBrains Mono"/
     "Fira Code"/"Cascadia Code" no están vendorizadas, caían a
     `monospace` genérica. `ui-monospace` (soportada en Win/Mac/Linux
     modernos) resuelve a la monoespaciada nativa de mejor calidad de cada
     sistema antes de llegar al fallback genérico. */
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", Menlo, Consolas, monospace;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.meta {
  color: var(--corp-gray);
  font-size: 0.75rem;
}

a.tab-pill {
  text-decoration: none;
  flex-shrink: 0;
}

/* Texto solo para lectores de pantalla (etiquetas de campos sin rótulo visible). */
.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;
}

/* ════ chrome.css ════ */
/* Chrome del aplicativo: barra superior de dos filas (.app-header, marca, usuario,
   pestañas de módulo .app-tab), campana de avisos (.notif-*), menú del celular
   (.mobile-nav-*), barra de estado inferior (.app-statusbar) y avatar (.app-avatar).
   La estructura HTML esperada está en vista-previa/index.html. */

/* ── Layout de app + barra superior de navegación (ADR-020)
   Reemplaza el botón "Inicio" flotante + taskbar estilo Windows XP
   (ADR-005/008, ver docs/UI_ADMIN_LAYOUT_XP_TASKBAR.md) por un header fijo
   arriba con pestañas de módulo — pedido explícito del cliente al aprobar
   el nuevo diseño visual (docs/UI-mejorada/), confirmado vía
   AskUserQuestion (sep 2026). `.app-shell` es un contenedor flex en
   columna con altura mínima de viewport: el header vive arriba (sticky),
   `.app-main` es el contenido (scroll normal de la página, ya no scroll
   interno propio como `.xp-main` antes) y `.app-statusbar` decorativo cae
   al final del flujo — visible sin scrollear en páginas cortas, al pie en
   las largas, igual que en la referencia aprobada (que tampoco lo fija). */

.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  flex-shrink: 0;
  background: #ffffff;
  border-bottom: 1px solid var(--corp-border);
  box-shadow: 0 1px 3px rgba(20, 22, 25, 0.04);
}

.app-header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1.25rem;
  border-bottom: 1px solid var(--corp-border);
}

.app-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}

.app-hamburger-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 8px;
  color: var(--corp-text);
  background: var(--corp-surface);
  border: 1px solid var(--corp-border);
  cursor: pointer;
}

.app-hamburger-btn:hover {
  background: var(--corp-light);
}

.app-hamburger-btn:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

/* WHY: visible solo <640px — en escritorio la navegación real vive en
   `.app-header-nav` (ver más abajo); en angosto esa fila se oculta y este
   botón es el único trigger del drawer (`.mobile-nav-overlay`). */
@media (max-width: 639px) {
  .app-hamburger-btn {
    display: inline-flex;
  }
}

.app-brand-logos {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.app-brand-logos img {
  height: 60px;
  width: auto;
  max-width: 240px;
  object-fit: contain;
}

.app-brand-logos-divisor {
  align-self: stretch;
  width: 1px;
  background: var(--corp-border-strong);
}

.app-brand-text {
  min-width: 0;
}

.app-brand-title {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--corp-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-brand-subtitle {
  margin: 0.1rem 0 0;
  font-size: 0.7rem;
  color: var(--corp-gray-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 639px) {
  .app-brand-subtitle,
  .app-brand-logos img:last-child,
  .app-brand-logos-divisor {
    display: none;
  }
}

.app-user {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
}

.app-user-info {
  text-align: right;
  min-width: 0;
}

@media (max-width: 639px) {
  .app-user-info {
    display: none;
  }
}

.app-user-name {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--corp-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
}

.app-user-rol {
  margin: 0;
  font-size: 0.68rem;
  color: var(--corp-gray-dim);
}

.app-logout-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 8px;
  color: var(--corp-gray);
  background: transparent;
  border: 1px solid transparent;
  text-decoration: none;
  transition: background-color 150ms ease-out, color 150ms ease-out, border-color 150ms ease-out;
}

.app-logout-btn:hover {
  color: var(--corp-danger);
  background: rgba(239, 68, 68, 0.08);
  border-color: rgba(239, 68, 68, 0.25);
}

.app-logout-btn:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

/* ── Campana de avisos (ADR-119) ─────────────────────────────────────── */
.app-notif {
  position: relative;
  flex-shrink: 0;
}

.app-notif-btn,
.app-nav-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  color: var(--corp-gray);
  background: transparent;
  border: 1px solid var(--corp-border);
  cursor: pointer;
}

.app-notif-btn:hover,
.app-nav-toggle:hover {
  color: var(--corp-text);
  background: var(--corp-light);
}

.app-notif-btn:focus-visible,
.app-nav-toggle:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

.app-notif-contador {
  position: absolute;
  top: -6px;
  right: -7px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--corp-danger);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  box-shadow: 0 0 0 2px #fff;
}

.app-notif-contador[hidden] {
  display: none;
}

.app-notif-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  width: 380px;
  max-height: min(70vh, 520px);
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--corp-border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(20, 22, 25, 0.16);
}

@media (max-width: 639px) {
  /* WHY: en celular la campana queda cerca del borde derecho — el panel se
     fija al ancho de la pantalla en vez de colgar de la campana. */
  .app-notif {
    position: static;
  }

  .app-notif-panel {
    position: fixed;
    top: 64px;
    left: 8px;
    right: 8px;
    width: auto;
  }
}

.notif-panel-cab {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  background: #fff;
  border-bottom: 1px solid var(--corp-border);
  font-size: 0.85rem;
}

.notif-leer-todas {
  border: 0;
  background: none;
  color: var(--corp-accent);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0.2rem 0;
}

.notif-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

.notif-item {
  display: flex;
  gap: 0.65rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--corp-border);
  color: var(--corp-text);
  text-decoration: none;
}

.notif-item:hover,
.notif-item:focus-visible {
  background: var(--corp-light);
}

.notif-item:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: -2px;
}

.notif-nueva {
  background: rgba(59, 130, 246, 0.06);
}

.notif-icono {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.85rem;
  color: #fff;
  background: var(--corp-accent);
}

.notif-aceptada .notif-icono {
  background: #16a34a;
}

.notif-rechazada .notif-icono {
  background: var(--corp-danger);
}

.notif-abierta .notif-icono {
  background: #0891b2;
}

.notif-texto {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.notif-titulo {
  font-size: 0.82rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.notif-nueva .notif-titulo {
  font-weight: 700;
}

.notif-mensaje {
  font-size: 0.78rem;
  color: var(--corp-gray);
  overflow-wrap: anywhere;
}

.notif-fecha {
  font-size: 0.7rem;
  color: var(--corp-gray-dim);
}

.notif-vacio,
.notif-pie {
  margin: 0;
  padding: 0.9rem;
  font-size: 0.78rem;
  color: var(--corp-gray-dim);
}

.notif-pie {
  padding-top: 0.6rem;
  font-size: 0.7rem;
}

.app-header-nav {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0 0.75rem;
  overflow-x: auto;
  scrollbar-width: thin;
}

@media (max-width: 639px) {
  .app-header-nav {
    display: none;
  }
}

.app-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  flex-shrink: 0;
  padding: 0.7rem 0.85rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--corp-gray-dim);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 150ms ease-out, background-color 150ms ease-out;
}

.app-tab:hover {
  color: var(--corp-text);
  background: var(--corp-surface);
}

/* WHY: navegación principal, visible en toda página autenticada — sin
   esto dependía del outline por defecto del navegador (no diseñado para
   convivir con el header), mismo criterio de `.app-hamburger-btn:focus-
   visible`. Offset negativo (no positivo) porque las pestañas van
   pegadas unas a otras: un offset positivo recorta el anillo contra la
   pestaña vecina. */
.app-tab:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: -2px;
}

.app-tab-icon {
  display: inline-flex;
  color: currentColor;
  opacity: 0.8;
}

.app-tab-activo {
  color: var(--corp-accent);
  border-bottom-color: var(--corp-accent);
  background: var(--corp-accent-dim);
}

.app-tab-activo .app-tab-icon {
  opacity: 1;
}

.app-main {
  flex: 1 1 auto;
  min-width: 0;
}

/* ── Navegación vertical (opcional) ─────────────────────────────────────
   WHY: el usuario elige ver los módulos como pestañas arriba (por defecto)
   o como barra lateral izquierda. Mismo HTML en los dos modos: el
   aplicativo solo agrega o quita `.app-shell-vertical` en `.app-shell`
   (botón `.app-nav-toggle` en `.app-user`) y guarda la preferencia. La
   barra sale del header con `position: fixed` en vez de `display: contents`
   para que el `<header>` conserve su rol de accesibilidad. En <640px no
   aplica: ahí la navegación es el drawer (`.mobile-nav-*`) en ambos modos. */
@media (max-width: 639px) {
  .app-nav-toggle {
    display: none;
  }
}

@media (min-width: 640px) {
  .app-shell-vertical .app-header-nav {
    position: fixed;
    top: var(--app-header-alto);
    bottom: 0;
    left: 0;
    width: var(--app-nav-ancho);
    flex-direction: column;
    align-items: stretch;
    gap: 0.1rem;
    padding: 0.75rem 0.5rem;
    overflow-x: hidden;
    overflow-y: auto;
    background: #ffffff;
    border-right: 1px solid var(--corp-border);
  }

  .app-shell-vertical .app-main,
  .app-shell-vertical .app-statusbar {
    margin-left: var(--app-nav-ancho);
  }

  .app-shell-vertical .app-header-top {
    border-bottom: 0;
  }

  .app-shell-vertical .app-tab {
    border-bottom: 0;
    border-left: 2px solid transparent;
    border-radius: 0 6px 6px 0;
  }

  .app-shell-vertical .app-tab-activo {
    border-left-color: var(--corp-accent);
  }
}

/* WHY: barra inferior decorativa (no interactiva — a diferencia de la
   taskbar XP anterior, ya no dispara ningún menú; la navegación real vive
   en `.app-header-nav`/el drawer móvil). Calca el pie institucional de la
   referencia aprobada: marca + módulo activo a la izquierda, reloj +
   avatar a la derecha. */
.app-statusbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 1.25rem;
  background: var(--corp-chrome-2);
  border-top: 1px solid var(--corp-chrome-border);
  color: var(--corp-chrome-muted);
  font-size: 0.72rem;
}

.app-statusbar-left {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  overflow: hidden;
}

.app-statusbar-left span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 639px) {
  .app-statusbar-left span:nth-child(2) {
    display: none;
  }
}

.app-statusbar-brand {
  flex-shrink: 0;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.9);
  color: #16181a;
  font-weight: 800;
  font-size: 0.68rem;
  letter-spacing: 0.03em;
}

.app-statusbar-sep {
  flex-shrink: 0;
  width: 1px;
  height: 12px;
  background: var(--corp-chrome-border);
}

.app-statusbar-right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-shrink: 0;
}

.app-statusbar-clock {
  color: var(--corp-chrome-dim);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 639px) {
  .app-statusbar-clock {
    display: none;
  }
}

.app-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-weight: 700;
  color: #ffffff;
  flex-shrink: 0;
}

.app-avatar {
  width: 26px;
  height: 26px;
  font-size: 0.7rem;
  background: var(--corp-accent);
}

/* ── Menú de navegación móvil (drawer) — calcado de pitstopIA
   (Layout.tsx) ───────────────────────────────────────────────────────────
   WHY: en pantallas angostas (<640px) las pestañas de `.app-header-nav`
   se ocultan (ver ADR-020) y se reemplazan por este drawer lateral
   estándar con ítems grandes, fáciles de tocar. Comparte el estado `open`
   de Alpine con el botón hamburguesa del header (ver `.app-hamburger-btn`,
   base.html) — un solo trigger, un solo drawer. */

.mobile-nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
}

@media (min-width: 640px) {
  .mobile-nav-overlay {
    display: none !important;
  }
}

.mobile-nav-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
}

.mobile-nav-drawer {
  position: relative;
  z-index: 10;
  width: 82%;
  max-width: 20rem;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #151719;
  border-right: 1px solid var(--corp-chrome-border);
}

.mobile-nav-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem;
  border-bottom: 1px solid var(--corp-chrome-border);
}

.mobile-nav-user {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}

.mobile-nav-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  font-weight: 700;
  color: #ffffff;
  background: var(--corp-accent);
  flex-shrink: 0;
}

.mobile-nav-user-name {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 700;
  color: #ffffff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mobile-nav-user-rol {
  margin: 0;
  font-size: 0.75rem;
  color: #a4a5a6;
}

.mobile-nav-close {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
  border-radius: 0.5rem;
  background: transparent;
  border: none;
  color: #a4a5a6;
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.mobile-nav-close:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

/* WHY: drawer sobre fondo oscuro (`--corp-chrome`) — un outline azul
   (`--corp-accent`, pensado para fondo claro) se perdería de contraste
   acá, por eso blanco puro en vez del token compartido con el resto del
   header. Offset negativo: los 3 controles son de ancho completo/edge-to-
   edge dentro del drawer. */
.mobile-nav-close:focus-visible,
.mobile-nav-item:focus-visible,
.mobile-nav-logout:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: -2px;
}

.mobile-nav-items {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem 0;
}

.mobile-nav-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  font-size: 1rem;
  color: #a4a5a6;
  text-decoration: none;
  transition: background-color 150ms ease-out;
}

.mobile-nav-item.xp-active {
  color: #ffffff;
  background: rgba(59, 130, 246, 0.15);
}

.mobile-nav-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(59, 130, 246, 0.18);
  color: #60a5fa;
  flex-shrink: 0;
}

.mobile-nav-footer {
  padding: 0.75rem;
  border-top: 1px solid var(--corp-border);
}

.mobile-nav-logout {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  border-radius: 0.5rem;
  font-size: 1rem;
  color: #f87171;
  background: transparent;
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 150ms ease-out;
}

.mobile-nav-logout:hover {
  background-color: rgba(255, 255, 255, 0.05);
}

.mobile-nav-logout .mobile-nav-icon {
  background: rgba(239, 68, 68, 0.15);
  color: #f87171;
}

/* ════ componentes.css ════ */
/* Componentes de contenido: badges, campos de formulario, botones (.btn-*), tarjetas
   (.card), tablas (.table-dark), encabezado de página (.page-header/.page-title),
   modales, estado vacío, indicadores (.kpi-card), avisos (.alert-card), pestañas
   (.tab-pill) y segmentador. */

/* ── Badges de estado (docs/UI_DESIGN_SYSTEM.md §5.4) — recipe: fondo 12%,
   texto en un tono ~700 (suficientemente oscuro para fondo claro), borde
   25-30% (ver ADR-013, antes eran tonos claros pensados para fondo oscuro) ─ */

.badge {
  /* WHY: 0.65rem (10.4px) quedaba por debajo del mínimo cómodo de
     legibilidad; 0.7rem (11.2px) mantiene el tamaño compacto del badge
     sin quedar por debajo del resto de la escala tipográfica de meta-
     texto de la app (11-12px, ver ADR-020 Ronda 2). */
  font-size: 0.7rem;
  padding: 0.125rem 0.5rem;
  border-radius: 4px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  background-color: rgba(120, 125, 130, 0.12);
  color: var(--corp-gray);
  border: 1px solid rgba(120, 125, 130, 0.2);
}

.badge-success {
  background-color: rgba(16, 185, 129, 0.12);
  color: #047857;
  border: 1px solid rgba(16, 185, 129, 0.3);
}

.badge-warning {
  background-color: rgba(245, 158, 11, 0.12);
  color: #b45309;
  border: 1px solid rgba(245, 158, 11, 0.3);
}

.badge-danger {
  background-color: rgba(239, 68, 68, 0.12);
  color: #dc2626;
  border: 1px solid rgba(239, 68, 68, 0.3);
}

.badge-info {
  background-color: rgba(59, 130, 246, 0.12);
  color: #1d4ed8;
  border: 1px solid rgba(59, 130, 246, 0.3);
}

.badge-neutral {
  background-color: rgba(120, 125, 130, 0.12);
  color: #5b6167;
  border: 1px solid rgba(120, 125, 130, 0.25);
}

/* WHY: contador dentro de un badge (pestañas de estado de Leads, ver
   leads.html) — `background: rgba(0,0,0,.08)` + `color: inherit` en vez
   de reusar `.card-title .count-pill` (fondo/color fijos) porque acá
   necesita adaptarse al tinte de cada variante de `.badge-*` en vez de
   siempre verse gris. */
.badge .count-pill {
  margin-left: 0.35rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 0.3rem;
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 700;
  background: rgba(0, 0, 0, 0.08);
  color: inherit;
}

/* WHY: reset de `<button>` nativo cuando `.filtro-estado-pill` se usa
   sobre un botón en vez de un `<a>` (ver calendario.html — el filtro de
   tipo no navega, solo cambia estado de Alpine) — sin esto el chrome por
   defecto del navegador (line-height, font-family) desentona con el resto
   de badges clicables de la app. */
button.filtro-estado-pill {
  font-family: inherit;
  line-height: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

/* ── Inputs (§5.1) ────────────────────────────────────────────────────────  */

/* WHY (v0.2.0): Ventas estiliza el elemento; Posventa (React) usa la clase
   `.input` y muchos `<input>` sin `type`. Ambos caminos reciben el mismo
   estilo, para que los campos se vean iguales en los dos aplicativos. */

input[type="text"],
input[type="number"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="date"],
input[type="datetime-local"],
input:not([type]),
select,
textarea,
.input {
  width: 100%;
  padding: 0.625rem 0.875rem;
  border-radius: 0.5rem;
  font-size: 0.7rem;
  color: var(--corp-text);
  background-color: var(--corp-surface);
  border: 1px solid var(--corp-border-strong);
  font-family: inherit;
  transition: all 200ms ease-out;
}

/* WHY (pedido explícito del cliente, sep 2026 — "mejora la estética y
   dimensión" de las cajas de fecha en Abonos y Pagos): `input[type="date"]`
   no estaba en la lista de arriba — se renderizaba con el estilo nativo
   del navegador (sin padding/borde/radio), visiblemente más angosto y
   descuadrado que los campos de monto/banco al lado. El ícono nativo del
   calendario queda pegado al borde derecho por defecto; se le da un poco
   de aire con padding-right y se fuerza `color-scheme:light` para que ese
   ícono (que el navegador pinta él mismo, no un SVG propio) se vea oscuro
   sobre el fondo claro de `--corp-surface` incluso si el sistema operativo
   está en modo oscuro. */
input[type="date"] {
  min-width: 9.5rem;
  padding-right: 0.6rem;
  color-scheme: light;
}

input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.7;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

/* WHY: convención calcada de pitstopIA (pedido explícito del cliente ahí,
   ago 2026) — refuerzo visual inmediato de que el texto libre se guarda en
   mayúsculas, mientras se escribe. Se excluyen email/password (semántica
   distinta, nunca se fuerzan) — select conserva el texto tal cual está
   guardado en el catálogo (marcas, ciudades, etc.), igual que allá. */
input:not([type="email"]):not([type="password"]),
textarea {
  text-transform: uppercase;
}

/* WHY: el mensaje de WhatsApp de Feria es contenido real que se envía tal
   cual al prospecto (con placeholders {nombre}/{marca}/{modelo} en
   minúscula) — forzarlo a mayúsculas como el resto del texto libre de la
   app lo volvería ilegible como mensaje y rompería el reemplazo de
   placeholders (semántica distinta, mismo criterio que email/password de
   arriba). */
textarea[name="mensaje"] {
  text-transform: none;
}

input::placeholder,
textarea::placeholder {
  color: var(--corp-gray-dim);
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  box-shadow: 0 0 0 2px var(--corp-accent);
  border-color: transparent;
}

input:disabled,
select:disabled,
textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

select option {
  background-color: var(--corp-dark);
  color: var(--corp-text);
}

/* WHY: pedido explícito del cliente (ago 2026) — los campos numéricos
   deben ingresarse solo desde el teclado (`type="number"` ya restringe
   eso por sí solo), sin las flechitas nativas de incrementar/decrementar
   del navegador. Se ocultan a nivel visual (Chrome/Safari/Edge vía
   `-webkit-appearance`, Firefox vía `-moz-appearance` en el input mismo)
   — el input sigue siendo `type="number"` (teclado numérico en móvil,
   validación nativa), solo se le quita el control de flechas. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* ── Botones (§5.2) ───────────────────────────────────────────────────────  */

.btn-primary,
.btn-secondary,
.btn-ghost,
.btn-danger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border-radius: 0.5rem;
  font-size: 0.7rem;
  cursor: pointer;
  text-decoration: none;
  transition: all 200ms ease-out;
}

.btn-primary:disabled,
.btn-secondary:disabled,
.btn-ghost:disabled,
.btn-danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary:active,
.btn-secondary:active,
.btn-ghost:active,
.btn-danger:active {
  transform: scale(0.98);
}

.btn-primary:focus-visible,
.btn-secondary:focus-visible,
.btn-ghost:focus-visible,
.btn-danger:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

.btn-primary {
  background-color: var(--corp-accent);
  color: #ffffff;
  font-weight: 600;
  padding: 0.625rem 1rem;
  border: none;
}

.btn-primary:hover {
  background-color: var(--corp-accent-hover);
}

.btn-secondary {
  color: var(--corp-text);
  font-weight: 600;
  padding: 0.625rem 1rem;
  background-color: var(--corp-surface);
  border: 1px solid var(--corp-border-strong);
}

.btn-secondary:hover {
  border-color: var(--corp-gray-dim);
}

.btn-ghost {
  color: var(--corp-gray);
  padding: 0.5rem 0.75rem;
  font-weight: 500;
  background: transparent;
  border: none;
}

.btn-ghost:hover {
  color: var(--corp-text);
  background-color: rgba(0, 0, 0, 0.05);
}

.btn-danger {
  background-color: var(--corp-danger);
  color: #ffffff;
  font-weight: 600;
  padding: 0.625rem 1rem;
  border: none;
}

.btn-danger:hover {
  background-color: #b91c1c;
}

/* ── Cards (§5.3) ─────────────────────────────────────────────────────────  */

.card {
  border-radius: 10px;
  background-color: var(--corp-dark);
  border: 1px solid var(--corp-border);
  overflow: hidden;
}

/* WHY: las tarjetas de catálogo de Parametrización (Marcas/Modelos/Líneas/
   Concesionarios/Orígenes) con tabla `.table-dark` de ancho `auto` (ver
   arriba) dejaban un bloque blanco enorme sin nada — la tarjeta seguía
   estirada a los 1100px de `.page.ancho` aunque su contenido real fuera
   angosto (pedido explícito del cliente, ago 2026: "genera ruido"). La
   tarjeta ahora se ajusta al ancho real de su contenido en vez del ancho
   de la página. */
.card-compacta {
  width: fit-content;
  max-width: 100%;
  min-width: 320px;
}

/* WHY: `.page` tiene 1.25rem (20px) de padding a cada lado — en un
   viewport de 320-360px (celulares comunes) el ancho de contenido
   disponible queda en ~280-320px, menos que el `min-width: 320px` de
   arriba, y la tarjeta desbordaba el viewport (scroll horizontal de toda
   la página, no solo de la tabla — pedido explícito del cliente, ago
   2026: validar responsive en celulares). Por debajo de 480px, la
   tarjeta se ajusta al ancho disponible en vez de forzar un mínimo. */
@media (max-width: 480px) {
  .card-compacta {
    min-width: 0;
  }
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--corp-border);
  flex-wrap: wrap;
}

/* WHY (docs/UI-mejorada/fonts/fonts.md, sep 2026): "Card Title / Subtitle
   (H3): 15px-16px, font-semibold" — antes 0.75rem (12px), quedaba
   apretado frente al resto de la escala. */
.card-title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--corp-text);
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.card-title .count {
  font-weight: 400;
  color: var(--corp-gray);
  font-size: 0.85rem;
}

.card-body {
  padding: 1.25rem;
}

/* ── Tabla (§5.5) ─────────────────────────────────────────────────────────
   WHY: sistema de tablas único para todo el proyecto — el stack (Jinja2 +
   HTMX + CSS vanilla, sin framework de componentes, ver ADR-001) no tiene
   un "componente de tabla" al estilo React/Vue; `.table-dark` dentro de
   un `.tabla-wrap` ES ese componente reutilizable — cualquier listado
   nuevo que use este par de clases hereda automáticamente el ancho
   completo, la distribución de columnas, el padding estándar
   (`--table-cell-py`/`--table-cell-px`, ver `:root`) y el comportamiento
   responsive de acá, sin repetir CSS por vista.

   Historial: antes `.table-dark` a secas dejaba la tabla en `width: auto`
   (angosta, pegada a la izquierda, con el resto de la tarjeta en blanco)
   y hacía falta un modificador `.table-distribuida` aparte para que
   ocupara el ancho completo — pedido explícito del cliente en su momento
   ("no es necesario distribuir sobre el ancho de la caja" para
   Parametrización). Revertido ahora (pedido explícito del cliente, ago
   2026, con captura de la vista de Marcas): "las columnas se ven
   apretadas, desalineadas y con espaciados inconsistentes... evitando que
   el contenido quede pegado a los bordes o con exceso de espacio en
   blanco". El ancho completo pasa a ser el comportamiento POR DEFECTO de
   toda tabla del proyecto — `.table-distribuida` queda solo como
   modificador de `min-width` para tablas con muchas columnas. */

/* WHY: reemplaza el `style="overflow-x:auto;"` que se repetía suelto en
   cada template (17 archivos) — un solo lugar define la estrategia
   responsive del proyecto para tablas: scroll horizontal contenido en vez
   de reflow a tarjetas apiladas (más simple de mantener en un stack sin
   componentes, y ya está probado en producción desde ADR-015). Breakpoint
   de referencia: 640px — el mismo que ya usa el resto de la app
   (`.app-header-nav`, `.mobile-nav-overlay`, etc., ver más abajo, en vez
   de introducir un segundo breakpoint de 768px que fragmentaría el
   estándar). */
.tabla-wrap {
  overflow-x: auto;
}

.table-dark {
  width: 100%;
  min-width: 640px;
  table-layout: fixed;
  font-size: 0.875rem;
  border-collapse: collapse;
}

/* WHY: modificador para tablas con muchas columnas (Feria — Fichas
   técnicas/Prospectos; Parametrización — Marca/Modelo de Feria) que
   necesitan más espacio mínimo que el estándar de 640px antes de que
   `.tabla-wrap` empiece a hacer scroll horizontal — ver ADR-015, pedido
   explícito del cliente: "de manera ecuánime y que ocupen el ancho de la
   caja". */
.table-dark.table-distribuida {
  min-width: 980px;
}

/* WHY: pedido explícito del cliente — solo la tabla "Fichas técnicas" de
   Feria (feria.html) a 0.70rem, sin afectar `.table-dark` en el resto del
   proyecto (Inventario, Gestión, Leads, etc. quedan en 0.875rem). El
   botón "Subir"/"Reemplazar" y el texto nativo "Sin archivos
   seleccionados" del <input type="file"> tienen reglas propias más
   específicas en otro lado (`.form-agregar-compacto .btn-primary` a
   0.8rem, compartida con Parametrización; `.table-dark input[type="file"]`
   a 0.72rem, compartida con Inventario/Documentos) — se sobreescriben acá
   solo para esta tabla con selectores más específicos
   (`.table-dark.tabla-fichas-tecnicas ...`). */
.table-dark.tabla-fichas-tecnicas {
  font-size: 0.7rem;
}

.table-dark.tabla-fichas-tecnicas input[type="file"] {
  font-size: 0.7rem;
}

.table-dark.tabla-fichas-tecnicas .btn-primary {
  font-size: 0.7rem;
}

/* WHY: `white-space: normal` (el default del navegador) deja que tanto
   los encabezados como el contenido de las celdas se partan en varios
   renglones cuando la columna queda angosta ("NÚMERO CELULAR" →
   "NÚME/RO/CELUL/AR", ver images/columnas.PNG, pedido explícito del
   cliente, ago 2026: "no queremos que los nombres de los campos o el
   contenido... se vea en varios renglones") — ahora en TODA tabla del
   sistema, no solo en las que antes tenían `.table-distribuida`. Si una
   columna con contenido genuinamente largo (ej. "Concepto" de un
   trámite/descuento) no alcanza, `.tabla-wrap` permite scroll horizontal
   en vez de partir el texto o truncarlo en silencio. */
.table-dark th,
.table-dark td {
  white-space: nowrap;
}

/* WHY: columnas con valores cortos y fijos que nunca deberían partirse
   (ej. Feria: "Modelo"/"Marca" — BJ30/T5/S5/T1, BAIC/ARCFOX) — con
   `table-layout: fixed`, al angostar la ventana esas columnas quedaban
   tan apretadas que hasta el encabezado se partía letra por letra (ver
   images/ajustesresponsive.PNG, pedido explícito del cliente, ago 2026).
   Ancho fijo en px en vez de `%` — nunca se comprime más allá de esto, el
   resto de la tabla se ajusta alrededor. */
.table-dark .col-angosta {
  width: 74px;
  white-space: nowrap;
  word-break: normal;
}

/* WHY: evita que las etiquetas de los botones de acción se partan letra
   por letra dentro de columnas estrechas ("SUBIR" apilado verticalmente,
   ver images/feria.PNG, pedido explícito del cliente: "no se ve el texto
   del botón"). */
.table-dark .btn-primary,
.table-dark .btn-ghost,
.table-dark .btn-secondary {
  white-space: nowrap;
  word-break: normal;
}

/* WHY: el formulario de subir/reemplazar un archivo (input + botón)
   dentro de una celda ya no intenta caber en una sola línea si la columna
   queda angosta — si no alcanza el ancho, el botón pasa a la línea de
   abajo en vez de comprimirse hasta volverse ilegible. */
.table-dark .form-agregar-compacto {
  flex-wrap: wrap;
}

/* WHY: el texto nativo del input de archivo ("Sin archivos
   seleccionados") hereda el tamaño de fuente normal del formulario y
   ocupaba casi toda la columna Acciones, empujando el botón fuera de
   vista (pedido explícito del cliente, ago 2026: "reduce el tamaño de
   letra de sin archivos seleccionados"). Más chico, solo dentro de
   `.table-dark` — no afecta otros inputs de archivo del resto de la app. */
.table-dark input[type="file"] {
  font-size: 0.72rem;
  max-width: 100%;
}

/* WHY: botón de acción icon-only para filas de tabla angostas (Feria —
   Prospectos: "Enviar ficha técnica") — el texto completo forzaba la fila
   a dos líneas dentro de una columna estrecha, subiendo la altura de cada
   fila (pedido explícito del cliente, ago 2026: "la altura quedó alta...
   asigna una imagen alusiva al envío"). Tamaño fijo, sin depender del
   ancho de la columna. */
.btn-icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  flex-shrink: 0;
}

.table-dark thead tr {
  background-color: rgba(120, 125, 130, 0.06);
  border-bottom: 1px solid var(--corp-border-strong);
}

.table-dark thead th {
  padding: var(--table-cell-py) var(--table-cell-px);
  text-align: left;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--corp-gray);
}

.table-dark tbody tr {
  border-bottom: 1px solid var(--corp-border);
  transition: background-color 150ms ease-out;
}

.table-dark tbody tr:hover {
  background-color: rgba(0, 0, 0, 0.025);
}

.table-dark tbody tr:last-child {
  border-bottom: none;
}

.table-dark tbody td {
  padding: var(--table-cell-py) var(--table-cell-px);
  color: var(--corp-text);
  vertical-align: middle;
}

.table-dark tbody td.muted {
  color: var(--corp-gray);
  font-size: 0.78rem;
}

/* WHY: los inputs de edición inline (Parametrización) heredaban el padding
   de un input de formulario de página completa (0.625rem 0.875rem) — sumado
   al padding de la celda, las filas quedaban mucho más altas que una fila
   de datos normal (pedido explícito del cliente, ago 2026: "se ven
   demasiado grandes"). Más compactos, solo dentro de `.table-dark`. */
.table-dark input[type="text"] {
  width: auto;
  padding: 0.2rem 0.5rem;
  font-size: 0.85rem;
}

.table-dark tr.fila {
  cursor: pointer;
}

/* ── Encabezados de página y formularios (§5.6) ──────────────────────────  */

.page-header {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

@media (min-width: 640px) {
  .page-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

/* WHY (docs/UI-mejorada/fonts/fonts.md, sep 2026): "Page Title (H1):
   24px-28px, font-bold" — antes 1.25rem (20px). */
.page-title {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--corp-text);
  text-wrap: balance;
}

.page-subtitle {
  font-size: 0.85rem;
  margin-top: 0.15rem;
  color: var(--corp-gray);
}

.tab-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid var(--corp-border-strong);
  background: var(--corp-dark);
  color: var(--corp-gray);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 150ms ease-out;
}

.tab-pill:hover {
  border-color: var(--corp-gray-dim);
  color: var(--corp-text);
}

.tab-pill.activo {
  background: var(--corp-accent);
  color: #ffffff;
  border-color: var(--corp-accent);
}

/* WHY (docs/UI-mejorada/fonts/fonts.md, sep 2026): "Form Labels / Headers
   de tabla: 12px-13px, font-medium/semibold" — antes 0.68rem (~11px). */
.form-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  margin-bottom: 0.4rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--corp-gray);
}

/* ── Modales (§5.7) ───────────────────────────────────────────────────────  */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background-color: rgba(20, 22, 25, 0.6);
  backdrop-filter: blur(4px);
  overflow-y: auto;
}

.modal-box {
  width: 100%;
  max-width: 32rem;
  max-height: 90vh;
  overflow-y: auto;
  background-color: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  border-radius: 12px;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.5rem;
  position: sticky;
  top: 0;
  background-color: var(--corp-dark);
  border-bottom: 1px solid var(--corp-border);
  border-radius: 12px 12px 0 0;
}

.modal-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--corp-text);
}

.modal-body {
  padding: 1.25rem 1.5rem;
  font-size: 0.7rem;
}

/* ── Estado vacío (§5.8) ──────────────────────────────────────────────────  */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 4rem 0;
  text-align: center;
}

.empty-state-icon {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 1rem;
  background-color: rgba(120, 125, 130, 0.1);
  color: var(--corp-gray);
}

.empty-state-text {
  font-size: 0.875rem;
  color: var(--corp-gray);
}

/* ── Animaciones (§5.9) ───────────────────────────────────────────────────  */

@keyframes fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
.animate-fadeIn { animation: fadeIn 0.2s ease-out; }

@keyframes slideInLeft { from { transform: translateX(-100%); } to { transform: translateX(0); } }
.animate-slideInLeft { animation: slideInLeft 0.25s ease-out; }

@keyframes spin { to { transform: rotate(360deg); } }
.animate-spin { animation: spin 1s linear infinite; }

.card-title .count-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.35rem;
  height: 1.35rem;
  padding: 0 0.4rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  background: var(--corp-surface);
  color: var(--corp-gray);
}

/* WHY: patrón repetido en 9+ partials de alta rápida (fotos, documentos,
   gastos, descuentos, pagos, accesorios, trámites, retoma) — un formulario
   corto de una sola fila que envuelve en pantallas angostas. Antes vivía
   como `style="display:flex;gap:0.5rem;align-items:center;flex-wrap:wrap;"`
   repetido a mano en cada template (ver checklist "Código" del skill de
   rediseño). */
.form-inline {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
}

.form-inline input,
.form-inline select {
  width: auto;
}

/* ── Páginas de gestión/inventario ────────────────────────────────────────  */

.page {
  padding: 1.5rem 1.25rem;
  max-width: 900px;
  margin: 0 auto;
}

/* WHY: 1100px dejaba franjas vacías grandes a los lados en monitores
   anchos, con tablas de varias columnas (ej. Marca/Modelo de Feria,
   Prospectos) sintiéndose apretadas en vez de aprovechar el espacio
   disponible (pedido explícito del cliente, ago 2026: "la UI aproveche
   todo el ancho de página"). Todos los módulos usan `.page.ancho` (ver
   grep — ninguno usa el `.page` de 900px suelto), así que este único
   valor sube el ancho de forma consistente en toda la app. */
.page.ancho {
  max-width: 1440px;
}

/* WHY (sep 2026, ajuste responsive de Gestión/Prospectos): `minmax(0, 1fr)`
   en vez de `1fr` — una pista `1fr` tiene como mínimo el ancho de su
   contenido, así que una tabla con `min-width` (`.table-dark`, 640px) o un
   correo largo en una celda ensanchaba la columna más allá del viewport y
   empujaba toda la vista de la tarjeta fuera de la pantalla en celular (la
   tarjeta llegaba a medir 704px en un viewport de 360px). Con mínimo 0 la
   columna respeta el ancho disponible y cada tabla hace su propio scroll
   dentro de `.tabla-wrap`. */
.detalle-grid {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}

.detalle-grid > * {
  min-width: 0;
}

@media (max-width: 800px) {
  .detalle-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.form-centrado {
  display: flex;
  justify-content: center;
  padding: 3rem 1rem;
}

/* ── Tarjetas KPI y de alerta (Reportes) — calcadas de pitstopIA
   (Dashboard.tsx: KpiCard/AlertCard) ───────────────────────────────────── */

.kpi-card {
  display: block;
  padding: 1.25rem;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 200ms ease-out;
}

.kpi-card:hover {
  box-shadow: 0 4px 14px rgba(20, 22, 25, 0.08);
}

.kpi-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.kpi-card-icon {
  width: 44px;
  height: 44px;
  border-radius: 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
}

.kpi-card-value {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.kpi-card-label {
  font-size: 0.85rem;
  margin-top: 0.15rem;
  color: var(--corp-gray);
}

/* WHY (pedido explícito del cliente, sep 2026): indicador de color por
   tarjeta KPI (Leads: Total/Nuevos/En gestión/Convertidos/Perdidos, ver
   leads.html) — un punto sólido junto a la etiqueta, del mismo color que
   el ícono y el borde de la tarjeta (`border-color` inline), para que las
   3 señales (ícono, borde, punto) se lean como un solo indicador
   consistente en vez de 3 pistas de color sueltas. */
.kpi-card-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 0.4rem;
  flex-shrink: 0;
}

/* WHY (pedido explícito del cliente, sep 2026 — ADR-081): caja KPI
   inhabilitada (Prospectos) — todo en gris, sin hover, para que se lea
   como "sin datos" y no como un indicador en cero. */
.kpi-card-inhabilitada {
  background: var(--corp-surface);
  border-color: var(--corp-border-strong);
  color: var(--corp-gray);
}

.kpi-card-inhabilitada:hover {
  box-shadow: none;
}

.kpi-card-inhabilitada .kpi-card-icon {
  background-color: #cbd5e1;
}

.kpi-card-inhabilitada .kpi-card-value {
  color: #94a3b8;
}

.kpi-card-inhabilitada .kpi-card-dot {
  background: #cbd5e1;
}

.kpi-card-sin-datos {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--corp-gray);
}

.kpi-card-link {
  margin-top: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--corp-accent);
  opacity: 0;
  transition: opacity 150ms ease-out;
}

.kpi-card:hover .kpi-card-link {
  opacity: 1;
}

.alert-card {
  padding: 1.1rem 1.25rem;
  border-left: 4px solid var(--corp-warning);
}

.alert-card.alert-card-danger {
  border-left-color: var(--corp-danger);
}

/* WHY (pedido explícito del cliente, sep 2026 — referencia
   08_leads_registro_y_radicación_de_nuevo_prospecto): círculo numerado
   para las secciones del formulario de alta de lead (leads_nuevo.html) —
   mismo lenguaje visual que `.app-avatar`/`.kpi-card-icon` (círculo de
   color), en tinte del acento único de la app en vez de un color propio. */
/* WHY (pedido explícito del cliente, sep 2026 — referencia
   08_leads_registro_y_radicación_de_nuevo_prospecto): segmentador Persona
   Natural/Empresa del formulario de alta de lead (ver leads_nuevo.html,
   models/lead.py::TipoClienteLead) — componente nuevo, reutilizable para
   cualquier toggle de 2 opciones futuro (no exclusivo de este formulario). */
.segmentador {
  display: inline-flex;
  background: var(--corp-surface);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
  flex-shrink: 0;
}

.segmentador button {
  border: none;
  background: transparent;
  padding: 0.4rem 0.85rem;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 6px;
  color: var(--corp-gray);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 150ms ease-out, color 150ms ease-out, box-shadow 150ms ease-out;
}

.segmentador button.activo {
  background: var(--corp-dark);
  color: var(--corp-accent);
  box-shadow: 0 1px 3px rgba(20, 22, 25, 0.12);
}

.modal-box.cotizacion-modal {
  max-width: 56rem;
  display: flex;
  flex-direction: column;
}

.alert-card-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.85rem;
}

.alert-card-icon {
  width: 36px;
  height: 36px;
  border-radius: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: rgba(245, 158, 11, 0.12);
  color: var(--corp-warning);
}

.alert-card-danger .alert-card-icon {
  background: rgba(239, 68, 68, 0.12);
  color: var(--corp-danger);
}

.alert-card-title {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--corp-text);
}

.alert-card-sub {
  font-size: 0.75rem;
  color: var(--corp-gray);
  margin-top: 0.1rem;
}

.alert-card-count {
  margin-left: auto;
}

/* ── Responsive de Gestión y Prospectos (sep 2026) ──────────────────────────
   WHY (pedido explícito del cliente, sep 2026: "algunas vistas se están
   sobreponiendo"): `.table-dark` mantiene cada celda en un solo renglón
   (`white-space: nowrap`, pedido de ago 2026) con columnas de ancho fijo
   (`table-layout: fixed`) — cuando el texto de una celda era más largo que
   su columna (nombre, correo, origen del prospecto, nombre de archivo) se
   dibujaba ENCIMA de la columna siguiente. Estas reglas conservan el
   renglón único pero recortan lo que no cabe con "…" (el valor completo
   queda en el `title` de cada celda en la plantilla). Acotado a las tablas
   de Gestión y Prospectos (modificador `.tabla-recortada`) en vez de
   `.table-dark` global: otras tablas (Inventario, Parametrización) llevan
   formularios dentro de las celdas que un `overflow: hidden` podría cortar. */
.table-dark.tabla-recortada th,
.table-dark.tabla-recortada td,
.table-dark.tabla-prospectos th,
.table-dark.tabla-prospectos td {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* WHY: 7 columnas con 2-3 datos apilados cada una no caben en 640px (el
   mínimo general de `.table-dark`) sin recortar casi todo — con 1200px la
   tabla se ve completa en un monitor normal y, en pantallas más angostas,
   `.tabla-wrap` hace scroll horizontal en vez de apretar las columnas. */
.table-dark.tabla-prospectos {
  min-width: 1200px;
}

/* WHY: 2 columnas de formulario (seguimiento en Vista Prospecto y en el
   modal de Gestión) — antes `1fr 1fr` inline: en celular el select "Tipo
   de contacto" quedaba cortado ("Sin especi…"). Una sola columna por
   debajo de 480px. */
.form-grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem;
}

@media (max-width: 480px) {
  .form-grid-2 {
    grid-template-columns: minmax(0, 1fr);
  }

  .form-grid-2 > * {
    grid-column: 1 / -1;
  }
}

.tab-pill-conteo {
  display: inline-block;
  min-width: 1.5rem;
  padding: 0.05rem 0.4rem;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.07);
  color: var(--corp-gray);
  font-size: 0.72rem;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.tab-pill.activo .tab-pill-conteo {
  background: rgba(255, 255, 255, 0.22);
  color: #ffffff;
}

.table-dark.param-tabla {
  min-width: 760px;
}

.table-dark.param-tabla thead tr {
  background: transparent;
}

.table-dark.param-tabla thead th {
  padding: 1rem 1.5rem;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--corp-gray);
}

.table-dark.param-tabla tbody td {
  padding: 0.85rem 1.5rem;
}

.table-dark.param-tabla th.param-col-acciones,
.table-dark.param-tabla td.param-col-acciones {
  text-align: right;
}

.table-dark.feria-tabla {
  min-width: 1040px;
}

button.feria-variable {
  cursor: pointer;
}

button.feria-variable:hover {
  border-style: solid;
  border-color: var(--corp-accent);
}

/* La lista de horas sale de la tarjeta (`.card` recorta con overflow). */
.card.card-desborde {
  overflow: visible;
}

/* WHY (ADR-116): Orden de Pedido en Prospecto (sin caja de pasos, ADR-114):
   las dos cajas de la columna izquierda pasan a ocupar todo el ancho. */
.detalle-grid-sin-pasos {
  grid-template-columns: minmax(0, 1fr);
}

.detalle-grid-sin-pasos > .workspace {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

@media (max-width: 800px) {
  .detalle-grid-sin-pasos > .workspace {
    grid-template-columns: minmax(0, 1fr);
  }
}

@keyframes alerta-emergente-entra {
  from { opacity: 0; transform: translateX(1.5rem); }
  to { opacity: 1; transform: none; }
}

@keyframes alerta-emergente-tiempo {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}
.btn-link { background: none; border: 0; padding: 0; color: var(--corp-danger, #c0392b); cursor: pointer; font: inherit; }

/* Aviso de error de un formulario o de la pantalla de ingreso (v0.2.0, antes
   en los estilos propios de Ventas). */
.error,
.error-banner {
  font-size: 0.85rem;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: rgba(239, 68, 68, 0.1);
  color: #b91c1c;
}

.error-banner svg {
  flex-shrink: 0;
}

/* ════ login.css ════ */
/* Pantalla de ingreso: panel de marca oscuro a la izquierda y formulario a la derecha. */

/* ── Login — pantalla dividida (marca a la izquierda, formulario a la
   derecha) — ver imagen de referencia en la conversación de diseño. El
   panel de marca se mantiene como "chrome" oscuro deliberado (ver
   ADR-013), el panel de formulario es claro. ──────────────────────────── */

.login-split {
  min-height: 100dvh;
  display: flex;
}

/* WHY (docs/UI-mejorada/, sep 2026 — alineación visual al login aprobado,
   screen 01): proporción 58/42 entre panel oscuro y panel de formulario
   (antes 50/50, `flex:1` en ambos), marca chica fija arriba (`.login-
   brand-mark`) separada del bloque de título centrado verticalmente
   (`.login-brand-content`, ya no contiene el logo ni la lista de
   features — la referencia no las muestra). */
.login-brand {
  flex: 1.4;
  display: flex;
  flex-direction: column;
  padding: 3rem 2.5rem;
  background:
    linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(160deg, var(--corp-chrome) 0%, var(--corp-chrome-2) 100%);
  background-size: 32px 32px, 32px 32px, 100% 100%;
  border-right: 1px solid var(--corp-chrome-border);
}

.login-brand-mark {
  display: flex;
}

/* WHY (pedido explícito del cliente, sep 2026, ver logo.png/screen.png):
   el logo real de la empresa en vez del texto "CCV"/"Compañía Colombiana
   de Vehículos" dibujado con CSS — ver el WHY en login.html sobre por qué
   es un archivo blanco aparte (`logo-empresa-blanco.png`) y no un filtro
   CSS sobre el logo oscuro de siempre. */
.login-brand-logo {
  height: 8cap;
  width: auto;
  max-width: 320px;
  object-fit: contain;
  object-position: left center;
}

.login-brand-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 1rem;
  max-width: 28rem;
  text-align: left;
}

.login-brand-title {
  margin: 0;
  font-size: 2.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: #ffffff;
  text-wrap: balance;
}

.login-brand-subtitle {
  margin: 0;
  color: var(--corp-chrome-muted);
  font-size: 0.95rem;
  line-height: 1.5;
}

.login-brand-subtitle strong {
  color: #ffffff;
  font-weight: 700;
}

.login-form-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 2rem 1.5rem;
}

.login-card {
  width: 100%;
  max-width: 23rem;
  background-color: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  border-radius: 12px;
}

.login-card-header {
  padding: 1.25rem 1.5rem 1rem;
  border-bottom: 1px solid var(--corp-border);
}

.login-card-title {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 1rem;
  font-weight: 700;
  color: var(--corp-text);
}

/* WHY (docs/UI-mejorada/, sep 2026): el ícono de llave pasa de un simple
   SVG en línea a una insignia cuadrada con esquinas redondeadas (fondo
   celeste, icono azul) — calcado de la referencia aprobada. */
.login-card-title-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--corp-accent-dim);
  color: var(--corp-accent);
}

.login-card-subtitle {
  margin: 0.25rem 0 0 2.9rem;
  font-size: 0.8rem;
  color: var(--corp-gray);
}

.login-card-body {
  padding: 1.25rem 1.5rem 1.5rem;
}

.login-field {
  position: relative;
  display: flex;
  align-items: center;
}

.login-field-icon {
  position: absolute;
  left: 0.75rem;
  color: var(--corp-gray-dim);
  pointer-events: none;
}

.login-field input {
  padding-left: 2.25rem;
}

.login-field-toggle {
  position: absolute;
  right: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0.25rem;
  color: var(--corp-gray-dim);
  cursor: pointer;
}

.login-field-toggle:hover {
  color: var(--corp-gray);
}

.login-field:has(.login-field-toggle) input {
  padding-right: 2.25rem;
}

/* WHY (docs/UI-mejorada/, sep 2026): botón propio del login — la
   referencia usa un degradado claro con texto oscuro en vez del
   `.btn-primary` sólido azul del resto de la app; se deja como clase
   aparte para no alterar el botón primario compartido por toda la
   herramienta. */
.login-submit-btn {
  margin-top: 1.25rem;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid var(--corp-border-strong);
  background: linear-gradient(180deg, #ffffff 0%, #dde3ea 100%);
  color: var(--corp-text);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  transition: filter 150ms ease-out, transform 150ms ease-out;
}

.login-submit-btn:hover {
  filter: brightness(0.97);
}

.login-submit-btn:active {
  transform: scale(0.98);
}

.login-submit-btn:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

.login-form-footer {
  margin: 0;
  color: var(--corp-gray-dim);
  font-size: 0.78rem;
  text-align: center;
}

@media (max-width: 760px) {
  .login-split {
    flex-direction: column;
  }
  .login-brand {
    flex: none;
    padding: 2.5rem 1.5rem;
    border-right: none;
    border-bottom: 1px solid var(--corp-chrome-border);
  }
  .login-brand-content {
    align-items: flex-start;
  }
  .login-form-panel {
    padding: 2.5rem 1.5rem 3rem;
  }
}

/* ════ catalogo.css ════ */
/* Catálogos (nació en Parametrización de Ventas, de ahí el prefijo .param-): migas,
   título con chip e indicadores, secciones con buscador y filtro, tablas con avatar
   de iniciales, chips de estado, acciones y paginación. */

/* ── Parametrización: rediseño (sep 2026) ────────────────────────────────
   WHY (pedido explícito del cliente, con referencia visual "Catálogo
   Maestro de Marcas"): encabezado con migas + indicadores, panel de
   pestañas agrupadas con contadores, y cada catálogo como sección con su
   alta, buscador/filtro y tabla paginada (Alpine `paramCatalogo()`, ver
   parametrizacion.html). Clases propias `param-*` en vez de tocar
   `.table-dark`/`.tab-pill` globales — Reportes/Inventario/Feria los
   siguen usando tal cual. */
.param-encabezado {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1.25rem;
  flex-wrap: wrap;
  padding-bottom: 1.5rem;
  margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--corp-border-strong);
}

.param-encabezado-texto {
  flex: 1 1 28rem;
  min-width: 0;
}

.param-migas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.85rem;
  color: var(--corp-gray);
  margin-bottom: 0.35rem;
}

.param-migas a {
  color: inherit;
  text-decoration: none;
}

.param-migas a:hover {
  color: var(--corp-text);
}

.param-migas-sep {
  color: var(--corp-gray-dim);
  opacity: 0.7;
}

.param-migas-actual {
  color: var(--corp-accent);
  font-weight: 500;
}

.param-titulo-fila {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.param-titulo {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--corp-text);
  margin: 0;
  text-wrap: balance;
}

.param-chip-global {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  color: #047857;
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.35);
  white-space: nowrap;
}

.param-descripcion {
  margin: 0.45rem 0 0;
  max-width: 62rem;
  font-size: 0.875rem;
  color: var(--corp-gray);
  line-height: 1.5;
}

.param-kpis {
  display: flex;
  background: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  border-radius: 12px;
  padding: 0.6rem 0.25rem;
}

.param-kpi {
  padding: 0.2rem 1.35rem;
  text-align: center;
  min-width: 0;
}

.param-kpi + .param-kpi {
  border-left: 1px solid var(--corp-border-strong);
}

.param-kpi-etiqueta {
  display: block;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--corp-gray-dim);
}

.param-kpi-valor {
  display: block;
  font-size: 1.35rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--corp-text);
}

/* Panel de pestañas agrupadas */
.param-nav {
  background: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  border-radius: 12px;
  padding: 0.35rem 1.25rem;
  margin-bottom: 1.75rem;
}

.param-nav-fila {
  display: grid;
  grid-template-columns: 10.5rem minmax(0, 1fr);
  align-items: center;
  gap: 0.75rem;
  padding: 0.9rem 0;
}

.param-nav-fila + .param-nav-fila {
  border-top: 1px solid var(--corp-border-strong);
}

.param-nav-etiqueta {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--corp-gray-dim);
}

.param-nav-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
}

.param-nav .tab-pill {
  background: var(--corp-surface);
  border-color: transparent;
  color: var(--corp-text);
  font-size: 0.875rem;
  padding: 0.5rem 0.95rem;
  text-decoration: none;
}

.param-nav .tab-pill:hover {
  background: var(--corp-darker);
  border-color: transparent;
}

.param-nav .tab-pill:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

.param-nav .tab-pill svg {
  color: var(--corp-gray);
}

.param-nav .tab-pill.activo {
  background: var(--corp-accent);
  color: #ffffff;
  box-shadow: 0 1px 2px rgba(37, 99, 235, 0.35);
}

.param-nav .tab-pill.activo svg {
  color: #ffffff;
}

/* Sección de catálogo: cabecera + alta + barra de búsqueda/filtro */
.param-seccion {
  background: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  border-radius: 12px;
  padding: 1.35rem 1.5rem;
}

.param-seccion-cabecera {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
}

.param-seccion-titulo {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--corp-text);
  margin: 0;
}

.param-conteo {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.55rem;
  border-radius: 6px;
  background: var(--corp-surface);
  border: 1px solid var(--corp-border);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--corp-text);
  font-variant-numeric: tabular-nums;
}

.param-seccion-desc {
  margin: 0.3rem 0 0;
  font-size: 0.85rem;
  color: var(--corp-gray);
  max-width: 44rem;
}

.param-alta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.param-alta input[type="text"],
.param-alta input[type="number"],
.param-alta select {
  height: 2.6rem;
  font-size: 0.875rem;
}

.param-alta .btn-primary {
  height: 2.6rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border-radius: 8px;
  white-space: nowrap;
}

.param-alta .param-check {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  color: var(--corp-gray);
  white-space: nowrap;
}

.param-input-icono {
  position: relative;
  flex: 1 1 15rem;
  min-width: 0;
  max-width: 22rem;
}

.param-input-icono svg {
  position: absolute;
  left: 0.8rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--corp-gray-dim);
  pointer-events: none;
}

.param-input-icono input {
  width: 100%;
  padding-left: 2.35rem;
}

.param-barra {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.15rem;
  padding-top: 1.15rem;
  border-top: 1px solid var(--corp-border-strong);
}

.param-barra .param-input-icono {
  max-width: 24rem;
}

.param-barra .param-input-icono input {
  height: 2.4rem;
  font-size: 0.85rem;
  text-transform: none;
}

.param-filtros {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.param-filtros-etiqueta {
  font-size: 0.85rem;
  color: var(--corp-gray);
  white-space: nowrap;
}

.param-filtros select {
  min-width: 14rem;
  height: 2.4rem;
  font-size: 0.85rem;
}

.param-btn-cuadrado {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 8px;
  border: 1px solid var(--corp-border-strong);
  background: var(--corp-dark);
  color: var(--corp-gray);
  cursor: pointer;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}

.param-btn-cuadrado:hover {
  background: var(--corp-surface);
  color: var(--corp-text);
}

.param-btn-cuadrado:active {
  transform: translateY(1px);
}

/* Tabla del catálogo */
.param-tabla-card {
  margin-top: 1.25rem;
  background: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  border-radius: 12px;
  overflow: hidden;
}

.param-nombre {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  min-width: 0;
}

.param-nombre-texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.param-nombre-texto strong {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--corp-text);
  overflow: hidden;
  text-overflow: ellipsis;
}

.param-nombre-sub {
  font-size: 0.75rem;
  color: var(--corp-gray-dim);
  overflow: hidden;
  text-overflow: ellipsis;
}

.param-avatar {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.35rem;
  height: 2.35rem;
  border-radius: 8px;
  font-size: 0.8rem;
  font-weight: 700;
  color: #ffffff;
  background: #1f2937;
}

.param-avatar-0 { background: #111827; }
.param-avatar-1 { background: #dc2626; }
.param-avatar-2 { background: #1d4ed8; }
.param-avatar-3 { background: #d97706; }
.param-avatar-4 { background: #b91c1c; }
.param-avatar-5 { background: #334155; }
.param-avatar-6 { background: #059669; }
.param-avatar-7 { background: #7c3aed; }

/* Ícono en vez de iniciales (concesionarios, orígenes, ferias...) */
.param-avatar-icono {
  background: var(--corp-accent-dim);
  color: var(--corp-accent-hover);
}

.param-pastilla {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
  background: var(--corp-surface);
  border: 1px solid var(--corp-border-strong);
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--corp-text);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.param-pastilla-alerta {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.45);
  color: #b45309;
}

.param-pastilla-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.04em;
}

.param-estado {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid transparent;
}

.param-estado::before {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: currentColor;
}

.param-estado-ok {
  color: #047857;
  background: rgba(16, 185, 129, 0.1);
  border-color: rgba(16, 185, 129, 0.35);
}

.param-estado-pendiente {
  color: #b45309;
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.4);
}

.param-estado-inactivo {
  color: var(--corp-gray);
  background: rgba(120, 125, 130, 0.1);
  border-color: rgba(120, 125, 130, 0.3);
}

/* Acciones como enlaces de texto separados por una línea fina */
.param-acciones {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: nowrap;
}

.param-acciones > * + * {
  border-left: 1px solid var(--corp-border-strong);
}

.param-accion {
  background: none;
  border: none;
  padding: 0.15rem 0.8rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--corp-gray);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}

.param-acciones > .param-accion:last-child {
  padding-right: 0;
}

.param-accion:hover {
  color: var(--corp-text);
  text-decoration: underline;
}

.param-accion:focus-visible {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.param-accion-principal {
  color: var(--corp-accent);
}

.param-accion-principal:hover {
  color: var(--corp-accent-hover);
}

.param-accion-peligro {
  color: var(--corp-danger);
}

.param-accion-peligro:hover {
  color: #b91c1c;
}

.param-accion-guardar {
  color: var(--corp-accent);
  font-weight: 600;
}

/* Archivo: logotipo / ficha técnica */
.param-archivo {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  min-width: 0;
}

.param-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 6rem;
  height: 2.75rem;
  padding: 0.35rem 0.55rem;
  border-radius: 6px;
  border: 1px solid var(--corp-border-strong);
  background: var(--corp-dark);
  flex-shrink: 0;
}

.param-logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.param-archivo-cambiar {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--corp-accent);
  cursor: pointer;
  white-space: nowrap;
}

.param-archivo-cambiar:hover {
  color: var(--corp-accent-hover);
  text-decoration: underline;
}

.param-archivo-subir {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.9rem;
  border: 1px dashed var(--corp-border-strong);
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--corp-text);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 150ms ease-out, background-color 150ms ease-out;
}

.param-archivo-subir:hover {
  border-color: var(--corp-accent);
  background: var(--corp-accent-dim);
}

.param-archivo-cambiar:focus-within,
.param-archivo-subir:focus-within {
  outline: 2px solid var(--corp-accent);
  outline-offset: 2px;
}

.param-sin-archivo {
  font-size: 0.8rem;
  font-style: italic;
  color: var(--corp-gray-dim);
  white-space: nowrap;
}

.param-enlace-archivo {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  max-width: 14rem;
  font-size: 0.85rem;
  color: var(--corp-accent);
  overflow: hidden;
  text-overflow: ellipsis;
}

.param-error-fila {
  margin: 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--corp-danger);
  white-space: normal;
}

/* Pie: conteo + paginación */
.param-pie {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.95rem 1.5rem;
  border-top: 1px solid var(--corp-border-strong);
  font-size: 0.875rem;
  color: var(--corp-gray);
}

.param-pie strong {
  color: var(--corp-text);
  font-variant-numeric: tabular-nums;
}

.param-paginacion {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.param-pagina {
  min-width: 2.1rem;
  height: 2.1rem;
  padding: 0 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--corp-border-strong);
  background: var(--corp-dark);
  color: var(--corp-text);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}

.param-pagina:hover:not(:disabled) {
  background: var(--corp-surface);
}

.param-pagina:disabled {
  color: var(--corp-gray-dim);
  cursor: default;
  opacity: 0.7;
}

.param-pagina.activa {
  background: var(--corp-accent);
  border-color: var(--corp-accent);
  color: #ffffff;
}

.param-vacio {
  padding: 2.5rem 1.5rem;
  text-align: center;
  color: var(--corp-gray);
  font-size: 0.9rem;
}

.param-vacio svg {
  display: block;
  margin: 0 auto 0.6rem;
  color: var(--corp-gray-dim);
}

.param-tabla tr[hidden] {
  display: none;
}

/* Apariencia y formatos */
.param-apariencia-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}

.param-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 8.5rem;
  border-radius: 10px;
  border: 1px solid var(--corp-border-strong);
  background: var(--corp-light);
  overflow: hidden;
  margin: 1rem 0;
}

.param-preview img {
  max-height: 100%;
  max-width: 100%;
  object-fit: contain;
}


.param-subida {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.param-textarea {
  width: 100%;
  margin-top: 0.4rem;
  text-transform: none;
  line-height: 1.5;
}

@media (max-width: 900px) {
  .param-kpis {
    width: 100%;
    justify-content: space-around;
  }

  .param-apariencia-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 640px) {
  .param-titulo {
    font-size: 1.4rem;
  }

  .param-kpi {
    padding: 0.2rem 0.75rem;
  }

  .param-nav-fila {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
  }

  .param-seccion {
    padding: 1.1rem;
  }

  .param-alta,
  .param-input-icono,
  .param-barra .param-input-icono {
    width: 100%;
    max-width: none;
  }

  .param-alta .btn-primary {
    width: 100%;
    justify-content: center;
  }

  .param-filtros,
  .param-filtros select {
    width: 100%;
    min-width: 0;
  }

  .param-filtros select {
    flex: 1 1 auto;
  }

  .param-pie {
    padding: 0.85rem 1rem;
  }
}

/* WHY: ajustes del rediseño de Parametrización tras verlo en el navegador:
   (1) `input[type=search]` no está en la regla global de campos, así que
   salía con el borde negro del navegador; (2) la regla global que pasa a
   MAYÚSCULAS el texto libre también afectaba el texto de ejemplo — se
   conserva para lo que se escribe, no para el placeholder; (3) el `select`
   global es `width:100%`, lo que apilaba "Filtrar por" en 3 renglones. */
.param-input-icono input[type="search"] {
  width: 100%;
  padding: 0.55rem 0.875rem 0.55rem 2.35rem;
  border-radius: 0.5rem;
  font-family: inherit;
  color: var(--corp-text);
  background: var(--corp-dark);
  border: 1px solid var(--corp-border-strong);
  transition: border-color 150ms ease-out, box-shadow 150ms ease-out;
}

.param-input-icono input[type="search"]:focus {
  outline: none;
  border-color: var(--corp-accent);
  box-shadow: 0 0 0 3px var(--corp-accent-dim);
}

.param-alta input::placeholder,
.param-barra input::placeholder {
  text-transform: none;
}

.param-alta input[type="text"],
.param-alta input[type="number"] {
  background: var(--corp-dark);
}

.param-filtros select {
  width: auto;
  flex: 0 1 auto;
  background-color: var(--corp-dark);
}

.param-alta select {
  width: auto;
}

.param-alta .btn-primary {
  font-size: 0.875rem;
  padding: 0 1.1rem;
}

/* WHY: el `<input type=file>` oculto (`.input-archivo-oculto`, absoluto) se
   posicionaba respecto de la página y no de su etiqueta — en celular,
   dentro de una tabla con scroll horizontal, ensanchaba toda la página. */
.param-archivo-cambiar,
.param-archivo-subir {
  position: relative;
}

@media (max-width: 640px) {
  .param-alta select,
  .param-filtros select {
    width: 100%;
    flex: 1 1 0;
  }

  .param-filtros-etiqueta {
    flex-basis: 100%;
  }
}

/* WHY: clase y no `style="display:flex"` en línea — `x-show` de Alpine
   reescribe `style.display` al mostrar la pestaña y borraba el flex. */
.param-apariencia {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.param-textarea {
  font-size: 0.875rem;
}

.param-seccion .btn-primary {
  font-size: 0.875rem;
  border-radius: 8px;
}

.param-accion.feria-enlace {
  padding: 0;
  font-size: 0.8rem;
}

/* ADR-118: formato del recibo de caja en Parametrización → Apariencia y formatos. */
.param-recibo-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem 1rem;
  margin-top: 0.75rem;
}

.param-recibo-form label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--corp-gray);
}

.param-recibo-ancho {
  grid-column: 1 / -1;
}

/* WHY: razón social, dirección y nota se guardan tal cual se escriben (el
   formulario global pasa los campos a mayúsculas). */
.param-campo-libre {
  text-transform: none;
}

@media (max-width: 640px) {
  .param-recibo-form { grid-template-columns: 1fr; }
}

/* ADR-125: casillas de la alerta en Parametrización → Apariencia y formatos. */
.param-alerta-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

.param-check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: 0.85rem;
  cursor: pointer;
}

.param-check input { margin-top: 0.2rem; }

.param-check small { color: var(--corp-gray); }

.param-check-inactivo { opacity: 0.55; }

/* ADR-126: Parametrización → Apariencia y formatos, en tarjetas de 2 columnas
   (referencia del cliente). Clases `apar-*`; reusa .param-textarea y
   .param-recibo-form. */
.param-apariencia.apar-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
  align-items: start;
}

@media (max-width: 900px) {
  .param-apariencia.apar-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
