@layer legado {
/* Ficha propia de Bandeja (2-nov-2026): original y campos en paralelo, apilados en móvil. */
.bf-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 1fr); gap: 1rem; }
.bf-original iframe, .bf-original img { width: 100%; height: min(68vh, 800px); object-fit: contain; border: 0; }
.bf-fields { display: grid; gap: .6rem; }
.bf-fields input, .bf-fields select { width: 100%; }
@media (max-width: 760px) { .bf-grid { grid-template-columns: 1fr; } .bf-original iframe, .bf-original img { height: 35vh; } }
/* estilos/11-cristal-contraste-y-kardex.css · fichero 11/11 de la hoja HEREDADA (líneas 21903-23007 del antiguo styles.css).
   Cristal capa compartida, contraste en modales oscuros, kardex e inventario. Tramos internos, en este orden:
     · 36-cristal-capa-compartida (21903-22407): Cristal iOS 26/27: capa compartida (hero, paneles, filtros, píldoras, botones, tablas, KPI, vacíos)
     · 37-contraste-modales-oscuros (22408-22742): Contraste en los modales oscuros, desplegables nativos, columna de acciones, fila resaltada
     · 38-kardex-e-inventario (22743-23007): Kardex e inventario (barra de mando pegajosa, pestañas, referencias)
   El orden ES la cascada: va tras 10-edicion-parte-y-proveedores.css y antes de css/coherencia.css; no se reordena. Índice: static/styles.css. */
/* ── tramo 36-cristal-capa-compartida (líneas 21903-22407 del antiguo styles.css): Cristal iOS 26/27: capa compartida (hero, paneles, filtros, píldoras, botones, tablas, KPI, vacíos) ── */
/* ══════════════════════════════════════════════════════════════════════════════════════════════
   LENGUAJE DE CRISTAL iOS 26/27 — CAPA COMPARTIDA                              (2026-08-19)

   Hasta ahora este acabado se aplicaba pantalla a pantalla con estilos EN LÍNEA, para no tocar
   este fichero mientras solo unas pocas vistas estaban convertidas. Con las 34 vistas dentro esa
   estrategia dejaría de tener sentido: `.panel` sale en 247 sitios, `.status-pill` en 178 y
   `.page-intro-v2` en 24 — reescribirlas a mano una por una habría multiplicado por veinte la
   duplicación que acabamos de quitar de encima.

   Así que el acabado se aplica UNA VEZ, sobre las primitivas compartidas. Va al FINAL del fichero
   a propósito: con la misma especificidad, gana la última regla, y así no hay que subir selectores
   ni meter `‹important›` en ninguna parte.

   Los valores viven en las variables `--cr-*` de aquí abajo, y `static/cristal.js` los lee con
   `var(--cr-…, <literal>)`. Una sola definición para el CSS y para los estilos en línea. El
   literal de reserva es el mismo valor, para que nada dependa de que la hoja haya cargado.

   Reglas al tocar esto:
   - No hay modo oscuro en la app (0 usos de `prefers-color-scheme`): no hace falta paleta doble.
   - El fondo de `body` NO se cambia: el degradado cálido que ya había es la tierra sobre la que
     este cristal está pensado, y es sobre la que se aprobó Facturas de proveedor.
   - Un `.panel` dentro de otro `.panel` va PLANO. Hay tres vistas con paneles anidados
     (inventario, albaranes de venta, partes) y, sin esta regla, salen tarjeta dentro de tarjeta.
   - El título del hero va con `clamp()`, no con 38px fijos: a 800 px de ancho se salía.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

:root {
  /* Superficies */
  --cr-hairline: 1px solid rgba(255,255,255,0.66);
  --cr-hairline-color: rgba(255,255,255,0.66);
  --cr-glass: linear-gradient(165deg, rgba(255,255,255,0.86), rgba(255,255,255,0.66));
  --cr-lift: 0 1px 0 rgba(255,255,255,0.92) inset, 0 26px 62px -32px rgba(20,26,40,0.36);
  --cr-lift-soft: 0 1px 0 rgba(255,255,255,0.9) inset, 0 20px 48px -28px rgba(20,26,40,0.32);
  --cr-lift-card: 0 1px 0 rgba(255,255,255,0.9) inset, 0 16px 38px -22px rgba(20,26,40,0.3);
  /* El lavado de las tarjetas KPI. Estaba usado en tres sitios SIN definir, asi que las
     tarjetas salian transparentes: parecian pegadas unas a otras y planas contra el papel. */
  --cr-kpi-wash: linear-gradient(160deg, rgba(255,255,255,0.96), rgba(250,248,246,0.92));
  --cr-hero-wash: linear-gradient(160deg, rgba(255,255,255,0.86), rgba(255,242,234,0.62));
  --cr-filter-wash: linear-gradient(165deg, rgba(255,255,255,0.82), rgba(255,255,255,0.62));
  --cr-inset-border: 1px solid rgba(255,255,255,0.8);
  --cr-pill-bg: rgba(255,255,255,0.92);
  --cr-sep: rgba(20,22,26,0.07);
  --cr-sep-soft: rgba(20,22,26,0.06);

  /* Tintas */
  --cr-ink: rgba(20,22,26,0.72);
  --cr-ink-soft: rgba(20,22,26,0.62);
  --cr-ink-strong: #14161a;
  --cr-orange: #ff5a00;
  --cr-orange-ink: #c24200;
  --cr-orange-deep: #a33800;

  /* Radios */
  --cr-r-hero: 30px;
  --cr-r-panel: 28px;
  --cr-r-filter: 26px;
  --cr-r-card: 22px;
  --cr-r-pill: 999px;
  --cr-r-field: 18px;

  /* Tonos de estado: una sola definición para toda la app */
  --cr-t-neutral-ink: rgba(20,22,26,0.62);
  --cr-t-neutral-border: rgba(20,22,26,0.16);
  --cr-t-info-ink: #26438f;
  --cr-t-info-border: rgba(58,102,204,0.3);
  --cr-t-sent-ink: #3d2a92;
  --cr-t-sent-border: rgba(96,72,214,0.32);
  --cr-t-success-ink: #06603a;
  --cr-t-success-border: rgba(20,160,90,0.34);
  --cr-t-warning-ink: #6b4400;
  --cr-t-warning-border: rgba(196,146,0,0.42);
  --cr-t-danger-ink: #9c1a13;
  --cr-t-danger-border: rgba(214,44,44,0.34);
}

