/* ==========================================================================
   DESIGN SYSTEM PQG — sistema visual único de la aplicación.

   Una sola hoja para toda PQG: **ningún módulo trae CSS propio** (encargo §2).
   Los componentes se nombran por lo que SON, no por dónde se usan, de modo que
   la misma tarjeta sirve en el Dashboard, en CxC y en Compras.

   Esta pasada es VISUAL. No cambia ninguna regla de negocio, ningún cálculo,
   ningún estado y ningún Permiso: sólo cómo se ve lo que la vista ya entrega.

   Compatibilidad: **todas las clases anteriores siguen existiendo**. La pasada
   redefine su aspecto, no su nombre, así que las 163 plantillas adoptan el
   sistema sin reescribirse una a una.

   Índice
     1. Tokens (color, tipografía, espacio, radio, sombra)
     2. Base y accesibilidad
     3. Layout: barra lateral, barra superior, área de trabajo
     4. Encabezado de pantalla
     5. Iconos
     6. Tarjeta de sección (panel) y rejillas
     7. Franja de indicadores (KPI) y tendencia
     8. Tarjetas de acción y accesos rápidos
     9. Botones
    10. Estados: badges, avisos, marcas
    11. Tablas
    12. Pestañas y barra de filtros
    13. Formularios
    14. Progreso, listas de comprobación y listas compactas
    15. Gráficas
    16. Calendario
    17. Panel de detalle, ficha y rejilla de Permisos
    18. Estado vacío y utilidades
    19. Responsive
   ========================================================================== */

/* ------------------------------------------------------------- 1. TOKENS */

:root {
  /* Superficies y texto -------------------------------------------------- */
  --c-bg:            #f2f5f9;
  --c-surface:       #ffffff;
  --c-surface-alt:   #f7f9fc;
  --c-surface-sunk:  #eef2f7;
  --c-border:        #e2e7ef;
  --c-border-strong: #cfd6e2;
  --c-border-soft:   #edf0f5;
  --c-text:          #131924;
  --c-text-2:        #4e5a6b;
  --c-text-3:        #778394;

  /* Primario — azul de producto ----------------------------------------- */
  --c-accent:        #1668c4;
  --c-accent-dark:   #10508f;
  --c-accent-soft:   #e8f1fc;
  --c-accent-line:   #bdd6f2;

  /* Paleta de SERIES — sólo para gráficas de varias series (`Progreso de
     comisiones`). NO son estados y no significan nada por sí mismos: sirven
     para distinguir una serie de otra, y **siempre** van acompañadas de una
     leyenda con el nombre. Ocho matices con contraste suficiente entre sí y
     sobre `--c-surface`; a partir del noveno se repiten, y quien identifica la
     barra es el globo, no el color. */
  --c-serie-0: #1668c4;  --c-serie-1: #0e8f9c;  --c-serie-2: #96660c;
  --c-serie-3: #5b41ab;  --c-serie-4: #1c7a44;  --c-serie-5: #b03028;
  --c-serie-6: #2b6a86;  --c-serie-7: #8a4a86;

  /* Turquesa — categoría secundaria, nunca un estado --------------------- */
  --c-teal:          #0e8f9c;
  --c-teal-soft:     #e2f4f6;
  --c-teal-line:     #b4dfe4;

  /* Navegación ----------------------------------------------------------- */
  --c-nav-bg:        #101725;
  --c-nav-bg-2:      #18202f;
  --c-nav-text:      #9fabbd;
  --c-nav-text-2:    #6e7a8c;
  --c-nav-active:    #1e293b;
  --c-nav-mark:      #4d9fe6;
  --c-nav-line:      #232d3e;

  /* Estados — el significado del color es el MISMO en toda PQG ----------- */
  --s-info-bg:  #eef2f7;  --s-info-fg:  #44506380;  --s-info-bd:  #d6dde7;
  --s-ok-bg:    #e7f5ec;  --s-ok-fg:    #1c7a44;    --s-ok-bd:    #b6e0c6;
  --s-aten-bg:  #fdf4e3;  --s-aten-fg:  #96660c;    --s-aten-bd:  #ecd5a4;
  --s-revi-bg:  #f1ecfb;  --s-revi-fg:  #5b41ab;    --s-revi-bd:  #d5c9f0;
  --s-bloq-bg:  #fdecea;  --s-bloq-fg:  #b03028;    --s-bloq-bd:  #f2c3bf;

  /* Tipografía ----------------------------------------------------------- */
  --fs-xs:  11px;
  --fs-sm:  12px;
  --fs:     13px;
  --fs-md:  14px;
  --fs-lg:  16px;
  --fs-xl:  20px;
  --fs-2xl: 26px;
  --ff: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --ff-num: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Espacio, radio, sombra ----------------------------------------------- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;

  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  --shadow-xs: 0 1px 2px rgba(16, 24, 40, .04);
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .04);
  --shadow:    0 1px 3px rgba(16, 24, 40, .06), 0 4px 10px -4px rgba(16, 24, 40, .06);
  --shadow-md: 0 2px 6px rgba(16, 24, 40, .07), 0 12px 24px -12px rgba(16, 24, 40, .12);

  --nav-w: 236px;
  --wa-max: 1500px;
  /* Alto de la barra superior: la cabecera fija de una tabla se detiene justo
     debajo, en vez de deslizarse por detrás. */
  --topbar-h: 43px;
}

/* Corrección del token de texto informativo (se escribe entero, sin alfa). */
:root { --s-info-fg: #445063; }

/* --------------------------------------------- 2. BASE Y ACCESIBILIDAD */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--ff);
  font-size: var(--fs);
  color: var(--c-text);
  background: var(--c-bg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--c-accent); text-underline-offset: 2px; }
a:hover { color: var(--c-accent-dark); }

h1, h2, h3, h4 { font-weight: 650; letter-spacing: -.01em; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--fs-sm);
  background: var(--c-surface-sunk);
  padding: 1px 5px;
  border-radius: var(--radius-sm);
}

/* Un foco visible SIEMPRE, con el mismo anillo en toda la aplicación. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.skip-link { position: absolute; left: -9999px; }
.skip-link:focus {
  left: var(--sp-2); top: var(--sp-2); z-index: 60;
  background: #fff; padding: 10px 14px; border: 1px solid var(--c-border);
  border-radius: var(--radius); box-shadow: var(--shadow-md);
}

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

/* ------------------------------------------------------------ 3. LAYOUT */

/* --- Anclas internas y la barra superior fija -----------------------------
   La `.topbar` es `sticky` en lo alto del documento, así que al pulsar un
   ancla del menú de secciones de una ficha 360° el navegador dejaba el título
   **debajo** de ella, cortado. `scroll-padding-top` en el contenedor que
   scrollea —que es el documento— lo resuelve **de una vez para toda PQG**: no
   hace falta una regla por plantilla ni un `scroll-margin-top` repetido en
   cada `id`, y cualquier ancla futura nace ya corregida.

   El valor es la altura de la barra más un respiro, para que el título quede
   visible **completo** y no pegado al borde. */
html { scroll-padding-top: calc(var(--topbar-h) + var(--sp-4)); }

.app { display: flex; min-height: 100vh; }

/* --- Barra lateral oscura ---------------------------------------------- */

.nav {
  width: var(--nav-w);
  flex: 0 0 var(--nav-w);
  background: var(--c-nav-bg);
  color: var(--c-nav-text);
  padding: 14px 12px 20px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  align-self: flex-start;
  max-height: 100vh;
  overflow-y: auto;
  scrollbar-width: thin;
}

.nav__brand {
  display: flex; align-items: center; justify-content: center;
  min-height: 72px;
  margin: -14px -12px 8px;
  padding: 14px 18px 13px;
  border-bottom: 1px solid var(--c-border);
  background: var(--c-surface);
}
.nav__brand-logo {
  display: block;
  width: 100%; max-width: 114px; height: auto;
}

.nav__group {
  padding: 14px 10px 5px;
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; color: var(--c-nav-text-2);
}

.nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; margin-bottom: 1px;
  color: var(--c-nav-text); text-decoration: none;
  font-size: var(--fs); min-height: 34px;
  border-radius: var(--radius-sm);
  transition: background .12s ease, color .12s ease;
}
.nav a .ic { width: 16px; height: 16px; flex: 0 0 16px; opacity: .8; }
.nav a:hover { background: var(--c-nav-bg-2); color: #fff; }
.nav a:hover .ic { opacity: 1; }
.nav a[aria-current="page"] {
  background: var(--c-nav-active); color: #fff; font-weight: 550;
  box-shadow: inset 2px 0 0 var(--c-nav-mark);
}
.nav a[aria-current="page"] .ic { color: var(--c-nav-mark); opacity: 1; }

/* Pie de la barra: quién soy y cómo salgo. */
.nav__foot {
  margin-top: auto; padding: 12px 10px 0;
  border-top: 1px solid var(--c-nav-line);
  font-size: var(--fs-sm); color: var(--c-nav-text);
  display: flex; align-items: center; gap: 10px;
}
.nav__avatar {
  width: 30px; height: 30px; flex: 0 0 30px;
  border-radius: var(--radius-pill);
  background: var(--c-nav-active); color: #fff;
  display: grid; place-items: center;
  font-size: var(--fs-sm); font-weight: 650;
}
.nav__who { min-width: 0; flex: 1 1 auto; }
.nav__who b { display: block; color: #fff; font-weight: 550;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav__foot form { margin: 0; }
.nav__foot button {
  background: none; border: 0; color: var(--c-nav-text-2);
  padding: 6px; cursor: pointer; min-height: 30px;
  border-radius: var(--radius-sm); display: grid; place-items: center;
}
.nav__foot button:hover { color: #fff; background: var(--c-nav-bg-2); }
.nav__foot button .ic { width: 16px; height: 16px; }

/* --- Área principal ----------------------------------------------------- */

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  background: var(--c-surface);
  border-bottom: 1px solid var(--c-border);
  padding: 11px 26px;
  font-size: var(--fs-sm); color: var(--c-text-2);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 20;
}
.topbar a { color: var(--c-text-2); text-decoration: none; }
.topbar a:hover { color: var(--c-accent); text-decoration: underline; }
.topbar b { color: var(--c-text); font-weight: 600; }

.workarea { padding: 22px 26px 72px; max-width: var(--wa-max); width: 100%; min-width: 0; }

/* ------------------------------------------ 4. ENCABEZADO DE PANTALLA */

/* Título + descripción breve + acciones principales. Los indicadores van
   debajo, en `.stats`, sólo cuando ayudan a operar la pantalla (encargo §5). */
.screen__head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--sp-5); flex-wrap: wrap; margin-bottom: var(--sp-4);
}
.screen__title {
  font-size: var(--fs-2xl); margin: 0 0 3px; line-height: 1.2;
  letter-spacing: -.02em;
}
.screen__eyebrow {
  display: block; font-size: var(--fs-xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  color: var(--c-accent); margin-bottom: 5px;
}
.screen__sub { margin: 0 0 var(--sp-3); color: var(--c-text-2); max-width: 86ch; }
.screen__head .screen__sub { margin-bottom: 0; }
.screen__actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin: var(--sp-3) 0; }
/* Acciones ADMINISTRATIVAS de una ficha: **dentro de la cabecera**, alineadas
   a la derecha del nombre y por encima del menú de secciones (encargo §3). Son
   pocas y sensibles —deshabilitar, inactivar— y se separan así de la edición,
   que vive dentro de cada sección.

   Ya no llevan franja ni rótulo propios: los botones dicen lo que hacen, y el
   rótulo «Acciones administrativas» sólo repetía la categoría. */
.screen__actions--admin {
  justify-content: flex-end; align-items: center; gap: var(--sp-2);
  margin: 0; flex-shrink: 0;
}
.screen__head .screen__actions { margin: 0; }

/* ------------------------------------------------------------ 5. ICONOS */

/* Iconografía vendorizada: un sprite SVG en línea, sin CDN y sin emojis como
   iconografía de producto (encargo §4). El icono es SIEMPRE decorativo: el
   significado lo lleva el texto que lo acompaña. */