/* ─── Hero de pantalla ───────────────────────────────────────────────────────────────────────── */
.page-intro-v2 {
  align-items: start;
  gap: 20px;
  padding: 22px 24px;
  border: var(--cr-hairline);
  border-radius: var(--cr-r-hero);
  background: var(--cr-hero-wash);
  box-shadow: var(--cr-lift);
}

.page-intro-v2 .eyebrow {
  font-size: 12px;
  font-weight: 750;
  text-transform: none;
  color: var(--cr-orange-ink);
}

.page-intro-v2 h2 {
  margin: 7px 0 0;
  font-size: 32px;   /* fijo: con el clamp cada ancho daba un titulo distinto y las secciones no parecian el mismo software */
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.1;
}

.page-intro-v2 p {
  max-width: 640px;
  margin: 6px 0 0;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--cr-ink);
  text-wrap: pretty;
}

.page-intro-v2 .page-intro-side {
  gap: 12px;
}

/* ─── Paneles ────────────────────────────────────────────────────────────────────────────────── */
.panel {
  border: var(--cr-hairline);
  border-radius: var(--cr-r-panel);
  background: var(--cr-glass);
  box-shadow: var(--cr-lift);
}

/* Panel dentro de panel: plano, o sale tarjeta dentro de tarjeta. */
.panel .panel {
  border-color: rgba(255,255,255,0.72);
  border-radius: var(--cr-r-card);
  background: rgba(255,255,255,0.5);
  box-shadow: none;
}

.panel-head,
.section-header-v2 {
  border-bottom-color: var(--cr-sep);
}

.section-header-v2 .eyebrow {
  font-size: 12px;
  font-weight: 800;
  text-transform: none;
  color: var(--cr-orange-ink);
}

.section-header-v2 h3,
.panel-head h3 {
  font-weight: 700;
  letter-spacing: -0.025em;
}

.section-header-v2 p {
  color: var(--cr-ink);
  font-weight: 500;
}

/* ─── Barra de filtros y campo de búsqueda ───────────────────────────────────────────────────── */
.filter-bar-v2 {
  padding: 14px 16px;
  border: var(--cr-hairline);
  border-radius: var(--cr-r-filter);
  background: var(--cr-filter-wash);
  box-shadow: var(--cr-lift-soft);
}

.filter-bar-v2 > .search-input,
.search-input {
  min-height: 44px;
  padding: 12px 15px;
  border: 1px solid rgba(255,255,255,0.84);
  border-radius: var(--cr-r-field);
  background: rgba(255,255,255,0.8);
  box-shadow: 0 1px 3px rgba(20,26,40,0.06) inset;
  font-size: 14px;
  font-weight: 500;
}