.ic {
  width: 16px; height: 16px;
  display: inline-block; vertical-align: -3px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
  flex: 0 0 auto;
}
.ic--sm { width: 14px; height: 14px; }
.ic--lg { width: 20px; height: 20px; }
.ic--xl { width: 24px; height: 24px; }

/* Icono dentro de un cuadro suave de color — el patrón de la referencia. */
.icobox {
  width: 34px; height: 34px; flex: 0 0 34px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: var(--c-accent-soft); color: var(--c-accent-dark);
}
.icobox .ic { width: 17px; height: 17px; }
.icobox--ok   { background: var(--s-ok-bg);   color: var(--s-ok-fg); }
.icobox--aten { background: var(--s-aten-bg); color: var(--s-aten-fg); }
.icobox--bloq { background: var(--s-bloq-bg); color: var(--s-bloq-fg); }
.icobox--revi { background: var(--s-revi-bg); color: var(--s-revi-fg); }
.icobox--teal { background: var(--c-teal-soft); color: var(--c-teal); }
.icobox--info { background: var(--c-surface-sunk); color: var(--c-text-2); }
.icobox--lg { width: 40px; height: 40px; flex-basis: 40px; border-radius: 11px; }
.icobox--lg .ic { width: 20px; height: 20px; }

/* ---------------------------------------- 6. TARJETA DE SECCIÓN Y REJILLAS */

.panel {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  margin: 0 0 var(--sp-4);
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
}
.panel__head {
  padding: 13px 18px;
  border-bottom: 1px solid var(--c-border-soft);
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--sp-3); flex-wrap: wrap;
}
.panel__title {
  margin: 0; font-size: var(--fs-md); font-weight: 650;
  display: flex; align-items: center; gap: 9px; color: var(--c-text);
}
.panel__title .ic { color: var(--c-text-3); }
.panel__sub { margin: 2px 0 0; font-size: var(--fs-sm); color: var(--c-text-3); }
.panel__actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.panel__body { padding: 16px 18px; min-width: 0; overflow-x: auto; }
.panel__body > * + * { margin-top: var(--sp-3); }
.panel__body > .table:first-child, .panel__body > .tabla:first-child { margin-top: 0; }
.panel__foot {
  padding: 11px 18px; border-top: 1px solid var(--c-border-soft);
  background: var(--c-surface-alt); font-size: var(--fs-sm);
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap;
}
/* Una tabla ocupa el ancho completo de su tarjeta, sin doble margen. */
.panel__body--flush { padding: 0; }
.panel__body--flush > * + * { margin-top: 0; }

.panel--aten { box-shadow: var(--shadow-sm), inset 3px 0 0 var(--s-aten-fg); }
.panel--bloq { box-shadow: var(--shadow-sm), inset 3px 0 0 var(--s-bloq-fg); }
.panel--ok   { box-shadow: var(--shadow-sm), inset 3px 0 0 var(--s-ok-fg); }
.panel--acc  { box-shadow: var(--shadow-sm), inset 3px 0 0 var(--c-accent); }

/* Rejilla de paneles (Dashboard y pantallas de resumen). */
.board { display: grid; gap: var(--sp-4); grid-template-columns: 1fr 1fr; align-items: start; }
.board__full { grid-column: 1 / -1; }
.board--2 { grid-template-columns: 1fr 1fr; }
.board--3 { grid-template-columns: repeat(3, 1fr); }

/* Bloque inferior del Dashboard (encargo §2.4): `Abastecimiento` a la
   izquierda, alto; a la derecha `Cuentas` arriba e `Inventario en riesgo`
   debajo. La suma de las dos derechas se aproxima a la altura de la izquierda
   **sin fijar ninguna altura absoluta**: `align-items: stretch` deja que la
   columna alta marque el alto y el apilado lo reparta.

   En pantalla angosta las tres caen en una sola columna por la regla de
   `.board` que ya existe, y el apilado se disuelve solo — ninguna tarjeta
   queda aislada ni deja un hueco al lado. */
.board--bottom { align-items: stretch; }
/* El panel de la izquierda llevaba el margen inferior de `.panel`, que queda
   FUERA de su caja: `stretch` estiraba la caja de margen, así que la tarjeta
   acababa `--sp-4` más baja que el apilado de la derecha. Sin ese margen las
   dos columnas terminan exactamente a la misma altura. */
.board--bottom > .panel { margin-bottom: 0; }
.board__stack { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; }
.board__stack > .panel { margin-bottom: 0; }

/* Primer bloque operativo del Dashboard: lo urgente conserva mayor peso y los
   accesos permanecen visibles sin empujar el Calendario fuera del primer
   recorrido. Es composición de componentes existentes, no otra tarjeta. */
/* §F6 — `Lo urgente hoy` **no lleva scroll interno**.

   La causa medida, no deducida: `.panel__body` declara `overflow-x: auto`, y
   por la propia especificación de CSS un eje `visible` junto a un eje que no lo
   es **computa a `auto`**. Es decir, el cuerpo ya tenía `overflow-y: auto`
   latente; sólo le faltaba una altura que lo activara. Se la daba
   `height: calc(100% - 51px)`, puesta para que las dos tarjetas de la franja
   quedaran a la misma altura: con ocho tarjetas urgentes el contenido no cabía
   en esa altura prestada y aparecía la barra de desplazamiento **dentro** de la
   tarjeta, justo donde el Usuario no la busca.

   Se retira la altura impuesta y la franja pasa a `align-items: start`: cada
   tarjeta mide lo que su contenido necesita y la única navegación vertical es
   la de la página, que es la natural. La simetría de altura era una preferencia
   estética; el scroll interno era un defecto de uso. */
.dashboard-priority {
  display: grid; gap: var(--sp-4); margin: 0 0 var(--sp-4);
  grid-template-columns: minmax(0, 1.65fr) minmax(25rem, 1fr);
  align-items: start;
}
.dashboard-priority > .panel { margin-bottom: 0; }
.dashboard-priority .panel__body { height: auto; }
/* Las ocho tarjetas del encargo §F7 en una rejilla que las acomoda en dos
   filas de cuatro a 1440 px y en dos de tres a 1280 px, sin recortar ninguna. */
.dashboard-priority .urgent {
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
}
.dashboard-priority .urgent__item { padding: 10px 11px; }
.dashboard-priority .quick {
  grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 0;
  gap: var(--sp-2);
  /* Nueve accesos = tres filas de tres. La cuadrícula queda cerrada y no
     deja el hueco que dejaba el octavo. */
  grid-auto-rows: 1fr;
}
.dashboard-priority .quick a {
  display: grid; grid-template-columns: 30px minmax(0, 1fr);
  align-items: center; min-height: 58px; padding: 8px 9px;
}

/* -------------------------------- 7. FRANJA DE INDICADORES Y TENDENCIA */

/* 3–6 indicadores clave, compactos y visuales. Nunca «KPIs porque sí»: cada
   uno tiene que ayudar a operar la pantalla en la que está (encargo §5). */
.stats {
  display: grid; gap: var(--sp-3); margin: 0 0 var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.stats--4 { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
/* Una sola tarjeta que RESUME la población y ocupa la fila entera, con sus
   desgloses debajo en su propia rejilla (`Pedidos activos`). Compartir rejilla
   con ellos dejaba a la tarjeta dominante del mismo tamaño que sus partes. */
.stats--1 { grid-template-columns: minmax(0, 1fr); margin-bottom: var(--sp-3); }
/* §F38 — `Ventas del mes` **domina la primera fila** de Mi panel.

   Con cinco o seis tarjetas del mismo tamaño la cabecera se leía como una lista
   sin jerarquía: la cifra que resume el mes competía con un conteo de
   Cotizaciones. Aquí ocupa la fila entera y las demás se reparten la siguiente
   en `.stats--4`, que ya se apila sola en pantalla angosta.

   No es una tarjeta distinta: es **la misma** `.stat--kpi`, en una rejilla de
   una sola columna y con el hueco inferior reducido para que las dos filas se
   lean como una sola cabecera. */
.stats--panel-lead {
  grid-template-columns: minmax(0, 1fr);
  margin-bottom: var(--sp-3);
}
/* La SEGUNDA fila de esa cabecera — §F38.

   Medido en el navegador: con `.stats--4` (`minmax(13rem, 1fr)`) las cinco
   tarjetas restantes caben en una fila a 1440 px pero **se parten en 4 + 1** a
   1280, porque a ese ancho el hueco disponible da 12.9 rem por tarjeta y el
   mínimo pedía 13. Una fila de cuatro y otra de una no es «las otras cuatro
   debajo»: es una tarjeta huérfana.

   Con `11.5rem` las cinco entran en una sola fila a 1280 y a 1440, y en
   pantalla más angosta se siguen apilando solas — no se fija ningún número de
   columnas, que es lo que dejaría una rejilla rota en un ancho no previsto. */
.stats--panel-rest { grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr)); }
.stats--dashboard { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.stats--fit { grid-template-columns: repeat(auto-fit, minmax(11rem, max-content)); }

.stat {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0;
  position: relative;
}
.stat__top { display: flex; align-items: center; gap: 10px; margin-bottom: 3px; }
.stat__top .stat__label { margin: 0; }
.stat__label {
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-2);
  text-transform: uppercase; letter-spacing: .07em;
  overflow: hidden; text-overflow: ellipsis;
}
.stat__value {
  font-size: var(--fs-xl); font-weight: 680; line-height: 1.2;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.stat__value--sm { font-size: var(--fs-lg); }
.stat__value--xl { font-size: var(--fs-2xl); }
.stat__meta { font-size: var(--fs-sm); color: var(--c-text-3); }
.stat__foot { margin-top: auto; padding-top: var(--sp-2); }
.stat a.stat__link { font-size: var(--fs-sm); text-decoration: none; }
.stat a.stat__link:hover { text-decoration: underline; }

/* El tono de una tarjeta refuerza al texto; nunca lo sustituye. */
.stat--aten { border-color: var(--s-aten-bd); }
.stat--bloq { border-color: var(--s-bloq-bd); }
.stat--ok   { border-color: var(--s-ok-bd); }
.stat--acc  { border-color: var(--c-accent-line); }
.stat--aten .stat__value { color: var(--s-aten-fg); }
.stat--bloq .stat__value { color: var(--s-bloq-fg); }
.stat--ok   .stat__value { color: var(--s-ok-fg); }

/* --- Tarjeta KPI de cabecera (componente compartido) ---------------------
   Una sola definición para TODAS las cabeceras (Dashboard, Clientes, y
   cualquier pantalla futura): la cifra manda, va CENTRADA y la lectura baja
   en una jerarquía fija — **cifra → título → contexto**. El contexto
   secundario se estructura en pares etiqueta/valor alineados; nunca en texto
   corrido, que es lo que descuadraba las tarjetas cuando una frase era larga
   y otra corta. Mejorar aquí evita copiar CSS pantalla por pantalla. */
.stat--kpi {
  align-items: center; text-align: center; gap: 2px; padding: 15px 16px 14px;
}
.stat--kpi .icobox { margin-bottom: 5px; }
.stat--kpi .stat__value { font-size: var(--fs-2xl); }
.stat--kpi .stat__value--sm { font-size: var(--fs-xl); }
/* El título NO se recorta con elipsis: envuelve. Una cifra sin su nombre
   completo no se puede interpretar, y la altura la iguala la rejilla. */
.stat--kpi .stat__label {
  overflow: visible; text-overflow: clip; white-space: normal; max-width: 100%;
}
.stat--kpi .stat__meta { text-align: center; }
.stat--kpi .delta { align-self: center; }
.stat--kpi .stat__foot {
  width: 100%; text-align: center;
  border-top: 1px solid var(--c-border-soft); margin-top: auto;
}

/* Contexto secundario de un KPI: pares etiqueta/valor en columnas alineadas.
   Sustituye a la frase corrida — dos datos distintos se leen de un vistazo y
   dos tarjetas contiguas quedan a la misma altura. */
.kpi-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: 4px var(--sp-3); width: 100%;
  margin-top: var(--sp-2); padding-top: var(--sp-2);
  border-top: 1px solid var(--c-border-soft);
}
.kpi-facts--1 { grid-template-columns: minmax(0, 1fr); }
/* Variante en FILAS para un contexto de tres cifras cortas cuyo rótulo es una
   palabra larga (`Pedidos activos`). En columnas, `Programados` no cabía en un
   tercio de la tarjeta y se partía a media palabra o se salía; en filas cada
   rótulo tiene el ancho entero, así que **los tres caben en una sola línea**,
   comparten exactamente la misma composición —rótulo a la izquierda, cifra a
   la derecha— y quedan alineados entre sí por construcción.

   `display: contents` en el par deja que rótulo y cifra participen
   directamente en la rejilla: sin él, cada par formaría su propia caja y las
   cifras dejarían de compartir columna. */