.filter-result-count {
  padding: 5px 12px;
  border: var(--cr-inset-border);
  border-radius: 999px;
  background: rgba(20,22,26,0.055);
  color: var(--cr-ink);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ─── Píldoras de estado ─────────────────────────────────────────────────────────────────────── */
/* Sobre blanco OPACO, con el color en el borde y en el texto: cuando la fila va tintada con el
   mismo tono, apilar los dos fondos hunde el contraste. */
.status-pill,
.status-badge {
  min-height: 26px;
  padding: 4px 10px;
  border: 1px solid var(--cr-t-neutral-border);
  border-radius: 999px;
  background: var(--cr-pill-bg);
  color: var(--cr-t-neutral-ink);
  font-size: 12px;
  font-weight: 700;
}

.status-pill.success,
.pill.success,
.status-badge.success {
  border-color: var(--cr-t-success-border);
  background: var(--cr-pill-bg);
  color: var(--cr-t-success-ink);
}

.status-pill.warning,
.pill.warning,
.status-badge.warning {
  border-color: var(--cr-t-warning-border);
  background: var(--cr-pill-bg);
  color: var(--cr-t-warning-ink);
}

.status-pill.danger,
.pill.danger,
.status-badge.danger {
  border-color: var(--cr-t-danger-border);
  background: var(--cr-pill-bg);
  color: var(--cr-t-danger-ink);
}

.status-pill.info,
.pill.info,
.status-badge.info {
  border-color: var(--cr-t-info-border);
  background: var(--cr-pill-bg);
  color: var(--cr-t-info-ink);
}

.status-pill.neutral,
.status-pill.offline,
.status-badge.neutral {
  border-color: var(--cr-t-neutral-border);
  background: var(--cr-pill-bg);
  color: var(--cr-t-neutral-ink);
}

.pill {
  border: var(--cr-inset-border);
  border-radius: 999px;
  background: rgba(20,22,26,0.055);
  color: var(--cr-ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ─── Botones ────────────────────────────────────────────────────────────────────────────────── */
.btn {
  min-height: 40px;
  padding: 9px 17px;
  border: var(--cr-inset-border);
  border-radius: 999px;
  background: rgba(255,255,255,0.9);
  box-shadow: 0 2px 8px -4px rgba(20,26,40,0.26);
  font-size: 14px;
  font-weight: 600;
}

.btn.primary {
  /* CONTRASTE. El degradado anterior (#ff7d29 -> #ff5a00) daba 2,56:1 y 3,13:1 con texto blanco:
     AA pide 4,5:1 y ni siquiera llegaba al 3:1 del texto grande. Era el control mas pulsado del ERP
     y lo puse yo en la capa cristal.

     Del brand sheet de TYPY salen dos colores: naranja #e46701 y gris #333333. Ninguna combinacion
     de los dos llega a AA sobre un relleno: blanco sobre #e46701 son 3,37:1 y el gris de marca
     sobre el naranja de marca, 3,75:1. Asi que hay que desviarse, y se hace lo MINIMO posible:
     mismo tono (27) y misma saturacion (99%) que #e46701, bajando solo 7 y 13 puntos de
     luminosidad. Con 6 no llegaba (4,19:1). Resultado 4,59:1 y 6,05:1 con blanco.

     El #e46701 de marca NO se toca en ningun otro sitio: para bordes, iconos, railes y logo WCAG
     solo pide 3:1 (1.4.11) y lo cumple (3,37:1 sobre blanco, 3,00:1 sobre el gris del fondo). Aqui
     falla unicamente porque lleva texto encima. */
  border-color: rgba(192,86,0,0.32);
  background: linear-gradient(170deg, var(--ty-marca-accion), var(--ty-marca-accion-fuerte));
  color: var(--ty-sobre-marca);
  box-shadow: 0 1px 0 rgba(255,255,255,0.4) inset, 0 12px 26px -10px rgba(255,90,0,0.6);
  font-weight: 700;
}

.btn.danger {
  border-color: var(--cr-t-danger-border);
  /* El fondo, o queda el rojo de la capa anterior con esta tinta roja encima: 2,17:1 medido. */
  background-color: var(--cr-pill-bg);
  background-image: none;
  color: var(--cr-t-danger-ink);
}

.btn.ghost {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}

/* ─── Tablas ─────────────────────────────────────────────────────────────────────────────────── */
.data-table th {
  border-bottom: 1px solid var(--cr-sep);
  background: rgba(255,255,255,0.5);
  color: var(--cr-ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
}

.data-table td {
  border-bottom: 1px solid var(--cr-sep-soft);
}

.data-table tbody tr:last-child td {
  border-bottom: 0;
}

/* ─── Barra de vistas guardadas / pestañas ───────────────────────────────────────────────────── */
.saved-view-bar-v2 button {
  min-height: 38px;
  padding: 8px 15px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--cr-ink);
  font-size: 13px;
  font-weight: 550;
}

.saved-view-bar-v2 button.active {
  border-color: rgba(255,255,255,0.9);
  background: linear-gradient(170deg, #ffffff, rgba(255,255,255,0.82));
  box-shadow: 0 1px 0 rgba(255,255,255,0.9) inset, 0 4px 12px -5px rgba(20,26,40,0.34);
  color: var(--cr-ink-strong);
  font-weight: 650;
}

.saved-view-bar-v2 button b {
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(20,22,26,0.07);
  color: var(--cr-ink);
  font-size: 12px;
  font-weight: 750;
  font-variant-numeric: tabular-nums;
}

.saved-view-bar-v2 button.active b {
  background: rgba(255,255,255,0.94);
  color: var(--cr-orange-deep);
}

/* ─── Tarjetas KPI ───────────────────────────────────────────────────────────────────────────── */
.billing-kpi,
.kpi-card,
.metric-card {
  padding: 17px 18px;
  border: 1px solid rgba(20,22,26,0.1);
  border-left: 1px solid rgba(20,22,26,0.1);
  border-radius: var(--cr-r-card);
  background: linear-gradient(160deg, rgba(255,255,255,0.9), rgba(245,244,243,0.78));
  box-shadow: var(--cr-lift-card);
}



.billing-kpi .kpi-sub,
.kpi-card .kpi-sub {
  color: var(--cr-ink);
  font-size: 12px;
  font-weight: 550;
}

.billing-kpi.active { box-shadow: var(--cr-lift-card), 0 0 0 2px rgba(255,90,0,0.18); border-color: rgba(255,90,0,0.42); outline: none; }

/* ─── Estados vacíos ─────────────────────────────────────────────────────────────────────────── */
.ops-empty-state,
.empty {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 56px 30px;
  border-top: 1px solid var(--cr-sep);
  color: var(--cr-ink);
  text-align: center;
}

.ops-empty-state strong,
.empty strong {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.ops-empty-state span,
.empty span {
  max-width: 460px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--cr-ink);
  text-wrap: pretty;
}

/* ─── Facturación: el bloque `.billing-ios` de más arriba pintaba tarjetas planas de radio 16 y
       tipografía SF Pro. Se le devuelve el acabado compartido; los selectores se repiten tal cual
       porque, con la misma especificidad, gana esta capa por venir después. ──────────────────── */
.billing-ios {
  font-family: inherit;
  gap: 14px;
}

.billing-ios .billing-list-panel,
.billing-ios .billing-detail-wrap article.panel,
.billing-ios article.panel {
  border: var(--cr-hairline);
  border-radius: var(--cr-r-panel);
  background: var(--cr-glass);
  box-shadow: var(--cr-lift);
}

/* El texto suelto de un panel, con el mismo margen que sus hermanos.
   Un `.panel` no lleva relleno propio a proposito: cada pieza de dentro trae el suyo (la cabecera
   18px, la tabla 22px por celda). Pero un parrafo suelto entre medias no traia ninguno y quedaba
   PEGADO al borde —medido: 1px, que es solo el grosor del borde— en Stock, Equipos y los
   plegables. Es la misma familia de defectos que Ruben venia señalando en sus capturas.
   El `h4` suelto, igual (10-oct-2026): en los diálogos de gastos sueltos de facturacion-tecnicos.js
   el titulo «Otros gastos del periodo» quedaba pegado al borde y su parrafo, 18 px mas adentro. */
.panel > p,
.panel > .muted,
.panel > small,
.panel > ul,
.panel > ol,
.panel > h4 {
  padding-inline: 18px;
}

.panel > p:first-child { padding-top: 16px; }
.panel > p:last-child { padding-bottom: 16px; }

.billing-ios .billing-kpi {
  border: 1px solid rgba(20,22,26,0.1);
  border-radius: var(--cr-r-card);
  background: linear-gradient(160deg, rgba(255,255,255,0.9), rgba(245,244,243,0.78));
  box-shadow: var(--cr-lift-card);
  padding: 17px 18px;
}

.billing-ios .billing-kpi.active { box-shadow: var(--cr-lift-card), 0 0 0 2px rgba(255,90,0,0.18); }

.billing-ios .status-pill {
  border: 1px solid var(--cr-t-neutral-border);
  background: var(--cr-pill-bg);
  font-weight: 700;
}

.billing-ios .status-pill.success { border-color: var(--cr-t-success-border); background: var(--cr-pill-bg); color: var(--cr-t-success-ink); }
.billing-ios .status-pill.warning { border-color: var(--cr-t-warning-border); background: var(--cr-pill-bg); color: var(--cr-t-warning-ink); }
.billing-ios .status-pill.danger { border-color: var(--cr-t-danger-border); background: var(--cr-pill-bg); color: var(--cr-t-danger-ink); }
.billing-ios .status-pill.info { border-color: var(--cr-t-info-border); background: var(--cr-pill-bg); color: var(--cr-t-info-ink); }
.billing-ios .status-pill.neutral { border-color: var(--cr-t-neutral-border); background: var(--cr-pill-bg); color: var(--cr-t-neutral-ink); }

.billing-ios .btn { border-radius: 999px; font-weight: 600; }
.billing-ios .btn.primary {
  border-color: rgba(255,90,0,0.3);
  background: linear-gradient(170deg, #ff7d29, var(--cr-orange));
}
.billing-ios .btn.primary:hover {
  border-color: rgba(255,90,0,0.4);
  background: linear-gradient(170deg, #ff6f14, #f05300);
}

.billing-ios .billing-invoice-table th {
  background: rgba(255,255,255,0.5);
  color: var(--cr-ink);
  font-weight: 700;
}

/* Ratón y fila seleccionada: van en NARANJA de marca y no en el color del estado, a proposito.
   El tinte de la fila dice QUE es (emitida, cobrada, vencida); esto dice DONDE estas. Si los dos
   usaran la misma escala no se podria distinguir "esta emitida" de "esta seleccionada". Se pinta
   sobre el `td`, que tapa el tinte del `tr` mientras dure el foco, y al quitarlo vuelve su color. */
.billing-ios .billing-invoice-row:hover td { background: rgba(255,90,0,0.06); }
.billing-ios .billing-invoice-row.selected td { background: rgba(255,90,0,0.11); }


/* ── tramo 37-contraste-modales-oscuros (líneas 22408-22742 del antiguo styles.css): Contraste en los modales oscuros, desplegables nativos, columna de acciones, fila resaltada ── */
/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   CONTRASTE EN LOS MODALES OSCUROS                                             2026-08-20

   Sale de un aviso concreto: "los dias del parte no se lee muy bien, falta contraste". El resumen
   de cada dia ("660 km sub. · 7 h viaje sub. · 660 km TYPY · Desayuno + Comida…") iba en
   `small.muted`: 12 px, peso 400 y color --muted (#9aa3bd). Sobre el fondo del modal —rgb(27,30,40),
   que es el degradado base #11151f mas el rgba(255,255,255,.04) del panel— eso da 6,7:1. Pasa el
   minimo de la norma, pero se lee mal de verdad: es dato DENSO en texto fino y claro sobre oscuro,
   donde los trazos se adelgazan y el minimo no basta.

   Midiendo aparecieron dos cosas mas, peores que la denunciada:

   1. La cabecera de la tabla estaba a 3,4:1 — POR DEBAJO del minimo. `.data-table thead th` la fija
      a #6b7280, un gris del tema CLARO, y se colaba en el modal.
   2. La capa de cristal que se aplico hoy al armazon claro se estaba metiendo en estos modales.
      Sus selectores van sin escopar (`.panel`, `.pill`, `.status-pill`, `.eyebrow`…) y empatan en
      especificidad con los del tema oscuro (`.wo-modal-content .panel` = 0,2,0), asi que ganaba por
      ir despues. Doce elementos por debajo del minimo y varios INVISIBLES: --cr-ink
      (rgba(20,22,26,.72)) sobre rgb(27,30,40) da 1,1:1, y el titulo del estado vacio 1:1.

   Este bloque va al FINAL del fichero para ganar por orden. Se ordena en tres pasos, y los tres
   hacen falta: sin el tercero se crea el fallo inverso.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

/* Los cinco contenedores que este fichero declara mas arriba como "clon del wo-modal", con los
   tokens oscuros, mas el propio wo-modal. Si se anade otro modal oscuro, su clase va aqui.
   FUERA a proposito: `.universal-inspector`, que es CLARO (fondo #fff, tinta #151515), y
   `.si-detail`, que no tiene tema propio y hereda el del modal que lo contiene. Meterlos habria
   producido gris claro sobre blanco. */

/* ─── 1) El detalle denunciado: color, tamano y peso ─────────────────────────────────────────── */
/* El color sube a #aab2c6 (7,8:1). No es un gris nuevo: es el que ya se habia elegido en este mismo
   modal para las tarjetas de material y de equipo. Se unifica en vez de anadir un tercer tono. Y en
   las celdas de tabla suben tambien tamano y grosor, que es la otra mitad del problema: el contraste
   solo no arregla un 12 px fino. */
.wo-modal-content .muted,
.wo-modal-content small.muted {
  color: #aab2c6;
}

.wo-modal-content td small,
.wo-modal-content td small.muted {
  display: block;
  margin-top: 3px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.45;
  color: #aab2c6;
}

/* Cabecera de tabla: pierde ante `.wo-modal-content table th` por ir despues con la misma
   especificidad, asi que hace falta una clase mas. Son las etiquetas de columna de la propia tabla
   que costaba leer (Fecha / Tipo / Detalle / Tecnico / Horas). */
.wo-modal-content .data-table thead th,
.wo-modal-content table thead th {
  color: #aab2c6;
  font-weight: 600;
}

/* ─── RESCATADO 2026-08-29 ────────────────────────────────────────────────────────────────────
   Las 19 reglas de este bloque estuvieron DESTRUIDAS entre el 27 y el 29 de agosto. El pase que
   retiro el camino muerto `app-modal` (20d997d) buscaba `.app-modal-card` linea a linea, y al
   encontrarlo dentro de una lista `:is(...)` se llevo la REGLA ENTERA en vez de quitar solo ese
   nombre. Quedaron 19 dos-puntos huerfanos y ningun error visible: los comentarios seguian ahi
   explicando un arreglo que ya no existia.
   Sin ellas, la capa clara vuelve a ganarle a los modales oscuros y pasa exactamente lo que
   describen los comentarios de abajo: Ruben, 29-ago, sobre un parte multivisita — "se ve otra vez
   claro". Medido antes de tocar: el panel «Dias del parte», 680x922, con fondo blanco al 50% y
   letra casi blanca encima; las pildoras de estado en blanco; las cabeceras de tabla en blanco con
   letra gris clara.
   Restauradas desde el propio commit que las borro, quitando `.app-modal-card` como se pretendia.
   LECCION: una limpieza de codigo muerto que empareja por NOMBRE no puede borrar por LINEA. */

/* ─── 2) Los modales oscuros quedan fuera de la capa de cristal ──────────────────────────────── */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) :is(.eyebrow, .section-header-v2 .eyebrow) {
  color: #ff944f;
}

:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) :is(.section-header-v2 p, .panel-head p, .ops-empty-state span, .pill, .muted) {
  color: #aab2c6;
}

:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .ops-empty-state strong {
  color: #eef1f8;
}

:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .pill {
  border-color: rgba(255, 255, 255, 12%);
  background: rgba(255, 255, 255, 8%);
}

/* Panel: ni degradado claro ni la linea blanca interior de --cr-lift, que sobre fondo oscuro se ve
   como un filo luminoso. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .panel {
  border: 1px solid rgba(255, 255, 255, 10%);
  border-radius: 16px;
  background: rgba(255, 255, 255, 4%);
  box-shadow: none;
}

/* Ademas del color, el FONDO: la capa de cristal le pone rgba(255,255,255,.5) a `.data-table th`,
   y sobre ese blanco el #aab2c6 se queda en 2:1. En el wo-modal no se veia porque ahi ya habia una
   regla propia; en app-sheet, bq-modal, po-modal y modal-card no la habia. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) :is(.data-table, table) thead th {
  border-bottom-color: rgba(255, 255, 255, 10%);
  background: rgba(255, 255, 255, 4%);
  color: #aab2c6;
}

/* Pildoras de estado: el tinte translucido de su propio color, no el blanco de la capa clara, Y la
   tinta clara que le corresponde. Hay que poner LAS DOS: el wo-modal ya tenia sus tintas claras,
   pero app-sheet y bq-modal no, asi que con solo el fondo oscuro quedaba verde #06603a sobre tinte
   oscuro — 1,5:1. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .status-pill {
  border: 1px solid rgba(255, 255, 255, 12%);
  background: rgba(255, 255, 255, 8%);
  color: #c3cade;
}
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .status-pill.success { background: rgba(74, 222, 128, 16%); color: #4ade80; }
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .status-pill.warning { background: rgba(251, 191, 36, 16%); color: #fbbf24; }
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .status-pill.danger { background: rgba(248, 113, 113, 16%); color: #f87171; }
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .status-pill.info { background: rgba(122, 179, 255, 16%); color: #7ab3ff; }
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) :is(.status-pill.neutral, .status-pill.offline) { background: rgba(255, 255, 255, 8%); color: #aab2c6; }

/* Barra de vistas guardadas: el chip activo de la capa clara era blanco con texto casi negro. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .saved-view-bar-v2 button {
  color: #aab2c6;
}
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .saved-view-bar-v2 button.active {
  border-color: rgba(255, 255, 255, 18%);
  background: rgba(255, 255, 255, 10%);
  box-shadow: none;
  color: #eef1f8;
}
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .saved-view-bar-v2 button b {
  background: rgba(255, 255, 255, 10%);
  color: #aab2c6;
}
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .saved-view-bar-v2 button.active b {
  background: rgba(255, 255, 255, 16%);
  color: #ffb184;
}

/* ─── 3) Y las tarjetas BLANCAS que viven dentro de esos modales, de vuelta al tema claro ────── */
/* Estas tarjetas (editor de presupuesto y de cliente) tienen fondo blanco fijo y ya tenian su
   arreglo mas arriba en el fichero — el de "NO VEO NADA AL CREAR PRESUPUESTOS", 28-jul—, que
   devuelve los tokens al tema claro. Pero el paso 2 va DESPUES que aquel y con colores literales,
   asi que sin esto les pintariamos gris claro sobre blanco: exactamente el fallo que aquel arreglo
   habia cerrado. Se cubren las MISMAS propiedades que toca el paso 2, ni una menos. */
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) :is(.eyebrow, .section-header-v2 .eyebrow) {
  color: #a33800;
}

:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) :is(.section-header-v2 p, .panel-head p, .ops-empty-state span, .pill, .muted) {
  color: #5a6072;
}

/* Estos van SUELTOS y no dentro del `:is()` de arriba a proposito: `:is()` adopta la especificidad
   MAXIMA de sus argumentos, asi que meter `td small.muted` (0,1,2) junto a `.muted` (0,1,0) la
   dejaba en 0,1,0 y perdia contra `.wo-modal-content td small.muted`, que es 0,2,2. */
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) td small,
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) td small.muted,
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) small.muted {
  color: #5a6072;
}

:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) :is(.ops-empty-state strong, .data-table thead th, table thead th) {
  color: #151515;
}

:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) :is(.pill, .status-pill) {
  border-color: rgba(20, 22, 26, 12%);
  background: rgba(20, 22, 26, 6%);
  color: #5a6072;
}

:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .status-pill.success { background: rgba(20, 160, 90, 12%); color: #06603a; }
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .status-pill.warning { background: rgba(196, 146, 0, 14%); color: #6b4400; }
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .status-pill.danger { background: rgba(214, 44, 44, 10%); color: #9c1a13; }
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .status-pill.info { background: rgba(58, 102, 204, 10%); color: #26438f; }
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) :is(.status-pill.neutral, .status-pill.offline) { background: rgba(20, 22, 26, 6%); color: #5a6072; }

:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .saved-view-bar-v2 button { color: #5a6072; }
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .saved-view-bar-v2 button.active { color: #151515; }
:is(.workorder-form-section, .quote-line-card, .quote-milestone-row, .quote-billing-card, .quote-total-card, .quote-equipment-checklist, .quote-material-flow-card) .saved-view-bar-v2 button b { color: #5a6072; }

/* ─── Desplegables nativos dentro de los modales oscuros ─────────────────── 2026-08-20 ─────── */
/* "NO SE VE NADA" al abrir el selector de Cliente en Editar parte: la lista salia en blanco sobre
   blanco. El `<select>` de estos modales lleva `color: #eef1f8 ‹important›` para que su valor se lea
   sobre el fondo oscuro, y los `<option>` HEREDAN ese color; pero la lista desplegada la pinta el
   sistema operativo con SU fondo, que en Windows es blanco. Resultado: texto casi blanco sobre
   blanco, y solo se leia la fila que estuviera resaltada.
   En toda la hoja no habia ni una regla para `option` salvo `.cm-pick option`, que ya resolvia esto
   mismo con texto oscuro sobre blanco. Se sigue ese criterio, y no el de oscurecer la lista, porque
   es el SEGURO: si una plataforma ignora nuestro `background` (macOS lo hace a menudo), con texto
   oscuro se sigue leyendo sobre el blanco del sistema; con texto claro seguiria invisible.
   No hace falta `‹important›`: una declaracion directa sobre el `option` gana siempre al valor
   heredado del `select`, aunque aquel lo lleve. */
/* UNA sola regla, y global. Antes esto estaba resuelto en un unico sitio suelto
   (`.cm-pick option`) y en ningun otro, asi que el fallo reaparecia en cualquier `<select>` de
   cualquier contenedor oscuro. Va sin escopar a proposito: la lista desplegada SIEMPRE la pinta el
   sistema operativo con su fondo claro, en toda la app y en cualquier tema, asi que el texto oscuro
   es correcto SIEMPRE. Si algun dia hace falta una lista oscura, esa pantalla lo pide expresamente;
   el defecto seguro es este. */
select option,
select optgroup {
  background-color: #ffffff;
  color: #151515;
}

select option:disabled {
  color: #8b8b8b;
}

/* Menu de acciones: las etiquetas largas ("Revisar factura subcontrata") parten en dos lineas y no
   se recortan nunca, independientemente del ancho que acabe teniendo el panel. */
.action-menu-pop .btn {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: left;
}

/* Aviso de dietas marcadas que la tarifa no sabe valorar: se descartaban en silencio del PDF y de
   la factura. Ambar, no rojo: no bloquea el parte, avisa de que se va a dejar de cobrar algo. */
.readiness-allowance-warning {
  margin-top: 8px;
  padding: 9px 11px;
  border: 1px solid var(--cr-t-warning-border, rgba(196, 146, 0, 42%));
  border-radius: 12px;
  background: rgba(226, 168, 0, 12%);
  color: var(--cr-t-warning-ink, #6b4400);
  font-size: 13px;
}


/* Dentro del modal oscuro el ambar del tema claro no se lee: se sube la tinta. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .readiness-allowance-warning {
  border-color: rgba(251, 191, 36, 34%);
  background: rgba(251, 191, 36, 14%);
  color: #fbbf24;
}

/* ─── Panel dentro de panel EN MODAL OSCURO ──────────────────────────────── 2026-08-20 ─────── */
/* Tres vueltas costo encontrar esto. El modal del parte es el mismo `<article class="panel">`, y
   dentro va `<section class="panel workorder-sessions-panel">`: un panel DENTRO de otro. La regla
   de aplanar anidados de la capa clara —`.app-shell .panel .panel`, 0,3,0— le gana al bloque
   oscuro —`:is(.wo-modal, …) .panel`, 0,2,0— y le pintaba BLANCO AL 50%. Sobre eso, el texto gris
   claro del tema oscuro se quedaba en 1,5:1: el "se ve blanco y no se entiende" de los partes
   multivisita.
   Falla solo con panel anidado, y por eso no salia al probar el panel suelto: hay que montar la
   estructura entera (app-shell > overlay > wo-modal > article.panel > wo-modal-content > panel).
   Con la misma cuenta de clases que la regla clara y viniendo despues, gana esta. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .panel .panel,
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) .panel .panel .panel {
  border-color: rgba(255, 255, 255, 9%);
  background: rgba(255, 255, 255, 3%);
  box-shadow: none;
  backdrop-filter: none;
}

/* En una pantalla de 492px la semana reparte 7 columnas a ~63px cada una, y con 8px de relleno a
   cada lado «30 ago» no cabe: medido, 1,2px de aire a la derecha. Cuatro pixeles menos de relleno
   por lado son los ocho que faltaban. Solo en estrecho: en escritorio sobra sitio. */
@media (max-width: 560px) {
  .agenda-cc .cc-colh { padding-left: 4px; padding-right: 4px; }
}

/* ─── COLUMNA DE ACCIONES ANCLADA A LA DERECHA ──────────────────────────────── 2026-08-29 ──── */
/* Una tabla con `min-width: 720px` dentro de un panel de 582 SIEMPRE se desplaza. Eso no es un
   fallo por si mismo —los datos se alcanzan— pero si la ultima columna es la que lleva la accion
   principal, la accion desaparece: Ruben en Cobros, «Registrar cobro» fuera de vista.
   Anclarla resuelve el caso general, que es lo que interesa: no depende del ancho de nadie.
   `--panel-solid` y no `--panel`: el fondo tiene que ser OPACO o las celdas que pasan por debajo
   se transparentan encima. Y el token existe en los dos temas (#ffffff en claro, #161b2b dentro
   del modal oscuro), asi que esto no vuelve a pintar blanco donde no toca. */
.data-table.acciones-ancladas {
  border-collapse: separate;
  border-spacing: 0;
}

.data-table.acciones-ancladas :is(th, td):last-child {
  position: sticky;
  right: 0;
  /* `background-color`, no `background`: la abreviatura reinicia TAMBIEN la imagen de fondo, y en
     una fila teñida por su estado eso borraba el degradado del tinte. Lo vigila el comprobador. */
  background-color: var(--panel-solid);
  /* Un borde, no una sombra: hace falta decir «hay mas tabla por debajo de esto» o la columna
     parece suelta, pero las sombras con token de la escala son VERTICALES y ademas cambian con el
     tema, asi que ninguna sirve aqui y escribir una a mano seria deuda nueva. El borde usa
     `--line`, que ya existe y el modal oscuro redefine. */
  border-left: 1px solid var(--line);
}

.data-table.acciones-ancladas thead th:last-child {
  /* El nivel CON NOMBRE de la escala, no un numero: la esquina tiene que quedar por encima de la
     cabecera pegajosa, y «pegado» es exactamente lo que es. */
  z-index: var(--ty-z-pegado);
}

/* ─── Fila resaltada: el tono sale de su propio estado ───────────────────────────────────────── */
/* Antes el raton y la seleccion pintaban NARANJA de marca, y en una tabla donde el fondo de la
   fila YA significa el estado eso confunde: una factura emitida (azul) seleccionada se veia
   melocoton y parecia otro estado. Ahora se mezcla el color del propio estado, que la fila trae en
   `--fila-tono`: seleccionar refuerza lo que la fila ya dice en vez de contradecirlo.
   El naranja queda de reserva para las tablas que aun no publican su tono. */
.billing-ios .billing-invoice-row:hover td {
  background: color-mix(in srgb, var(--fila-tono, #ff5a00) 10%, transparent);
}

.billing-ios .billing-invoice-row.selected td {
  background: color-mix(in srgb, var(--fila-tono, #ff5a00) 20%, transparent);
}

/* El h3 de seccion usa un naranja OSCURO pensado para fondo claro (#d9631e): sobre el modal se
   queda en 4,2:1. Mismo naranja claro que el antetitulo, que ahi si se lee. */
:is(.wo-modal, .po-modal, .app-sheet, .bq-modal, .modal-card) :is(.section-header-v2 h3, .section-title-row h3, .panel-head h3) {
  color: #ff944f;
}

/* Estado vacio de la lista de partes: el mensaje nombra al filtro que esconde las filas y trae el
   boton que lo quita (ver `emptyStateHtml` en pantallas.js). Los botones van debajo del texto y
   centrados con el, porque `.empty` centra su contenido. */
.empty-fix-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 12px;
}


/* ── tramo 38-kardex-e-inventario (líneas 22743-23007 del antiguo styles.css): Kardex e inventario (barra de mando pegajosa, pestañas, referencias) ── */
/* ── El kardex: el libro del almacen leido (kardex.js) ─────────────────────────────────────── */
/* Solo maquetacion y tipografia: los colores salen de los tonos que ya existen (.status-pill,
   .kpi-card-v3, .pill), para no abrir un tercer criterio de que significa cada color. */
.kardex-filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px 12px;
  align-items: end;
  margin: 12px 0;
}
.kardex-filtros .field > span {
  display: block;
  font-size: 12px;
  font-weight: 700;
  margin-bottom: 4px;
}
.kardex-filtros .kardex-filtro-texto {
  grid-column: span 2;
}
.kardex-filtros .kardex-limpiar {
  justify-self: start;
}
.kardex-cantidad {
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  white-space: nowrap;
}
.kardex-cantidad.kardex-entrada { color: var(--teal); }
.kardex-cantidad.kardex-salida { color: var(--brand-strong); }
.kardex-cantidad.kardex-traslado { color: var(--blue); }
.kardex-cantidad.kardex-sin-signo { opacity: 0.7; }
.kardex-tabla td.kardex-saldo {
  font-variant-numeric: tabular-nums;
  font-weight: 900;
}
.kardex-tabla td.kardex-saldo-incierto {
  opacity: 0.6;
  font-style: italic;
}
.kardex-tabla td.kardex-nota {
  max-width: 260px;
  white-space: normal;
  font-size: 12px;
}
.kardex-tabla .status-pill {
  margin-top: 4px;
}
.kardex-pie {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
}
.kardex-ficha {
  display: grid;
  gap: 18px;
}
.kardex-ficha h4 {
  margin: 0 0 8px;
}
.kardex-ficha h5 {
  margin: 10px 0 6px;
  font-size: 12px;
  text-transform: none;
  opacity: 0.75;
}
.kardex-alertas {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.kardex-alertas .status-pill {
  white-space: normal;
  text-align: left;
}
.kardex-dos-columnas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}
.kardex-deudas {
  margin: 0;
  padding-left: 18px;
}
.kardex-donde {
  display: grid;
  gap: 2px;
  padding: 4px 0;
  font-size: 12px;
}
.kardex-donde + .kardex-donde {
  margin-top: 6px;
}
@media (max-width: 720px) {
  .kardex-filtros .kardex-filtro-texto {
    grid-column: span 1;
  }
}

/* ─── Inventario: barra de mando pegajosa y pestañas de sección ── 4-sep-2026 ─────────────────────
   POR QUÉ. La pantalla de Inventario medía unas 30 pantallas y el buscador quedaba a 2,4 pantallas
   de la tabla que filtra (Rubén, 4-sep-2026). La barra de mando se pega bajo la barra superior y la
   pantalla se reparte en pestañas de sección (inventario.js).

   LA ALTURA DE LA BARRA SUPERIOR SE MIDE, NO SE ESCRIBE. La regla que gana
   (`.top-command-bar.command-topbar`) suma dos filas de 42 y 32 px, relleno, hueco y borde, y a
   <=980 px se apila en cinco filas. `--typy-topbar-alto` y `--typy-mando-alto` las escribe
   `mideAlturasPegajosas()` (ui.js) con un ResizeObserver; el valor de reserva es el medido a 1440 px.
   Son variables de layout (familia `--typy-*`, como `--typy-visual-vh`), no tokens de diseño.

   z-index: `.module-canvas` es un contexto de apilamiento (container-type), así que aquí solo se
   compite con los hermanos del lienzo (la barra de selección múltiple, las cabeceras de tabla); la
   barra superior (z 70) queda encima por construcción. `--ty-z-pegado` vale 10 en los tres temas.

   Fondo OPACO: el vidrio al 62 % de `.filter-bar-v2` pegado dejaba ver las filas por debajo, que es
   exactamente el «solape» que hizo que Contabilidad quitara su cabecera pegajosa (contabilidad.js).
   `background-color` + `background-image` y no la abreviatura, por el lint. */
.filter-bar-v2.es-pegajosa {
  position: sticky;
  top: var(--typy-topbar-alto, 104px);
  z-index: var(--ty-z-pegado);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--ty-e-2) var(--ty-e-3);
  background-color: var(--panel-solid);
  background-image: var(--cr-filter-wash);
}

/* Pegada, la barra tiene que ser BAJA: medida el 4-sep-2026 a 1440 px con el lienzo de 775 px (menu
   y rail desplegados), los nueve chips envolvian en tres filas y la barra media 254 px, un cuarto de
   la pantalla fijo. Por eso el contador va a la derecha del buscador y los chips en UNA fila que se
   desplaza en horizontal (el mismo carrusel que ya usan a <=560 px). */
.filter-bar-v2.es-pegajosa > .search-input {
  grid-column: 1;
  grid-row: 1;
}

.filter-bar-v2.es-pegajosa > .filter-result-count {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  white-space: nowrap;
}

.filter-bar-v2.es-pegajosa > .saved-view-bar-v2 {
  grid-column: 1 / -1;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
  padding: var(--ty-e-1);
  margin: calc(var(--ty-e-1) * -1);
}

.filter-bar-v2.es-pegajosa > .saved-view-bar-v2 button {
  flex: 0 0 auto;
}

.command-module-inventory .list-bulk-bar {
  top: calc(var(--typy-topbar-alto, 104px) + var(--typy-mando-alto, 64px));
}

/* Pestañas de sección: control segmentado, para que no se confundan con los chips de vista (que son
   píldoras y FILTRAN). Radios de la escala del sistema (14 / 10) en vez de 999. La activa lleva el
   naranja de acción, 4,59:1 con texto blanco (`.settings-tab.active` es el precedente medido). */
.saved-view-bar-v2.inventory-section-tabs {
  gap: var(--ty-e-1);
  padding: var(--ty-e-1);
  border: var(--cr-inset-border);
  border-radius: var(--ty-r-3);
  background-color: var(--panel-solid);
}

.saved-view-bar-v2.inventory-section-tabs button {
  border-radius: var(--ty-r-2);
}

.saved-view-bar-v2.inventory-section-tabs button.active {
  background-color: var(--ty-marca-accion);
  background-image: none;
  color: var(--ty-sobre-marca);
}

.saved-view-bar-v2.inventory-section-tabs button.active b {
  background-color: var(--ty-sobre-marca);
  color: var(--ty-marca-accion);
}

/* Referencias en monoespaciada y sin partir (DESIGN-SYSTEM.md §7). La columna del nombre tiene un
   ANCHO MINIMO: sin el, con el lienzo estrecho (775 px con menu y rail desplegados) el navegador la
   dejaba en 115 px y cada fila medía 184 px por las ocho lineas del nombre; la tabla ya se desplaza
   en horizontal dentro de su carcasa, asi que es mejor ancha y baja que estrecha y alta.
   `break-word` y no `anywhere`: `anywhere` entra en el calculo del ancho minimo y encogia la columna. */
.ref-mono {
  font-family: var(--ty-fuente-dato);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.inventory-table .inv-col-material {
  min-width: 220px;
  overflow-wrap: break-word;
}

/* El explorador del kardex (kardex.js, de esta misma mañana) pintaba sus filtros y su pie sin el
   relleno horizontal que llevan los parrafos del panel (`.panel > p { padding-inline: 18px }`): la
   etiqueta «Material» tocaba el borde recortado de la tarjeta. Lo cazo el auditor al pasar la pestaña
   Movimientos a cuatro anchos el 4-sep-2026; el kardex se habia desplegado sin esa pasada. */
.kardex-explorador > .kardex-filtros,
.kardex-explorador > .kardex-pie {
  padding-inline: 18px;
}

/* Móvil: con la barra superior apilada (~200 px) más buscador, chips y pestañas, una barra pegajosa
   entera se comía la mitad de una pantalla de 812 px. Se despega y solo el buscador queda pegado,
   que a este ancho ya ocupa su propia fila. */
@media (max-width: 560px) {
  .filter-bar-v2.es-pegajosa {
    position: static;
    grid-template-columns: minmax(0, 1fr);
  }

  .filter-bar-v2.es-pegajosa > .filter-result-count {
    grid-column: 1;
    grid-row: auto;
  }

  .filter-bar-v2.es-pegajosa > .search-input {
    position: sticky;
    top: var(--typy-topbar-alto, 104px);
    z-index: var(--ty-z-pegado);
  }

  .command-module-inventory .list-bulk-bar {
    top: var(--typy-topbar-alto, 104px);
  }

  /* A 360 px la tabla mide 944 px dentro de una carcasa de 257 (medido el 4-sep-2026): la columna de
     acciones anclada, con sus cuatro botones apilados, tapaba mas de la mitad de lo visible y solo
     asomaban la casilla y dos letras de la referencia. En movil se desancla: se llega a las acciones
     desplazando la tabla, que es lo que ya hacen las demas tablas del ERP a este ancho. */
  .command-module-inventory .data-table.acciones-ancladas :is(th, td):last-child {
    position: static;
    border-left: 0;
  }

  /* Las cinco tarjetas KPI apiladas median ~1.400 px y dejaban el buscador a dos pantallas del
     titulo, que era justo el problema de partida. En movil van en UNA fila que se desplaza en
     horizontal, el mismo carrusel que los chips; la cifra de cada una sigue leyendose de un vistazo. */
  .command-module-inventory .inventory-kpis .kpi-cta-strip {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(200px, calc(1vw * 72));
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
    padding-bottom: var(--ty-e-1);
  }

  .command-module-inventory .inventory-kpis .kpi-cta {
    scroll-snap-align: start;
  }
}

/* La tabla de conceptos sueltos (facturacion-tecnicos.js) tiene DOS columnas y vive en un dialogo
   mediano: el `min-width: 720px` de `.data-table`, pensado para los listados, la hacia mas ancha que
   el dialogo y obligaba a desplazar para ver el importe (10-oct-2026). Concepto ancho, importe fijo. */
.data-table.ty-tabla-conceptos {
  min-width: 0;
  table-layout: fixed;
}

.data-table.ty-tabla-conceptos th:last-child,
.data-table.ty-tabla-conceptos td:last-child {
  width: clamp(6.5rem, 30%, 9.5rem);
}

/* En movil el relleno de 22 px por celda se comia la mitad de la casilla del concepto. */
@media (max-width: 560px) {
  .data-table.ty-tabla-conceptos th,
  .data-table.ty-tabla-conceptos td {
    padding-inline: 8px;
  }
}

.data-table.ty-tabla-conceptos input {
  width: 100%;
}
}