.kpi-facts--rows {
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 3px var(--sp-3); text-align: left;
}
.kpi-facts--rows .kpi-fact { display: contents; }
.kpi-facts--rows .kpi-fact__label {
  letter-spacing: .04em; line-height: 1.3; align-self: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kpi-facts--rows .kpi-fact__value { text-align: right; }
.kpi-fact { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kpi-fact__label {
  font-size: var(--fs-xs); color: var(--c-text-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.kpi-fact__value {
  font-size: var(--fs-sm); font-weight: 650;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.kpi-fact__value--aten { color: var(--s-aten-fg); }
.kpi-fact__value--muted { color: var(--c-text-3); font-weight: 550; }

/* --- Tarjeta KPI de un SUBENCABEZADO (*refinement 6* §B4.4) ---------------
   Misma tarjeta, misma composición y mismo comportamiento; **menos peso
   visual**. Una franja secundaria —la de revisión de `Cuentas por cobrar`—
   tenía exactamente la altura y el tamaño de cifra del encabezado principal, y
   por eso se leía como un segundo encabezado en vez de como contexto.

   Lo que se reduce es **altura, relleno y tamaño de la cifra**; lo que NO se
   reduce es el título, ni el contraste, ni el área pulsable: sigue siendo
   legible y sigue llevando a su conjunto exacto. Achicar el texto hasta
   volverlo decorativo habría cambiado el problema, no resuelto. */
.stats--sub { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: var(--sp-2); }
.stat--mini { padding: 9px 12px 8px; gap: 1px; }
.stat--mini .icobox { width: 24px; height: 24px; flex: 0 0 24px; margin-bottom: 2px; }
.stat--mini .icobox .ic { width: 13px; height: 13px; }
.stat--mini .stat__value { font-size: var(--fs-lg); }
.stat--mini .stat__value--sm { font-size: var(--fs-md); }
.stat--mini .stat__label { font-size: 10px; letter-spacing: .05em; }
.stat--mini .stat__meta { font-size: var(--fs-xs); }
.stat--mini .stat__foot { padding-top: 5px; }

/* --- Tarjeta KPI CLICKABLE (regla global §1 del refinement 2) -------------
   Una cifra que representa un conjunto de hechos lleva a esos hechos, y el
   destino llega **ya filtrado** al mismo subconjunto. La tarjeta entera es un
   `<a>`: sin JavaScript, así que el teclado, el botón central del ratón y
   «abrir en pestaña nueva» funcionan solos.

   El texto NO se pinta de color de enlace —la cifra manda y el subrayado la
   ensuciaría—; lo que indica que es pulsable es el estado al pasar por encima
   y un anillo de foco visible, que es lo que el teclado necesita. */
.stat--link {
  text-decoration: none; color: inherit; cursor: pointer;
  transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.stat--link:hover { border-color: var(--c-accent-line); box-shadow: var(--shadow-md); }
.stat--link:focus-visible { outline: 2px solid var(--c-accent-line); outline-offset: 2px; }
.stat--link .stat__label { text-decoration: none; }
@media (prefers-reduced-motion: no-preference) {
  .stat--link:hover { transform: translateY(-1px); }
}

/* --- Tarjeta de VENDEDOR de `Mi panel` (*refinement 6* §B1.1) ------------
   La entrada del Administrador: una tarjeta por Vendedor con su nombre y las
   tres cifras que permiten decidir a quién abrir. **No es un KPI**: el KPI
   tiene UNA cifra dominante y centrada, y aquí las tres pesan lo mismo, así
   que reutilizar `.stat--kpi` habría obligado a deshacer justo lo que ese
   componente define. Lo que sí se reutiliza es `.kpi-facts--rows`, que ya
   resuelve los pares rótulo/cifra alineados.

   La tarjeta entera es un `<a>`, con el mismo estado de hover y el mismo
   anillo de foco que `.stat--link`: sin JavaScript. */
.sellercards {
  display: grid; gap: var(--sp-3); margin: 0 0 var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.sellercard {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0; text-decoration: none; color: inherit; cursor: pointer;
  transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.sellercard:hover { border-color: var(--c-accent-line); box-shadow: var(--shadow-md); }
.sellercard:focus-visible { outline: 2px solid var(--c-accent-line); outline-offset: 2px; }
@media (prefers-reduced-motion: no-preference) {
  .sellercard:hover { transform: translateY(-1px); }
}
.sellercard__head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sellercard__name {
  font-size: var(--fs-lg); font-weight: 650; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sellercard__foot {
  margin-top: auto; padding-top: var(--sp-2);
  font-size: var(--fs-xs); color: var(--c-text-3);
}

/* La tarjeta DOMINANTE de una cabecera —`Pedidos activos` sobre sus cuatro
   estados operativos— ocupa dos columnas de la rejilla cuando hay sitio. En
   una pantalla angosta vuelve a una sola: `auto-fit` ya reparte, y forzar dos
   columnas donde no caben dejaría justo los huecos que el encargo prohíbe. */
.stat--wide { grid-column: span 2; }
@media (max-width: 720px) {
  .stat--wide { grid-column: span 1; }
}

/* --- Cifra BIMONEDA de una tarjeta KPI (encargo §2.1) --------------------
   CxC y CxP son la excepción al KPI de un solo número, porque manejan dos
   monedas y **nunca se suman entre sí** (RN-138). El orden de lectura que el
   negocio pidió es *importe MXN → importe USD → título → contexto*, así que
   los importes se apilan **encima** del título, centrados y con cifras
   tabulares para que las dos líneas queden alineadas. */
.stat__money {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  width: 100%;
}
.stat__money-line {
  font-size: var(--fs-xl); line-height: 1.2;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  color: var(--c-text-2); overflow-wrap: anywhere;
}
/* El importe manda; el código de moneda lo acompaña sin competir con él. Las
   dos líneas son igual de importantes —una NO es el total y la otra un
   detalle—, así que van al mismo tamaño: sumarlas está prohibido (RN-138). */
.stat__money-line b { font-weight: 680; color: var(--c-text); }
.stat__money-line--none { color: var(--c-text-3); font-weight: 600; }

/* --- Comparación CxC / CxP por moneda (encargo §2.5) ---------------------
   Tabla compacta de tres cifras. El signo se refuerza con color **y** con el
   propio signo escrito: el color nunca es el único canal, y el `title` de
   cada celda repite que esto es una COMPARACIÓN — las dos carteras siguen
   separadas y no existe ninguna función que las netee (RN-213). */
.ledger { margin-bottom: var(--sp-2); }
.ledger th[scope="row"] { font-weight: 650; }
.ledger td, .ledger th { padding-top: 6px; padding-bottom: 6px; }
.ledger__pos { color: var(--s-ok-fg); font-weight: 650; cursor: help; }
.ledger__neg { color: var(--s-bloq-fg); font-weight: 650; cursor: help; }

/* Indicador compacto de alerta en una tabla: un punto con su descripción.
   **El color nunca es el único canal** — el punto SIEMPRE viaja con su
   `title` y su `aria-label`, que dicen exactamente qué falta. Sustituye a los
   globos de texto largo, que hacían saltar el alto de la fila según cuántas
   palabras llevara cada Cliente. */
.alerts { white-space: nowrap; }
.alerts > * + * { margin-left: 6px; }

/* Una señal de la columna `Alertas` — §F13.

   ## El defecto que se corrige, medido y no deducido

   Los puntos se veían **huecos**, sin su color. La causa era una **colisión de
   nombres en el propio CSS**: `.dot` estaba declarado DOS veces, aquí para la
   alerta y mucho más abajo para el checklist compacto de Próximas salidas, que
   declara `background: transparent` y un borde gris. Con la misma
   especificidad gana la última, así que la regla del checklist **borraba el
   relleno de `.dot--aten` y `.dot--bloq`** en una pantalla que no tiene nada
   que ver con ella. Por eso la alerta pasa a llamarse `.alerta__dot`: pertenece
   a este componente, y así ninguna de las dos puede volver a pisar a la otra.

   ## La forma que el negocio pidió

   Agustín prefiere el patrón anterior —**punto de color**, color según la
   gravedad, y el globo explicando exactamente qué significa— y pidió que el
   texto no viva permanentemente al lado, porque tres etiquetas por fila
   volvían pesada la tabla.

   **El color no es el único portador del significado**, y eso no se negocia:
   cada punto es `tabindex="0"`, así que se alcanza con el teclado; lleva su
   globo instantáneo dibujado por la página (mismo mecanismo que `.dot__tip`,
   por el mismo motivo: el `title` nativo tarda y sólo enseña el cursor `?`); y
   lleva **texto completo para lector de pantalla**, que dice qué falta. Lo que
   se retira es la etiqueta *visible* permanente, no la información. */
.alerta {
  position: relative; display: inline-flex; align-items: center;
  font-size: var(--fs-sm); white-space: nowrap;
}
.alerta:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 3px; border-radius: 50%; }
.alerta__dot {
  display: inline-block; width: 11px; height: 11px; border-radius: 50%;
  vertical-align: middle; border: 1px solid rgba(0, 0, 0, .18); flex: none;
}
.alerta__dot--aten { background: var(--s-aten-fg); border-color: var(--s-aten-fg); }
.alerta__dot--bloq { background: var(--s-bloq-fg); border-color: var(--s-bloq-fg); }
.alerta__dot--ok   { background: var(--s-ok-fg);   border-color: var(--s-ok-fg); }
/* El globo: sale **al instante**, con el ratón y con el teclado. */
.alerta__tip {
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-1);
  white-space: normal; width: max-content; max-width: 22rem;
  text-transform: none; letter-spacing: 0; text-align: left;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
  padding: 4px 9px; z-index: 5;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .08s ease;
}
.alerta:hover .alerta__tip, .alerta:focus-visible .alerta__tip { opacity: 1; visibility: visible; }
/* Dentro de la celda, el globo del primero y del último no puede desbordarla. */
.alerts .alerta:first-child .alerta__tip { left: 0; transform: none; }
.alerts .alerta:last-child .alerta__tip { left: auto; right: 0; transform: none; }
/* La etiqueta VISIBLE de una señal, cuando la columna es suya y no comparte
   sitio con otras: en `Solicitudes de precio` cada fila tiene **una** señal, así
   que el texto cabe al lado y ahorra el globo para el detalle. En la columna
   `Alertas` de Clientes, donde conviven hasta tres, la etiqueta no se dibuja y
   el texto vive en el globo y en el lector de pantalla (§F13, §F72). */
.alerta__label { margin-left: 5px; }
.alerta__sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Tendencia — la dirección NUNCA es sólo color: lleva su flecha y su texto. */
.delta {
  font-size: var(--fs-sm); font-weight: 600; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 3px;
}
.delta--up::before   { content: "▲"; font-size: 8px; }
.delta--down::before { content: "▼"; font-size: 8px; }
.delta--up.delta--good, .delta--down.delta--good { color: var(--s-ok-fg); }
.delta--up.delta--bad, .delta--down.delta--bad { color: var(--s-bloq-fg); }
.delta--flat { color: var(--c-text-3); font-weight: 500; }
.delta__ref { color: var(--c-text-3); font-weight: 400; }

/* Micrográfica: la silueta de los últimos meses bajo la cifra. Es
   ORIENTACIÓN, no lectura de valores: las cifras exactas viven en la gráfica
   completa y en su tabla accesible. */
.spark {
  display: flex; align-items: flex-end; gap: 2px;
  height: 30px; margin-top: 8px;
}
.spark__b {
  flex: 1 1 0; min-height: 2px; border-radius: 2px 2px 0 0;
  background: var(--c-accent-line);
}
.spark__b--now { background: var(--c-accent); }
.spark__b--none { background: var(--c-border); }
.spark--ok .spark__b { background: #b6e0c6; }
.spark--ok .spark__b--now { background: var(--s-ok-fg); }
.spark--aten .spark__b { background: #ecd5a4; }
.spark--aten .spark__b--now { background: var(--s-aten-fg); }
.spark--teal .spark__b { background: var(--c-teal-line); }
.spark--teal .spark__b--now { background: var(--c-teal); }

/* Toda micrográfica lleva su equivalente en cifras, plegado: el dato exacto
   nunca vive sólo en un píxel. */
.spark__data { margin-top: 6px; }
.spark__data summary { font-size: var(--fs-xs); color: var(--c-text-3); }
.spark__data .tabla { margin-top: 6px; }
.spark__data .tabla th, .spark__data .tabla td { padding: 4px 8px; font-size: var(--fs-sm); }

/* ------------------------- 8. TARJETAS DE ACCIÓN Y ACCESOS RÁPIDOS */

.cards {
  display: grid; gap: var(--sp-3); margin-bottom: var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}
.card {
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: 16px; display: flex; flex-direction: column; gap: 6px;
}
.card__head { display: flex; align-items: center; gap: 10px; }
.card__title {
  margin: 0; font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-2);
  text-transform: uppercase; letter-spacing: .07em;
}
.card__value {
  margin: 0; font-size: var(--fs-xl); font-weight: 680; line-height: 1.25;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.card__meta { margin: 0; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.card__detail { margin: 0; color: var(--c-text-2); font-size: var(--fs-sm); }
.card__action { margin: auto 0 0; padding-top: var(--sp-2); }
.card__diag {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px dashed var(--c-border);
  grid-template-columns: 12rem 1fr; font-size: var(--fs-sm);
}

/* Accesos rápidos: acciones reales — icono + color + etiqueta corta. */
.quick {
  display: grid; gap: 10px; margin: 0 0 var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
}
.quick a {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 13px 14px;
  border: 1px solid var(--c-border); border-radius: var(--radius);
  background: var(--c-surface); color: var(--c-text);
  text-decoration: none; font-size: var(--fs); font-weight: 550;
  box-shadow: var(--shadow-xs);
  transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
  min-height: 76px;
}
.quick a:hover {
  border-color: var(--c-accent-line); box-shadow: var(--shadow);
  transform: translateY(-1px); color: var(--c-text);
}
.quick a .icobox { width: 30px; height: 30px; flex-basis: 30px; border-radius: 8px; }
.quick a .icobox .ic { width: 16px; height: 16px; }
.quick__label { line-height: 1.3; }

/* Fila compacta de accesos, cuando el bloque no es protagonista. */
.quick--row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.quick--row a { flex-direction: row; align-items: center; min-height: 38px; padding: 7px 12px; }

/* ----------------------------------------------------------- 9. BOTONES */

/* Cuatro niveles y ni uno más: primario (la acción de la pantalla),
   secundario (complementaria), fantasma (navegación o acción menor) y
   excepcional (sólo lo realmente excepcional) — encargo §17. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 14px; min-height: 34px; line-height: 1.3;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-border-strong);
  background: var(--c-surface); color: var(--c-text);
  font-family: inherit; font-size: var(--fs); font-weight: 550;
  cursor: pointer; text-decoration: none;
  box-shadow: var(--shadow-xs);
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
  white-space: nowrap;
}
.btn:hover { background: var(--c-surface-alt); border-color: var(--c-text-3); color: var(--c-text); }
.btn:active { box-shadow: none; }
.btn .ic { width: 15px; height: 15px; }

.btn--primary {
  background: var(--c-accent); border-color: var(--c-accent); color: #fff;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .12);
}
.btn--primary:hover { background: var(--c-accent-dark); border-color: var(--c-accent-dark); color: #fff; }

.btn--secondary {
  background: var(--c-accent-soft); border-color: var(--c-accent-line);
  color: var(--c-accent-dark);
}
.btn--secondary:hover { background: #dbe9fa; border-color: var(--c-accent); color: var(--c-accent-dark); }

.btn--ghost {
  background: transparent; border-color: transparent; color: var(--c-text-2);
  box-shadow: none;
}
.btn--ghost:hover { background: var(--c-surface-sunk); color: var(--c-text); border-color: transparent; }

/* Excepcional: sólo para acciones realmente excepcionales (cancelar, revertir,
   corregir historia). Se ve distinta a propósito. */
.btn--danger {
  background: var(--c-surface); border-color: var(--s-bloq-bd); color: var(--s-bloq-fg);
}
.btn--danger:hover { background: var(--s-bloq-bg); border-color: var(--s-bloq-fg); color: var(--s-bloq-fg); }

.btn--sm { padding: 4px 10px; min-height: 28px; font-size: var(--fs-sm); }
.btn--sm .ic { width: 14px; height: 14px; }
.btn--lg { padding: 10px 18px; min-height: 40px; font-size: var(--fs-md); }
.btn--block { width: 100%; }
.btn--icon { padding: 6px; width: 32px; min-height: 32px; }

.btn:disabled, .btn[aria-disabled="true"] {
  opacity: .5; cursor: not-allowed; box-shadow: none;
}

/* Grupo de botones con jerarquía visible de izquierda a derecha. */
.btns { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }

/* ------------------------------------------------------- 10. ESTADOS */

/* Un estado se lee por su TEXTO; el color sólo lo refuerza (encargo §3, §21). */
.chip, .pill, .badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 600; line-height: 1.6;
  border: 1px solid var(--c-border); background: var(--c-surface-alt);
  color: var(--c-text-2); white-space: nowrap;
}
.chip .ic, .pill .ic, .badge .ic { width: 12px; height: 12px; }
.chip--ok, .badge--ok {
  background: var(--s-ok-bg); border-color: var(--s-ok-bd); color: var(--s-ok-fg);
}
.chip--aten, .badge--aten {
  background: var(--s-aten-bg); border-color: var(--s-aten-bd); color: var(--s-aten-fg);
}
.chip--bloq, .chip--off, .chip--n3, .badge--bloq {
  background: var(--s-bloq-bg); border-color: var(--s-bloq-bd); color: var(--s-bloq-fg);
}
.chip--revi, .chip--exc, .badge--revi, .badge--exc {
  background: var(--s-revi-bg); border-color: var(--s-revi-bd); color: var(--s-revi-fg);
}
.chip--sens { background: var(--s-aten-bg); border-color: var(--s-aten-bd); color: var(--s-aten-fg); }
.chip--dep, .chip--nat, .chip--acc, .badge--acc {
  background: var(--c-accent-soft); border-color: var(--c-accent-line); color: var(--c-accent-dark);
}
.chip--teal { background: var(--c-teal-soft); border-color: var(--c-teal-line); color: var(--c-teal); }
.chip--lg { font-size: var(--fs-sm); padding: 3px 11px; }

/* Familias de estado operativo — encargo §20 del *Functional refinement 3*.
   Una clase por FAMILIA, no por pantalla: el mismo estado se ve igual en el
   listado de Pedidos, en Mi panel y en la ficha del Cliente, porque las tres
   piden su clase a `commercial.selectors.status_family`.

   **No se inventó ningún estado por tener color** y **el color nunca es el
   único canal**: la etiqueta de texto acompaña siempre al badge. */
.badge--borrador { background: var(--c-surface-alt); border-color: var(--c-border); color: var(--c-text-2); }
.badge--por-preparar { background: var(--s-aten-bg); border-color: var(--s-aten-bd); color: var(--s-aten-fg); }
.badge--esperando-material { background: var(--s-revi-bg); border-color: var(--s-revi-bd); color: var(--s-revi-fg); }
.badge--listo { background: var(--c-teal-soft); border-color: var(--c-teal-line); color: var(--c-teal); }
.badge--programado { background: var(--c-accent-soft); border-color: var(--c-accent-line); color: var(--c-accent-dark); }
.badge--en-ruta { background: var(--c-accent-soft); border-color: var(--c-accent-line); color: var(--c-accent-dark); }
.badge--entregado { background: var(--s-ok-bg); border-color: var(--s-ok-bd); color: var(--s-ok-fg); }
.badge--cancelado { background: var(--s-bloq-bg); border-color: var(--s-bloq-bd); color: var(--s-bloq-fg); }
.badge--neutro { background: var(--c-surface-alt); border-color: var(--c-border); color: var(--c-text-2); }

/* Punto de estado: el segundo canal, además del texto. */
.chip::before { content: none; }
.chip--dot::before {
  content: ""; display: inline-block; width: 6px; height: 6px;
  border-radius: 50%; background: currentColor; flex: 0 0 6px;
}

/* Avisos --------------------------------------------------------------- */

.note {
  border: 1px solid var(--s-info-bd); background: var(--s-info-bg); color: var(--s-info-fg);
  padding: 11px 14px; border-radius: var(--radius); font-size: var(--fs);
  display: block;
}
.note--ok   { border-color: var(--s-ok-bd);   background: var(--s-ok-bg);   color: var(--s-ok-fg); }
.note--aten { border-color: var(--s-aten-bd); background: var(--s-aten-bg); color: var(--s-aten-fg); }
.note--revi { border-color: var(--s-revi-bd); background: var(--s-revi-bg); color: var(--s-revi-fg); }
.note--bloq { border-color: var(--s-bloq-bd); background: var(--s-bloq-bg); color: var(--s-bloq-fg); }
.note + .note { margin-top: var(--sp-2); }
.note a { color: inherit; font-weight: 600; }

/* La marca no decora: es el canal que NO depende del color. */
.note--ok::before   { content: "✓ "; font-weight: 700; }
.note--aten::before { content: "⚠ "; font-weight: 700; }
.note--bloq::before { content: "✕ "; font-weight: 700; }
.note--revi::before { content: "◆ "; font-weight: 700; }

.messages { list-style: none; padding: 0; margin: 0 0 var(--sp-4); }

/* Compatibilidad incremental con las plantillas anteriores a esta pasada.
   `datos` y `cifras` ya expresaban dos patrones estables: pares dato/valor y
   una franja de cifras reconciliables. Se incorporan al sistema común sin
   obligar a reescribir docenas de pantallas ni mantener CSS por módulo. */
.datos {
  display: grid; grid-template-columns: 13rem minmax(0, 1fr);
  gap: 7px var(--sp-4); margin: 0; font-size: var(--fs);
}
.datos dt { color: var(--c-text-2); }
.datos dd { margin: 0; font-weight: 550; min-width: 0; }

.cifras {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-2);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.cifras li {
  min-width: 0; padding: 10px 12px;
  border: 1px solid var(--c-border-soft); border-radius: var(--radius);
  background: var(--c-surface-alt); color: var(--c-text-2);
}
.cifras li b { color: var(--c-text); font-variant-numeric: tabular-nums; }

/* Algunas pantallas heredadas ya usaban el título canónico, pero todavía no
   lo envolvían en `panel__head`. Conservarlas es seguro: la tarjeta les da la
   misma cabecera sin duplicar una variante por módulo. */
.panel > .panel__title {
  padding: 13px 18px; border-bottom: 1px solid var(--c-border-soft);
}
.panel > p.help, .panel > p.note { margin: 12px 18px; }
.panel__body > h2 {
  margin: 0 0 var(--sp-3); font-size: var(--fs-md); font-weight: 650;
  color: var(--c-text); letter-spacing: -.01em;
}

/* ------------------------------------------------------------ 11. TABLAS */

.table, .tabla {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: var(--fs); background: var(--c-surface);
}
.table th, .table td, .tabla th, .tabla td {
  text-align: left; padding: 10px 14px;
  border-bottom: 1px solid var(--c-border-soft);
  vertical-align: top;
}
.table th, .tabla th {
  background: var(--c-surface-alt);
  font-size: var(--fs-xs); font-weight: 650;
  text-transform: uppercase; letter-spacing: .06em; color: var(--c-text-2);
  white-space: nowrap;
  border-bottom: 1px solid var(--c-border);
}
.table thead th, .tabla thead th { position: sticky; top: var(--topbar-h); z-index: 1; }
/* Dentro de una tarjeta la cabecera se pega **al borde de la tarjeta**, no bajo
   la barra superior: la tarjeta ya está debajo de ella.

   El selector es de DESCENDENCIA a propósito. Con `>` sólo acertaba a la tabla
   que colgaba directamente de la tarjeta, así que una tabla dentro de un
   `<form>` o de un `<details>` —once plantillas del proyecto— se quedaba con
   `top: var(--topbar-h)` y su cabecera flotaba 43 px hacia abajo, **encima de
   la primera fila**. Se veía como encabezados cortados y contenido superpuesto
   en la parte de arriba de la tabla. Se corrige aquí, una vez, y no plantilla
   por plantilla (mismo criterio que D-424). */
:is(.panel, .panel__body, .tablewrap) :is(.table, .tabla) thead th { top: 0; }

/* La tarjeta ya no recorta —recortar rompería la cabecera fija—, así que las
   esquinas superiores las redondea la propia cabecera de la tabla. */
.panel > .table:first-child thead tr:first-child th:first-child,
.panel > .tabla:first-child thead tr:first-child th:first-child { border-top-left-radius: var(--radius-lg); }
.panel > .table:first-child thead tr:first-child th:last-child,
.panel > .tabla:first-child thead tr:first-child th:last-child { border-top-right-radius: var(--radius-lg); }
.panel > .table:last-child tbody tr:last-child td:first-child,
.panel > .tabla:last-child tbody tr:last-child td:first-child { border-bottom-left-radius: var(--radius-lg); }
.panel > .table:last-child tbody tr:last-child td:last-child,
.panel > .tabla:last-child tbody tr:last-child td:last-child { border-bottom-right-radius: var(--radius-lg); }
.table tbody tr:hover, .tabla tbody tr:hover { background: var(--c-surface-alt); }
.table tbody tr:last-child td, .tabla tbody tr:last-child td { border-bottom: 0; }
.table tfoot td, .tabla tfoot td {
  background: var(--c-surface-alt); font-weight: 650;
  border-top: 1px solid var(--c-border); border-bottom: 0;
}

/* Una columna de cifras va **CENTRADA** y tabular — regla transversal de la
   pasada final de aceptación funcional (§F1).

   Hasta esta pasada `.num` alineaba a la derecha, con el argumento contable de
   que una columna de importes se compara unidad contra unidad. Agustín revisó
   las tablas completas del sistema y decidió lo contrario, **a sabiendas de esa
   convención previa**: en PQG un campo compacto —folio, fecha, estado,
   cantidad, kg, conteo, importe— se centra bajo su encabezado, y sólo el campo
   descriptivo largo —Material, Cliente, Proveedor, descripción, notas— queda a
   la izquierda. El motivo es el que se ve en pantalla: con columnas anchas y
   contenidos cortos, unos datos pegados al borde derecho y otros al izquierdo
   hacían que los valores «bailaran» de una columna a otra.

   `tabular-nums` se conserva: aunque ya no se comparen por el borde derecho,
   los dígitos siguen ocupando el mismo ancho y la columna se lee pareja.

   `.mid` sigue existiendo y **no queda duplicado**: añade `nowrap` para el dato
   que además no se debe partir nunca (un folio), que es una garantía distinta
   del centrado. */
.table .num, .tabla .num { text-align: center; font-variant-numeric: tabular-nums; }
.table .nowrap, .tabla .nowrap { white-space: nowrap; }
.table .state, .tabla .state { text-align: center; }
.table .actions, .tabla .actions { width: 1%; white-space: nowrap; text-align: right; }

/* `.mid` — **dato CORTO y centrado**, encargo del *Functional refinement 8*.
   Es para lo que se lee de un vistazo y **no se compara por magnitud**: un
   folio, una fecha, un conteo pequeño, una etiqueta breve. En una columna más
   ancha que su contenido, ese dato pegado al borde izquierdo es lo que hacía
   que la tabla se viera «desordenada» — no estaba mal alineado, estaba lejos
   de su encabezado.

   **No sustituye a `.num`, y la diferencia sigue importando** aunque desde la
   pasada final ambas centren: `.mid` añade `white-space: nowrap`, la garantía
   de que ese dato **no se parte nunca en dos líneas**. Un importe puede
   ajustarse; un folio no. _(Hasta la pasada final este párrafo decía que la
   diferencia era la alineación —`.num` a la derecha—; **dejó de aplicar** con
   §F1, que centró también las cifras.)_

   Lleva `white-space: nowrap` porque su razón de ser es **caber en una línea**:
   `OC-000007` partido en `OC-` / `000007` estiraba la fila entera a 60 px. */
.table .mid, .tabla .mid {
  text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* Con anchos declarados, `nowrap` no puede imponer un mínimo mayor que el
   porcentaje de su `<col>`: si el dato no cupiera, se recorta con puntos
   suspensivos en vez de sacar la tabla de la pantalla. */
.table--fixed td.mid, .table--fixed th.mid {
  overflow: hidden; text-overflow: ellipsis; word-break: keep-all;
}
.cell-clip {
  display: block; max-width: 24rem; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.sort-link {
  display: inline-flex; align-items: center; gap: 5px;
  color: inherit; text-decoration: none;
}
.sort-link:hover, .sort-link:focus-visible { color: var(--c-accent-dark); }
.sort-link__arrow { color: var(--c-text-3); font-size: .9em; }
.sort-link--active .sort-link__arrow { color: var(--c-accent); }

/* Acciones dentro de una celda: compactas, y cada una con su propio `form`. */
/* Las acciones de un requisito del checklist: **apiladas, no en una línea**.

   `.actions` fuerza `nowrap`, y aquí conviven hasta tres controles —abrir el
   documento, marcarlo listo y, al retirarlo, su motivo—: en una sola línea la
   columna crecía hasta desbordar la tarjeta y los botones quedaban fuera de la
   vista. Apiladas caben, y el motivo deja de empujar. */
/* Cambiar la modalidad de entrega: el motivo y el botón en una línea, dentro
   de la lista de datos del Pedido. */
.modechange { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 6px 0 0; }
.modechange input[type="text"] { max-width: 18rem; }

.checkactions { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.checkactions form { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin: 0; }
.checkactions input[type="text"] { max-width: 13rem; }

/* Quitar / restaurar una fila de un borrador, SIN JavaScript.

   Es una casilla y dos etiquetas: la casilla nace marcada —la Línea entra—, la
   etiqueta visible dice `Quitar`, y al desmarcarla el par se invierte y la fila
   se pinta retirada. Todo el estado vive en el propio formulario, así que
   recargar, volver atrás o navegar con el teclado se comportan como el Usuario
   espera y el `POST` sigue siendo el mismo de siempre. */
.rowdrop { display: inline-flex; }
.rowdrop > input {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  margin: 0; pointer-events: none;
}
.rowdrop > label {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; min-height: 26px; cursor: pointer;
  border: 1px solid var(--c-border); border-radius: var(--radius);
  background: var(--c-surface); color: var(--c-text-2);
  font-size: var(--fs-sm); font-weight: 600; white-space: nowrap;
}
.rowdrop > label:hover { border-color: var(--s-bloq-fg); color: var(--s-bloq-fg); }
.rowdrop > .rowdrop__in { display: none; }
.rowdrop > input:not(:checked) ~ .rowdrop__out { display: none; }
.rowdrop > input:not(:checked) ~ .rowdrop__in { display: inline-flex; }
.rowdrop > input:not(:checked) ~ .rowdrop__in:hover {
  border-color: var(--c-accent); color: var(--c-accent-dark);
}
/* El anillo de foco lo lleva la etiqueta, porque la casilla no se ve. */
.rowdrop > input:focus-visible ~ label { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* La fila retirada **se sigue viendo** —no desaparece— pero deja de parecer
   parte de la Cotización, y su precio deja de pedir atención. */
tr.quotable:has(.rowdrop > input:not(:checked)) { color: var(--c-text-3); }
tr.quotable:has(.rowdrop > input:not(:checked)) th[scope="row"] { text-decoration: line-through; }
tr.quotable:has(.rowdrop > input:not(:checked)) .quotable__price { opacity: .45; }

.table td form, .tabla td form { display: inline-block; margin: 0 4px 0 0; }
.table td .btn, .tabla td .btn { padding: 3px 9px; min-height: 26px; font-size: var(--fs-sm); }

/* Fila desplegable: el detalle vive DENTRO de la fila, no en otra pantalla. */
.table tr.row--sub td, .tabla tr.row--sub td {
  background: var(--c-surface-alt); padding-top: 6px; padding-bottom: 10px;
}
.table tr.row--sub:hover, .tabla tr.row--sub:hover { background: var(--c-surface-alt); }

/* Tabla dentro de una tarjeta a sangre: las esquinas las pone la tarjeta. */
.panel__body--flush .table th:first-child,
.panel__body--flush .tabla th:first-child { padding-left: 18px; }
.panel__body--flush .table td:first-child,
.panel__body--flush .tabla td:first-child { padding-left: 18px; }
.panel__body--flush .table th:last-child,
.panel__body--flush .tabla th:last-child { padding-right: 18px; }
.panel__body--flush .table td:last-child,
.panel__body--flush .tabla td:last-child { padding-right: 18px; }

.tablewrap {
  width: 100%; max-width: 100%; min-width: 0;
  overflow-x: auto; border-radius: var(--radius-lg);
  overscroll-behavior-inline: contain;
}

/* Anchos DECLARADOS por la tabla, no negociados por el contenido — corrección
   de aceptación del *Functional refinement 6* (§1 de la pasada de corrección).

   El problema medido en el navegador, no deducido de las clases: en Existencias
   a 1440 px la tabla pedía **1257 px** para 1034 disponibles, así que `Bloqueado`
   y `Lotes` quedaban fuera de la pantalla; y como cada columna se dimensionaba
   por su contenido, un nombre de Material largo movía TODAS las demás — los
   valores «bailaban» de una fila a otra y de una página a otra.

   `table-layout: fixed` con un `<colgroup>` resuelve las dos cosas de raíz: los
   anchos los fija la plantilla una vez, el encabezado queda **exactamente**
   sobre su dato y ninguna fila puede reacomodar la rejilla. El texto largo se
   recorta con `.cell-clip`, que ya conserva el valor completo en su `title`. */
.table--fixed { table-layout: fixed; }
/* Con anchos fijos, una celda textual larga tiene que poder partirse en vez de
   ensanchar su columna: `overflow-wrap` es lo que impide que un código sin
   espacios desborde la celda y empuje el borde. */
.table--fixed td { overflow-wrap: anywhere; }
.table--fixed td.num, .table--fixed th.num { overflow-wrap: normal; }
/* `.table th` es `nowrap`, y con anchos fijos eso IMPONE un mínimo mayor que el
   porcentaje declarado: era lo que seguía sacando la tabla del contenedor
   después de fijar la rejilla. En una tabla de anchos declarados el encabezado
   **puede** partirse en dos líneas —los títulos son cortos— y a cambio la
   rejilla cabe entera sin desplazamiento horizontal. */
.table--fixed th { white-space: normal; letter-spacing: .02em; }
/* Una celda de anchos fijos parte las palabras largas para no desbordar, pero
   hay valores que **no se deben partir jamás**: un importe con su moneda y una
   situación de una sola palabra. `Provision\nal` y `USD\n$1.05` eran ilegibles
   y falseaban el dato al leerlo de un vistazo. */
.table--fixed td.num, .table--fixed .nobreak { overflow-wrap: normal; word-break: keep-all; }

/* Subtabla dentro de una fila desplegable. **No es la misma rejilla que la de
   arriba y no debe fingir que lo es**: antes heredaba `.table` completa —mismo
   tamaño, mismo encabezado pegajoso, columnas propias— y el resultado eran dos
   rejillas distintas apiladas cuyos bordes no coincidían, que es justo lo que
   se leía como «desalineado». Aquí se declara como lo que es: un detalle,
   sangrado, más compacto y con su encabezado quieto. */
.table--sub { font-size: var(--fs-sm); background: var(--c-surface); }
.table--sub th, .table--sub td { padding: 7px 10px; }
.table--sub thead th { position: static; text-transform: none; letter-spacing: 0; }
.table--sub tbody tr:last-child td { border-bottom: 1px solid var(--c-border-soft); }
.subtable {
  margin: 6px 0 10px; padding-left: 14px;
  border-left: 2px solid var(--c-border);
}
.subtable + .subtable { margin-top: 10px; }
.subtable__head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 5px; font-size: var(--fs-sm);
}
.subtable__coa { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }

.paginacion {
  display: flex; gap: var(--sp-3); align-items: center; margin: 0 0 var(--sp-4);
  font-size: var(--fs-sm); color: var(--c-text-2);
}

/* ------------------------------------ 12. PESTAÑAS Y BARRA DE FILTROS */

.tabs {
  display: flex; gap: 3px; flex-wrap: wrap; margin: 0 0 var(--sp-4);
  border-bottom: 1px solid var(--c-border);
}
.tabs a {
  padding: 9px 15px; text-decoration: none; color: var(--c-text-2);
  border-bottom: 2px solid transparent; font-size: var(--fs); font-weight: 550;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  display: inline-flex; align-items: center; gap: 7px;
  margin-bottom: -1px;
}
.tabs a:hover { color: var(--c-text); background: var(--c-surface-alt); }
.tabs a[aria-current="page"], .tabs a.tabs__active {
  color: var(--c-accent-dark); border-bottom-color: var(--c-accent); font-weight: 650;
  background: transparent;
}
.tabs .tabs__count {
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-2);
  background: var(--c-surface-sunk); border-radius: var(--radius-pill);
  padding: 1px 7px; margin-left: 2px;
}
.tabs a[aria-current="page"] .tabs__count { background: var(--c-accent-soft); color: var(--c-accent-dark); }

/* Barra de filtros: una tarjeta clara, no un montón de campos sueltos.
   `.buscador` es la misma pieza y se define justo debajo; `.filters` existe
   para el caso en el que la barra NO lleva buscador. */
.filters {
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-xs);
  padding: 12px 16px; margin: 0 0 var(--sp-4);
  display: flex; gap: var(--sp-3); align-items: flex-end; flex-wrap: wrap;
}
.filters .field { margin-bottom: 0; max-width: 18rem; }
.filters__spacer { flex: 1 1 auto; }

/* El buscador es la barra de filtros de PQG y, en un listado de Maestro, la
   acción PRINCIPAL: por eso ocupa una fila propia y no vive plegado. */
.buscador {
  /* `flex-end` y no `center`: con la etiqueta encima del campo, centrar dejaba
     el botón `Buscar` a media altura del bloque y visiblemente por encima de
     la caja de búsqueda. Alineados por abajo, botón y caja comparten línea. */
  display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-xs);
  padding: 12px 16px; margin-bottom: var(--sp-4);
}
.buscador .field { margin-bottom: 0; }
.buscador label:not(.buscador__check) {
  font-size: var(--fs-sm); color: var(--c-text-2); white-space: nowrap;
}
/* El campo de búsqueda es el protagonista de la barra: manda el ancho. */
.buscador input[type=search], .buscador input[type=text] { flex: 1 1 17rem; min-width: 13rem; }
.buscador select { min-width: 10rem; }
.buscador__check {
  display: flex; gap: 6px; align-items: center; font-size: var(--fs-sm);
  white-space: nowrap; padding-bottom: 0;
}
/* Dentro de una tarjeta, la barra no dibuja una segunda tarjeta. */
.panel__body > .buscador,
.panel__body .buscador {
  border: 0; box-shadow: none; padding: 0; margin-bottom: 0; background: transparent;
}

/* ------------------------------------------------------- 13. FORMULARIOS */

/* Un control se estiliza por SER un control, no por estar dentro de `.field`.
   Así desaparece de toda PQG la caja gris del navegador, incluidas las barras
   de filtro que no envuelven cada campo en su etiqueta. */
input[type=text], input[type=search], input[type=email], input[type=password],
input[type=number], input[type=date], input[type=datetime-local], input[type=month],
input[type=time], input[type=url], input[type=tel], input[type=file],
select, textarea {
  padding: 8px 11px; min-height: 36px;
  border: 1px solid var(--c-border-strong); border-radius: var(--radius-sm);
  font: inherit; color: var(--c-text); background: #fff;
  transition: border-color .12s ease, box-shadow .12s ease;
  max-width: 100%;
}
input:hover:not(:disabled), select:hover:not(:disabled), textarea:hover:not(:disabled) {
  border-color: var(--c-text-3);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); outline: none;
}
input:disabled, select:disabled, textarea:disabled {
  background: var(--c-surface-sunk); color: var(--c-text-3); cursor: not-allowed;
}
input[type=checkbox], input[type=radio] { width: 16px; height: 16px; accent-color: var(--c-accent); }
select {
  appearance: none;
  padding-right: 30px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--c-text-3) 50%),
    linear-gradient(135deg, var(--c-text-3) 50%, transparent 50%);
  background-position: calc(100% - 16px) calc(50% + 1px), calc(100% - 11px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
select[multiple], select[size] { appearance: auto; background-image: none; padding-right: 11px; }

/* Un `<button>` sin clase sigue siendo un botón de PQG, no del navegador. */
button:not([class]) {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 14px; min-height: 34px;
  border-radius: var(--radius-sm); border: 1px solid var(--c-border-strong);
  background: var(--c-surface); color: var(--c-text);
  font: inherit; font-weight: 550; cursor: pointer; box-shadow: var(--shadow-xs);
}
button:not([class]):hover { background: var(--c-surface-alt); border-color: var(--c-text-3); }

.field { margin-bottom: var(--sp-3); max-width: 46rem; }
.field label {
  display: block; font-weight: 600; font-size: var(--fs-sm);
  margin-bottom: 4px; color: var(--c-text);
}
.field input[type=text], .field input[type=email], .field input[type=password],
.field input[type=number], .field input[type=date], .field input[type=file],
.field select, .field textarea {
  width: 100%; padding: 8px 11px;
  border: 1px solid var(--c-border-strong); border-radius: var(--radius-sm);
  font: inherit; background: #fff; color: var(--c-text);
  min-height: 36px;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--c-text-3); }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-accent-soft); outline: none;
}
.field .help { color: var(--c-text-3); font-size: var(--fs-sm); margin-top: 4px; }
.errorlist { color: var(--s-bloq-fg); font-size: var(--fs-sm); margin: 4px 0; padding-left: 18px; }
.field .errorlist { list-style: none; padding-left: 0; margin: 5px 0 0; font-weight: 550; }
.field .errorlist li::before { content: "⚠ "; }
.field--error input, .field--error select, .field--error textarea {
  border-color: var(--s-bloq-fg); background: #fffafa;
}

label { cursor: pointer; }

/* Formulario en tarjeta, con sus secciones. */
.form-card {
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: 20px; margin-bottom: var(--sp-4); max-width: 62rem;
}
.form-card h3, .panel__body h3 {
  font-size: var(--fs-xs); margin: var(--sp-5) 0 var(--sp-2);
  text-transform: uppercase; letter-spacing: .07em; color: var(--c-text-3);
  font-weight: 650;
  padding-bottom: 5px; border-bottom: 1px solid var(--c-border-soft);
}
.form-card h3:first-child, .panel__body h3:first-child { margin-top: 0; }
.form-row { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.form-row .field { flex: 1 1 15rem; max-width: none; }
.form-card > form > p,
.panel__body > form:not(.buscador) > p {
  max-width: 46rem; margin: 0 0 var(--sp-3);
}
.form-card > form > p > label,
.panel__body > form:not(.buscador) > p > label {
  display: block; margin-bottom: 4px; color: var(--c-text);
  font-size: var(--fs-sm); font-weight: 600;
}
.form-card > form > p > :is(input, select, textarea),
.panel__body > form:not(.buscador) > p > :is(input, select, textarea) {
  width: 100%;
}
.helptext {
  display: block; margin-top: 4px; color: var(--c-text-3);
  font-size: var(--fs-sm);
}
.form-card__foot {
  margin-top: var(--sp-5); padding-top: var(--sp-4);
  border-top: 1px solid var(--c-border-soft);
  display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center;
}

/* Pantalla de acceso: centrada, sin barra lateral. */
.acceso { max-width: 27rem; margin: 8vh auto 0; }
.acceso .panel { box-shadow: var(--shadow-md); }
.acceso__brand {
  display: flex; align-items: center; gap: 11px; justify-content: center;
  margin-bottom: var(--sp-5); font-size: var(--fs-xl); font-weight: 680;
  letter-spacing: -.02em;
}
.acceso__brand .nav__logo { width: 36px; height: 36px; flex-basis: 36px; border-radius: 10px; }
.acceso__brand .nav__logo .ic { width: 20px; height: 20px; }

/* Segundo factor (D-553): el QR del alta y la tanda de códigos de
   recuperación, que se muestra UNA vez y se copia a mano o se imprime. */
.qr {
  display: flex; justify-content: center; padding: var(--sp-4) 0;
}
.qr svg { background: #fff; border-radius: var(--radius-md); padding: 8px; }
.codigos {
  list-style: none; margin: 0 0 var(--sp-4); padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--sp-2);
}
.codigos code { font-size: var(--fs-md); letter-spacing: .08em; }

/* ---------------------- 14. PROGRESO, COMPROBACIÓN Y LISTAS COMPACTAS */

.meter {
  height: 8px; border-radius: var(--radius-pill); background: var(--c-surface-sunk);
  overflow: hidden; min-width: 6rem;
}
.meter__fill { height: 100%; background: var(--c-accent); border-radius: var(--radius-pill); }
.meter--ok   .meter__fill { background: var(--s-ok-fg); }
.meter--aten { background: #f7ecd4; }
.meter--aten .meter__fill { background: var(--s-aten-fg); }
.meter--bloq { background: #f7dcda; }
.meter--bloq .meter__fill { background: var(--s-bloq-fg); }
.meter--lg { height: 10px; }
/* La barra de avance NO puede pisar la columna siguiente — corrección de
   aceptación del *Functional refinement 6*.

   Medido en el navegador a 1440 px, no deducido: `.meter` lleva un piso de
   `min-width: 6rem` (96 px) y la cifra `0 / 3,000` va en `nowrap` (52 px), así
   que con el hueco de 10 px la fila pedía **158 px dentro de una celda de 122**.
   Como `.meter-row` es un flex sin `min-width: 0`, los 36 px sobrantes no se
   repartían: se salían de la celda. La cifra terminaba 22 px fuera de su `td` y
   **8 px encima del primer punto del checklist** — el checklist no se encimaba
   solo, se lo encimaba la columna de al lado.

   El reparto correcto es el que respeta qué es dato y qué es adorno: **la cifra
   conserva su ancho** —es el dato— y **la barra se encoge**, porque el piso de
   `6rem` existe para una barra suelta, no para una que comparte una celda de
   ancho declarado. Si aun así no cabe, la cifra **baja a un segundo renglón**
   en vez de salirse: envolver es legible, desbordar es encimar. */
.meter-row { display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap; }
.meter-row .meter { flex: 1 1 auto; min-width: 2.5rem; }
.meter-row .meter-row__label {
  font-size: var(--fs-sm); color: var(--c-text-2); white-space: nowrap;
  font-variant-numeric: tabular-nums; flex: 0 0 auto;
}

/* Leyenda de tramos: el color se explica con palabras, siempre. */
.legend { display: flex; gap: var(--sp-4); flex-wrap: wrap; font-size: var(--fs-sm);
  color: var(--c-text-2); margin-top: var(--sp-2); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.legend .legend--ok i   { background: var(--s-ok-fg); }
.legend .legend--aten i { background: var(--s-aten-fg); }
.legend .legend--bloq i { background: var(--s-bloq-fg); }
.legend .legend--acc i  { background: var(--c-accent); }

.check { list-style: none; margin: 0; padding: 0; font-size: var(--fs); }
.check li { padding: 4px 0 4px 24px; position: relative; }
.check li::before { position: absolute; left: 0; font-weight: 700; }
.check li.check--si::before { content: "✓"; color: var(--s-ok-fg); }
.check li.check--no::before { content: "○"; color: var(--c-text-3); font-weight: 500; }
.check li.check--no { color: var(--c-text-2); }
.check li.check--na::before { content: "—"; color: var(--c-text-3); font-weight: 500; }

/* Checklist COMPACTO: un punto por requisito (Functional refinement 6 §B10.3).
   El checklist en renglones hacía ilegible una tabla de veinte Líneas. Cada
   estado tiene FORMA además de color —relleno, hueco, aspa, anillo— porque el
   color no puede ser el único portador del significado; el nombre completo va
   en el `title` de cada punto y en su texto para lector de pantalla. */
.dots { display: inline-flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.dot {
  width: 12px; height: 12px; border-radius: 50%; display: inline-block;
  position: relative; cursor: default;
  border: 1.5px solid var(--c-text-3); background: transparent;
}
.dot:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* El globo del punto — corrección de aceptación §3.
   Con sólo `title` y `cursor: help`, lo que el Usuario veía al pasar por encima
   era **el signo `?` del cursor**, y el texto del navegador tardaba uno o dos
   segundos en aparecer. El globo lo dibuja la página: sale **al instante**, con
   el ratón y con el teclado, y dice el requisito y su estado. El `title` se
   conserva como respaldo, y `cursor: help` se retira porque ese `?` era el
   defecto que había que corregir. Mismo mecanismo que `.chart__tip`. */
.dot__tip {
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-1);
  white-space: nowrap; text-transform: none; letter-spacing: 0;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
  padding: 3px 8px; z-index: 5;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .08s ease;
}
.dot:hover .dot__tip, .dot:focus-visible .dot__tip { opacity: 1; visibility: visible; }
/* El globo del primer y del último punto no puede salirse de la celda. */
.dots .dot:first-child .dot__tip { left: 0; transform: none; }
.dots .dot:last-child .dot__tip { left: auto; right: 0; transform: none; }
.dot--ok     { background: var(--s-ok-fg);   border-color: var(--s-ok-fg); }
.dot--pend   { background: transparent;      border-color: var(--c-text-3); }
.dot--previa { background: var(--s-revi-bg); border-color: var(--s-revi-fg); box-shadow: inset 0 0 0 2px var(--c-surface); }
.dot--falta  { background: var(--s-bloq-bg); border-color: var(--s-bloq-fg); }
.dot--falta::before,
.dot--falta::after {
  content: ""; position: absolute; left: 1px; top: 4px;
  width: 7px; height: 1.5px; background: var(--s-bloq-fg);
}
.dot--falta::before { transform: rotate(45deg); }
.dot--falta::after  { transform: rotate(-45deg); }
.dots__sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Lista compacta dentro de un panel (entregas de hoy, riesgos, alertas). */
.rows { list-style: none; margin: 0; padding: 0; font-size: var(--fs); }
.rows li {
  display: flex; gap: 10px; align-items: center; padding: 8px 0;
  border-bottom: 1px solid var(--c-border-soft); flex-wrap: wrap;
}
.rows li:first-child { padding-top: 0; }
.rows li:last-child { border-bottom: 0; padding-bottom: 0; }
.rows .rows__main { flex: 1 1 12rem; min-width: 0; }
.rows .rows__num {
  font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 650;
}
.rows a { text-decoration: none; font-weight: 550; }
.rows a:hover { text-decoration: underline; }

/* Fila de urgencia: icono + cifra grande + etiqueta. El bloque «Lo urgente
   hoy» del Dashboard y cualquier bandeja con prioridad visual. */
.urgent {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
.urgent__item {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 12px 14px; border-radius: var(--radius);
  border: 1px solid var(--c-border); background: var(--c-surface);
  text-decoration: none; color: inherit;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.urgent__item .icobox { flex: 0 0 auto; }
.urgent__body { display: flex; flex-direction: column; }
.urgent__item:hover { border-color: var(--c-accent-line); box-shadow: var(--shadow-sm); color: inherit; }
.urgent__body { min-width: 0; }
.urgent__value {
  display: block; font-size: var(--fs-xl); font-weight: 680; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.urgent__label { display: block; font-size: var(--fs-sm); color: var(--c-text-2); }
.urgent__note {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; font-size: var(--fs-xs); font-weight: 600; margin-top: auto;
  padding-top: 3px;
}
.urgent__note--aten { color: var(--s-aten-fg); }
.urgent__note--bloq { color: var(--s-bloq-fg); }
.urgent__note--ok   { color: var(--s-ok-fg); }

/* --------------------------------------------------------- 15. GRÁFICAS */

/* Gráfica de columnas en CSS puro: sin librerías y sin CDN. UNA serie = un
   matiz y sin leyenda; el título de la tarjeta dice qué se grafica. El valor
   se rotula SELECTIVAMENTE (último punto / máximo); el resto vive en el
   `title` y en la tabla accesible que acompaña a toda gráfica. */

.chart { margin: 4px 0 0; }
.chart__cols {
  display: flex; align-items: flex-end; gap: 10px; height: 132px;
  border-bottom: 1px solid var(--c-border); padding: 20px 4px 0;
}
.chart__col {
  flex: 1 1 0; display: flex; flex-direction: column; align-items: center;
  justify-content: flex-end; height: 100%; min-width: 0; position: relative;
}
.chart__bar {
  width: 100%; max-width: 26px; min-height: 2px;
  background: var(--c-accent); border-radius: 5px 5px 0 0;
  transition: background .12s ease;
}
.chart__col:hover .chart__bar { background: var(--c-accent-dark); }
.chart__col--off .chart__bar { background: var(--c-border-strong); }
.chart__col--neg .chart__bar { background: var(--s-bloq-fg); }
.chart__val {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-2);
  white-space: nowrap; font-variant-numeric: tabular-nums;
  background: var(--c-surface); padding: 0 2px;
  z-index: 1;
}
/* --- El valor, al pasar por encima o al enfocar (*refinement 6* §B1.6) ----
   Antes se escribían dos valores permanentes sobre las barras —el máximo y el
   último— y en columnas contiguas se encimaban entre sí y sobre la gráfica.
   Ahora el valor vive en un globo que aparece **sólo** al señalar la columna,
   con ratón o con teclado.

   `pointer-events: none` evita que el globo se interponga entre el cursor y la
   barra, que produciría un parpadeo; `visibility` acompaña a `opacity` para
   que el globo no sea alcanzable mientras está oculto. Ningún dato depende de
   esto: el `title` nativo y la tabla `Ver tabla` siguen ahí. */
.chart__tip {
  position: absolute; bottom: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-1);
  white-space: nowrap; font-variant-numeric: tabular-nums;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
  padding: 2px 7px; z-index: 3;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .1s ease;
}
.chart__col:hover .chart__tip,
.chart__col:focus-visible .chart__tip { opacity: 1; visibility: visible; }
.chart__col:focus-visible { outline: 2px solid var(--c-accent-line); outline-offset: 2px; }
/* El globo del primer y del último mes no puede salirse del panel. */
.chart__col:first-child .chart__tip { left: 0; transform: none; }
.chart__col:last-child .chart__tip { left: auto; right: 0; transform: none; }

.chart__col:nth-child(even) .chart__val { top: 20px; }
.chart__col:first-child .chart__val { left: 0; transform: none; }
.chart__col:last-child .chart__val { left: auto; right: 0; transform: none; }

/* Rótulos del eje — encargo §9 del *Functional refinement 3*.

   Antes se escalonaban en vertical (`translateY`) para que cupieran doce meses.
   El resultado era justo lo que el encargo manda corregir: rótulos encimados y
   una línea base que no existe. Ahora **no se escalona ninguno**; lo que se
   reduce, y sólo cuando hace falta, es la DENSIDAD.

   **Ningún valor se pierde al ocultar un rótulo**: cada columna lleva su
   `title` con mes e importe, y la gráfica trae siempre su tabla `Ver tabla`
   completa. Reducir densidad es una decisión de presentación, no de datos. */
.chart__labels { display: flex; gap: 10px; padding: 8px 4px 0; }
.chart__labels span {
  flex: 1 1 0; text-align: center; font-size: var(--fs-xs); color: var(--c-text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chart details { margin-top: 14px; }

/* En panel angosto —dos o tres gráficas por fila, o móvil— doce rótulos no
   caben legibles. Se muestra uno de cada dos: la serie sigue completa, los
   valores siguen en el `title` de cada columna y en la tabla desplegable. */
@media (max-width: 1200px) {
  .chart__labels span:nth-child(even) { visibility: hidden; }
}
/* --- Barras AGRUPADAS: varias series dentro de cada columna ---------------
   `Progreso de comisiones` (*refinement 6* §B3.4). Un mes = una columna;
   dentro, una barra por Vendedor. Reutiliza `.chart`, `.chart__cols`,
   `.chart__labels`, `.chart__tip` y `details > Ver tabla` — lo único propio es
   cómo se reparte el ancho de la columna entre las series.

   **Ninguna serie se oculta para que quepan las demás**: cuando hay tantas que
   las barras se aplastarían, la columna crece (su `min-width` lo fija la vista
   según cuántas series haya) y la gráfica se desplaza en horizontal. Ocultar
   una serie habría hecho que la gráfica dejara de reconciliar con la tabla. */
/* `overflow-x: auto` obliga al eje vertical a dejar de ser `visible` —lo dice
   la especificación—, así que el globo del valor, que vive ENCIMA de la barra,
   quedaría recortado por el propio contenedor que hace posible el desplazamiento
   horizontal. Se resuelve dándole sitio DENTRO de la caja: el `padding` superior
   de las columnas reserva la altura del globo, y así no hay nada que recortar. */
.chart__scroll { overflow-x: auto; }
.chart--grouped .chart__cols { gap: 8px; height: 178px; padding-top: 30px; }
.chart--grouped .chart__labels { gap: 8px; }
.chart--grouped .chart__labels span { flex: 1 1 auto; }
.chart__col--group { flex: 1 1 auto; }
.chart__group {
  display: flex; align-items: flex-end; justify-content: center;
  gap: 3px; width: 100%; height: 100%;
}
.chart__seg {
  flex: 1 1 0; max-width: 18px; min-height: 2px;
  border-radius: 4px 4px 0 0; position: relative;
  background: var(--c-serie-0);
  transition: filter .12s ease;
}
.chart__seg:hover { filter: brightness(.82); }
.chart__seg:focus-visible { outline: 2px solid var(--c-accent-line); outline-offset: 2px; }
.chart__seg:hover .chart__tip,
.chart__seg:focus-visible .chart__tip { opacity: 1; visibility: visible; }
/* Una comisión vigente NEGATIVA existe —un Ajuste puede restar más que la base—
   y se declara con trama, no sólo con color: el matiz ya está ocupado
   identificando al Vendedor. */
.chart__seg--neg {
  background-image: repeating-linear-gradient(45deg,
    rgba(255,255,255,.55) 0 3px, transparent 3px 6px);
}
/* La columna agrupada NO se apaga en gris: el gris borraría los matices que
   distinguen a los Vendedores. El mes consultado se marca en la tabla. */
.chart--grouped .chart__col--off .chart__seg { opacity: .78; }

.serie { background: var(--c-serie-0); }
.serie--0 { background: var(--c-serie-0); }
.serie--1 { background: var(--c-serie-1); }
.serie--2 { background: var(--c-serie-2); }
.serie--3 { background: var(--c-serie-3); }
.serie--4 { background: var(--c-serie-4); }
.serie--5 { background: var(--c-serie-5); }
.serie--6 { background: var(--c-serie-6); }
.serie--7 { background: var(--c-serie-7); }
.legend i.serie { width: 9px; height: 9px; border-radius: 50%; }

.chart__zero { text-align: center; color: var(--c-text-3); font-size: var(--fs-sm); padding: 24px 0; }
.chart details { margin-top: var(--sp-2); }
.chart details summary { font-size: var(--fs-sm); color: var(--c-text-2); }

/* Barras horizontales — antigüedad de saldo, reparto por categoría. */
.hbars { display: flex; flex-direction: column; gap: 9px; }
.hbar { display: grid; grid-template-columns: 8.5rem 1fr auto; gap: 10px; align-items: center; }
.hbar__label { font-size: var(--fs-sm); color: var(--c-text-2); }
.hbar__track { height: 10px; background: var(--c-surface-sunk); border-radius: var(--radius-pill); overflow: hidden; }
.hbar__fill { height: 100%; background: var(--c-accent); border-radius: var(--radius-pill); }
.hbar__value { font-size: var(--fs-sm); font-weight: 650; font-variant-numeric: tabular-nums; }
.hbar--ok   .hbar__fill { background: var(--s-ok-fg); }
.hbar--aten .hbar__fill { background: var(--s-aten-fg); }
.hbar--bloq .hbar__fill { background: var(--s-bloq-fg); }
.hbar--revi .hbar__fill { background: var(--s-revi-fg); }

/* ------------------------------------------------------- 16. CALENDARIO */

.cal {
  width: 100%; border-collapse: separate; border-spacing: 0; table-layout: fixed;
  background: var(--c-surface); border: 1px solid var(--c-border);
  border-radius: var(--radius-lg); overflow: hidden;
}
.cal th {
  padding: 9px 10px; font-size: var(--fs-xs); font-weight: 650;
  text-transform: uppercase; letter-spacing: .06em; color: var(--c-text-2);
  background: var(--c-surface-alt); border-bottom: 1px solid var(--c-border);
  text-align: left;
}
.cal td {
  vertical-align: top; border-right: 1px solid var(--c-border-soft);
  border-bottom: 1px solid var(--c-border-soft);
  padding: 6px 8px; height: 104px; font-size: var(--fs-sm);
}
.cal td:last-child, .cal th:last-child { border-right: 0; }
.cal td.cal--fuera { background: var(--c-surface-alt); color: var(--c-text-3); }
.cal td.cal--hoy { background: var(--c-accent-soft); }
.cal__dia { font-weight: 650; font-size: var(--fs-sm); color: var(--c-text-2); }
.cal__viaje {
  display: block; margin-top: 4px; padding: 3px 8px; border-radius: var(--radius-sm);
  background: var(--c-accent-soft); border: 1px solid var(--c-accent-line);
  color: var(--c-accent-dark); text-decoration: none;
  font-size: var(--fs-xs); font-weight: 550; line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal__viaje:hover { filter: brightness(.97); }
.cal__viaje--listo { background: var(--s-ok-bg); border-color: var(--s-ok-bd); color: var(--s-ok-fg); }
.cal__viaje--aten  { background: var(--s-aten-bg); border-color: var(--s-aten-bd); color: var(--s-aten-fg); }
.cal__viaje--bloq  { background: var(--s-bloq-bg); border-color: var(--s-bloq-bd); color: var(--s-bloq-fg); }
.cal__mas { display: block; margin-top: 3px; font-size: var(--fs-xs); color: var(--c-text-2); }

/* Tira de una semana: tarjeta por día con sus viajes y su capacidad. Es el
   bloque protagonista del Dashboard y el resumen del Calendario completo. */
.calweek {
  display: grid; gap: 10px;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}
.calday {
  border: 1px solid var(--c-border); border-radius: var(--radius);
  background: var(--c-surface); padding: 10px; min-height: 150px;
  display: flex; flex-direction: column; gap: 7px;
}
.calday--hoy { border-color: var(--c-accent); box-shadow: 0 0 0 2px var(--c-accent-soft); }
.calday--fuera { background: var(--c-surface-alt); }
.calday__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  padding-bottom: 7px; border-bottom: 1px solid var(--c-border-soft);
}
.calday__dow {
  font-size: var(--fs-xs); font-weight: 650; text-transform: uppercase;
  letter-spacing: .07em; color: var(--c-text-2);
}
.calday__num { font-size: var(--fs-lg); font-weight: 680; line-height: 1; }
.calday__mes { font-size: var(--fs-xs); color: var(--c-text-3); }
.calday__trips { display: flex; flex-direction: column; gap: 5px; }
.calday__foot { margin-top: auto; padding-top: 7px; border-top: 1px solid var(--c-border-soft); }
.calday__cap { display: flex; justify-content: space-between; gap: 6px;
  font-size: var(--fs-xs); color: var(--c-text-2); margin-bottom: 4px; }
.calday__vacio { font-size: var(--fs-xs); color: var(--c-text-3); }

.trip {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--c-border); border-left-width: 3px;
  border-radius: var(--radius-sm); padding: 5px 8px; background: var(--c-surface-alt);
  font-size: var(--fs-xs); line-height: 1.45;
}
.trip:hover { background: var(--c-surface-sunk); color: inherit; }
.trip b { display: block; font-weight: 650; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.trip span { color: var(--c-text-2); }
.trip--ok   { border-left-color: var(--s-ok-fg); }
.trip--aten { border-left-color: var(--s-aten-fg); }
.trip--bloq { border-left-color: var(--s-bloq-fg); }
.trip--acc  { border-left-color: var(--c-accent); }

/* ----------------------- 17. PANEL DE DETALLE, FICHA Y REJILLA DE PERMISOS */

.split { display: flex; gap: var(--sp-4); align-items: flex-start; }
.split__main { flex: 1 1 auto; min-width: 0; }
.split__side { flex: 0 0 21rem; position: sticky; top: 60px; }

/* Ficha: pares dato/valor legibles, nunca un muro de texto. */
.kv {
  display: grid; grid-template-columns: 13rem 1fr; gap: 7px var(--sp-4);
  font-size: var(--fs); margin: 0;
}
.kv dt { color: var(--c-text-2); }
.kv dd { margin: 0; font-weight: 550; }
.kv--tight { grid-template-columns: 9rem 1fr; gap: 5px var(--sp-3); }

/* Datos clave de una ficha 360°, en fila. */
.facts {
  display: grid; gap: var(--sp-3); margin: 0 0 var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
.fact { min-width: 0; }
.fact__label {
  display: block; font-size: var(--fs-xs); font-weight: 600; color: var(--c-text-3);
  text-transform: uppercase; letter-spacing: .06em;
}
.fact__value { display: block; font-size: var(--fs-md); font-weight: 650; margin-top: 2px; }

.diff { margin: 0; padding: 0; list-style: none; font-size: var(--fs); }
.diff li { padding: 3px 0; display: flex; gap: 7px; align-items: baseline; flex-wrap: wrap; }
.diff--add li::before { content: "+"; color: var(--s-ok-fg); font-weight: 700; }
.diff--del li::before { content: "−"; color: var(--s-bloq-fg); font-weight: 700; }
.diff--dep li::before { content: "+"; color: var(--c-accent); font-weight: 700; }

/* Bloque desplegable — módulo de Permisos y cualquier detalle plegado. */
details > summary { cursor: pointer; }

.module {
  border: 1px solid var(--c-border); border-radius: var(--radius);
  background: var(--c-surface); margin-bottom: var(--sp-2);
  box-shadow: var(--shadow-xs); overflow: hidden;
}
.module > summary {
  padding: 11px 14px; cursor: pointer; background: var(--c-surface);
  display: flex; justify-content: space-between; gap: var(--sp-3); align-items: center;
  font-weight: 650; list-style: none;
}
.module > summary:hover { background: var(--c-surface-alt); }
.module > summary::-webkit-details-marker { display: none; }
.module > summary::before { content: "▸"; color: var(--c-text-3); margin-right: 7px; }
.module[open] > summary::before { content: "▾"; }
.module[open] > summary { border-bottom: 1px solid var(--c-border-soft); }
.module__count { font-weight: 500; font-size: var(--fs-sm); color: var(--c-text-2); }
.module__body { padding: 10px 14px 14px; }

.plane { margin-top: var(--sp-3); }
.plane__label {
  font-size: var(--fs-xs); font-weight: 650; text-transform: uppercase;
  letter-spacing: .07em; color: var(--c-text-3);
  border-bottom: 1px solid var(--c-border-soft);
  padding-bottom: 4px; margin-bottom: 7px;
}

.perm { display: flex; gap: 10px; padding: 6px 0; align-items: flex-start; flex-wrap: wrap; }
.perm input[type=checkbox] { margin-top: 3px; flex: 0 0 auto; width: 16px; height: 16px;
  accent-color: var(--c-accent); }
.perm__label { flex: 1 1 22rem; min-width: 16rem; }
.perm__name { display: block; font-weight: 550; }
.perm__meta { display: block; color: var(--c-text-3); font-size: var(--fs-sm); margin-top: 1px; }
.perm__scope { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); }
.perm__scope select {
  padding: 4px 8px; border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm); font: inherit; font-size: var(--fs-sm); background: #fff;
}

/* --------------------------------------- 18. ESTADO VACÍO Y UTILIDADES */

.empty {
  padding: 34px 20px; text-align: center; color: var(--c-text-2);
  background: var(--c-surface); border: 1px dashed var(--c-border-strong);
  border-radius: var(--radius-lg); font-size: var(--fs);
}
.empty .icobox { margin: 0 auto var(--sp-3); }
.empty b { display: block; color: var(--c-text); font-size: var(--fs-md); margin-bottom: 4px; }
.empty .btn { margin-top: var(--sp-3); }

.muted { color: var(--c-text-3); }
.help { color: var(--c-text-3); font-size: var(--fs-sm); }
.num { font-variant-numeric: tabular-nums; }
/* Una fila que sigue siendo historia pero ya no dirige trabajo —una Línea de
   cotización retirada—: se atenúa, **nunca se esconde**. El color no es el
   único canal: la fila lleva además su globo `Retirada` y su motivo escrito. */
.row--off > td { color: var(--c-text-3); background: var(--c-surface-alt); }
.stack > * + * { margin-top: var(--sp-3); }

/* -------------------------------------------------------- 19. RESPONSIVE */

/* Prioridad: escritorio, portátil y ancho reducido razonable (encargo §20).
   No se persigue el móvil completo, que no forma parte del piloto. */

@media (max-width: 1400px) {
  .board--3 { grid-template-columns: 1fr 1fr; }
  .board--2 { grid-template-columns: 1fr; }
  .dashboard-priority { grid-template-columns: minmax(0, 1.45fr) minmax(23rem, 1fr); }
}

@media (max-width: 1280px) {
  :root { --nav-w: 208px; --fs-2xl: 23px; }
  .workarea { padding: 18px 18px 56px; }
  .topbar { padding: 10px 18px; }
  .calweek { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 1100px) {
  .board, .board--2, .board--3 { grid-template-columns: 1fr; }
  .dashboard-priority { grid-template-columns: 1fr; }
  .split { flex-direction: column; }
  .split__side { position: static; flex: 1 1 auto; width: 100%; }
}

@media (max-width: 900px) {
  .app { flex-direction: column; }
  .nav {
    width: auto; flex: none; position: static; max-height: none;
    flex-direction: row; flex-wrap: wrap; align-items: center; gap: 2px;
    padding: 10px 12px;
  }
  .nav__brand {
    width: calc(100% + 24px);
    margin: -10px -12px 4px;
    padding: 12px 18px 11px;
  }
  .nav__group { padding: 6px 8px 2px; }
  .nav a { padding: 7px 10px; }
  .nav__foot { width: 100%; margin-top: 10px; }
  .calweek { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kv, .kv--tight { grid-template-columns: 1fr; }
  .datos { grid-template-columns: 1fr; }
  .card__diag { grid-template-columns: 1fr; }
  .table, .tabla { display: block; overflow-x: auto; }
  .hbar { grid-template-columns: 7rem 1fr auto; }
}

@media print {
  .nav, .topbar, .screen__actions, .quick, .btn { display: none !important; }
  .panel, .stat { box-shadow: none; border-color: #ccc; }
  .workarea { padding: 0; }
}
