/* =====================================================================
   ERP Mely — Sistema de diseño (estilo Apple + acento de marca)
   Homologado con Mely EOS (Mely 90), el sistema que el equipo ya adoptó:
   misma cara, mismos tokens, misma sensación para toda la familia Mely.
   Colores y tipografía tomados del Brandbook v01 + style.css de EOS.
   ===================================================================== */
:root {
  /* --- Marca / acentos --- */
  /* LOS DOS NARANJAS, y cuál va dónde (2026-08-02, reporte de Operaciones del 30-jul:
     «¿se puede cambiar el color naranja de las letras y poner algo más oscuro?»):
        --orange      -> FONDOS, bordes, filetes, rellenos, anillos de foco
        --orange-ink  -> LETRAS
     No es gusto: el de marca contra el blanco da 2.9:1, y el mínimo para leer texto
     es 4.5:1. Estaba en `a { }`, o sea en TODOS los enlaces del ERP. Lo vigila
     inventario/tests/test_naranja_solo_para_fondos.py — si lo tecleas en un `color:`,
     truena. */
  --orange:        #FD6B00;   /* naranja de marca — NUNCA para letras */
  --orange-bright: #FF8C33;
  --orange-soft:   #FFF3EA;
  --orange-ink:    #B34E00;   /* naranja de las LETRAS: 4.9:1 sobre blanco */
  --orange-line:   #FFDCBE;   /* borde naranja tenue (avisos, chips activos) */

  /* EL AZUL DEL DATO QUE NO PIDE NADA (2026-09-17). Mismo molde que los naranjas:
        --blue-soft  -> FONDO del aviso
        --blue-line  -> su BORDE tenue
        --blue-ink   -> LETRAS (5.9:1 sobre ese fondo; el mínimo para leer es 4.5:1)

     No es un color nuevo en el ERP — es el que YA se usaba, suelto, en los tres
     únicos lugares donde hacía falta decir «esto no es una alarma»: el «Revisado»
     del buzón, el nivel de servicio del cliente y el tercer veredicto del cierre
     (`.v-explicas`, cuya propia hoja dice «el azul NO es una alarma»). Aquí se le
     da nombre para que el cuarto lugar no invente el suyo. Los tres usos viejos se
     quedan con su hex tecleado: repintarlos no era de esta tanda y ninguno de los
     tres pinta un aviso.

     Por qué nació: hasta hoy `.flash-info` y `.flash-warning` eran LA MISMA regla
     —el naranja de «es tu turno»— así que los 104 avisos informativos del ERP se
     leían como regaños. Lo cazó el ensayo de estreno del PR #364: dos avisos
     juntos en una factura de proveedor, uno de alarma y otro de buena noticia,
     salieron pintados igualitos. Ninguna prueba lo vio: el CSS no se ejecuta en
     la suite. Lo vigila `administracion/tests_el_dato_no_se_lee_como_alarma.py`. */
  --blue-soft:     #EAF1F9;   /* fondo azul tenue (aviso informativo) */
  --blue-line:     #B5CDE6;   /* borde azul tenue, hermano de --orange-line */
  --blue-ink:      #1F5C9E;   /* azul de las LETRAS: 5.9:1 sobre --blue-soft */

  /* --- Neutros (estilo Apple) + "stone" cálido del brandbook --- */
  --stone:         #7F7770;   /* gris cálido del brandbook (#83766F ≈) */
  --stone-light:   #E8E5E1;
  --ink:           #1D1D1F;   /* tinta principal */
  --ink-2:         #6E6E73;   /* texto secundario */
  --paper:         #F5F5F7;   /* fondo de la app */
  --card:          #FFFFFF;
  --card-2:        #FAFAFA;   /* superficie hundida (encabezado de tabla, campos) */
  --hairline:      #E3E3E6;   /* líneas finísimas */
  --hairline-2:    #EFEEF0;   /* línea aún más tenue (separadores internos) */
  /* --- Alias de consolidación (rediseño 2026-07-22) ---------------------------
     Varias pantallas (Catálogos, Ventas, Compras…) escribían var(--line/--acc/
     --line-2/--ink-3, <hex>) — tokens que NO existían, así que caían a un magic
     value ligeramente distinto del sistema (bordes #d9d6cc en vez del hairline,
     hints casi ilegibles…). Definirlos aquí, UNA vez, alinea ~64 usos al sistema
     central sin tocar cada pantalla. `--ink-3` se sube a un gris que SÍ cumple
     contraste AA (antes #9a9a90 ≈ 2.8:1, ilegible en texto chico). */
  --line:          var(--hairline);
  --line-2:        var(--hairline-2);
  --acc:           var(--orange);
  --ink-3:         #767676;   /* texto terciario (hints) — AA sobre blanco (~4.5:1) */
  --mono:          "JetBrains Mono", ui-monospace, Menlo, Monaco, monospace;
  /* --- Segunda tanda de alias (auditoría del front-end, 2026-08-01) ------------
     Seis tokens más que las plantillas nombraban sin que existieran. Tres de ellos
     se usaban SIN respaldo — y eso no es un color aproximado, es un color que NUNCA
     SE APLICÓ: `color: var(--muted)` sin fallback es una declaración inválida, el
     navegador la tira entera y el texto se queda del color que herede. Por eso había
     "grises" que salían en negro pleno (la misma familia de fallas que «.sub no
     pinta sola»), y líneas del organigrama sin su color. 17 lugares así.
     Los otros tres sí traían respaldo, pero fuera del sistema (#f4f4f5, #faf9f6):
     alinearlos aquí, una vez, corrige los 29 usos sin tocar ninguna plantilla. */
  --muted:         var(--ink-2);      /* 9 usos · texto secundario */
  --panel:         var(--paper);      /* 7 usos · superficie de panel (traía #f4f4f5) */
  --org-linea:     var(--hairline);   /* 7 usos · líneas del árbol del organigrama */
  --surface-2:     var(--card-2);     /* 3 usos · superficie hundida (traía #faf9f6) */
  --paper-2:       var(--card-2);     /* 2 usos · fondo de renglón expandido */
  --org-borde:     var(--hairline);   /* 1 uso  · borde de la cajita del organigrama */

  /* --- Semáforo (estados) --- */
  --success:       #34A853;
  --warning:       #F59E0B;
  --critical:      #E0352B;

  /* LAS TINTAS DEL SEMÁFORO (2026-09-17, aprobado por Pablo). Tercera vez que se
     hace el mismo arreglo en esta casa, y la regla ya es la de siempre:
        --success  / --critical       -> FONDOS, bordes, filetes, puntos, degradados
        --success-ink / --critical-ink -> LETRAS
     Igual que --orange-ink (30-jul, lo reportó Operaciones) y que --blue-ink (esta
     misma mañana). Un color puede ser vivo de fondo; esa misma letra no se lee.

     Los números, medidos con la cuenta del navegador (el mínimo para texto es 4.5:1):
        #1C6B36 sobre su aviso verde 5.36:1 · sobre papel 6.02:1   (antes 2.50 y 2.81)
        #9A271F sobre su aviso rojo  6.25:1 · sobre papel 7.19:1   (antes 3.56 y 4.09)

     ⚠️ NINGUNO DE LOS DOS ES UN COLOR NUEVO. Los dos ya vivían tecleados a mano en
     esta hoja —#1c6b36 en `.aviso-ok` y #9a271f en `.aviso-peligro`—, y eran **los
     únicos 2 de 25 lugares** que llegaban al mínimo. Los otros 23 pintaban con el
     color de marca: el verde de «ya se pagó» (`.saldado`) daba 2.81:1 y el rojo de
     «falta» (`.falta`, que vive en 155 plantillas) daba 4.09:1. Aquí sólo se le da
     nombre al que ya era correcto y se le manda a los otros veintitrés.

     Lo destapó el candado `administracion/tests_el_dato_no_se_lee_como_alarma.py`
     (PR #365), que los dejó declarados como deuda con su número; al ir a pagarla
     salió que no eran dos, eran veintitrés. Ese mismo candado los vigila ahora.
     El CSS no se ejecuta en la suite (§4), así que un color que no se lee no truena
     nada por su cuenta: sólo la medición lo ve. */
  --success-ink:   #1C6B36;   /* verde de las LETRAS */
  --critical-ink:  #9A271F;   /* rojo de las LETRAS */

  --shadow:        0 1px 3px rgba(0,0,0,.06), 0 8px 24px rgba(0,0,0,.04);
  --shadow-hover:  0 2px 6px rgba(0,0,0,.07), 0 14px 34px rgba(0,0,0,.06);
  --shadow-lift:   0 2px 6px rgba(0,0,0,.06), 0 18px 40px rgba(0,0,0,.08);
  --radius:        16px;   /* rediseño 2026-07-21: tarjetas un pelín menos redondas */
  --radius-btn:    12px;   /* botones = rectángulo suave (antes píldora 980px) */
}

* { box-sizing: border-box; }

body {
  margin: 0;
  /* La fuente del sistema (SF Pro en Mac) es la que da el "feel Apple". */
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
               "Helvetica Neue", Helvetica, Arial, "Raleway", sans-serif;
  background: var(--paper);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.5;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--orange-ink); }

/* ====== Foco de teclado visible y consistente en TODO control (a11y, brief 2026-07-22) ======
   :focus-visible = el anillo sale SOLO al navegar con teclado (no lo roba el clic de mouse).
   Antes solo .btn e inputs lo tenían; links, summary, checkboxes/radios y botones sueltos
   quedaban sin señal de foco. Un solo bloque central lo cubre para todo el ERP. */
a:focus-visible,
summary:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible,
button:focus-visible,
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ====== Barra superior (glass, estilo Apple) ====== */
header.topbar {
  position: sticky; top: 0; z-index: 100;
  display: flex; align-items: center; gap: 22px;
  padding: 0 28px; height: 60px;
  background: rgba(255,255,255,.72);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--hairline);
}
.topbar .logo { height: 28px; width: auto; display: block; flex-shrink: 0; }
/* Los MÓDULOS ya no viven en una barra horizontal: viven en el RIEL LATERAL izquierdo
   (árbol de acordeón). Ver la sección "RIEL LATERAL DE MÓDULOS" al final del archivo. */
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
/* Lente de empresa: pastillas multi-selección en el topbar (marca las empresas que ves). */
.lente-empresa { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.lente-empresa .lente-ic { font-size: 13px; line-height: 1; }
.lente-pill { display: inline-flex; align-items: center; gap: 4px; padding: 4px 11px; border: 1px solid var(--hairline); border-radius: 980px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); background: rgba(255,255,255,.5); cursor: pointer; user-select: none; white-space: nowrap; transition: color .15s, background .15s, border-color .15s; }
.lente-pill:hover { border-color: var(--orange); }
.lente-pill input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.lente-pill.on { color: #fff; background: linear-gradient(135deg, #ff944d, var(--orange)); border-color: transparent; }
.lente-check { display: none; font-weight: 700; }
.lente-pill.on .lente-check { display: inline; }
.lente-pill:focus-within { outline: 2px solid var(--orange); outline-offset: 2px; }
.nav-user { display: flex; align-items: center; gap: 10px; padding-left: 12px; border-left: 1px solid var(--hairline); }
.nav-avatar { width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(135deg, #ff944d, var(--orange)); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; flex-shrink: 0; text-decoration: none; }
.nav-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.logout-form { display: inline; margin: 0; }
.nav-logout { color: var(--ink-2); font-size: 12px; font-weight: 600; text-decoration: none; padding: 5px 11px; border: 1px solid var(--hairline); border-radius: 980px; transition: all .15s; white-space: nowrap; background: none; font-family: inherit; cursor: pointer; }
.nav-logout:hover { border-color: var(--orange); color: var(--orange-ink); }

/* ====== Layout ====== */
main, .contenido { max-width: 1080px; margin: 0 auto; padding: 38px 28px; }

/* ====== MAYÚSCULAS: de regla general a OPT-IN — corregido 2026-08-01 ==================
   La decisión original (2026-06-27) fue correcta en su INTENCIÓN y decía, textual:
   «NO se tocan los textos del sistema (títulos, ayudas, botones, encabezados)».
   Pero la regla se escribió apuntando además a `tbody td` — es decir, a TODA celda de
   tabla — y ahí se rompió su propia promesa: dentro de un <td> no solo viven datos,
   también vive texto del sistema.

   La prueba está en Compras › Necesidades (`compras/necesidades.html:37,38`):
       <td …><span class="sub">cubierto</span></td>
       <td …><span class="sub">sin fecha aún</span></td>
   Quien escribió esa pantalla los puso en minúsculas A PROPÓSITO (son frases del ERP,
   no datos del negocio) y la regla los volvió «CUBIERTO» y «SIN FECHA AÚN», repetidos
   once veces, gritando igual que los dos renglones que sí pedían una acción. Eso es lo
   que Pablo señaló el 2026-08-01: «cuando todo grita, nada resalta».

   Ojo con lo que esto NO era: en esa misma tabla la columna Producto YA venía exenta
   (`:28`, `class="dato no-mayus"`). Que «SNOW PEA LAS 5 ESTACIONES» saliera en
   mayúsculas y «kingman pp» en minúsculas NO lo causaba el CSS — así están escritos los
   nombres EN LA BASE. La regla los emparejaba de vista y de paso TAPABA que el catálogo
   viene con mayúsculas inconsistentes. Tapar un problema de datos con una regla de
   pintura es justo lo contrario de la §4.7 (nada falla en silencio): el catálogo se
   normaliza aparte, como decisión de datos, no de estilo.

   La corrección respeta la intención original y sólo VOLTEA el default: en vez de
   «todo el <tbody> en mayúsculas, con .no-mayus para escaparse» (203 escapes en 69
   plantillas), ahora es «nada en mayúsculas, con .dato para pedirlas» — y `.dato` ya se
   usa 416 veces, así que las columnas que de verdad son códigos (almacén, unidad,
   folio) conservan su mayúscula sin tocar una sola plantilla.

   También salen los <input>/<select>/<textarea>: ahí la mayúscula era pura pintura (el
   valor enviado nunca cambió), y hacía que lo TECLEADO se viera distinto de lo que se
   iba a guardar. Un campo que muestra algo diferente de lo que manda es un problema de
   diagnosticabilidad, no una preferencia visual.

   Los 203 `.no-mayus` que quedan por ahí no estorban (apagan algo que ya está apagado);
   se van barriendo pantalla por pantalla en la tanda del rediseño. */
.contenido .dato { text-transform: uppercase; }
/* Un folio no se parte en su guion (8-oct-2026, «Todas las CxP»): «CXP-» arriba y «412»
   abajo se lee como dos datos, y pasaba en cuanto otra columna pedía espacio. */
.tabla td.dato > a { white-space: nowrap; }
.contenido .vacio,
.contenido .no-mayus,
.contenido .no-mayus * { text-transform: none; }

/* Texto SOLO para lector de pantalla (2026-08-02). El ERP no tenía cómo escribirlo,
   así que cada vez que hacía falta —dar contexto a un botón «✕» que en pantalla se
   entiende por su posición, nombrar la columna de acciones de una tabla— la opción
   era `aria-label` (que reemplaza el texto, no lo complementa) o nada.
   `display:none` NO sirve: un lector de pantalla tampoco lo lee. La receta es
   sacarlo del flujo sin quitarlo del árbol. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

h1 { font-size: 34px; font-weight: 700; margin: 0 0 4px; letter-spacing: -.6px; line-height: 1.1; }
h2 { font-size: 19px; font-weight: 600; margin: 0 0 14px; letter-spacing: -.3px; }
h3 { font-size: 15px; font-weight: 600; margin: 0 0 12px; }
.subtitle, .lede { color: var(--ink-2); margin: 0 0 24px; font-size: 15px; max-width: 65ch; }

.page-head { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 28px; gap: 16px; flex-wrap: wrap; }
.page-head .sub { color: var(--ink-2); font-size: 15px; margin: 6px 0 0; max-width: 60ch; }

/* Chip de estado (ej. "En la nube · al día") */
.chip { display: inline-flex; align-items: center; gap: 8px; background: var(--orange-soft); color: var(--orange-ink); font-size: 13px; font-weight: 600; padding: 8px 15px; border-radius: 980px; white-space: nowrap; }
.chip .live { width: 7px; height: 7px; border-radius: 50%; background: var(--orange); box-shadow: 0 0 0 3px rgba(253,107,0,.18); }

/* ====== Tarjeta ====== */
.card, .tarjeta { background: var(--card); border: none; border-radius: var(--radius); box-shadow: var(--shadow); }
.card { padding: 22px; margin-bottom: 18px; }
.tarjeta { overflow: hidden; }
.card-link { color: var(--orange-ink); font-size: 13px; font-weight: 600; text-decoration: none; display: inline-block; margin-top: 12px; }
.card-link:hover { text-decoration: underline; }

/* Título de una sección DENTRO de una pantalla (p. ej. «Lo que ya llegó» y «Lo
   que está por llegar» en Recepciones). Va encima de su tarjeta y necesita aire
   arriba para que se lea como un corte, no como parte de la tabla anterior. */
.seccion-titulo { margin: 26px 0 10px; }
.seccion-titulo:first-of-type { margin-top: 4px; }

/* Dos columnas que se apilan en pantalla chica (p.ej. "De esta orden": llegadas | facturas). */
.dos-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 640px) { .dos-cols { grid-template-columns: 1fr; } }
.lista-enlaces { list-style: none; margin: 8px 0 0; padding: 0; }
.lista-enlaces li { padding: 6px 0; border-bottom: 1px solid var(--hairline); font-size: 14px; }
.lista-enlaces li:last-child { border-bottom: none; }

/* ====== KPIs (tablero) ====== */
/* ⚠️ ERA `repeat(4, 1fr)` FIJO, y con TRES tarjetas dejaba una columna vacía y
   apretaba las otras a 163 px — un «US$ 101,133.27» de seis cifras a 38 px pide
   289 px y se DESBORDABA encima de la tarjeta vecina. Lo cazó el ensayo del
   2026-08-04 contra datos con el tamaño de los reales; con los montos chicos de
   la semilla limpia nunca se veía. `auto-fit` colapsa la columna vacía, así que
   tres tarjetas usan el ancho completo. El `clamp` es el cinturón: si aun así
   no cabe, la cifra encoge en vez de invadir a su vecina. */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; margin-bottom: 26px; }
.kpi { background: var(--card); border-radius: var(--radius); padding: 22px 22px 20px; box-shadow: var(--shadow); transition: transform .18s ease, box-shadow .18s ease; }
/* Los KPIs informan, no navegan: sin efecto de botón (hover que levanta = promesa falsa). */
.kpi:hover { box-shadow: var(--shadow); }
/* …SALVO la que abre su detalle (Pablo, 23-sep-2026: «que pueda entrar al indicador y ver
   más detalle»). Esa sí es liga: `a.kpi`, levanta como un acceso y lleva su «Ver …›» escrito,
   porque en el teléfono no hay hover que avise que se puede picar. */
a.kpi { display: block; text-decoration: none; color: inherit; }
a.kpi:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.kpi .ir { font-size: 13px; font-weight: 600; color: var(--orange-ink); margin-top: 10px; }
.kpi .label { font-size: 13px; color: var(--ink-2); font-weight: 500; display: flex; align-items: center; gap: 9px; }
.kpi .num { font-size: clamp(24px, 2.6vw, 38px); font-weight: 700; letter-spacing: -1px; margin-top: 12px; line-height: 1; font-variant-numeric: tabular-nums; }
.kpi .foot { font-size: 13px; color: var(--ink-2); margin-top: 8px; }
.ico { width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 15px; }
.ico.g { background: rgba(52,168,83,.12);  color: var(--success-ink); }
.ico.a { background: rgba(245,158,11,.16); color: var(--warning); }
.ico.r { background: rgba(224,53,43,.12);  color: var(--critical-ink); }
.ico.o { background: var(--orange-soft);   color: var(--orange-ink); }
.ico.b { background: #e8f0fe;              color: #3949ab; }
.kpi-grid > * { min-width: 0; }
@media (max-width: 820px){ .kpi-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px){ .kpi-grid { grid-template-columns: 1fr; } }

/* ====== Accesos (tarjetas de navegación del tablero) ====== */
.accesos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.acceso {
  display: block; text-decoration: none; color: inherit;
  background: var(--card); border-radius: var(--radius); padding: 22px;
  box-shadow: var(--shadow); transition: transform .18s ease, box-shadow .18s ease;
}
.acceso:hover { transform: translateY(-2px); box-shadow: var(--shadow-hover); }
.acceso .ico { width: 40px; height: 40px; border-radius: 12px; font-size: 20px; margin-bottom: 14px; }
.acceso .t { font-size: 16px; font-weight: 600; color: var(--ink); }
.acceso .d { font-size: 13px; color: var(--ink-2); margin-top: 4px; line-height: 1.45; }
.acceso .pronto { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--ink-2); background: var(--stone-light); padding: 2px 8px; border-radius: 980px; margin-left: 8px; vertical-align: middle; }
.acceso .badge { margin-top: 12px; }
.accesos > * { min-width: 0; }
/* El título de la SIGUIENTE sección necesita aire (2026-08-24): sin él, un `h2`
   que cae debajo de una rejilla de accesos se pega a la tarjeta de arriba y se lee
   como pie de ESA tarjeta en vez de encabezado de lo de abajo. Se cazó en el
   tablero de Indicadores, a 1400 y a 390 px. */
.accesos + h2 { margin-top: 30px; }
@media (max-width: 820px){ .accesos { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px){ .accesos { grid-template-columns: 1fr; } }

/* ====== Buscador ====== */
.buscador { display: flex; gap: 10px; align-items: center; margin-bottom: 20px; flex-wrap: wrap; }
.buscador input {
  flex: 1; min-width: 240px;
  padding: 11px 16px; border: 1.5px solid var(--hairline); border-radius: var(--radius-btn);
  font: inherit; font-size: 14px; background: #fff; color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
}
.buscador input:focus { outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px rgba(253,107,0,.12); }
.buscador .limpiar { color: var(--ink-2); text-decoration: none; font-weight: 600; padding: 8px; }
.buscador .limpiar:hover { color: var(--orange-ink); }

/* ====== Botones ======
   Rediseño 2026-07-21: rectángulo suave (radius-btn) + opción "D" aprobada por Pablo:
   el botón PRINCIPAL nace con CONTORNO naranja y texto naranja; al pasar el mouse (o al
   TOCARLO en móvil, vía :active — donde no hay hover) se LLENA de naranja. Discreto en
   reposo, pero la acción responde y se vuelve obvia al ir a usarla. */
/* ⚠️⚠️ `hidden` TIENE QUE GANAR (2026-08-17, cazado en el ensayo del R-100).
   El navegador le da a `[hidden]` un `display:none`… de la hoja del USUARIO, que
   pierde contra CUALQUIER clase nuestra. `.btn` trae `display:inline-flex`, así
   que **un botón con `hidden` se seguía viendo** — y ninguna prueba de Django lo
   ve, porque no ejecutan CSS.

   No era sólo la pantalla de cotizar: mordía igual en `compras/ocs.html` y en
   `inventario/traspaso.html`, donde el botón que no debía verse **borra un
   renglón**. Con una sola fila, el humano podía quitarla y quedarse sin ninguna.

   El `!important` es el correcto aquí y es lo que hacen todos los `normalize`:
   `hidden` no es estilo, es «esto no existe para el usuario». */
[hidden] { display: none !important; }

.btn { background: #fff; color: var(--orange-ink); border: 1.5px solid var(--orange); border-radius: var(--radius-btn); padding: 9px 18px; font-size: 14px; font-family: inherit; font-weight: 600; letter-spacing: .2px; cursor: pointer; transition: background .15s, color .15s, transform .1s; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
.btn:hover { background: var(--orange); color: #fff; }
.btn:active { background: var(--orange); color: #fff; transform: scale(.98); }
.btn:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
/* Secundario (ghost): contorno GRIS y texto tinta — se distingue del principal (contorno naranja). */
.btn-ghost { background: #fff; color: var(--ink); border: 1px solid var(--hairline); }
.btn-ghost:hover { border-color: var(--orange); color: var(--orange-ink); background: #fff; }
/* Acción destructiva (borrar/cancelar/rechazar): rojo SÓLIDO, para que no se confunda con
   un botón normal (y para que resalte más que el principal, que ahora es contorno). */
.btn-peligro { background: var(--critical); color: #fff; border-color: var(--critical); }
.btn-peligro:hover { background: var(--critical); color: #fff; filter: brightness(.92); }
/* APAGADO. Un botón deshabilitado se veía IDÉNTICO a uno vivo (2026-09-02): en
   «Mi tarjeta» el botón de comprobar se apaga cuando el tipo de gasto no tiene
   cuenta casada, y se seguía viendo naranja y con la manita — se picaba y no
   pasaba nada. El CSS no corre en la suite (§4d), así que ningún candado lo
   veía; lo cazó el navegador. Va sobre .btn entero, no sobre una pantalla: el
   día que otra apague un botón, ya se ve apagado. */
.btn:disabled, .btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; filter: grayscale(.5);
}
.btn:disabled:hover, .btn[disabled]:hover {
  background: #fff; color: var(--orange-ink); border-color: var(--orange); transform: none;
}
.btn-ghost:disabled:hover, .btn-ghost[disabled]:hover {
  color: var(--ink); border-color: var(--hairline);
}

/* ====== EL MARCADOR DE «CUÁNTO FALTA» (R-141, 2026-09-02) ==============
   Una cuenta que se arma mientras tecleas y dice si cuadra. Nació para
   repartir una salida del banco entre varias cuentas (la dispersión de
   nómina), y el color significa lo de siempre (ley 04): ámbar «te falta»,
   verde «cuadra», rojo «te pasaste». El botón de guardar cuelga de ese
   veredicto, así que el color y el candado dicen LO MISMO. */
/* ⚠️ Se llama `.cuadre` y NO `.marcador` porque ese nombre YA ESTABA TOMADO
   en mely_piezas.css (una rejilla de dos columnas): el ensayo del 2-sep vio
   las líneas encimadas porque la regla vieja ganaba. Una clase también pasa
   por la pregunta del glosario — «¿cómo se llama esta cosa en el resto del
   ERP?» (§4b). `display:block` explícito para que ninguna regla de layout
   futura se la vuelva a llevar. */
.cuadre { display: block; padding: 16px 18px; border-radius: 12px; margin: 14px 0;
          font-variant-numeric: tabular-nums; }
.cuadre.falta  { background: #FFF4E8; border: 1px solid #FFC48A; }
.cuadre.cuadra { background: #E8F5EC; border: 1px solid #9CCFAE; }
.cuadre.pasado { background: #FDECEC; border: 1px solid #E5A3A3; }
.cuadre-linea { display: flex; justify-content: space-between; gap: 14px; padding: 3px 0; font-size: .95rem; }
.cuadre-linea.total { border-top: 2px solid rgba(0,0,0,.15); margin-top: 8px; padding-top: 10px;
                      font-weight: 750; font-size: 1.1rem; }
.cuadre-linea .et { color: #4A4842; }
/* La tabla de renglones que se teclean (montos a la derecha, como todo el dinero). */
.desg td, .desg th { vertical-align: middle; }
.desg input[type=text] { width: 128px; text-align: right; font-variant-numeric: tabular-nums; }
.desg select { min-width: 190px; }

/* R-142 · el par que se parece demasiado, enmarcado en la lista. Ámbar (ley
   04): «es tu turno, míralo» — no rojo, porque todavía no hay nada mal: hay
   algo que revisar. */
.fila-dup > td { background: #FFF9F2; border-top: 2px solid #FFC48A; padding-top: 10px; }
.dup-aviso { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: .9rem; }

/* LA CELDA QUE CLASIFICA EN EL RENGLÓN (R-122, y de vuelta el 21-sep-2026).
   Pablo: «antes era más fácil clasificar y avanzar … no tenía que irme a otra
   pantalla». Sus controles son piezas `{% campo %}`, que ya traen su forma; lo
   único que falta es que se apilen angostos en vez de heredar el ancho de la
   celda, y que no dejen aire de sobra entre uno y otro. */
.tabla td .campo { margin: 0; min-width: 13rem; }
.tabla td .campo + .campo { margin-top: 5px; }
/* El botón y la liga del renglón, juntos y a la derecha, sin partirse. */
.tg-acc { display: flex; gap: 8px; align-items: center; justify-content: flex-end;
          flex-wrap: wrap; white-space: nowrap; }
tr.es-copia > td { background: #FFFDF9; border-bottom: 2px solid #FFC48A; }

/* ====== Formularios ====== */
/* ⚠️⚠️ EL `:not(.sr-only)` NO ES ADORNO — 2026-08-19.
   `.sr-only` (arriba) pide `width:1px` para esconder un control del ojo sin
   quitárselo al lector de pantalla. Esta regla pesa (0,4,1) contra su (0,1,0) y
   LE GANABA: todo `<input type="file" class="sr-only">` medía el 100 % de su
   bloque, y como `.sr-only` es `position:absolute`, sin ancestro posicionado se
   anclaba al DOCUMENTO. Medido: una ficha se iba a 2445 px de ancho.

   Vivía tapado por pura suerte —el bloque de papeles va dentro de `.tarjeta`,
   que trae `overflow:hidden` y lo recortaba—, así que ninguna pantalla lo
   enseñaba y la suite jamás lo vio: el CSS no se ejecuta en las pruebas. Se
   destapó al quitar esa tarjeta en el rediseño de las fichas.

   Un `width:1px` que nunca gana es una defensa que no existe. */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not(.sr-only),
select, textarea {
  padding: 10px 14px; border: 1.5px solid var(--hairline); border-radius: 12px;
  font-size: 14px; font-family: inherit; background: #fff; color: var(--ink); width: 100%;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--orange); box-shadow: 0 0 0 3px rgba(253,107,0,.12); }

/* ⭐ R-154 (Pablo, 2026-09-07): «quitar flechas que mueven los números al teclearlos,
   ya que me modifica el tecleo». Las flechitas del campo numérico son un botón de
   1.5 mm pegado al cursor: se pican sin querer y cambian la cantidad DESPUÉS de
   haberla tecleado — y el ERP se entera de la buena. Se van de TODA la casa (aquí,
   y no en la pieza, porque hay campos numéricos escritos a mano —el apartado, la
   captura del vale— y el defecto es el mismo en los dos).
   Su hermana gemela vive en el JS de `base_erp.html`: la RUEDA del ratón sobre un
   campo numérico enfocado también cambia el número, y eso el CSS no lo tapa. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }

.form-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 18px 20px; align-items: start; margin-top: 4px; }
.form-grid label { display: flex; flex-direction: column; font-size: 11px; font-weight: 700; color: var(--ink-2); gap: 7px; letter-spacing: .4px; text-transform: uppercase; grid-column: span 4; min-width: 0; }
.form-grid label .hint { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-2); font-size: 11.5px; }
.form-grid .col-2 { grid-column: span 2; }
.form-grid .col-3 { grid-column: span 3; }
.form-grid .col-4 { grid-column: span 4; }
.form-grid .col-6 { grid-column: span 6; }
.form-grid .col-8 { grid-column: span 8; }
.form-grid .col-12 { grid-column: span 12; }
.form-grid .form-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; align-items: center; gap: 12px; border-top: 1px solid var(--hairline); padding-top: 18px; }
.req { color: var(--orange-ink); }
.bloque { margin-top: 4px; }
.bloque-titulo { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-2); margin: 22px 0 2px; }
@media (max-width: 720px) {
  .form-grid { grid-template-columns: 1fr; }
  .form-grid label, .form-grid [class*="col-"] { grid-column: 1 / -1; }
}

/* ====== Tarjetas de rol (radio seleccionable) ====== */
.rol-opciones { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 4px; }
.rol-card { position: relative; display: flex; flex-direction: column; gap: 4px; padding: 16px; border: 1.5px solid var(--hairline); border-radius: 14px; cursor: pointer; transition: border-color .15s, box-shadow .15s, background .15s; }
.rol-card input { position: absolute; opacity: 0; pointer-events: none; }
.rol-card:hover { border-color: var(--orange); }
.rol-card.sel, .rol-card:has(input:checked) { border-color: var(--orange); background: var(--orange-soft); box-shadow: 0 0 0 3px rgba(253,107,0,.12); }
.rol-emoji { font-size: 22px; }
.rol-nombre { font-size: 14px; font-weight: 700; color: var(--ink); }
.rol-desc { font-size: 12px; color: var(--ink-2); font-weight: 500; }
.check-inline { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink); font-size: 13px; }
.check-inline input { width: auto; }
@media (max-width: 640px) { .rol-opciones { grid-template-columns: 1fr; } }

/* ====== Sombreros de trabajo agrupados por área (pantalla de usuario) ======
   Rediseño 2026-07-21: columnas MÁS ANCHAS y con más aire (antes minmax 240 + gap 10 armaba
   muchas columnas apretadas → se veían amontonados). Menos columnas, más legibles. */
.sombreros-areas { margin-top: 8px; }
.sombrero-area { margin-bottom: 26px; }
.sombrero-area:last-child { margin-bottom: 0; }
.sombrero-area-titulo { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-2); border-bottom: 1px solid var(--hairline); padding-bottom: 9px; margin: 0 0 14px; }
.sombrero-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; }
.sombrero-casilla { display: flex; align-items: flex-start; gap: 11px; padding: 14px 16px; border: 1.5px solid var(--hairline); border-radius: 12px; cursor: pointer; transition: border-color .15s, background .15s, box-shadow .15s; }
.sombrero-casilla:hover { border-color: var(--orange); }
.sombrero-casilla:has(input:checked) { border-color: var(--orange); background: var(--orange-soft); box-shadow: 0 0 0 3px rgba(253,107,0,.12); }
.sombrero-casilla:has(input:disabled) { opacity: .6; cursor: default; box-shadow: none; }
.sombrero-casilla:has(input:disabled):hover { border-color: var(--hairline); }
.sombrero-casilla input { width: auto; margin-top: 2px; flex-shrink: 0; }
.sombrero-texto { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.sombrero-nombre { font-size: 14px; font-weight: 600; color: var(--ink); }
.sombrero-desc { font-size: 12.5px; color: var(--ink-2); font-weight: 500; line-height: 1.4; }
@media (max-width: 640px) { .sombrero-grid { grid-template-columns: 1fr; } }

/* ====== Buzón de problemas: filtro activo visible + botones compactos en móvil ====== */
a.btn[aria-current="page"] { background: var(--orange-soft); border-color: var(--orange); color: var(--orange-ink); }
@media (max-width: 640px) { .acciones-fila .btn { padding: 7px 12px; font-size: 13px; } }

/* ====== Lista operativa (filas con acción, ej. recepción) ====== */
/* R-118 (2026-08-21) · el renglón-título que agrupa una tabla por cuenta bancaria
   (conciliación). Gris de fondo y sin mayúsculas: es un separador, no un dato. En
   teléfono la tabla se vuelve tarjetas; el título conserva su banda completa. */
.tabla tr.fila-grupo td { background: var(--paper-2); font-size: 13px; padding-top: 12px; }
@media (max-width: 640px) { .tabla tr.fila-grupo td { width: 100%; text-align: left; } }

.fila-op { display: flex; align-items: center; gap: 16px; padding: 14px 16px; border-bottom: 1px solid var(--hairline); flex-wrap: wrap; }
.fila-op:last-child { border-bottom: none; }
.fila-op .info { flex: 1 1 220px; min-width: 0; }
.fila-op .info strong { font-weight: 600; }
.fila-op .info .sub { color: var(--ink-2); font-size: 12.5px; margin-top: 2px; }
.fila-op .pend { font-family: inherit; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--orange-ink); white-space: nowrap; }
.fila-op .acc { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.fila-op .acc input { width: 92px; }
.fila-op .acc input.lote { width: 120px; }
/* El "tipo de cambio del banco" (name=tc_aplicado) no cabe en 92px: dale aire.
   min-width gana sobre el width fijo de arriba, así SOLO se ensancha este input
   (los demás de la fila conservan su ancho). En móvil la fila envuelve, no se rompe. */
.fila-op .acc input[name="tc_aplicado"] { min-width: 150px; }
/* El motivo (cancelación/rechazo) es texto que otra persona leerá: dale ancho para que se lea. */
.fila-op .acc input[name="motivo"] { flex: 1 1 220px; width: auto; }

/* ====== Tabla ======
   Filas ESBELTAS (regla de Pablo 2026-07-21): en una pantalla debe caber mucho.
   Un dato por celda, la unidad en su columna/encabezado (no pegada al número),
   folios cortos y clickeables al detalle. */
.tabla { width: 100%; border-collapse: collapse; }
.tabla thead th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--ink-2); font-weight: 600; padding: 8px 12px; border-bottom: 1px solid var(--hairline);
  background: var(--card-2);  /* rediseño 2026-07-21: encabezado con fondo tenue, separa mejor de las filas */
}
.tabla tbody td { padding: 6px 12px; border-bottom: 1px solid var(--hairline); vertical-align: middle; font-size: 13.5px; line-height: 1.35; }
.tabla tbody tr:last-child td { border-bottom: none; }
.tabla tbody tr:hover { background: #fafafa; }
/* Botones DENTRO de una tabla: discretos y uniformes, todos del mismo tamaño
   (nada de botones toscos que engordan la fila). Gana a los estilos .btn genéricos. */
.tabla .btn, .tabla button.btn, .tabla a.btn {
  padding: 3px 10px; font-size: 12px; border-radius: 8px; line-height: 1.5;
}
/* Folio/identificador clickeable: se ve como dato, no como botón; subraya al pasar. */
/* (25-sep-2026) Y tampoco se parte en dos renglones, igual que su hermano de abajo que no
   liga: en la lista de notas de crédito salía «NC-» arriba y «00002» abajo. */
.tabla a.folio { color: var(--ink); font-weight: 600; text-decoration: none; white-space: nowrap; }
/* El folio que NO liga (la factura que emitió otro: «la emitió CONTPAQ») se ve igual de firme
   y no se parte en dos renglones en el teléfono (8-sep-2026, Cuentas por cobrar). */
.tabla span.folio { font-weight: 600; white-space: nowrap; }
.tabla a.folio:hover { text-decoration: underline; color: var(--acc, #FD6B00); }
/* Badges dentro de tablas: compactos para no engordar la fila. */
.tabla .badge { padding: 2px 8px; font-size: 11px; }
/* Números con la MISMA letra del sistema (decisión de Pablo 2026-07-28): se acabó la
   mono de "máquina de escribir" y su cero rayado. tabular-nums mantiene cada cifra del
   mismo ancho, así que las columnas siguen alineando perfecto. */
.num { text-align: right; font-family: inherit; font-variant-numeric: tabular-nums; }
/* El encabezado de una columna de NÚMEROS va donde están los números: a la derecha.
   Sin esto, `.tabla thead th { text-align: left }` le ganaba a `.num` por especificidad
   y el título quedaba desfasado del dato en las 124 columnas numéricas del ERP
   (lo cazó Pablo el 2026-07-27 en «Crédito de clientes»; se corrige en la hoja
   central porque la falla era de todas las tablas, no de esa pantalla). */
.tabla thead th.num { text-align: right; }
/* Secundarios DENTRO de tablas y en la paginación (código corto, "—", "(parcial:…)"):
   en gris. Las reglas .sub existentes estaban acotadas a otros contextos y aquí no
   pintaban nada (lo cazó la revisión UX 2026-07-28). */
.tabla .sub, .paginacion .sub { color: var(--ink-2); }
/* Encabezado ORDENABLE ({% th_orden %}, 2026-07-28): el subrayado punteado avisa que
   se puede tocar (también en tablet, donde no hay hover); la flechita ▲/▼ dice cómo
   está ordenado hoy. */
.tabla thead th .th-orden {
  color: inherit; text-decoration: underline dotted; text-decoration-color: rgba(0,0,0,.3);
  text-underline-offset: 3px;
}
.tabla thead th .th-orden:hover { color: var(--orange-ink); text-decoration-color: var(--orange-ink); }
.tabla thead th .flecha { font-size: 8.5px; color: var(--orange-ink); }
/* Columna escondida con el botón «Columnas» (base_erp.html, 2026-07-28). La doble
   clase (.tabla td.col-oculta) es a propósito: en móvil las celdas son display:flex
   (.tabla tbody td) y esta regla debe ganarle también ahí. */
.tabla th.col-oculta, .tabla td.col-oculta { display: none; }
/* El botón «Columnas» y su menú (los arma base_erp.html sobre toda tabla data-columnas). */
.cols-control { position: relative; display: flex; justify-content: flex-end; padding: 10px 12px 0; }
.cols-btn { padding: 7px 14px; font-size: 12.5px; }
.cols-menu {
  display: none; position: absolute; top: calc(100% + 4px); right: 12px; z-index: 30;
  background: var(--card, #fff); border: 1px solid var(--hairline); border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12); padding: 10px 16px; min-width: 190px;
}
.cols-control.abierto .cols-menu { display: block; }
/* Con pocas filas, el menú es más alto que la tarjeta y su overflow:hidden lo
   recortaría: mientras el menú esté abierto, la tarjeta deja asomar. */
.tarjeta:has(.cols-control.abierto) { overflow: visible; }
.cols-menu label { display: flex; gap: 9px; align-items: center; font-size: 13.5px; padding: 8px 0; cursor: pointer; white-space: nowrap; }
.cols-menu input[type="checkbox"] { accent-color: var(--orange); width: 16px; height: 16px; }
.cols-menu .cols-pie { border-top: 1px solid var(--hairline); margin-top: 8px; padding-top: 10px; }
.cols-menu .cols-todas { background: none; border: none; padding: 0; font: inherit; font-size: 13px; font-weight: 600; color: var(--orange-ink); cursor: pointer; }
.cols-menu .cols-nota { font-size: 11.5px; color: var(--ink-2); margin-top: 6px; }
/* Selector "Ordenar por" del teléfono (los encabezados ordenables viven en el thead,
   que en móvil no existe). .solo-movil lo enciende la media query de 640px. */
.orden-movil { align-items: center; gap: 10px; margin: 0 0 14px; }
.orden-movil label { font-size: 13px; color: var(--ink-2); font-weight: 600; white-space: nowrap; }
.orden-movil select { flex: 1; }
/* --- Alineación CONTABLE del dinero (2026-07-27) --------------------------------
   `{{ x|dinero:m }}` produce «US$ 1,234.56» de una pieza; alineado a la derecha, el
   SÍMBOLO se recorre según el tamaño del número y la columna «baila». `.din` separa
   las dos partes: el símbolo pegado a la izquierda y los dígitos a la derecha, como
   en un estado de cuenta. Esta caja la escribe `{% monto valor moneda %}` (un solo
   lugar la dibuja para todo el ERP); los filtros `prefijo` y `cifra` arman la misma
   caja a mano donde haga falta partirla. */
.din { display: inline-flex; align-items: baseline; gap: 7px; }
/* El símbolo NUNCA hereda la negrita. Cuando el énfasis envuelve toda la caja
   (`<strong>` en el total, o `.dinero` en una columna), el «MX$» de ESA fila
   salía más grueso que el de las demás y la columna de símbolos se veía pareja
   a medias — el énfasis es del NÚMERO, no de la moneda (regla de acabado del
   2026-07-27). Aquí se resuelve de una vez para todas las tablas, en vez de
   cuidarlo celda por celda. */
.din .mo { color: var(--ink-2); font-size: 12px; font-weight: 400; }
/* El hueco de los dígitos se reserva en `rem` a propósito, NO en `ch`: `1ch` mide
   un dígito de la letra DE ESA celda, y el renglón de Totales va en negritas, que
   es más ancha. Con `ch`, la fila del total reservaba más hueco que las de arriba
   y su símbolo se recorría — la misma columna chueca, ahora entre el cuerpo y el
   total. `rem` no depende de la negrita ni del contexto: todas las filas reservan
   EXACTAMENTE lo mismo y los símbolos caen en la misma vertical.
   7.5rem = 120px ≈ «10,253,760.55» en negritas (13 dígitos, el inventario en
   pesos, hoy la cifra más ancha del ERP). Si algún día una columna rebasa esto,
   esa fila volverá a empujar su símbolo: este número es el que hay que subir. */
.din .ci { min-width: 7.5rem; text-align: right; font-variant-numeric: tabular-nums; }
/* …y un hueco más chico para una columna de PRECIOS POR PIEZA ({% monto … unitario=True %},
   2026-09-03). 7.5rem está calibrado para la cifra más ancha del ERP (13 dígitos); sobre
   un «0.4820» deja un boquete de más de un centímetro y el «US$» se lee despegado, como
   si fuera otro dato. 5rem ≈ «1,234.5678», que cubre cualquier precio unitario de Mely.
   Las columnas de precios siguen alineadas ENTRE SÍ: cambia contra qué ancho, no la ley.
   Se cazó en el navegador con las tres columnas de costo de «Qué trajo»; el CSS no se
   ejecuta en la suite y ninguna prueba lo veía. */
.din-unit .ci { min-width: 5rem; }
/* …salvo en la cifra grande de un KPI (2026-08-02). Ahí el hueco fijo no sirve para
   nada —no hay columna con la cual alinearse, es UNA sola cifra— y en cambio sí
   estorba: a 38px, «US$» más un hueco de 7.5rem no cabe en la tarjeta y la caja se
   parte en dos renglones («US$» arriba, «5,000.00» abajo), como si fueran dos datos.
   Se cazó en Finanzas mirando la pantalla; ninguna prueba lo veía. */
.kpi .num { white-space: nowrap; }
/* …y ALINEADA A LA IZQUIERDA, como su etiqueta y su pie (2026-08-24). La regla
   global `.num { text-align: right }` de más arriba está hecha para las COLUMNAS de
   números de las tablas, donde alinear a la derecha es lo correcto porque las cifras
   se comparan entre sí de arriba abajo. La tarjeta del tablero usa la misma palabra
   `num` y se la comía sin desactivarla: la etiqueta y el pie a la izquierda y el
   número pegado al borde derecho, con un hueco en medio. Se cazó mirando la maqueta
   de la puerta de Indicadores; ninguna prueba lo veía — el CSS no se ejecuta en la
   suite. Aquí no hay columna con la cual alinearse: es UNA sola cifra. */
.kpi .num { text-align: left; }
.kpi .num .din .ci { min-width: 0; }
.producto strong { display: block; font-size: 14px; font-weight: 600; }
.producto .sub { display: block; color: var(--ink-2); font-size: 12.5px; margin-top: 2px; }
/* Cantidades con el MISMO peso (Pablo 2026-07-28: nada de unas negritas y otras no);
   la negrita queda solo para los totales del pie y el dinero (.dinero). */
.disponible { font-weight: 400; }
.dinero { font-weight: 600; }
.vacio { text-align: center; color: var(--ink-2); padding: 48px 16px; }
.tabla tfoot td { padding: 16px; background: var(--paper); font-weight: 700; border-top: 2px solid var(--hairline); }
/* El total respira más que las filas (16px), pero por la DERECHA se alinea con su
   columna (12px, como el cuerpo y el encabezado): si no, el total quedaba 4px
   corrido y una columna de dinero por lo demás cuadrada se veía chueca justo en
   el renglón que más se mira. Solo las celdas de números; el resto del pie no se
   toca. */
.tabla tfoot td.num { padding-right: 12px; }
.tabla tfoot .total { color: var(--ink); font-size: 16px; }

/* ====== Badges de estado ====== */
.badge { display: inline-block; padding: 4px 11px; border-radius: 980px; font-size: 12px; font-weight: 600; letter-spacing: .1px; white-space: nowrap; }
.badge.ok      { background: rgba(52,168,83,.12); color: var(--success-ink); }
.badge.bajo    { background: rgba(245,158,11,.16); color: var(--warning); }
.badge.cero    { background: rgba(224,53,43,.10); color: var(--critical-ink); }
.badge.custodia{ background: #e8f0fe; color: #3949ab; }
.badge.neutra  { background: rgba(0,0,0,.05); color: var(--ink-2); }
/* B7 — Chip del almacén SELECCIONADO en Consulta: realce de MARCA (naranja Mely sólido),
   NO el ámbar de .badge.bajo (que en todo el ERP significa "atención/advertencia"). Así
   el ámbar sigue queriendo decir solo "cuidado" y el chip activo se lee como "estás aquí". */
.badge.activo  { background: var(--orange); color: #fff; }
/* "Revisado" del buzón de problemas: azul = "en curso, ya lo vi" (no el gris de "apagado"). */
.badge.revisado{ background: rgba(57,73,171,.12); color: #3949ab; }
/* Nivel de servicio del cliente (Express/Stock/Full): azul = dato pactado, no un semáforo
   (un nivel no es "bueno" ni "malo"; verde/ámbar/rojo mentirían). */
.badge-nivel   { background: rgba(57,73,171,.12); color: #3949ab; }
/* Variantes con GUION (badge-ok, badge-medio…): el mismo semáforo que las de arriba
   pero escrito como una sola clase. Compras y otros módulos usan esta forma; sin estas
   reglas los badges salían sin color (blancos). Se homologan los colores con los tokens. */
.badge-ok      { background: rgba(52,168,83,.12);  color: var(--success-ink); }   /* verde: cerrada, autorizada, recibida */
.badge-medio   { background: rgba(245,158,11,.16); color: var(--warning); }   /* ámbar: en curso, anticipo, avala */
.badge-alto    { background: rgba(224,53,43,.10);  color: var(--critical-ink); }  /* rojo: rechazada, con discrepancia */
.badge-vencido { background: rgba(224,53,43,.10);  color: var(--critical-ink); }  /* rojo: vencido / fuera de plazo */
.badge-neutro  { background: rgba(0,0,0,.05);      color: var(--ink-2); }     /* gris: borrador, neutro */
.badge-bajo    { background: rgba(245,158,11,.16); color: var(--warning); }   /* ámbar (paridad con .badge.bajo) */

/* Badge de estado del PEDIDO (.est) — CENTRALIZADO (rediseño 2026-07-22; antes cada plantilla
   de Ventas redefinía .est-* con colores hardcodeados). Mapea el estado al semáforo, mismo look
   que .badge del resto del ERP. El parcial ventas/_estado.html emite estas clases. */
.est { display: inline-block; padding: 4px 11px; border-radius: 980px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.est-borrador { background: rgba(0,0,0,.05); color: var(--ink-2); }
.est-detenido_fiscal, .est-detenido_precio, .est-detenido_credito { background: rgba(245,158,11,.16); color: var(--warning); }
.est-aprobado, .est-en_surtido, .est-surtido, .est-cerrado { background: rgba(52,168,83,.12); color: var(--success-ink); }
.est-cancelado, .est-rechazado { background: rgba(224,53,43,.10); color: var(--critical-ink); }

/* Caja de AVISO — CENTRALIZADA (rediseño 2026-07-22; antes cada pantalla la hardcodeaba con
   rgba/px inline). Info (naranja de marca) · Alerta (ámbar) · Peligro (rojo) · OK (verde). */
.aviso { display: flex; gap: 10px; align-items: flex-start; padding: 12px 15px; border-radius: 12px; font-size: 13.5px; line-height: 1.5; border: 1px solid transparent; }
.aviso .ic { flex-shrink: 0; margin-top: 1px; }
/* ⚠️⚠️ EL BLANCO DEL DEDO DE LA LIGA DE UN AVISO: 44 px (§2.9).
   Medida en el navegador el 2026-08-11 y salía en 16 px — y es LA PEOR de todas
   las que se han encontrado, porque es la liga del §4.11: la que dice «qué sigue»
   y deja el papel a un clic. La más importante de la pantalla era la más difícil
   de atinar. Hay 24 avisos con liga en Compras, Ventas, Finanzas y Comercial.
   El tamaño VISUAL del texto no cambia: solo el área que se puede picar.

   ⚠️⚠️ ESTE 44 px SE QUEDA SIN MEDIA QUERY A PROPÓSITO — DECISIÓN DE PABLO,
   2026-09-09. No es un descuido ni un pendiente: es lo único que sobrevivió a la
   tanda que adelgazó las filas (ver «LOS BLANCOS DE DEDO QUE ENGORDARON LA
   PANTALLA DE LA COMPUTADORA», más abajo en este archivo). Se midió: la caja del
   aviso pasa de 47 a 70 px por culpa de este 44. Se le presentó a Pablo con las
   dos opciones y escogió dejarlo, por dos razones que siguen valiendo:

     · El aviso sale UNA VEZ por pantalla, no en cada renglón. Cuesta 23 px una
       sola vez — no 25 px veinte veces, que era lo que hacía «abrumadora» la
       lista. La causa que Pablo reportó ya está atendida sin tocar esto.
     · Es la liga del §7 «lleva de la mano»: la que dice qué sigue y deja el papel
       a un clic. Un blanco grande ahí se defiende aunque haya ratón.

   Si alguna sesión futura la ve «suelta» y la quiere mudar a la media query del
   dedo por coherencia: NO. Ya se preguntó y ya se contestó. */
.aviso a {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 4px;
}
/* La MISMA corrección del 2026-09-17, en la otra puerta: la caja de aviso. Su
   propia receta ya la quería azul —`piezas.py` dice, junto al tono, «info →
   azul: contexto, algo que conviene saber»— y la hoja la pintaba naranja. Son
   106 cajas: se revisaron UNA POR UNA, y las cuatro que de verdad pedían turno
   se pasaron a `tono="alerta"`, que es como se dice eso. */
.aviso-info { background: var(--blue-soft); color: var(--blue-ink); border-color: var(--blue-line); }
.aviso-alerta { background: rgba(245,158,11,.12); color: #8a5a00; border-color: rgba(245,158,11,.35); }
.aviso-peligro { background: rgba(224,53,43,.07); color: var(--critical-ink); border-color: rgba(224,53,43,.22); }
.aviso-ok { background: rgba(52,168,83,.10); color: var(--success-ink); border-color: rgba(52,168,83,.28); }

/* Texto de ayuda debajo de un campo. Sin esta regla heredaba el tamaño del
   cuerpo y pesaba MÁS que su propia etiqueta: la jerarquía quedaba al revés
   en todos los formularios que la usan (hallazgo UX, 2026-07-26). */
.ayuda { font-size: 12.5px; color: var(--ink-2); margin: 4px 0 0; line-height: 1.45; }
/* Texto de dato faltante (rojo) — se usaba en varias pantallas sin estar definido. */
.falta { color: var(--critical-ink); font-weight: 600; }
/* Su hermano VERDE: dinero que ya salió del banco. Nació con la tabla de «Por
   llegar» (Pablo, 2026-08-17: «en rojo si no se ha pagado, en verde si ya se
   pagó») y obedece la ley 04: verde = ya está. Se llaman igual que se leen:
   .falta = falta salir · .saldado = ya salió. */
.saldado { color: var(--success-ink); font-weight: 600; }

.nota-pie { color: var(--ink-2); font-size: 13px; margin-top: 16px; max-width: 75ch; line-height: 1.55; }

/* ====== Acceso al detalle técnico (capa más profunda, no puerta paralela) ====== */
.detalle-tecnico {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  margin-top: 28px; padding: 18px 20px;
  background: var(--stone-light); border: 1px solid var(--hairline);
  border-radius: 14px;
}
.detalle-tecnico .dt-titulo { font-size: 14px; font-weight: 600; color: var(--ink); }
.detalle-tecnico .dt-sub { font-size: 12.5px; color: var(--ink-2); margin-top: 3px; line-height: 1.5; max-width: 65ch; }
.detalle-tecnico .btn { flex-shrink: 0; }
.dt-inline { color: var(--ink-2); font-size: 13px; margin-top: 18px; }
@media (max-width: 560px){ .detalle-tecnico { flex-direction: column; align-items: flex-start; } }

/* ====== Mensajes flash ====== */
.flash {
  scroll-margin-top: 124px; /* barra 60px + sub-barra: el aviso se asoma DEBAJO de ellas (#5, I1 §2.6) */ padding: 11px 16px; border-radius: 12px; margin-bottom: 18px; font-size: 14px; font-weight: 500; }
.flash-error, .flash-danger { background: rgba(224,53,43,.10); color: var(--critical-ink); }
.flash-success { background: rgba(52,168,83,.12); color: var(--success-ink); }
/* ⚠️ INFO Y WARNING SON DOS COSAS Y VAN EN DOS RENGLONES (2026-09-17).
   Compartían esta línea, y por eso «ese gasto ya se había capturado, no se
   duplicó» gritaba igual que «la factura quedó con diferencia». El naranja se
   queda donde la ley 04 lo manda —«es tu turno»— y el dato que no pide nada
   estrena el azul de la casa. */
.flash-warning { background: var(--orange-soft); color: var(--orange-ink); }
.flash-info { background: var(--blue-soft); color: var(--blue-ink); }

/* ====== Estado vacío grande (próximamente) ====== */
.estado-vacio { text-align: center; padding: 60px 24px; }
.estado-vacio .emoji { font-size: 46px; }
.estado-vacio h2 { font-size: 22px; margin: 14px 0 6px; }
.estado-vacio p { color: var(--ink-2); max-width: 46ch; margin: 0 auto 22px; }

/* ====== Login propio ====== */
.login-body { display: flex; min-height: 100vh; align-items: center; justify-content: center; }
.login-wrap { width: 100%; max-width: 380px; padding: 24px; }
.login-card { background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow); padding: 36px 32px; text-align: center; }
.login-logo { height: 34px; width: auto; margin-bottom: 18px; }
.login-card h1 { font-size: 22px; margin: 0 0 2px; }
.login-sub { color: var(--ink-2); font-size: 13px; margin: 0 0 22px; }
.login-label { display: block; text-align: left; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--ink-2); margin-bottom: 14px; }
.login-label input { margin-top: 6px; }
.login-btn { width: 100%; justify-content: center; margin-top: 6px; }
.login-pie { text-align: center; color: var(--ink-2); font-size: 12px; margin-top: 18px; }
/* «Olvidé mi contraseña», debajo del botón de Entrar (14-sep-2026). */
.login-olvide { text-align: center; font-size: 13px; margin: 14px 0 0; }

/* ====== Footer ====== */
footer.app-footer, .pie { text-align: center; padding: 28px 16px; color: var(--ink-2); font-size: 12px; letter-spacing: .2px; }

/* ====== Botón de menú (mostrar/ocultar el riel; en móvil abre el cajón) ====== */
/* position:relative para poder colgar el punto rojo (.nav-toggle-burbuja) sobre el ☰. */
.nav-toggle { display: inline-flex; align-items: center; justify-content: center; position: relative; background: none; border: none; color: var(--ink); font-size: 22px; cursor: pointer; padding: 4px 8px; line-height: 1; border-radius: 9px; transition: background .15s; }
.nav-toggle:hover { background: rgba(0,0,0,.05); }
/* A2/A4 — Al plegarse la barra de módulos dentro del ☰, su burbuja de Pendientes queda
   escondida. Este punto rojo sobre el ☰ avisa —sin abrir el menú— que algo espera tu
   firma. Mismo rojo que la burbuja del escritorio (.nav-burbuja). */
.nav-toggle-burbuja {
  position: absolute; top: -1px; right: -1px; box-sizing: border-box;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: 980px;
  background: var(--critical); color: #fff; font-size: 10px; font-weight: 700;
  line-height: 12px; text-align: center; border: 2px solid rgba(255,255,255,.92);
}

.solo-movil { display: none; }

/* A1 — Entre ~1080 y ~1240px la barra entera aún cabe, pero el nombre del usuario y la
   etiqueta "Mi seguridad" son lo primero que la desborda y recorta "Cerrar sesión".
   Se ocultan aquí (el candado 🔒 se queda) para ganar ese espacio antes de que corte. */
@media (max-width: 1240px) {
  .nav-name { display: none; }
  .nav-seguridad .etq { display: none; }
}

@media (max-width: 1080px) {
  header.topbar { padding: 0 14px; gap: 12px; }
  /* El lente se queda (Pablo lo quiere en todas las pantallas), pero compacto:
     el icono 🏢 se va y las pastillas encogen un poco. */
  .lente-empresa { gap: 5px; }
  .lente-empresa .lente-ic { display: none; }
  .lente-pill { padding: 4px 9px; font-size: 12px; }
}

@media (max-width: 640px) {
  main, .contenido { padding: 22px 14px 48px; }
  h1 { font-size: 26px; }
  /* iOS Safari hace zoom al enfocar un input con font-size <16px (molesto al teclear el
     código). 16px lo evita en toda pantalla chica. */
  input:not([type="checkbox"]):not([type="radio"]), select, textarea { font-size: 16px; }
  /* Lo marcado "solo móvil" (p. ej. el selector Ordenar por) aparece aquí. */
  .solo-movil { display: block; }
  form.orden-movil { display: flex; }
  /* Varios sombreros (se suman) deben envolver, no salirse de la tarjeta en el celular. */
  .tabla tbody td .chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
  .tabla thead { display: none; }
  .tabla tbody td { display: flex; justify-content: space-between; gap: 12px; padding: 10px 14px; text-align: right; }
  /* (8-sep-2026) Una insignia suelta dentro de la celda apilada es un hijo del flex y
     con `align-items: stretch` se estiraba a la altura de la celda: «calza exacto» salía
     como una columna verde de 100 px junto al texto. Cazado en la foto a 390 px de
     «¿Qué es este movimiento?»; pasa en toda tabla con una pastilla al lado del dato. */
  .tabla tbody td > .badge { align-self: center; }
  /* El rótulo de la fila en teléfono. `text-transform: none` NO es adorno: en escritorio
     el encabezado vive en el <thead>, pero en teléfono lo pinta este ::before DENTRO de la
     celda — y ahí HEREDA el estilo de la celda. Una columna de folios (`.dato`, que va en
     mayúsculas a propósito: es la excepción de la ley 09) le contagiaba sus mayúsculas al
     rótulo, y «Surte la orden» se leía «SURTE LA ORDEN» — un rótulo gritado, que es
     justo lo que la ley 09 prohíbe. Pasa en TODA tabla del ERP con columna de folio, y
     solo se ve en teléfono: por eso vivió invisible hasta que se midió a 390 px
     (hallazgo del ensayo de Recibir mercancía, 2026-08-02). El rótulo nunca es un folio,
     así que apagarlo aquí no puede quitarle las mayúsculas a nada que las merezca. */
  .tabla tbody td::before { content: attr(data-th); color: var(--ink-2); font-weight: 600; text-align: left; text-transform: none; letter-spacing: normal; }
  .tabla tbody td.producto { text-align: left; }
  /* ⚠️ EL NOMBRE CORTO EN BANDEROLA, medido a 390 px (17-sep-2026, la maqueta del
     precio del papel). `td.producto` ya dice «alinéate a la izquierda», pero en la
     tarjeta del teléfono la celda es un flex con `space-between`: el bloque del
     nombre sigue midiendo lo que mide su texto, así que «King Panda PP» se iba
     pegado al borde derecho, contra su propio rótulo. `text-align` no lo puede
     arreglar — lo que falta es que el bloque CREZCA. Va aquí, en la pieza de la
     tabla, y no en la plantilla que lo descubrió: le pasa a toda pantalla que
     ponga un nombre de dos renglones en una columna de producto. */
  .tabla tbody td.producto > .nombre-largo { flex: 1 1 auto; min-width: 0; text-align: left; }
  .tabla tfoot td { display: flex; justify-content: space-between; }
  /* EL PIE TAMBIÉN LLEVA SU RÓTULO (2026-08-21). El cuerpo ya lo tenía, pero el
     tfoot se quedaba con las cifras DESNUDAS: apilado en teléfono se leía
     «2 / $5,850.00 / $3,510.00» sin decir cuál era cuál — justo en el renglón
     del total, que es el que más se mira. Se vio midiendo el margen a 390 px.
     Solo se pinta si la celda trae `data-th`, así que ninguna tabla vieja cambia. */
  .tabla tfoot td[data-th]::before { content: attr(data-th); color: var(--ink-2); font-weight: 600; text-align: left; text-transform: none; letter-spacing: normal; }
  /* R-153 (7-sep-2026): las celdas VACÍAS del pie (unidad, almacén, dueño, valor en la fila
     de totales) en escritorio guardan la columna; en la tarjeta serían cuatro barras grises
     sin nada. Se esconden. Cazado en la foto a 390 px. */
  .tabla tfoot td:empty { display: none; }
  /* Cada renglón se ve como tarjeta separada (sin esto, tablas largas son un muro). */
  .tabla tbody tr { display: block; border-bottom: 2px solid var(--hairline); padding-bottom: 6px; margin-bottom: 10px; }
  /* B15 — El botón flotante "Reportar problema" (abajo a la derecha) alcanzaba a tapar el
     "Siguiente →" de la paginación al llegar al fondo. Este aire debajo lo despeja. */
  .paginacion { margin-bottom: 56px; }
}

/* --- Botón global "reportar un problema" (en la base, todas las pantallas) --- */
.report-fab {
  position: fixed; right: 18px; bottom: 18px; z-index: 50;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--hairline); border-radius: 980px;
  padding: 10px 18px; font-family: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; box-shadow: var(--shadow); display: inline-flex; align-items: center; gap: 8px;
}
.report-fab:hover { border-color: var(--orange); color: var(--orange-ink); }
/* Burbuja roja con el número de reportes abiertos (solo Administradores; lleva a la bandeja). */
.report-badge {
  position: fixed; right: 10px; bottom: 44px; z-index: 51;
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 980px;
  background: #d64545; color: #fff; font-size: 12px; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; box-shadow: var(--shadow); border: 2px solid var(--card);
}
.report-badge:hover { background: #b23b3b; }
.report-overlay {
  display: none; position: fixed; inset: 0; z-index: 60;
  background: rgba(0,0,0,.45); align-items: center; justify-content: center; padding: 20px;
}
.report-card {
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  width: 100%; max-width: 460px; padding: 24px;
}
.report-title { margin: 0 0 4px; font-size: 20px; }
.report-sub { margin: 0 0 14px; color: var(--ink-2); font-size: 14px; }
.report-text {
  width: 100%; box-sizing: border-box; border: 1px solid var(--hairline); border-radius: 12px;
  padding: 12px; font-family: inherit; font-size: 15px; resize: vertical;
}
.report-text:focus { outline: none; border-color: var(--orange); }
.report-acciones { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }
@media (max-width: 640px) {
  /* En móvil el botón se encoge a solo el ícono para no tapar los botones de la pantalla.
     Pero se le respeta EL BLANCO DEL DEDO (44 × 44, regla de la casa 2026-08-02): al
     quedarse sin texto medía 43 × 41, y es el botón con el que alguien avisa que algo
     está fallando — justo el que no se puede fallar al tocar. Medido a 390 px en el
     Ensayo de Estreno; era el único control por debajo del blanco en las trece
     pantallas de la tanda, y sale en TODAS las del ERP. */
  .report-fab-text { display: none; }
  .report-fab { padding: 12px 14px; min-width: 44px; min-height: 44px; justify-content: center; }
}

/* --- Botón global «?» — Pregúntale al ERP (el de más a la izquierda) --- */
/* 1-oct-2026: se recorre de 192 a 380 px para dejarle su lugar al «💡 ¡Tengo una idea!»,
   que va en medio. La maqueta decía 192/366; medidos en el navegador con la letra real,
   «⚠ Reportar problema» mide 177 px y con 192 el «💡» se le encimaba 3 px. */
.ayuda-fab { right: 380px; }

/* --- El Coach ERP (5-oct-2026): el «?» se volvió un PANEL A UN LADO (decisión 6 de
   Pablo: «a un lado pero que pueda minimizarse o desplegarse»). En computadora la página
   se recorre para que el panel no tape lo que la persona está siguiendo; en el teléfono
   el panel ocupa la pantalla y «Minimizar» la devuelve. Su botón es una LIGA (sin JS
   lleva a la página completa), por eso se le quita el subrayado. --- */
.coach-fab { text-decoration: none; }
.coach-panel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 400px; z-index: 55;
  background: var(--card); border-left: 1px solid var(--hairline); box-shadow: var(--shadow-lift);
  display: flex; flex-direction: column;
}
.coach-panel[hidden] { display: none; }
.coach-cabeza { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px;
  padding: 16px 18px; border-bottom: 1px solid var(--hairline); }
.coach-titulo { margin: 0; font-size: 18px; }
.coach-sub { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-2); }
.coach-platica { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 14px 18px;
  display: flex; flex-direction: column; gap: 14px; }
.coach-bienvenida p { margin: 0; font-size: 14.5px; line-height: 1.5; color: var(--ink-2); }
.coach-turno { display: flex; flex-direction: column; gap: 8px; }
.coach-yo { align-self: flex-end; max-width: 88%; background: var(--orange-soft); color: var(--ink);
  border-radius: 14px; padding: 9px 13px; font-size: 14.5px; line-height: 1.45; overflow-wrap: anywhere; }
.coach-el .ayuda-resp:first-child, .coach-el .ia-caida:first-child, .coach-el .ia-pensando { margin-top: 0; }
.coach-el .ayuda-resp + .ayuda-resp { margin-top: 8px; }
.coach-pie { display: flex; gap: 8px; align-items: center; padding: 12px 18px;
  padding-bottom: max(12px, env(safe-area-inset-bottom)); border-top: 1px solid var(--hairline); }
.coach-pie .ayuda-q { flex: 1; min-width: 0; }
.coach-atajos { margin: 0; padding: 10px 18px 0; border-top: 1px solid var(--hairline); }
.coach-atajos + .coach-pie { border-top: 0; }
/* La línea de cobertura del Coach (tanda 3, 16-oct-2026): cuánto del ERP tiene ficha. */
.coach-cobertura { margin: 8px 18px 0; font-size: 12px; color: var(--ink-2); line-height: 1.4; }
.coach-cobertura a { color: var(--orange-ink); font-weight: 600; }
.coach-cobertura + .coach-pie { border-top: 0; }
/* La ficha de la pantalla dentro del panel (400 px): el rótulo se parte y el texto de la
   explicación va a la izquierda; con el `nowrap` del rótulo, el valor quedaba en 40 px. */
.coach-platica .tabla.pares { width: 100%; }
.coach-platica .tabla.pares .par-rot { white-space: normal; width: 38%; padding-right: 12px; vertical-align: top; }
.coach-platica .tabla.pares .par-val.texto { text-align: left; max-width: none; font-weight: 500; }
/* «¿Qué tengo pendiente hoy?»: una lista corta, cada renglón con su liga (T9). */
.coach-lista { margin: 4px 0 8px; padding-left: 20px; font-size: 14.5px; line-height: 1.5; }
.coach-lista li { margin: 0 0 10px; }
.coach-lista li > * { display: block; }
.coach-que { color: var(--ink-2); font-size: 13.5px; }
.coach-ir { color: var(--orange-ink); font-weight: 600; text-decoration: none; }
.coach-ir:hover { text-decoration: underline; }
/* Tras un 👎: «¿qué pasó?» con dos caminos (tanda 4). */
.coach-que-paso { margin-top: 10px; padding: 12px 14px; border: 1px solid var(--hairline);
  border-radius: 12px; background: var(--card); }
.coach-que-paso > p { margin: 0 0 8px; font-size: 14px; font-weight: 600; }
.coach-que-paso-botones { display: flex; flex-wrap: wrap; gap: 8px; }
.coach-que-paso-detalle { margin-top: 10px; }
.coach-que-paso-detalle .btn { margin-top: 8px; }
body.coach-abierto .coach-fab { display: none; }
@media (min-width: 901px) {
  body.coach-abierto { padding-right: 400px; }
  body.coach-abierto .report-fab, body.coach-abierto .report-badge { transform: translateX(-400px); }
}
@media (max-width: 900px) {
  /* Debajo de la barra de arriba (60 px, la misma medida que el menú del teléfono): la
     barra es fija y de capa más alta, y encima del panel le tapaba «Minimizar». */
  .coach-panel { width: 100%; border-left: 0; top: 60px; }
  body.coach-abierto { overflow: hidden; }
  body.coach-abierto .report-fab, body.coach-abierto .report-badge { display: none; }
}

/* --- Botón global «💡 ¡Tengo una idea!» (1-oct-2026), entre «?» y «⚠» --- */
.idea-fab { right: 204px; }
/* El emoji trae su propia altura de renglón y estiraba el botón 5 px sobre sus vecinos. */
.idea-fab > span[aria-hidden] { line-height: 1; }
/* Su burbuja (ideas nuevas, sólo para quien abre la bandeja) se cuelga de SU botón,
   no del de reportar: misma altura que `.report-badge`, recorrida igual que él. */
.idea-badge { right: 196px; }
.idea-card { max-width: 520px; max-height: 92vh; overflow-y: auto; }
.idea-card .campo { margin-bottom: 12px; }
.idea-adjunto {
  border: 1px dashed var(--hairline); border-radius: 12px; padding: 10px 12px;
  font-size: 13px; color: var(--ink-2);
  display: flex; justify-content: space-between; gap: 8px; align-items: center; flex-wrap: wrap;
}
.ayuda-card { max-width: 520px; max-height: 85vh; overflow-y: auto; }
/* La caja de escribir: fondo suave que se ilumina al tocarla (especificación
   visual aprobada por Pablo sobre la maqueta, 2026-08-22). font-size 16px a
   propósito: con menos, el iPhone hace ZOOM al enfocar el campo. */
.ayuda-q {
  width: 100%; box-sizing: border-box; border: 1.5px solid transparent; border-radius: 12px;
  padding: 12px 14px; font-family: inherit; font-size: 16px; background: #f2f2f5;
  transition: background .15s, border-color .15s, box-shadow .15s;
}
.ayuda-q:focus { outline: none; background: #fff; border-color: var(--orange);
  box-shadow: 0 0 0 4px var(--orange-soft); }
.ayuda-atajos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ayuda-atajo {
  border: 1px solid var(--hairline); border-radius: 980px; padding: 8px 13px;
  font-family: inherit; font-size: 13px; background: var(--card); color: var(--ink);
  cursor: pointer; text-align: left; min-height: 44px;
}
.ayuda-atajo:hover { border-color: var(--orange); color: var(--orange-ink); }
.ayuda-resultados:not(:empty) { margin-top: 8px; }
/* La respuesta vive en su propia tarjeta suave (especificación de la maqueta). */
.ayuda-resp {
  background: #fafafa; border: 1px solid var(--hairline); border-radius: 14px;
  padding: 14px 16px; margin-top: 12px;
}
.ayuda-resp p { margin: 0 0 8px; font-size: 15px; line-height: 1.6; overflow-wrap: anywhere; }
.ayuda-resp p:last-child { margin-bottom: 0; }
.ayuda-fuente { color: var(--ink-2); font-size: 12.5px; overflow-wrap: anywhere;
  border-top: 1px solid var(--hairline); margin-top: 12px; padding-top: 10px; }
.ayuda-fuente .etiqueta { font-size: 10.5px; font-weight: 700; letter-spacing: .6px;
  color: #a5a5aa; margin-right: 6px; }

/* --- La capa de IA en el panel (tanda 1, 2026-08-22; estilo aprobado en maqueta) --- */
.ia-marca { display: flex; align-items: center; gap: 7px; margin-bottom: 10px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
  color: var(--ink-2); }
.ia-marca .punto { width: 7px; height: 7px; border-radius: 50%; background: #2e9e5b;
  box-shadow: 0 0 0 3px rgba(46,158,91,.15); }
.ia-marca .tiempo { font-weight: 600; letter-spacing: 0; text-transform: none; color: #a5a5aa; }
.ia-voto { margin-top: 12px; display: flex; gap: 8px; align-items: center;
  justify-content: flex-end; font-size: 12.5px; color: var(--ink-2); }
.ia-voto button { border: 1px solid var(--hairline); background: #fff; border-radius: 10px;
  width: 44px; height: 36px; cursor: pointer; font-size: 15px; line-height: 1;
  font-family: inherit; transition: border-color .15s, transform .1s, background .15s; }
.ia-voto button:hover { border-color: var(--orange); background: var(--orange-soft);
  transform: translateY(-1px); }
.ia-caida { display: flex; gap: 10px; align-items: flex-start; margin-top: 12px;
  background: #FFF8E6; border: 1px solid #F0E1AC; border-radius: 12px;
  padding: 11px 14px; font-size: 13.5px; line-height: 1.5; color: #6b5a1e; }
.ia-caida .icono { flex: none; }
.ia-pensando { display: flex; align-items: center; gap: 10px; margin-top: 14px;
  font-size: 14px; color: var(--ink-2); }
.ia-pensando .puntos { display: inline-flex; gap: 4px; }
.ia-pensando .puntos span { width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange); animation: ia-brinca 1.2s infinite ease-in-out; }
.ia-pensando .puntos span:nth-child(2) { animation-delay: .15s; }
.ia-pensando .puntos span:nth-child(3) { animation-delay: .3s; }
@keyframes ia-brinca { 0%, 60%, 100% { opacity: .25; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-4px); } }
/* La mini gráfica de una respuesta con datos (tanda 2): LA DIBUJA EL ERP con
   los números de la métrica probada — jamás el modelo. Estilo de la maqueta. */
.mini-grafica { margin: 12px 0 4px; }
.mini-grafica .titulo { font-size: 10.5px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: #a5a5aa; margin-bottom: 10px; }
.mini-grafica .barras { display: flex; align-items: flex-end; gap: 9px; height: 96px; }
.mini-grafica .mes { flex: 1; display: flex; flex-direction: column; align-items: center;
  gap: 5px; min-width: 0; height: 100%; justify-content: flex-end; }
.mini-grafica .valor { font-size: 10px; font-variant-numeric: tabular-nums;
  color: var(--ink-2); white-space: nowrap; }
.mini-grafica .barra { width: 100%; border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, var(--orange-bright), var(--orange)); }
.mini-grafica .mes.actual .barra { box-shadow: 0 2px 8px rgba(253,107,0,.35); }
.mini-grafica .mes.cero .barra { height: 3px !important; background: #dcdce1;
  border-radius: 3px; }
.mini-grafica .etiquetas { display: flex; gap: 9px; margin-top: 7px;
  border-top: 1px solid var(--hairline); padding-top: 6px; }
.mini-grafica .etiquetas span { flex: 1; text-align: center; font-size: 11px;
  color: var(--ink-2); }
.mini-grafica .etiquetas .actual { color: var(--orange-ink); font-weight: 700; }

@media (max-width: 640px) {
  /* En móvil los tres botones se encogen a solo el ícono (regla de arriba) y se
     recorren uno junto al otro, respetando el blanco del dedo de cada uno. */
  .ayuda-fab { right: 130px; }
  /* El «💡» en medio, con el mismo blanco del dedo que los otros dos (44 × 44). */
  .idea-fab { right: 74px; }
  .idea-badge { right: 66px; }
}

/* Tablas de consulta anchas: en tablet no se parten a tarjetas (eso es ≤640px) pero sí
   desbordan — este envoltorio les da scroll horizontal en vez de perder columnas. */
/* M16 — Pista de scroll: cuando la tabla es más ancha que la pantalla (tablet), aparece
   una sombra en el borde con contenido oculto (a la derecha al inicio; a la izquierda al
   desplazar). Técnica de "sombras de scroll" con fondos: las capas blancas (local, se
   mueven con el contenido) tapan la sombra cuando NO queda nada oculto de ese lado; las
   sombras (scroll, fijas a la caja) solo asoman si hay más tabla escondida. */
.tabla-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  background-image:
    linear-gradient(to right, var(--card), rgba(255,255,255,0)),
    linear-gradient(to left,  var(--card), rgba(255,255,255,0)),
    radial-gradient(farthest-side at 0 50%,   rgba(0,0,0,.14), rgba(0,0,0,0)),
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.14), rgba(0,0,0,0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}

/* --- Impresión: las notas (salida/entrega) salen limpias, como documento --- */
.solo-imprimir { display: none; }
@media print {
  header.topbar, .side-nav, .nav-backdrop, footer.app-footer, .report-fab, .report-badge, .report-overlay,
  .page-head .btn, .page-head a, .no-imprimir, .flash { display: none !important; }
  .app-shell { display: block !important; }
  body { background: #fff; }
  .card, .tarjeta { box-shadow: none; border: 1px solid #ddd; }
  .solo-imprimir { display: block; margin-top: 36px; }
}

/* Paginación de tablas de consulta (existencias, kardex). */
.paginacion { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; }

/* Chips de filtro (Consulta: elegir almacén). Son ligas vestidas de badge. */
.filtros-chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px; }
.filtros-chips a { text-decoration: none; }
.filtros-chips a:hover { filter: brightness(.96); }

/* Los papeles que salen de la empresa (facturas, notas, estados de cuenta, órdenes de
   compra) ya NO viven dentro de esta hoja: son hojas sueltas con su propio diseño en
   templates/documentos/papel.html, para verse igual impresas, en PDF o sin sesión. */

/* Burbuja roja de Pendientes en la barra de módulos: cuenta lo que espera TU firma. */
.nav-burbuja { display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 980px;
  background: var(--critical); color: #fff; font-size: 11px; font-weight: 700;
  vertical-align: middle; margin-left: 2px; }

/* --- Revisión UX §2.6 del módulo Administración (2026-07-18): móvil --- */
/* Los formularios de captura de finanzas usan .form-col, que no existía: los campos
   salían como un chorizo vertical pegado. Un campo por renglón, con aire. */
.form-col { display: flex; flex-direction: column; gap: 14px; max-width: 560px; }
.form-col .campo { display: flex; flex-direction: column; gap: 5px; }
.form-col .campo > label { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.form-col .campo .sub { font-size: 12.5px; }
/* Captura en fila (.fila-op .acc): 92px alcanzaba para un número corto, no para una
   fecha, una referencia bancaria ni el nombre de un chofer. Los de texto y fecha
   crecen; los números conservan su ancho compacto (ahora legible). */
.fila-op .acc input[type="text"] { flex: 1 1 170px; width: auto; min-width: 150px; }
.fila-op .acc input[type="date"] { width: 158px; }
.fila-op .acc input[type="number"] { width: 130px; }
/* =====================================================================
   LOS BLANCOS DE DEDO QUE ENGORDARON LA PANTALLA DE LA COMPUTADORA
   =====================================================================
   ⚠️⚠️ LA CAUSA, dicha por Pablo el 2026-09-09 mirando una lista:
   «las filas son muy gordas… lo que cabe en mi pantalla es mucho más en el
   Excel y en tu maqueta muy poco y abrumador».

   Las tres reglas de abajo nacieron el 2026-08-11 de un ensayo en TELÉFONO y se
   escribieron SIN media query, así que también engordaron la computadora. Peor:
   el comentario de la de tablas se defendía sola —«El renglón no crece — ya era
   más alto que 44»— y eso era cierto para las filas gordas de entonces. En
   cuanto una fila adelgaza, el 44 px se vuelve su PISO. Un comentario que afirma
   una medida no la vuelve cierta para siempre; hay que volver a medirla.

   MEDIDO en Chrome headless a 1400 px el 2026-09-09, en pantallas reales sobre
   la semilla fea (10 pantallas, el censo entero vive en el PR):

       fila de tabla SIN liga ......... 31 px
       fila de tabla CON liga ......... 57 px   ← +26 px por renglón
       migas SIN liga ................. 19 px
       migas CON liga ................. 44 px   ← +25 px arriba de todo

   Y son casi todas: 80 plantillas tienen una `<a>` dentro de un `<td>` de
   `.tabla` —el folio, el nombre del cliente, el «Abrir»—. Veinte renglones son
   520 px tirados: media pantalla de laptop, y por eso la lista «abruma».

   EL BLANCO DEL DEDO NO SE TIRA: SE MUDA A DONDE HAY DEDO. Los 44 px siguen
   completos en teléfono y tablet, que es donde nacieron y donde importan (el
   almacenista de pie, el vendedor en un rancho). En la computadora se apunta con
   el ratón, que atina a un renglón de 31 px sin problema.

   `(pointer: coarse)` ADEMÁS de los 640 px, y no en su lugar: el teléfono
   ACOSTADO mide más de 640 px de ancho y seguiría siendo un dedo. Ninguna
   computadora de Mely es de tocar, así que no le quita nada a nadie.
   ⚠️ Se decidió CON LA FOTO, no de oído: el antes/después está en el CHANGELOG
   del 2026-09-09 y las fotos, en el PR.
   ===================================================================== */
/* Blancos de dedo: los chips de filtro se tocan con el pulgar.
   ⚠️ ESTABAN EN 34 px, y el comentario de al lado ya decía «mínimo táctil ~44px»:
   la corrección de 2026-08-02 se quedó a la mitad y nadie volvió a medirla. Se
   cazó al recorrer Comercial en el teléfono el 2026-08-11. Con estos chips el
   vendedor filtra el pipeline por etapa parado en un rancho.
   ⚠️ 2026-09-09: esta línea era además un DUPLICADO — los mismos 44 px ya viven
   en el bloque de teléfono de abajo («Y LOS CHIPS DE FILTRO», R-64, 2026-08-04),
   que es donde deben estar. Aquí sólo engordaba la barra de filtros de la
   computadora: 44 px por chip, y 96 px en el pipeline de Comercial, que los
   parte en dos renglones. Se queda el `padding`, que sí es de las dos. */
.filtros-chips .badge { padding: 8px 14px; }
/* ⚠️ EL BLANCO DEL DEDO DE UNA LIGA DE TABLA: 44 px (§2.9). Medidas en 15 px el
   2026-08-11. Son las PUERTAS de las listas del ERP —el folio que abre el pedido,
   el nombre del cliente que abre su expediente—: en el teléfono, la fila mide 50 px
   pero el toque solo cuenta sobre el texto de la liga.
   `inline-flex` y no `block`: dentro de una celda, un bloque rompería la línea y
   descuadraría la tabla. El `inline-flex` se queda SIEMPRE (alinea la liga con el
   resto de la celda y no engorda nada); lo que se muda al dedo es el alto mínimo. */
.tabla td a { display: inline-flex; align-items: center; }
/* ⚠️ EL BLANCO DEL DEDO DE LAS MIGAS: 44 px (§2.9). Medidas en 38 px el
   2026-08-11. Son el camino de VUELTA —«Comercial › este cliente»— y en el
   teléfono la vuelta se usa más que en la computadora, porque no hay dos ventanas
   abiertas al mismo tiempo. Justo por eso el alto mínimo se queda SÓLO en el
   teléfono: en la computadora la vuelta también está en el menú de la izquierda,
   que ahí siempre se ve. */
.migas a { display: inline-flex; align-items: center; }
/* Y aquí es donde SÍ hay dedo. Teléfono, tablet, y cualquier pantalla que se
   toque sin importar su ancho. */
@media (max-width: 640px), (pointer: coarse) {
  .tabla td a { min-height: 44px; }
  .migas a { min-height: 44px; }
  /* Y LOS CHIPS DE FILTRO (2026-08-04, R-64): eran un «estás aquí» y hoy son
     APAGADORES que se prenden y apagan de a varios (Consulta de inventario), o
     sea EL control que se toca de la pantalla. Estaban DOS veces —sin media
     query arriba, y otra vez a 640 px abajo—; ésta es la única que queda, y de
     paso gana la tablet. */
  .filtros-chips a, .filtros-chips .badge {
    min-height: 44px;
    display: inline-flex; align-items: center;
  }
}
/* Los textos de ayuda pesan menos que el dato (la explicación no compite con la cifra). */
.fila-op .sub, .form-col .sub { color: var(--ink-2); font-size: 12.5px; }

/* ===================================================================
   RBAC (2026-07-19): editor de Roles por niveles, excepciones por
   persona y panel de acceso efectivo (Configuración → Roles/Usuarios).
   =================================================================== */
/* Lista de roles */
.roles-lista { display: flex; flex-direction: column; gap: 12px; }
.rol-card { display: block; text-decoration: none; color: var(--ink); }
.rol-card:hover { box-shadow: var(--shadow-hover); }
.rol-card-cab { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.rol-nombre { font-size: 16px; font-weight: 700; }
.rol-personas { color: var(--ink-2); font-size: 13px; }
.rol-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* Pastillas de nivel (0=sin acceso · 1=lectura · 2=operativo · 3=total) */
.pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; padding: 5px 12px; border-radius: 980px; white-space: nowrap; }
.pill-n0 { background: #F1F1F3; color: #5F5F66; }  /* contraste AA (revisión UX M4) */
.pill-n1 { background: #ECECEF; color: #4B4B50; }
.pill-n2 { background: var(--orange-soft); color: var(--orange-ink); }
.pill-n3 { background: var(--ink); color: #fff; }
.pill-persona { background: var(--orange-soft); color: var(--orange-ink); text-decoration: none; }

/* Buscador del editor */
.buscador-rbac { position: relative; margin: 0 0 16px; }
.buscador-rbac input { width: 100%; font: inherit; font-size: 15px; color: var(--ink); background: var(--card); border: 1.5px solid var(--hairline); border-radius: 14px; padding: 12px 16px 12px 44px; box-shadow: var(--shadow); box-sizing: border-box; }
.buscador-rbac input:focus { outline: none; border-color: var(--orange); }
.buscador-rbac .lupa { position: absolute; left: 16px; top: 13px; color: var(--ink-2); }
.buscador-rbac .sin-resultados { margin: 12px 4px 0; color: var(--ink-2); font-size: 14px; }

/* Acordeón de módulos */
.acordeon-rbac { display: flex; flex-direction: column; gap: 10px; }
.grupo-modulos-titulo { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-2); margin: 12px 2px 0; }
.grupo-modulos-titulo .hint { font-weight: 500; text-transform: none; letter-spacing: 0; }
.modulo-rbac { background: var(--card); border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; }
.modulo-rbac .mod-cab { width: 100%; border: 0; background: transparent; cursor: pointer; display: flex; align-items: center; gap: 12px; padding: 15px 18px; font: inherit; text-align: left; list-style: none; }
.modulo-rbac summary.mod-cab::-webkit-details-marker { display: none; }
.modulo-rbac .mod-cab:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.mod-emoji { font-size: 20px; flex-shrink: 0; }
.mod-nombre { font-size: 15.5px; font-weight: 700; }
.mod-resumen { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.modulo-rbac .flecha { color: var(--ink-2); transition: transform .18s; }
.modulo-rbac.abierto .flecha, .modulo-rbac[open] .flecha { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .modulo-rbac .flecha { transition: none; } }
.mod-cuerpo { border-top: 1px solid var(--hairline); padding: 16px 18px 18px; }

/* Selector de nivel (segmentado) */
.seg { display: flex; background: #EFEFF1; border-radius: 11px; padding: 3px; gap: 2px; max-width: 560px; flex-wrap: wrap; }
.seg-opcion { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 13px; font-weight: 600; color: #5B5B60; padding: 8px 10px; border-radius: 9px; white-space: nowrap; cursor: pointer; }
.seg-opcion input { position: absolute; opacity: 0; pointer-events: none; }
.seg-opcion.sel, .seg-opcion:has(input:checked) { background: #fff; color: var(--ink); box-shadow: 0 1px 4px rgba(0,0,0,.12); }  /* :has = respaldo sin JS */
.seg-opcion:focus-within { outline: 2px solid var(--orange); outline-offset: 1px; }
@media (max-width: 560px) { .seg-opcion { flex: 1 1 45%; } }

/* Acciones dentro del módulo */
.acciones-rbac { margin: 14px 0 0; padding: 0; list-style: none; }
.accion-rbac { display: flex; align-items: baseline; gap: 10px; padding: 8px 2px; border-top: 1px solid #F1F1F3; font-size: 14px; }
.accion-rbac:first-child { border-top: 0; }
.accion-rbac .marca { flex-shrink: 0; width: 20px; text-align: center; font-weight: 700; }
.accion-rbac.si .marca { color: var(--success-ink); }
.accion-rbac.no .marca { color: #C7C7CC; }
.accion-rbac.no .txt { color: #A0A0A6; }
.accion-rbac .desde { margin-left: auto; flex-shrink: 0; font-size: 12px; color: var(--ink-2); white-space: nowrap; }
.tag-dinero { font-size: 12px; }

/* Excepciones por persona */
.excepcion { display: flex; gap: 12px; align-items: flex-start; padding: 13px 15px; border-radius: 14px; margin-top: 10px; border: 1.5px solid var(--hairline); }
.excepcion.mas { background: #EAF6EE; border-color: rgba(52,168,83,.35); }
.excepcion.menos { background: #FBEFEE; border-color: rgba(224,53,43,.3); }
.excepcion.espera { background: var(--orange-soft); border-color: rgba(253,107,0,.3); }
.excepcion .signo { flex-shrink: 0; width: 26px; height: 26px; border-radius: 50%; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 15px; }
.excepcion.mas .signo { background: var(--success); }
.excepcion.menos .signo { background: var(--critical); }
.excepcion.espera .signo { background: transparent; font-size: 18px; }
.excepcion-cuerpo { min-width: 0; }
.excepcion .que { font-weight: 700; font-size: 14px; }
.excepcion .motivo { font-size: 13.5px; margin-top: 2px; }
.excepcion .rastro { font-size: 12.5px; color: var(--ink-2); margin-top: 5px; }
.excepcion form { margin-left: auto; flex-shrink: 0; }
.btn-liga { border: 0; background: transparent; color: var(--ink-2); font: inherit; font-size: 13px; cursor: pointer; text-decoration: underline; padding: 6px; }
.btn-liga:hover { color: var(--critical-ink); }

/* Alta de excepción */
.excepcion-alta { margin-top: 14px; }
.excepcion-alta summary { cursor: pointer; font-weight: 600; color: var(--orange-ink); font-size: 14px; padding: 6px 0; }
.excepcion-form { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; max-width: 620px; }
.excepcion-form label { display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.excepcion-form input[type="search"], .excepcion-form input[type="text"] { font: inherit; font-size: 14.5px; padding: 10px 12px; border: 1.5px solid var(--hairline); border-radius: 10px; color: var(--ink); }
.excepcion-form input:focus { outline: none; border-color: var(--orange); }
.excepcion-form select { font: inherit; font-size: 14px; border: 1.5px solid var(--hairline); border-radius: 10px; padding: 6px; color: var(--ink); }
.excepcion-tipo { display: flex; gap: 18px; flex-wrap: wrap; }

/* Acceso efectivo */
.efectivo { display: flex; flex-direction: column; margin-top: 8px; }
.efe-fila { display: flex; align-items: center; gap: 10px; padding: 10px 2px; border-top: 1px solid #F1F1F3; font-size: 14px; flex-wrap: wrap; }
.efe-fila:first-child { border-top: 0; }
.efe-mod { font-weight: 600; min-width: 210px; }
.efe-extra { font-size: 12.5px; font-weight: 700; padding: 4px 10px; border-radius: 980px; }
.efe-extra.mas { background: #EAF6EE; color: var(--success-ink); }
.efe-extra.menos { background: #FBEFEE; color: var(--critical-ink); }
.efe-origen { margin-left: auto; font-size: 12px; color: var(--ink-2); }
@media (max-width: 640px) { .efe-origen { flex-basis: 100%; margin-left: 30px; } .efe-mod { min-width: 140px; } }

/* ===================================================================
   REDISEÑO 2026-07-21 — Componentes NUEVOS (additivos).
   Nada de lo anterior los usa todavía: agregarlos no puede romper
   pantallas actuales. Se van aplicando por pantalla en tandas.
   =================================================================== */

/* --- Migas de pan (dónde estoy) --- */
.migas { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-2); margin: 0 0 14px; flex-wrap: wrap; }
.migas a { color: var(--ink-2); text-decoration: none; }
.migas a:hover { color: var(--orange-ink); }
.migas .sep { color: var(--stone); }
.migas .actual { color: var(--ink); font-weight: 600; }

/* --- Tira de resumen (cifras grandes de un vistazo) --- */
.resumen-cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 20px; }
.cifra { background: var(--card); border-radius: 14px; padding: 14px 16px; box-shadow: var(--shadow); }
.cifra .et { font-size: 12.5px; color: var(--ink-2); display: flex; align-items: center; gap: 6px; }
.cifra .val { font-size: 24px; font-weight: 700; margin-top: 4px; letter-spacing: -.5px; font-variant-numeric: tabular-nums; line-height: 1.1; }
.cifra .val small { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.cifra .val.alerta { color: var(--warning); }
.cifra .val.bien { color: var(--success-ink); }
.cifra.ojo { border: 1px solid rgba(245,158,11,.4); }

/* --- Palanca estilo iOS (sí/no) — para candados/opciones on-off --- */
.palanca { position: relative; display: inline-block; width: 46px; height: 28px; flex-shrink: 0; cursor: pointer; vertical-align: middle; }
.palanca input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.palanca .riel { position: absolute; inset: 0; background: #C7C7CC; border-radius: 980px; transition: background .2s; }
.palanca .bolita { position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: transform .2s; }
.palanca input:checked + .riel { background: var(--orange); }
.palanca input:checked ~ .bolita { transform: translateX(18px); }
.palanca input:focus-visible ~ .riel { outline: 2px solid var(--orange); outline-offset: 2px; }
.palanca input:disabled ~ .riel { opacity: .5; }

/* --- Renglón de ajuste (etiqueta + descripción a la izquierda, control a la derecha) --- */
.ajuste { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 15px 20px; border-bottom: 1px solid var(--hairline-2); }
.ajuste:last-child { border-bottom: none; }
.ajuste .info { min-width: 0; }
.ajuste .info .tit { font-size: 14px; font-weight: 600; }
.ajuste .info .des { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; max-width: 56ch; }
.ajuste .ctrl { flex-shrink: 0; }
@media (max-width: 560px) { .ajuste { flex-direction: column; align-items: flex-start; gap: 10px; } }

/* --- Error por campo (borde rojo + mensaje bajo el campo) --- */
.campo-error input, .campo-error select, .campo-error textarea,
input.error, select.error, textarea.error {
  border-color: var(--critical); box-shadow: 0 0 0 3px rgba(224,53,43,.14);
}
.error-inline { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--critical-ink); margin-top: 6px; }

/* --- Barra de guardar pegajosa (aparece con cambios sin guardar) --- */
.barra-guardar {
  position: sticky; bottom: 16px; z-index: 40; margin-top: 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: var(--card); border: 1px solid var(--hairline); border-radius: 14px;
  padding: 12px 16px; box-shadow: var(--shadow-lift);
}
.barra-guardar .estado { font-size: 13px; color: var(--ink-2); display: flex; align-items: center; gap: 8px; }
.barra-guardar .punto { width: 8px; height: 8px; border-radius: 50%; background: var(--orange); flex-shrink: 0; }
.barra-guardar .acciones { display: flex; gap: 8px; flex-shrink: 0; }
kbd { font-family: inherit; font-size: 11px; background: var(--card-2); border: 1px solid var(--hairline); border-bottom-width: 2px; border-radius: 6px; padding: 1px 6px; color: var(--ink-2); }
@media (max-width: 560px) { .barra-guardar { flex-direction: column; align-items: stretch; } .barra-guardar .acciones .btn { flex: 1; justify-content: center; } }

/* --- Aviso tipo "toast" (confirmación flotante) --- */
.toast-erp {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 20px);
  background: var(--ink); color: #fff; font-size: 13.5px; font-weight: 500;
  padding: 11px 18px; border-radius: 12px; box-shadow: var(--shadow-lift);
  display: flex; align-items: center; gap: 9px; opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s; z-index: 200; max-width: 82vw;
}
.toast-erp.ver { opacity: 1; transform: translate(-50%, 0); }
.toast-erp .paloma { color: var(--success-ink); flex-shrink: 0; }

/* ===================================================================
   RIEL LATERAL DE MÓDULOS (rediseño 2026-07-22) — TODO se navega desde un
   ÁRBOL de módulos a la izquierda (acordeón, varios abiertos a la vez). El
   riel se puede OCULTAR (botón ☰ del topbar) para que las tablas usen todo
   el ancho. En móvil el riel es un cajón que se desliza desde la izquierda.
   Progresivo: sin JS las sub-secciones salen abiertas (usable); el JS pliega
   las que no van y recuerda tu preferencia (localStorage).
   =================================================================== */
.app-shell { max-width: 1480px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; }
.app-shell:has(.side-nav) { grid-template-columns: 270px minmax(0, 1fr); }  /* 270 desde el menú por áreas (11-oct-2026): los nombres de Excel completos caben, como en la maqueta aprobada. */
/* El contenido llena su columna (las tablas ganan ancho): ya no se centra a 1080px. */
.app-shell > .contenido { max-width: none; margin: 0; padding: 34px 30px 60px; min-width: 0; }

/* --- El riel (columna izquierda, pegajoso, con su propio scroll) --- */
.side-nav { position: sticky; top: 60px; align-self: start; height: calc(100vh - 60px); overflow-y: auto; overflow-x: hidden; border-right: 1px solid var(--hairline); background: #FBFBFC; padding: 14px 12px; scrollbar-width: thin; }
.side-tree { display: flex; flex-direction: column; gap: 1px; }

/* Renglón del módulo (enlace + chevron para desplegar) */
.nv-grp { display: flex; flex-direction: column; }
.nv-grp-fin { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--hairline); }
.nv-head { display: flex; align-items: stretch; gap: 2px; }
.nv-mod { flex: 1; min-width: 0; display: flex; align-items: center; gap: 11px; padding: 9px 11px; border-radius: 10px; color: var(--ink); text-decoration: none; font-size: 14px; font-weight: 500; white-space: nowrap; transition: background .15s, color .15s; }
.nv-mod .nv-ic { width: 20px; height: 20px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; color: var(--ink-2); font-size: 15px; line-height: 1; transition: color .15s; }
.nv-mod .nv-ic svg { width: 20px; height: 20px; display: block; }
.nv-mod .nv-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.nv-mod:hover { background: rgba(0,0,0,.04); }
/* Módulo activo: contorno naranja tenue (como la referencia de Pablo) + ícono de marca. */
.nv-mod.active { background: var(--orange-soft); color: var(--orange-ink); font-weight: 600; box-shadow: inset 0 0 0 1.5px var(--orange-line); }
.nv-mod.active .nv-ic { color: var(--orange-ink); }
.nv-mod:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }

/* Chevron de desplegar (no navega; solo abre/cierra la rama) */
.nv-chev { flex-shrink: 0; width: 30px; border: none; background: none; color: var(--stone); cursor: pointer; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.nv-chev svg { width: 16px; height: 16px; display: block; transition: transform .18s; }
.nv-chev:hover { background: rgba(0,0,0,.06); color: var(--ink); }
.nv-chev:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.nv-grp.plegado .nv-chev svg { transform: rotate(-90deg); }
@media (prefers-reduced-motion: reduce) { .nv-chev svg { transition: none; } }

/* Sub-secciones (abiertas por defecto → sirve sin JS; el JS pliega las cerradas) */
.nv-sub { display: flex; flex-direction: column; gap: 1px; padding: 1px 0 6px; }
.nv-grp.plegado > .nv-sub { display: none; }
.nv-sub a { display: flex; align-items: center; gap: 8px; padding: 7px 11px 7px 20px; margin-left: 19px; border-left: 1.5px solid var(--hairline); color: var(--ink-2); text-decoration: none; font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: background .15s, color .15s, border-color .15s; }
.nv-sub a:hover { background: rgba(0,0,0,.04); color: var(--ink); border-left-color: var(--stone); }
.nv-sub a.active { color: var(--orange-ink); font-weight: 600; border-left-color: var(--orange); }
.nv-sub a .nav-burbuja { margin-left: auto; }

/* ====== EL CAJÓN DE CATÁLOGOS (2026-08-18) ======
   Un TERCER nivel dentro del submenú: Catálogos tenía doce destinos al mismo
   nivel y Pablo pidió agruparlos. Se dibuja distinto del módulo de arriba a
   propósito — no es otro módulo, es una repisa dentro de éste: sin ícono, con
   la misma sangría que los destinos hermanos y su flecha a la derecha.

   ⚠️ El cabezal es un <button>, no un <a>: no lleva a ningún lado, abre. Un
   ancla que no navega deja a quien usa teclado esperando una página que nunca
   llega, y a quien usa lector de pantalla oyendo «enlace» donde hay un botón. */
.nv-cajon { display: flex; flex-direction: column; }
.nv-cajon-cab {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 11px 7px 20px; margin-left: 19px;
  border: 0; border-left: 1.5px solid var(--hairline); background: none;
  color: var(--ink-2); font: inherit; font-size: 13.5px; font-weight: 600;
  text-align: left; cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.nv-cajon-cab:hover { background: rgba(0,0,0,.04); color: var(--ink); border-left-color: var(--stone); }
.nv-cajon-cab:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.nv-cajon-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nv-cajon-fl { flex-shrink: 0; color: var(--stone); display: inline-flex; }
.nv-cajon-fl svg { width: 15px; height: 15px; display: block; transform: rotate(-90deg); transition: transform .18s; }
.nv-cajon.abierto .nv-cajon-fl svg { transform: none; }
@media (prefers-reduced-motion: reduce) { .nv-cajon-fl svg { transition: none; } }

.nv-cajon-sub { display: none; flex-direction: column; gap: 1px; padding-bottom: 4px; }
.nv-cajon.abierto > .nv-cajon-sub { display: flex; }
/* Los destinos del cajón sangran un escalón más que sus hermanos sueltos: es lo
   único que dice «esto está DENTRO de aquello» cuando el cajón está abierto. */
.nv-cajon-sub a {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 11px 7px 34px; margin-left: 19px;
  border-left: 1.5px solid var(--hairline);
  color: var(--ink-2); text-decoration: none; font-size: 13.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background .15s, color .15s, border-color .15s;
}
.nv-cajon-sub a:hover { background: rgba(0,0,0,.04); color: var(--ink); border-left-color: var(--stone); }
.nv-cajon-sub a.active { color: var(--orange-ink); font-weight: 600; border-left-color: var(--orange); }

/* --- EL MENÚ POR ÁREAS (11-oct-2026, maqueta aprobada por Pablo) ---------------
   Tres títulos que NO se pican (Operaciones · Administración y finanzas · Comercial)
   agrupan los módulos; abajo, sin título y tras una raya, Catálogos, Indicadores y
   Configuración. El título sólo existe si su área trae algún módulo para esta persona. */
.nv-area-bloque { display: flex; flex-direction: column; gap: 1px; }
.nv-area { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin: 14px 11px 4px; }
.nv-area-fin { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--hairline); }
/* Los nombres completos se leen enteros: una opción larga («Política de crédito y
   cobranza») baja de renglón en vez de cortarse con «…». */
.nv-sub a, .nv-cajon-sub a { white-space: normal; line-height: 1.3; }
.nv-mod .nv-t { white-space: normal; line-height: 1.25; }
/* Lo que el buscador esconde se esconde de verdad: `.nv-sub a` y `.nv-cajon` traen
   display:flex, que le gana al [hidden] del navegador. */
.side-tree [hidden], .nv-buscar [hidden] { display: none !important; }
/* El buscador: pegado arriba del riel, también en el cajón del teléfono. */
.nv-buscar { position: sticky; top: -14px; z-index: 2; background: #FBFBFC; margin: -14px -12px 4px; padding: 14px 12px 10px; }  /* top = −el padding del riel: así se pega arriba sin taparle el primer renglón */
.side-tree { padding-top: 6px; }
.nv-buscar input { width: 100%; box-sizing: border-box; min-height: 38px; font-size: 14px; }
.nv-buscar-vacio { margin: 8px 4px 0; font-size: 13px; color: var(--ink-3); }
@media (max-width: 900px) { .nv-buscar input { font-size: 16px; } }  /* 16 px: el iPhone no hace zoom al escribir */

/* Menú OCULTO (escritorio): el riel desaparece y el contenido usa todo el ancho. */
.nav-backdrop { display: none; }
@media (min-width: 901px) {
  html.nav-colapsado .app-shell:has(.side-nav) { grid-template-columns: minmax(0, 1fr); }
  html.nav-colapsado .side-nav { display: none; }
}

/* Móvil/tablet: el riel es un CAJÓN que se desliza desde la izquierda (lo abre el ☰). */
@media (max-width: 900px) {
  .app-shell, .app-shell:has(.side-nav) { display: block; max-width: none; grid-template-columns: none; }
  .app-shell > .contenido { padding: 22px 14px 48px; }
  .side-nav { position: fixed; top: 60px; left: 0; z-index: 160; width: 270px; max-width: 84vw; height: calc(100vh - 60px); box-shadow: 0 10px 40px rgba(0,0,0,.18); transform: translateX(-100%); transition: transform .2s ease; }
  body.nav-open .side-nav { transform: translateX(0); }
  body.nav-open .nav-backdrop { display: block; position: fixed; inset: 60px 0 0 0; background: rgba(0,0,0,.4); z-index: 150; }
}

/* Aire entre tarjetas de Configuración (la .tarjeta no trae separación por defecto). */
.config-cuerpo { min-width: 0; }
.config-cuerpo .tarjeta, .config-cuerpo .card { margin-bottom: 16px; }
.config-cuerpo .tarjeta:last-child, .config-cuerpo .card:last-child { margin-bottom: 0; }

/* ===================================================================
   BARRIDO DE DISEÑO 2026-07-23 — componentes que varias pantallas ya
   nombraban pero NO estaban definidos (caían a defaults del navegador),
   y utilidades que reemplazan CSS embebido duplicado. Todo ADITIVO:
   ninguna regla de arriba los usa, así que agregarlos no rompe nada.
   =================================================================== */

/* Enlaces dentro de un aviso flash: heredan el color del aviso y van
   subrayados (antes cada pantalla lo ponía con style="" en línea). */
.flash a { color: inherit; font-weight: 600; text-decoration: underline; }
.flash a:hover { text-decoration: none; }
/* En teléfono la liga del aviso es EL botón del «qué sigue» (§4.11): se le da blanco
   de toque en vez de dejarla como texto subrayado de 20 px al final del párrafo. */
@media (max-width: 560px) {
  .flash a { display: inline-block; margin-top: 8px; padding: 8px 14px;
             border: 1px solid currentColor; border-radius: 999px; text-decoration: none; }
}

/* Formulario/fila EN LÍNEA (campo + botón lado a lado). Lo usaban varias
   pantallas de Compras (configuracion, oc_detalle, llegada_detalle) y de
   Finanzas sin que la regla existiera → se veían como bloques apilados. */
.fila-inline { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0; }

/* Etiqueta compacta apilada (rótulo chico arriba, campo abajo) — llegada_detalle. */
.etq-mini { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; font-weight: 600; color: var(--ink-2); }
.etq-mini input { font-weight: 400; }

/* Tabla de LOTES (compacta) y su contenedor: scrap, enviar_scrap, muestras,
   aprobacion_detalle, ajuste, traspaso y transferencia la nombraban sin
   definirla; el input "Mover" se angosta y alinea a la derecha. */
.lotes-area { margin-top: 8px; }
.tabla-lotes tbody td { padding-top: 6px; padding-bottom: 6px; }
.tabla-lotes tbody input { width: 110px; text-align: right; }

/* Fila de tabla en ALERTA (vencida / por costear): reemplaza el #fdf1f0
   embebido por el rojo de marca a baja opacidad, del sistema de tokens. */
.fila-alerta td, .fila-vencida td, .fila-por-costear td { background: rgba(224,53,43,.06); }

/* Separación entre TARJETAS apiladas (fuera de Configuración, que ya la trae
   vía .config-cuerpo). Varias pantallas de Compras la ponían con style="" —
   se centraliza aquí y se borran esos <style> duplicados. Solo tarjetas de
   primer nivel: las anidadas no se tocan. */
.contenido > .tarjeta { margin-bottom: 16px; }
.contenido > .tarjeta:last-child { margin-bottom: 0; }

/* --- Teléfono con su lada (D57, 2026-07-28) -----------------------------------
   El país va PEGADO al teléfono, no perdido en otra sección: quien captura tiene
   que ver la lada cambiar al elegir el país. La regla vive aquí, una sola vez,
   porque la usan cuatro pantallas (lead, clientes ×2, proveedores ×2). */
.tel-fila { display: flex; gap: 8px; align-items: stretch; }
.tel-fila select { flex: 0 0 auto; width: auto; min-width: 128px; }
.tel-fila input { flex: 1; min-width: 0; }
.tel-fila .lada {
  display: flex; align-items: center; padding: 0 12px;
  border: 1.5px solid var(--hairline); border-radius: 12px;
  background: var(--card-2); font-family: var(--mono); font-size: 14px;
  color: var(--ink-2); white-space: nowrap;
}
@media (max-width: 560px) {
  .tel-fila { flex-wrap: wrap; }
  .tel-fila select { width: 100%; flex: 1 1 100%; }
}

/* =====================================================================
   MI DÍA — la pantalla de entrada (rediseño 2026-07-28)
   =====================================================================
   Pablo: «ahora que ya tiene información el sistema, los recuadros son muy
   grandes». Tenía razón: con datos reales la pantalla pedía ~2,000 px de scroll
   para decir unas 15 líneas. Aquí vive la dieta:
     · dos columnas en computadora (pendientes | libreta), apiladas en teléfono;
     · las tarjetas de firma se fundieron en UNA tabla (eso pasó en la vista);
     · tareas y avisos son RENGLONES de ~44 px, no tarjetones de ~140.
   ===================================================================== */

/* El encabezado de Mi día no necesita el párrafo largo: la franja de abajo dice
   lo mismo con números. */
.page-head.compacta { margin-bottom: 16px; }

/* --- La franja de conteos (una línea, lo que hay hoy) --- */
.franja-dia { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.chip-dia {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  font-size: 13px; font-weight: 600; padding: 5px 13px; border-radius: 980px;
  background: rgba(0,0,0,.05); color: var(--ink-2);
  transition: filter .15s;
}
.chip-dia:hover { filter: brightness(.95); }
.chip-dia.firma { background: rgba(224,53,43,.10); color: var(--critical-ink); }
.chip-dia.tarea { background: rgba(245,158,11,.16); color: #8a5a00; }
.chip-dia.rec   { background: var(--orange-soft); color: var(--orange-ink); }

/* --- Las dos columnas --- */
.dia-grid { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.dia-izq > .bloque-titulo:first-child { margin-top: 0; }
.dia-der > .card:first-child { margin-top: 0; }
/* En pantalla angosta se apila, y la LIBRETA queda arriba de los trámites: es lo
   que Pablo abre a diario. El orden lo decide el CSS para no ensuciar el HTML. */
@media (max-width: 900px) {
  .dia-grid { grid-template-columns: 1fr; }
}

/* Tarjeta que contiene una LISTA: el aire lo pone cada renglón, no la tarjeta
   (si la tarjeta trae sus 22px, cada lista arranca hundida y se pierde media
   pantalla en márgenes). */
.card-lista { padding: 6px 0; }
.card-lista > .bloque-titulo, .card-lista .rec-cabeza, .card-lista .rec-grupo,
.card-lista .rec-vacio, .card-lista .rec-aviso, .card-lista .rec-nuevo { padding-left: 16px; padding-right: 16px; }
.bloque-titulo.sin-aire { margin: 10px 0 6px; }

/* --- Renglón de tarea / aviso (antes: tarjetón .acceso de ~140 px) --- */
.fila-mini {
  display: flex; align-items: center; gap: 12px; padding: 10px 16px;
  text-decoration: none; color: inherit; border-top: 1px solid var(--hairline-2);
}
.card-lista > .fila-mini:first-child { border-top: none; }
.fila-mini:hover { background: #fafafa; }
.fila-mini-n {
  min-width: 26px; text-align: right; font-weight: 700; font-size: 15px;
  font-variant-numeric: tabular-nums; color: var(--orange-ink); flex-shrink: 0;
}
.fila-mini-n.aviso { color: var(--warning); }
/* La bandeja al día (2-oct-2026): su puerta se queda en Mi día, pero en cero no grita. */
.fila-mini.tenue .fila-mini-n, .fila-mini.tenue .fila-mini-txt strong { color: var(--ink-3); font-weight: 600; }
.fila-mini-txt { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.4; }
.fila-mini-txt .sub { color: var(--ink-2); }
.fila-mini-ir { font-size: 12.5px; font-weight: 600; color: var(--orange-ink); white-space: nowrap; flex-shrink: 0; }
@media (max-width: 460px) { .fila-mini-ir { display: none; } }
/* --- El reparto por dueño (21-sep-2026): edad, plazo y lo atorado --- */
.fila-mini-txt .fm-edad { display: block; font-size: 11.5px; color: var(--ink-3); line-height: 1.3; margin-top: 1px; }
.fila-mini-txt .fm-jefe { display: block; font-size: 11.5px; color: var(--critical-ink); line-height: 1.3; }
.fila-mini.atorada { box-shadow: inset 3px 0 0 var(--critical); }   /* raya, no relleno (T8) */
.fila-mini.atorada .fila-mini-n { color: var(--critical-ink); }
/* El renglón de «buscando…» de un bloque que llega después (22-sep-2026): los tres
   puntos que brincan son los mismos de «Pensando…» de la ayuda. */
.fila-mini.cargando { color: var(--ink-2); cursor: default; gap: 10px; }
.fila-mini.cargando:hover { background: transparent; }
.fila-mini.cargando .puntos { display: inline-flex; gap: 4px; flex: none; }
.fila-mini.cargando .puntos span { width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange); animation: ia-brinca 1.2s infinite ease-in-out; }
.fila-mini.cargando .puntos span:nth-child(2) { animation-delay: .15s; }
.fila-mini.cargando .puntos span:nth-child(3) { animation-delay: .3s; }
.fila-mini.cargando.fallo { color: var(--critical-ink); }
details.vigilancia { margin-top: 18px; }
details.vigilancia summary { cursor: pointer; list-style: none; display: flex; gap: 8px; align-items: baseline; padding: 6px 0; }
details.vigilancia summary::-webkit-details-marker { display: none; }
details.vigilancia summary .bloque-titulo { margin: 0; }
details.vigilancia summary .sub { font-size: 12px; color: var(--ink-3); }
details.vigilancia summary::before { content: "▸"; color: var(--ink-3); font-size: 12px; }
details.vigilancia[open] summary::before { content: "▾"; }
.tabla td.num, .tabla th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* =====================================================================
   MIS RECORDATORIOS — la libreta
   ===================================================================== */
.rec-cabeza { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.rec-cabeza .bloque-titulo { margin: 10px 0 6px; padding: 0; }
.rec-cuenta {
  font-size: 12px; font-weight: 700; color: var(--orange-ink);
  background: var(--orange-soft); border-radius: 980px; padding: 2px 9px;
  font-variant-numeric: tabular-nums;
}

/* El formulario de anotar: el campo de texto manda; la fecha, el "quién" y el
   botón viven PEGADOS abajo (un formulario repartido pierde cambios en silencio
   — lección de Tipos de gasto, 2026-07-28). */
.rec-nuevo { padding-bottom: 10px; border-bottom: 1px solid var(--hairline-2); }
.rec-nuevo input[type="text"] { font-size: 14px; }
.rec-nuevo-opciones { display: flex; gap: 8px; align-items: flex-end; margin-top: 8px; flex-wrap: wrap; }
.rec-op { display: flex; flex-direction: column; gap: 4px; flex: 1 1 120px; min-width: 0;
          font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--ink-2); }
.rec-op input, .rec-op select { font-size: 13px; padding: 7px 10px; }
.rec-op-hint { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-3); }
.rec-nuevo-opciones .btn { padding: 7px 16px; font-size: 13px; flex-shrink: 0; }

.rec-vacio { font-size: 13px; color: var(--ink-2); line-height: 1.5; margin: 14px 0; }
.rec-grupo {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--ink-2); padding: 12px 16px 4px;
}
.rec-aviso { font-size: 11.5px; color: var(--ink-3); line-height: 1.5; margin: 8px 0 4px; }

/* Un renglón de la libreta: palomita · texto · borrar. */
.rec-fila {
  display: flex; align-items: flex-start; gap: 10px; padding: 8px 16px;
  border-top: 1px solid var(--hairline-2); text-decoration: none; color: inherit;
}
.rec-grupo + .rec-fila { border-top: none; }
.rec-fila:hover { background: #fafafa; }
.rec-form { margin: 0; flex-shrink: 0; display: flex; }
.rec-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rec-texto { font-size: 13.5px; line-height: 1.4; overflow-wrap: anywhere; }
.rec-meta { font-size: 11.5px; color: var(--ink-2); line-height: 1.35; }
.rec-tarde { color: var(--critical-ink); font-weight: 600; }
.rec-dequien { color: var(--orange-ink); font-weight: 600; }
.rec-estado { flex-shrink: 0; align-self: center; }

/* La palomita. Es un BOTÓN de formulario, disfrazado de casilla. El cuadrito se ve
   de 18 px, pero el ÁREA TOCABLE es de 44x44 (el `::after` invisible de abajo): con
   18 px de blanco nadie le atina con el pulgar, y ésta es la acción que más se usa
   en toda la libreta. */
.rec-check {
  position: relative;
  width: 18px; height: 18px; margin-top: 2px; padding: 0; flex-shrink: 0;
  border: 1.5px solid var(--stone-light); border-radius: 6px; background: #fff;
  cursor: pointer; font-size: 12px; line-height: 1; color: transparent;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .15s, background .15s;
}
.rec-check::after { content: ""; position: absolute; inset: -13px; }
.rec-check:hover { border-color: var(--orange); }
.rec-check:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.rec-check.puesto { background: var(--success); border-color: var(--success); color: #fff; font-weight: 700; }
.rec-fila.atrasado .rec-check { border-color: rgba(224,53,43,.45); }

/* La × de borrar: discreta, pero VISIBLE. En var(--stone-light) (#E8E5E1) era un
   fantasma sobre blanco — un control que nadie encuentra no existe. --ink-3 cumple
   contraste AA y sigue sin competir con la palomita, que es la acción principal. */
.rec-borrar {
  border: none; background: none; cursor: pointer; flex-shrink: 0;
  /* El padding ES el área tocable (~34x34): la × mide 17 px y sin esto solo se
     alcanza con el mouse. Menos que la palomita a propósito — borrar no debe ser
     más fácil de tocar por accidente que palomear. */
  padding: 8px 10px; margin: -8px -6px -8px 0;
  font-size: 17px; line-height: 1; color: var(--ink-3); font-family: inherit;
  transition: color .15s;
}
.rec-borrar:hover { color: var(--critical-ink); }
.rec-borrar:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; border-radius: 6px; }

/* Palomeado: tachado y en gris, pero LEGIBLE (es el avance del día, no basura). */
.rec-fila.hecho .rec-texto { text-decoration: line-through; color: var(--ink-2); }

/* «Lo que encargué» y «Mis trámites»: sin palomita (no son tuyos para palomear). */
.rec-fila.enc { align-items: center; }

.rec-mas { border-top: 1px solid var(--hairline-2); }
.rec-mas > summary {
  cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--orange-ink);
  padding: 9px 16px; list-style: none;
}
.rec-mas > summary::-webkit-details-marker { display: none; }
.rec-mas > summary:hover { text-decoration: underline; }
.rec-mas .rec-fila:first-of-type { border-top: 1px solid var(--hairline-2); }

/* El estado vacío del buzón, DENTRO de la columna de Mi día: los 60 px de aire y el
   emoji de 46 px están pensados para una página completa; en una columna de dos, se
   comían media pantalla al lado de la libreta. Aquí se encoge (la libreta sigue
   teniendo su propio vacío, que es el que invita a anotar). */
.dia-izq .estado-vacio { padding: 26px 18px; }
.dia-izq .estado-vacio .emoji { font-size: 30px; }
.dia-izq .estado-vacio h2 { font-size: 17px; margin: 8px 0 4px; }
.dia-izq .estado-vacio p { font-size: 13px; max-width: 40ch; margin-bottom: 0; }

/* Este bloque existía para que `.no-mayus` pudiera ganarle a la regla que ponía en
   MAYÚSCULAS todo `input`: aquella regla llevaba ocho `:not(...)` encima y pesaba
   tanto que ninguna excepción por clase la vencía sin `!important`.
   Desde el 2026-08-01 los campos de captura ya no se pintan en mayúsculas (ver el
   bloque «MAYÚSCULAS: de regla general a OPT-IN» arriba), así que no queda nada a
   qué ganarle. Se conserva la regla —sin `!important`, que ya no hace falta— porque
   69 plantillas siguen escribiendo `.no-mayus` en sus campos: quitarla de golpe sería
   barrer 203 usos en la misma tanda que el rediseño, y esas dos cosas se revisan por
   separado. No pinta nada nuevo: apaga algo que ya está apagado. */
.contenido .no-mayus input,
.contenido .no-mayus select,
.contenido .no-mayus textarea,
.contenido input.no-mayus,
.contenido select.no-mayus,
.contenido textarea.no-mayus { text-transform: none; }

/* --- Renglón de «Esperan tu firma» (un trámite, dos líneas) --- */
.fila-firma {
  display: flex; align-items: center; gap: 14px; padding: 11px 16px;
  text-decoration: none; color: inherit; border-top: 1px solid var(--hairline-2);
}
.card-lista > .fila-firma:first-child { border-top: none; }
.fila-firma:hover { background: #fafafa; }
.ff-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ff-linea { font-size: 13.5px; line-height: 1.35; }
.ff-folio { color: var(--ink-2); font-variant-numeric: tabular-nums; margin-right: 4px; }
.ff-det { font-size: 12.5px; color: var(--ink-2); line-height: 1.35; overflow-wrap: anywhere; }
.ff-quien { font-size: 11.5px; color: var(--ink-3); line-height: 1.3; }
/* El dinero conserva su ranura propia: aunque no haya tabla, los montos siguen
   alineados uno debajo de otro (§4.10b, alineación contable). */
.ff-monto {
  min-width: 104px; text-align: right; flex-shrink: 0;
  font-size: 13.5px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.ff-sin-tc { font-size: 11px; font-weight: 500; color: var(--warning); }
.ff-ir { font-size: 12.5px; font-weight: 600; color: var(--orange-ink); white-space: nowrap; flex-shrink: 0; }
@media (max-width: 560px) {
  .fila-firma { flex-wrap: wrap; gap: 6px 12px; }
  .ff-txt { flex: 1 1 100%; }
  .ff-monto { min-width: 0; text-align: left; }
  .ff-ir { margin-left: auto; }
}

/* ── Piezas compartidas de formularios plegados (bandeja «Por apartar», pedidos,
   entregas). Antes vivían solo en el <style> local de pedido_editar.html: la
   bandeja las usaba sin tenerlas y el bloque de desapartar salía crudo
   (revisión UX 2026-07-29). Los <style> locales que las repiten no chocan:
   declaran los mismos valores. ── */
.subt { font-size: 15px; margin: 0 0 8px; }
.caja-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end; margin-top: 10px; padding: 12px; background: var(--stone-light, #F5F3EF); border-radius: 10px; }
.caja-form input { border: 1px solid var(--hairline, #d9d6cc); border-radius: 9px; padding: 8px 10px; font-size: 14px; background: #fff; }
.caja-form input[type=number] { width: 130px; }
summary.ajustar-btn { cursor: pointer; list-style: none; display: inline-block; padding: 6px 12px; font-size: 13px; border: 1px solid var(--hairline, #d9d6cc); border-radius: 9px; color: var(--ink-2); background: #fff; }
summary.ajustar-btn::-webkit-details-marker { display: none; }
/* VARIOS botones de renglón en UNA celda (Cargos en reclamación, 6-oct-2026): «Ya lo
   reclamé · El banco lo devolvió · No procede». Cada <details> es de bloque y se
   apilaban en tres renglones de distinta altura, con el texto partido. En la celda
   `td.acciones-renglon` van en fila, enteros y parejos; el que se abre baja su
   captura debajo de la fila, no en medio de los botones. */
.tabla td.acciones-renglon { text-align: right; }
/* Cada botón es una unidad: la celda puede partir ENTRE botones (a 1400 px los tres
   no caben junto a seis columnas sin sacar la tabla del marco), nunca a la mitad de
   uno. Y van compactos, del tamaño de los demás botones de renglón de la casa. */
.tabla td.acciones-renglon details.ajustar { display: inline-block; vertical-align: top;
  white-space: nowrap; margin: 2px 0 2px 4px; }
.tabla td.acciones-renglon summary.ajustar-btn { padding: 4px 9px; font-size: 12.5px; }
.tabla td.acciones-renglon details.ajustar[open] { display: block; white-space: normal;
  text-align: left; margin-left: 0; }
.tabla td.acciones-renglon details.ajustar[open] > summary { display: inline-block; }
@media (max-width: 640px) {
  .tabla td.acciones-renglon { text-align: left; }
}
/* El subtítulo gris también dentro de tarjetas (la lección «.sub no pinta sola»). */
.card .sub, .tarjeta .sub { color: var(--ink-2); font-size: 13.5px; }
@media (max-width: 640px) {
  .caja-form input { font-size: 16px; }
  .caja-form .rg-campo { min-width: 100%; }
}

/* =====================================================================
   EL BLANCO DEL DEDO — 44 px de alto mínimo en teléfono (2026-08-02)
   =====================================================================
   Cazado caminando el ERP a 390 px, que es el ensayo que faltaba. Tres
   controles de la barra y del riel se quedaron chicos y NINGUNA prueba lo ve
   (el CSS no se ejecuta en la suite):

       ☰ abrir el menú ........ 30 × 35 px
       Cerrar sesión .......... 29 × 34 px
       ▾ desplegar un módulo .. 39 × 30 px  (ocho de ellos)

   Importa más de lo que suena: en el teléfono el ☰ es LA puerta —sin él no se
   navega a ningún lado— y es justo la zona donde vivió el peor defecto de la
   historia del ERP, cuando la barra se salía 170 px y «Cerrar sesión» quedaba
   fuera de alcance. Ahí llega, pero llegaba a un blanco de 29 px.

   44 px es el mínimo de Apple y el que ya usan los botones de los papeles de
   Mely; aquí se homologa. El tamaño VISUAL no cambia: el blanco crece con
   relleno, así que la barra se ve igual y el dedo sí atina.

   ⚠️ Y LA TABLET SE HABÍA QUEDADO FUERA (revisión de UX §6, 2026-08-15). La
   regla nació mirando el teléfono y se escribió a 640 px — pero el riel del menú
   se esconde desde **900 px** (ver «Móvil/tablet: el riel es un CAJÓN»). O sea:
   entre 641 y 900 px —un iPad de pie, una tablet de almacén— el ☰ vuelve a ser la
   ÚNICA puerta del ERP y medía 35 × 30. Los tres controles del riel y de la barra
   suben a su propio bloque de 900, que es exactamente el rango en el que el menú
   está colapsado; lo demás (botones, campos, chips) se queda en 640, donde nació.
   Con él viaja el `min-height` del `.lente-pill` —el control que decide QUÉ
   EMPRESA estás viendo—, que tenía el mismo hueco desde el otro lado: vivía en el
   bloque de 620 px de `mely_piezas.css`. La barra no se deforma: `header.topbar`
   mide 60 px fijos y centra su contenido, así que un blanco de 44 px cabe dentro.
   ===================================================================== */
@media (max-width: 900px) {
  .nav-toggle, .nav-logout { min-height: 44px; min-width: 44px;
                             display: inline-flex; align-items: center; justify-content: center; }
  .nv-chev { min-height: 44px; min-width: 44px; width: 44px; }
  /* El cabezal del cajón es la ÚNICA forma de llegar a los nueve catálogos
     que viven dentro. En teléfono, un blanco de 30 px se falla; va al mismo
     44 px que el resto de los controles del riel. */
  .nv-cajon-cab { min-height: 44px; }
  .lente-pill { min-height: 44px; }
}

@media (max-width: 640px) {
  /* Y lo mismo para TODO lo que se toca dentro de la pantalla (2026-08-02, segunda
     pasada del ensayo). En computadora un botón de 38 px se atina con el ratón; en
     el teléfono se falla y se pica lo de al lado — y varios de estos abren un
     formulario de dinero. Medidos a 390 px antes de esta regla:

         Registrar nota de crédito . 38     Anular ................... 32
         Corregir fecha ........... 38     Anular la nota ........... 26
         Corregir el adelanto ..... 37     Volver a cotejar ......... 37

     Sube el ALTO, no la letra: la pantalla se ve igual, el blanco crece. */
  .btn, .btn-liga, summary.ajustar-btn {
    min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }

  /* Y LOS CAMPOS TAMBIÉN SE TOCAN (2026-08-03). La regla de arriba nació mirando
     botones, así que los `select` y los `input` se quedaron fuera: medían 40-42 px.
     Se cazó al meter «¿Cómo llegó este camión?» a Recibir mercancía — un desplegable
     de 42 px en la pantalla donde un almacenista trabaja de pie, con el teléfono en
     una mano y una caja en la otra.

     Sube el ALTO MÍNIMO, no la letra ni el relleno: en escritorio no cambia nada
     (esta regla vive dentro de la media query del teléfono) y en teléfono el campo se
     ve igual de grande, solo que el dedo tiene dónde caer. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]),
  select, textarea {
    min-height: 44px;
  }

  /* Y LAS PALOMITAS DE UNA TABLA (2026-08-04, tanda 3 de la corrida). Medían
     13 px — un tercio del blanco del dedo. Se toleraba mientras eran un adorno;
     desde que la corrida de pagos se ARMA palomeando, son EL control de la
     pantalla que se toca, y es el mismo razonamiento que subió los chips.

     ⚠️ Agrandar el `input` a 44 px pintaría un cuadro enorme. Lo que crece es el
     `<label>` que lo envuelve: el label ES el blanco (alterna la palomita de
     forma nativa, sin una línea de JS) y la palomita se ve igual de siempre. */
  .tabla label.palomita {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px; margin: -11px 0; cursor: pointer;
  }

  /* Y LOS CHIPS DE FILTRO (2026-08-04, R-64) SE MUDARON. Vivían aquí, a 640 px,
     y también arriba sin media query —dos copias de lo mismo—. Desde el
     2026-09-09 viven UNA sola vez, con las tablas y las migas, en el bloque
     «LOS BLANCOS DE DEDO…», que además alcanza la tablet. Buscar
     `.filtros-chips a` ahí. */
}

/* ========================================================================
   EL VALE DE MUESTRAS · la pantalla donde se firma   (R-110/R-111, 2026-08-20)
   ------------------------------------------------------------------------
   LA CAUSA, dicha por Pablo mirando la pantalla: «se hace difícil de leer».
   Lo que había era una tabla de seis columnas estirada a todo lo ancho. En un
   monitor de 1900 px el nombre de la caja quedaba a más de mil píxeles de su
   cantidad: el ojo tenía que cruzar la pantalla entera para juntar «Chinatown»
   con «5». Una tabla ancha sirve para veinte renglones que se comparan entre
   sí; un vale trae tres y lo que se compara es la caja con SU número.

   Por eso el renglón se lee como un recibo: la CANTIDAD primero y grande, la
   caja a su lado, y lo secundario —clave, lote, ubicación— debajo en chico,
   dentro del mismo golpe de vista.

   ⚠️ `minmax(0, 1fr)` y no `1fr` pelón: un `1fr` lo estira su hijo más ancho
   —aquí, el nombre larguísimo de una impresión— y el riel derecho se sale de
   la pantalla. Ya mordió antes (ver la ficha en pasos del catálogo).
   ==================================================================== */
.vale-b { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 18px; align-items: start; }
.vale-centro { min-width: 0; }
/* El riel se queda a la vista al bajar: en un vale largo, el botón de firmar no
   se debe perder por arriba. `top` deja libre la barra pegajosa del ERP. */
.vale-lado { min-width: 0; position: sticky; top: 12px; }
.vale-lado .card { margin-bottom: 14px; }

.vale-renglones { border-top: 1px solid var(--hairline); margin-top: 6px; }
.vale-b .rgl {
  display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 0 16px;
  align-items: baseline; padding: 14px 2px; border-bottom: 1px solid var(--hairline-2);
}
.vale-b .rgl .cant,
.vale-total .cant {
  font-size: 26px; font-weight: 700; line-height: 1; color: var(--ink);
  text-align: right; font-variant-numeric: tabular-nums;
}
.vale-b .rgl .cant small,
.vale-total .cant small {
  display: block; margin-top: 5px; font-size: 12px; font-weight: 600; color: var(--ink-2);
}
.vale-b .rgl-que { min-width: 0; }
.vale-b .rgl .caja { font-size: 17px; font-weight: 600; line-height: 1.3; color: var(--ink); }
.vale-b .rgl .de-donde { margin-top: 4px; font-size: 13px; line-height: 1.4; color: var(--ink-2); }
.vale-b .rgl .de-donde b { font-weight: 600; }

.vale-total {
  display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 0 16px;
  align-items: baseline; padding: 14px 2px 0;
}
.vale-total .cant { font-weight: 800; }
.vale-total .qq {
  font-size: 13px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-2);
}

/* Las firmas, sin tabla: son dos renglones y una tabla de dos filas es andamio. */
.firma-renglon { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 9px 0; border-bottom: 1px solid var(--hairline-2); }
.firma-renglon:last-of-type { border-bottom: 0; }
.firma-rol { font-size: 14px; font-weight: 600; color: var(--ink); flex: 1 1 auto; min-width: 0; }
.firma-quien { flex: 1 1 100%; font-size: 12.5px; color: var(--ink-2); }

@media (max-width: 900px) {
  /* En teléfono y tablet angosta el riel se acomoda DEBAJO, en una sola columna:
     lo que sale se lee primero, y la firma queda al final, que es el orden en que
     se decide. */
  .vale-b { grid-template-columns: minmax(0, 1fr); }
  .vale-lado { position: static; }
  .vale-b .rgl, .vale-total { grid-template-columns: 68px minmax(0, 1fr); }
  .vale-b .rgl .cant, .vale-total .cant { font-size: 22px; }
  .vale-b .rgl .caja { font-size: 16px; }
}

/* ========================================================================
   EL VALE DE MUESTRAS · la captura   (R-110, 2026-08-20)
   ------------------------------------------------------------------------
   Cada caja del vale vive en su propio bloque, con su tabla de lotes adentro.
   El bloque se ve como una tarjeta más floja que `.tarjeta`: son HERMANOS que
   se repiten, y ponerles el mismo peso que a las secciones del vale haría que
   la pantalla pareciera diez pantallas apiladas.
   ==================================================================== */
.bloque-titulo.bt-suelto { margin: 24px 0 10px; }

.caja-vale {
  background: var(--card); border: 1px solid var(--hairline);
  border-radius: 14px; padding: 14px; margin-bottom: 12px;
}
.cv-cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.cv-num {
  font-size: 12px; font-weight: 600; color: var(--ink-2);
  background: var(--card-2); border: 1px solid var(--hairline);
  border-radius: 999px; padding: 5px 11px; white-space: nowrap;
}
.cv-quitar { margin-left: auto; }
.cv-lotes { margin-top: 12px; }

.mas-cajas { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 2px 0 20px; }

@media (max-width: 560px) {
  /* En teléfono el botón de quitar se va al renglón de abajo, a todo lo ancho
     del pulgar, en vez de quedar apretado contra el número de la caja. */
  .cv-quitar { margin-left: 0; width: 100%; }
}

/* ══════════════════════════════════════════════════════════════════════════
   EL CENSO DE ARRANQUE (2026-08-20)
   ──────────────────────────────────────────────────────────────────────────
   Cada área trae EL GRÁFICO QUE CONTESTA SU PREGUNTA, no el mismo repetido:
   cuadre = barras enfrentadas · cartera y aduana = tira apilada ·
   catálogos = cobertura · contabilidad = línea de meses · bancos = SIN
   gráfico (son pocas cuentas y una lista dice más, ley 05).

   El color significa UNA sola cosa (ley 04): rojo = falta y sin eso no se
   puede decidir · ámbar = a medias · verde = completo · gris = no existe
   todavía, que NO es un hueco de captura.
   ══════════════════════════════════════════════════════════════════════════ */
.censo-falta   { --censo: #E5484D; }
.censo-parcial { --censo: #E8940C; }

.censo-h2  { margin:0; font-size:1.08rem; }
.censo-linea { margin:4px 0 10px; }

/* La tira: TODO el ERP en una línea, se lee en un segundo */
.censo-tira-card { margin-bottom:26px; }
.censo-tira { display:flex; height:34px; border-radius:9px; overflow:hidden;
              margin:6px 0 10px; box-shadow:0 1px 2px rgba(0,0,0,.08); }
.censo-tira span { display:flex; align-items:center; justify-content:center;
                   color:#fff; font-size:.78rem; font-weight:600;
                   letter-spacing:.02em; min-width:0; white-space:nowrap; }
.censo-tira .t-listo   { background:#3A7D44; }
.censo-tira .t-parcial { background:#E8940C; }
.censo-tira .t-falta   { background:#E5484D; }
.censo-tira .t-nada    { background:#C9C6C1; color:#4A4843; }
.censo-tira-pie { display:flex; gap:15px; flex-wrap:wrap; font-size:.82rem;
                  color:var(--ink-2); margin-bottom:4px; }
.censo-tira-pie i { display:inline-block; width:10px; height:10px;
                    border-radius:3px; margin-right:5px; font-style:normal; }

.tono-listo      { background:#3A7D44; }
.tono-parcial    { background:#E8940C; }
.tono-falta      { background:#E5484D; }
.tono-sin_modulo { background:#C9C6C1; }
.tono-txt-listo      { color:#3A7D44; }
.tono-txt-parcial    { color:#B36B00; }
.tono-txt-falta      { color:#C03B3F; }
.tono-txt-sin_modulo { color:var(--ink-2); }

/* El bloque de un área */
.censo-area { margin-bottom:30px; }
.censo-area-cab { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
                  margin:0 0 12px; }
.censo-dic { font-size:.86rem; font-weight:600; }
.censo-par { display:grid; grid-template-columns:1.2fr .8fr; gap:18px;
             align-items:start; }

/* EL CUADRE: dos barras enfrentadas — el hueco se VE como espacio vacío */
.censo-cuadre + .censo-cuadre { margin-top:18px; padding-top:16px;
                                border-top:1px solid var(--line, #EDEBE8); }
.cc-fila { display:grid; grid-template-columns:112px 1fr; gap:12px;
           align-items:center; margin-bottom:9px; }
.cc-et  { font-size:.82rem; color:var(--ink-2); text-align:right; line-height:1.3; }
.cc-pie { font-size:.74rem; }
.cc-pista { position:relative; background:#EFEDEA; border-radius:6px; height:26px; }
.cc-barra { position:absolute; inset:0 auto 0 0; border-radius:6px; display:flex;
            align-items:center; padding-left:9px; color:#fff; font-size:.8rem;
            font-weight:600; white-space:nowrap; overflow:hidden; }
.cc-erp   { background:#4A4843; }
.cc-fuera { background:#8E8B85; }
.cc-cero  { position:absolute; left:11px; top:50%; transform:translateY(-50%);
            font-size:.8rem; color:#8A8781; font-style:italic; }
.cc-hueco { margin:6px 0 0; padding:9px 12px; background:#FFF0F0;
            border-left:4px solid #E5484D; border-radius:0 8px 8px 0;
            font-size:.92rem; }
.cc-hueco b { color:#B3272B; }
.cc-hueco.ok { background:#F1F8F2; border-left-color:#3A7D44; }
.cc-hueco.ok b { color:#2C6135; }
.cc-fuente { margin:7px 0 0; font-size:.79rem; color:#8A8781; }
.cc-fuente.centrado { text-align:center; }
.cc-sin-externa { margin:8px 0 0; padding:10px 12px; background:#FFF4E8;
                  border-left:4px solid var(--orange, #FD6B00);
                  border-radius:0 8px 8px 0; font-size:.9rem; }
/* Lo operado DESPUÉS del corte se dice, pero FUERA del marcador: si entrara, la
   barra subiría sola con los días y fingiría un avance que nadie trabajó. */
.censo-aparte { margin:10px 0 0; padding:8px 11px; background:#F5F4F2;
                border-radius:8px; font-size:.86rem; color:var(--ink); }

.censo-avance { display:flex; align-items:center; gap:10px; margin:11px 0 0;
                font-size:.86rem; color:var(--ink-2); }
.av-pista { flex:1; background:#EFEDEA; border-radius:5px; height:8px; overflow:hidden; }
.av-llena { height:100%; background:#3A7D44; border-radius:5px; }

/* COBERTURA: la pregunta es «¿qué tanto está?», y eso es un porcentaje */
.censo-filas { margin-top:14px; }
.censo-rotulo { margin:14px 0 6px; font-size:.86rem; color:var(--ink-2); }
.censo-cob { display:grid; grid-template-columns:1fr 118px 62px; gap:11px;
             align-items:center; padding:8px 0; }
.censo-cob + .censo-cob { border-top:1px solid #F1EFEC; }
.cb-et { font-size:.92rem; line-height:1.35; }
.cb-pista { background:#EFEDEA; border-radius:5px; height:9px; overflow:hidden; }
.cb-llena { height:100%; border-radius:5px; background:#8E8B85; }
.cb-llena.tono-listo   { background:#3A7D44; }
.cb-llena.tono-parcial { background:#E8940C; }
.cb-llena.tono-falta   { background:#E5484D; }
.cb-pct { text-align:right; font-size:.86rem; font-weight:600;
          font-variant-numeric:tabular-nums; }

/* Un dato suelto: rótulo a la izquierda, cifra a la derecha */
.censo-dato { display:grid; grid-template-columns:1fr auto; gap:12px;
              align-items:baseline; padding:8px 0; }
.censo-dato + .censo-dato { border-top:1px solid #F1EFEC; }
.cd-et  { font-size:.92rem; line-height:1.35; }
.cd-val { font-variant-numeric:tabular-nums; white-space:nowrap; font-weight:600;
          min-width:0; overflow-wrap:anywhere; }
.censo-dato.alerta .cd-val { color:#C03B3F; }
/* Cuando el «valor» es una FRASE y no una cifra (las áreas que todavía no
   existen), el molde de dato numérico la maltrata: la manda a la derecha y en
   negritas, como si fuera un número. Aquí el texto se lee como texto. */
.censo-dato.texto { grid-template-columns:200px 1fr; align-items:start; }
.censo-dato.texto .cd-val { font-weight:400; white-space:normal; text-align:left;
                            color:var(--ink-2); font-variant-numeric:normal; }
.censo-dato.texto .cd-et { font-weight:600; }

/* SEMÁFORO: se ve, no se lee */
.censo-semaforo { display:flex; height:22px; border-radius:6px; overflow:hidden;
                  margin:10px 0 7px; }
.censo-semaforo span { min-width:3px; }
.sf-1 { background:#8FBF97; } .sf-2 { background:#E8C86A; }
.sf-4 { background:#D9603F; } .sf-5 { background:#B3272B; }
.censo-leyenda { display:flex; gap:13px; flex-wrap:wrap; font-size:.79rem;
                 color:var(--ink-2); }
.censo-leyenda i { display:inline-block; width:9px; height:9px; border-radius:2px;
                   margin-right:4px; font-style:normal; }

/* LOS MESES: el tiempo va en línea */
.censo-meses { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 6px; }
.censo-meses div { flex:1 1 62px; text-align:center; padding:9px 4px;
                   border-radius:8px; font-size:.72rem; }
.censo-meses div b { display:block; font-size:.78rem; }
.censo-meses div span { opacity:.85; }
.m-cerrado   { background:#3A7D44; color:#fff; }
.m-reabierto { background:#E8940C; color:#fff; }
.m-en_cierre { background:#E8C86A; color:#4A4843; }
.m-abierto   { background:#FFF; border:2px dashed #C9C6C1; color:var(--ink-2); }

/* La columna de la derecha: qué preguntar y qué hacer */
.censo-preg { background:var(--card); border:1px solid var(--line, #E7E4E0);
              border-radius:12px; padding:15px 17px; }
.censo-preg h3 { margin:0 0 3px; font-size:.8rem; letter-spacing:.04em;
                 text-transform:uppercase; color:var(--ink-2); }
.censo-preg .aquien { font-size:.85rem; color:var(--ink-2); margin:0 0 11px; }
.censo-preg ol { margin:0 0 12px; padding-left:17px; font-size:.92rem; line-height:1.55; }
.censo-preg li + li { margin-top:6px; }
.censo-btn { display:block; text-align:center; padding:9px; border-radius:9px;
             background:#FFF4E8; border:1px solid #FFC48A; color:#B34700;
             font-size:.88rem; font-weight:600; text-decoration:none; }
.censo-btn:hover { background:#FFE9D2; }

/* ── TELÉFONO ──────────────────────────────────────────────────────────────
   A 390 px la etiqueta peleaba el ancho con la cifra y salía UNA PALABRA POR
   RENGLÓN. Aquí el rótulo toma la línea completa y el número se va abajo, a la
   derecha, que es donde el ojo lo busca. La tira de arriba pierde su texto
   (los tramos angostos no caben) y se lee por el pie de colores.            */
@media (max-width: 900px){
  .censo-par { grid-template-columns:1fr; }
}
@media (max-width: 560px){
  .cc-fila { grid-template-columns:1fr; gap:3px; }
  .cc-et { text-align:left; }
  .censo-cob { grid-template-columns:1fr 62px; row-gap:6px; }
  .censo-cob .cb-pista { grid-column:1 / -1; order:3; }
  .censo-dato, .censo-dato.texto { grid-template-columns:1fr; }
  .cd-val { text-align:right; }
  .censo-dato.texto .cd-val { text-align:left; margin-top:3px; }
  .censo-tira span { font-size:0; }
  .censo-meses div { flex:1 1 46px; }
}

/* El total del ÁMBITO en la Consulta, bajo las dos tablas gemelas (2026-08-20).
   No es un párrafo de prosa: es el renglón del gran total, y por eso se ve como
   un pie de tabla —etiqueta a la izquierda, cifra a la derecha— y no como una
   explicación. Suma DINERO y nunca piezas: sumar «piezas de caja» con «piezas
   de cinta» daría un número que no significa nada (§4.7). */
/* EXISTENCIAS EN EL TELÉFONO (Pablo, 23-sep-2026): cada caja ocupaba una pantalla entera
   (código, producto, total, unidad, disponible…) y encontrar una era bajar y bajar. En el
   teléfono: un renglón por caja con producto · total · disponible, y los cinco botones de
   arriba juntos en «Más». Al tocar la caja se abre su detalle con todo lo demás. En la
   computadora no cambia nada. */
.acciones-mas > summary { display: none; }
.acciones-mas-lista { display: contents; }
@media (max-width: 640px) {
  details.acciones.acciones-mas { display: block; margin: 0 0 10px; }
  .acciones-mas > summary { display: inline-flex; list-style: none; cursor: pointer; }
  .acciones-mas > summary::-webkit-details-marker { display: none; }
  .acciones-mas > summary::after { content: " ▾"; }
  .acciones-mas[open] > summary::after { content: " ▴"; }
  .acciones-mas-lista { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 8px; }
  /* Anchos FIJOS: producto la mitad, total y disponible un cuarto cada uno. Con el
     acomodo automático los encabezados de número pedían más que el teléfono. */
  .tabla.exis-compacta { width: 100%; table-layout: fixed; }
  .tabla.exis-compacta th:not([data-col]), .tabla.exis-compacta td:not([data-col]) { width: 50%; }
  .tabla.exis-compacta [data-col="total"], .tabla.exis-compacta [data-col="disponible"] { width: 25%; }
  .tabla.exis-compacta th, .tabla.exis-compacta td { padding-left: 8px; padding-right: 8px; overflow-wrap: anywhere; }
  .tabla.exis-compacta thead th { font-size: 10.5px; letter-spacing: .2px; }
  /* El total del pie trae una cifra por unidad («290,038 PZA · 12 MIL»): que baje de
     renglón en vez de empujar la tabla fuera de su tarjeta. */
  .tabla.exis-compacta tfoot td, .tabla.exis-compacta tfoot td * { white-space: normal; }
  .tabla.exis-compacta thead [data-col]:not([data-col="total"]):not([data-col="disponible"]),
  .tabla.exis-compacta tbody [data-col]:not([data-col="total"]):not([data-col="disponible"]),
  .tabla.exis-compacta tfoot [data-col]:not([data-col="total"]):not([data-col="disponible"]) { display: none; }
  /* El «Columnas» no aplica: en el teléfono las columnas ya son las tres de siempre. */
  .tabla-scroll:has(.exis-compacta) + .cols-control, .cols-control:has(+ .tabla-scroll .exis-compacta) { display: none; }
}
.existencias-total { display:flex; justify-content:space-between; align-items:baseline;
                     gap:16px; margin:18px 0 0; padding-top:13px;
                     border-top:2px solid var(--ink, #1D1D1F); font-size:.93rem; }
.existencias-total b { font-size:1.05rem; white-space:nowrap;
                       font-variant-numeric:tabular-nums; }
@media (max-width: 560px){
  .existencias-total { flex-direction:column; gap:4px; }
  .existencias-total b { align-self:flex-end; }
}

/* ══ MI SEGUNDO CEREBRO (tanda 3, 2026-08-23 — estilo aprobado en maqueta) ══
   La plática privada del director: hilo + captura + el lado de pláticas y
   acuerdos. En teléfono el lado baja abajo del hilo. */
.cerebro-pagina { display: grid; grid-template-columns: minmax(0, 1fr) 300px;
  gap: 16px; align-items: start; max-width: 1060px; }
.cerebro { background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 22px 24px; }
.cerebro-encabezado { display: flex; align-items: center; gap: 12px; }
.cerebro-encabezado h1 { margin: 0; font-size: 21px; letter-spacing: -.2px; }
.cerebro-glifo { width: 38px; height: 38px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--orange-bright), var(--orange));
  display: flex; align-items: center; justify-content: center; font-size: 19px;
  box-shadow: 0 2px 6px rgba(253,107,0,.35); }
.cerebro-nueva { margin-left: auto; }
.cerebro-priv { display: inline-flex; align-items: center; gap: 6px;
  margin: 10px 0 6px; font-size: 12.5px; color: var(--ink-2);
  background: #f6f6f8; border: 1px solid var(--hairline); border-radius: 999px;
  padding: 4px 12px; }
.hilo { max-height: 62vh; overflow-y: auto; padding: 6px 2px; margin-top: 8px;
  display: flex; flex-direction: column; gap: 12px; }
.turno-mio { align-self: flex-end; max-width: 82%; background: var(--orange-soft);
  border: 1px solid var(--orange-line); border-radius: 14px 14px 4px 14px;
  padding: 10px 14px; font-size: 15px; line-height: 1.55; overflow-wrap: anywhere; }
.turno-ia { align-self: flex-start; max-width: 92%; background: #fafafa;
  border: 1px solid var(--hairline); border-radius: 14px 14px 14px 4px;
  padding: 12px 16px; }
.turno-ia p { margin: 0 0 8px; font-size: 15px; line-height: 1.6; overflow-wrap: anywhere; }
.turno-ia p:last-child { margin-bottom: 0; }
.turno-ia .fuentes { color: var(--ink-2); font-size: 12px; border-top: 1px solid var(--hairline);
  margin-top: 10px; padding-top: 8px; overflow-wrap: anywhere; }
.turno-ia .fuentes .etiqueta { font-size: 10px; font-weight: 700; letter-spacing: .6px;
  color: #a5a5aa; margin-right: 6px; }
.cerebro-vacio { color: var(--ink); background: #fafafa; border: 1px dashed var(--hairline);
  border-radius: 14px; padding: 18px; }
.cerebro-captura { display: flex; gap: 10px; margin-top: 14px; align-items: flex-end; }
.cerebro-captura textarea { flex: 1; resize: vertical; min-height: 48px;
  font-family: inherit; font-size: 16px; padding: 12px 14px; background: #f2f2f5;
  border: 1.5px solid transparent; border-radius: 12px;
  transition: background .15s, border-color .15s, box-shadow .15s; }
.cerebro-captura textarea:focus { outline: none; background: #fff;
  border-color: var(--orange); box-shadow: 0 0 0 4px var(--orange-soft); }
.cerebro-lado .temas { background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 16px 18px; margin-bottom: 14px; }
.cerebro-lado .temas h2 { margin: 0 0 10px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .5px; text-transform: uppercase; color: var(--ink-2); }
.cerebro-lado .temas a { display: block; padding: 8px 2px; font-size: 13.5px;
  color: var(--orange-ink); border-top: 1px solid var(--hairline);
  text-decoration: none; overflow-wrap: anywhere; }
.cerebro-lado .temas a:first-of-type { border-top: 0; }
.cerebro-lado .temas a.activa { font-weight: 700; }
.acuerdo-chip { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin-top: 10px; background: var(--orange-soft); border: 1px solid var(--orange-line);
  border-radius: 12px; padding: 10px 14px; font-size: 13.5px; overflow-wrap: anywhere; }
.acuerdo-chip .btn-mini { border: 1.5px solid var(--orange); background: #fff;
  color: var(--orange-ink); border-radius: 10px; padding: 6px 12px; font-size: 13px;
  font-weight: 600; cursor: pointer; font-family: inherit; }
.acuerdo-chip .btn-mini-gris { border-color: #d8d8dc; color: var(--ink-2); }
.acuerdo-ok { margin-top: 10px; font-size: 13px; color: #2e7d4f; background: #EAF6EE;
  border: 1px solid #cde8d6; border-radius: 10px; padding: 8px 12px; }
@media (max-width: 900px) {
  .cerebro-pagina { grid-template-columns: 1fr; }
  .hilo { max-height: 56vh; }
}

/* ══ EL CONSULTOR (tanda 4, 2026-08-23 — estilo aprobado en maqueta) ══ */
.consultor-pagina { display: grid; grid-template-columns: minmax(0, 1fr) 240px;
  gap: 16px; align-items: start; max-width: 1060px; }
.hoja { background: var(--card); border-radius: 18px; box-shadow: var(--shadow);
  padding: 28px 32px; }
.hoja h1 { margin: 0 0 2px; font-size: 23px; letter-spacing: -.3px; }
.hoja .hoja-sub { color: var(--ink-2); font-size: 13.5px; margin: 0 0 20px; }
.hoja .seccion { margin-top: 22px; }
.hoja .seccion h2 { font-size: 12.5px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--ink-2); margin: 0 0 12px; }
.hoja .hallazgo { display: flex; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--hairline); border-radius: 12px; margin-bottom: 10px;
  align-items: flex-start; }
.hoja .sello { flex: none; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; font-size: 17px; }
.hoja .sello.rojo { background: #FDEBEB; } .hoja .sello.ambar { background: #FFF8E6; }
.hoja .sello.verde { background: #EAF6EE; } .hoja .sello.gris { background: #f2f2f5; }
.hoja .hallazgo p { margin: 0 0 6px; font-size: 14.5px; line-height: 1.55;
  overflow-wrap: anywhere; }
.hoja .hallazgo p:last-child { margin-bottom: 0; }
.hoja .impacto { color: var(--ink); }
.hoja .sugerencia { color: var(--ink); }
.hoja .sugerencia .de-ia { font-size: 10.5px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase; color: var(--ink-2); }
.hoja .liga { font-size: 12.5px; }
.hoja .liga a { color: var(--orange-ink); }
.hoja .pie-honesto { margin-top: 24px; border-top: 1px solid var(--hairline);
  padding-top: 14px; font-size: 12.5px; color: var(--ink-2); line-height: 1.6; }
.consultor-lado { background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 16px 18px; }
.consultor-lado h2 { margin: 0 0 10px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .5px; text-transform: uppercase; color: var(--ink-2); }
.consultor-lado a { display: block; padding: 8px 2px; font-size: 13.5px;
  color: var(--orange-ink); border-top: 1px solid var(--hairline); text-decoration: none; }
.consultor-lado a:first-of-type { border-top: 0; }
.consultor-lado a.activa { font-weight: 700; }
@media (max-width: 900px) { .consultor-pagina { grid-template-columns: 1fr; } }

/* ── La bitácora del «?» con la capa de IA (mejora 1, 2026-09-02) ─────────────
   La pregunta larga se parte (52ch en escritorio); la respuesta de la IA va
   plegada bajo la pregunta; «Cómo le fue» lleva la pastilla y, debajo, la nota
   (tiempo y motivo). En teléfono la fila es tarjeta: la pregunta y la respuesta
   van en su propio renglón a lo ancho, y NADA lleva nowrap — con el tope de 52ch
   una pregunta larga empujaba la tarjeta fuera de la pantalla y partía el
   rótulo letra por letra (se vio en la maqueta a 390 px). */
.tabla td.pregunta { max-width: 52ch; white-space: normal; overflow-wrap: anywhere; }
.respuesta-ia { margin: 6px 0 0; font-size: 12.5px; color: var(--ink-2); }
.respuesta-ia summary { cursor: pointer; color: var(--orange-ink); font-weight: 600; }
.respuesta-ia p { margin: 6px 0 0; padding: 8px 10px; background: #f6f6f8; border-radius: 8px;
  line-height: 1.5; white-space: normal; overflow-wrap: anywhere; }
.tabla td.como { white-space: nowrap; }
.tabla td.como small, .tabla td .motivo { display: block; color: var(--ink-2); font-size: 11.5px;
  margin-top: 2px; overflow-wrap: anywhere; white-space: normal; }
@media (max-width: 640px) {
  .tabla td.pregunta { max-width: none; flex-direction: column; align-items: flex-start; text-align: left; gap: 4px; }
  .tabla td.como { white-space: normal; flex-wrap: wrap; }
  .tabla td.como small, .tabla td .motivo { width: 100%; text-align: right; }
  .respuesta-ia { width: 100%; }
}

/* ── Las claves del SAT para importar, en Categorías (2026-09-04) ────────────
   Tres campos cortos que se capturan juntos (se piden juntos al agente
   aduanal). Se apilan en su celda para no ensanchar la tabla, y en teléfono
   ocupan el ancho como cualquier otro campo. */
.claves-sat-form { display: flex; flex-direction: column; gap: 6px; min-width: 170px; }
.claves-sat-form input { width: 100%; box-sizing: border-box; }
@media (max-width: 640px) { .claves-sat-form { min-width: 0; width: 100%; } }

/* ══════════════════════════════════════════════════════════════════════════
   EL EXPEDIENTE DEL CAMIÓN — 2026-09-09
   ─────────────────────────────────────────────────────────────────────────
   Pablo, viendo la pantalla vieja: «es demasiado densa, confusa, no me gusta;
   todo eso veo en una sola pantalla sin moverme, es exagerado». Y tenía el
   número de su lado: 7 tarjetas, 37 botones y 4.4 pantallas de laptop, con lo
   ÚNICO pendiente hasta el fondo. Se rehízo con una idea: **un camión tiene un
   solo siguiente paso**, y el almacenista viene a despachar.

   Estas clases viven aquí y NO en `mely_piezas.css` a propósito: hoy las usa
   una sola pantalla. Que una SEGUNDA las necesite es la señal de volverlas
   pieza (§4c) — una sola vez, todavía no.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── ① El encabezado del viaje ─────────────────────────────────────────── */
.viaje{background:var(--card);border:1px solid var(--hairline);border-radius:20px;
  box-shadow:var(--shadow);padding:26px 28px 8px;margin-bottom:18px}
.viaje-top{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}
.viaje-id{flex:1 1 300px;min-width:0}
.viaje-id h1{font-size:30px;line-height:1.1;letter-spacing:-.02em;margin:0 0 6px;
  font-weight:680;color:var(--ink)}
.viaje-ruta{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:14px;color:var(--ink-2)}
.viaje-ruta b{color:var(--ink);font-weight:560}
.viaje-ruta .flecha{color:var(--stone);flex:0 0 auto}
.viaje-top .volver{margin-left:auto}

/* La línea del viaje: cinco hitos con la hora real de cada uno. */
.linea{display:grid;grid-template-columns:repeat(5,1fr);margin-top:26px;
  border-top:1px solid var(--hairline-2);padding-top:20px}
.hito{position:relative;text-align:center;padding-top:22px}
.hito::before{content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:12px;height:12px;border-radius:50%;background:var(--card);
  border:2px solid var(--stone-light);z-index:2}
.hito::after{content:"";position:absolute;top:5px;left:0;right:0;height:2px;
  background:var(--stone-light);z-index:1}
.hito:first-child::after{left:50%}
.hito:last-child::after{right:50%}
.hito.hecho::before{background:var(--success);border-color:var(--success)}
.hito.hecho::after{background:var(--success)}
.hito.ahora::before{background:var(--orange);border-color:var(--orange);
  box-shadow:0 0 0 5px var(--orange-soft)}
.hito.ahora::after{background:linear-gradient(90deg,var(--success) 50%,var(--stone-light) 50%)}
.hito.roto::before{background:var(--critical);border-color:var(--critical)}
.hito-t{font-size:12.5px;font-weight:600;color:var(--ink);letter-spacing:-.01em}
.hito.pend .hito-t{color:var(--ink-3);font-weight:500}
.hito-s{font-size:11.5px;color:var(--ink-3);margin-top:2px}

/* ── ② El acto: lo único que toca ahora ────────────────────────────────── */
.acto{background:var(--card);border:1px solid var(--orange-line);border-radius:20px;
  box-shadow:var(--shadow);margin-bottom:18px;overflow:hidden}
.acto-cinta{background:linear-gradient(90deg,var(--orange),var(--orange-bright));height:4px}
.acto-cuerpo{padding:24px 28px 26px}
.acto-ojo{font-size:11px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--orange-ink);margin-bottom:8px}
.acto h2{font-size:21px;line-height:1.2;margin:0 0 6px;font-weight:640;color:var(--ink);
  letter-spacing:-.015em}
.acto .dice{font-size:14px;color:var(--ink-2);margin:0 0 20px;max-width:62ch;line-height:1.5}
.acto .dice:last-child{margin-bottom:0}
.acto.alerta{border-color:#F6D9A8}
.acto.alerta .acto-cinta{background:linear-gradient(90deg,var(--warning),#FBBF24)}
.acto.alerta .acto-ojo{color:#92620A}
.acto.listo{border-color:#BFE3CC}
.acto.listo .acto-cinta{background:linear-gradient(90deg,var(--success),#5BC77C)}
.acto.listo .acto-ojo{color:#1E7A3C}
.acto.malo{border-color:#F3B4B0}
.acto.malo .acto-cinta{background:linear-gradient(90deg,var(--critical),#EF6E66)}
.acto.malo .acto-ojo{color:var(--critical-ink)}
.acto h3.sub-acto{font-size:13px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-3);font-weight:600;margin:26px 0 12px}

.cierre{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:22px;
  padding-top:20px;border-top:1px solid var(--hairline-2)}
.cierre .lado{font-size:13px;color:var(--ink-2);flex:1 1 240px;line-height:1.45}
.btn-grande{background:var(--orange);color:#fff;border:0;border-radius:var(--radius-btn);
  padding:14px 26px;font-size:15px;font-weight:620;cursor:pointer;line-height:1.2;
  box-shadow:0 1px 2px rgba(253,107,0,.28),0 8px 20px rgba(253,107,0,.20);
  transition:transform .12s ease, box-shadow .12s ease}
.btn-grande:hover{transform:translateY(-1px);
  box-shadow:0 2px 4px rgba(253,107,0,.3),0 12px 26px rgba(253,107,0,.26)}
.btn-grande:disabled{background:var(--stone-light);color:var(--ink-3);box-shadow:none;
  cursor:not-allowed;transform:none}

/* El motivo que devolvió el PAC, citado tal cual. */
.pac-dijo{background:var(--card-2);border-left:3px solid var(--warning);border-radius:0 10px 10px 0;
  padding:12px 16px;font-size:13.5px;color:var(--ink-2);margin:0 0 20px;line-height:1.5}
.pac-dijo b{color:var(--ink);font-weight:600}

/* ── ③ De dónde a dónde ────────────────────────────────────────────────── */
.ruta{background:var(--card);border:1px solid var(--hairline);border-radius:20px;
  box-shadow:var(--shadow);padding:22px 28px;margin-bottom:18px}
.ruta-grid{display:grid;grid-template-columns:1fr auto 1fr;gap:20px;align-items:center}
.punto .rot{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);
  font-weight:600;margin-bottom:5px}
.punto .lugar{font-size:15px;font-weight:560;color:var(--ink);line-height:1.35}
.punto .cp{font-size:12.5px;color:var(--ink-3);margin-top:3px}
.punto.der{text-align:right}
.trecho{text-align:center;color:var(--ink-3);font-size:12.5px;min-width:120px}
.trecho .barra{height:2px;background:var(--stone-light);border-radius:2px;margin:8px 0;position:relative}
.trecho .barra::after{content:"";position:absolute;right:-1px;top:-3px;border:4px solid transparent;
  border-left-color:var(--stone-light)}
.trecho b{color:var(--ink-2);font-weight:600}

/* ── ④ Los papeles, como documentos ────────────────────────────────────── */
.papeles-camion{margin-bottom:18px}
.papeles-camion h3{font-size:12px;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3);
  font-weight:600;margin:0 0 12px 4px}
.docs{display:grid;grid-template-columns:repeat(auto-fill,minmax(224px,1fr));gap:12px}
.doc{background:var(--card);border:1px solid var(--hairline);border-radius:14px;padding:16px;
  display:flex;gap:13px;align-items:flex-start;text-decoration:none;
  transition:border-color .12s ease, box-shadow .12s ease, transform .12s ease}
.doc:hover{border-color:var(--orange-line);box-shadow:var(--shadow);transform:translateY(-1px)}
.doc .hoja{flex:0 0 auto;width:34px;height:40px;border-radius:5px;background:var(--card-2);
  border:1px solid var(--hairline);position:relative}
.doc .hoja::before{content:"";position:absolute;top:0;right:0;border:7px solid transparent;
  border-top-color:var(--stone-light);border-right-color:var(--stone-light)}
.doc .hoja::after{content:"";position:absolute;left:7px;right:7px;top:16px;height:2px;
  background:var(--hairline);box-shadow:0 6px 0 var(--hairline),0 12px 0 var(--hairline)}
.doc.cp .hoja{background:var(--orange-soft);border-color:var(--orange-line)}
.doc .qq{display:block;min-width:0}
.doc .n{display:block;font-size:14px;font-weight:580;color:var(--ink);line-height:1.3}
.doc .d{display:block;font-size:12px;color:var(--ink-3);margin-top:3px;line-height:1.4}
.doc .folio{display:block;font-size:11.5px;color:var(--ink-2);margin-top:5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.doc-faltante{border-style:dashed;background:transparent;box-shadow:none;cursor:default}
.doc-faltante:hover{transform:none;border-color:var(--hairline);box-shadow:none}
.doc-faltante .n{color:var(--ink-3);font-weight:520}
.doc-extras{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}

/* ── ⑤ El resto, en pestañas ───────────────────────────────────────────── */
.resto{background:var(--card);border:1px solid var(--hairline);border-radius:20px;
  box-shadow:var(--shadow);overflow:hidden;margin-bottom:18px}
.tabs{display:flex;gap:2px;padding:6px;background:var(--card-2);
  border-bottom:1px solid var(--hairline);overflow-x:auto}
.tab{flex:0 0 auto;border:0;background:transparent;font-size:13.5px;font-weight:540;
  color:var(--ink-2);padding:9px 16px;border-radius:10px;cursor:pointer;white-space:nowrap;
  min-height:40px}
.tab:hover{color:var(--ink)}
.tab[aria-selected="true"]{background:var(--card);color:var(--ink);box-shadow:0 1px 2px rgba(0,0,0,.06)}
.panel{padding:24px 28px 28px}
.panel>h4{font-size:13px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3);
  font-weight:600;margin:0 0 14px}
.aire{margin-top:26px;padding-top:22px;border-top:1px solid var(--hairline-2)}

/* Plegable discreto, con su flecha. */
details.plieg{margin-top:20px;border-top:1px solid var(--hairline-2);padding-top:18px}
details.plieg>summary{cursor:pointer;font-size:13.5px;color:var(--ink-2);list-style:none;
  display:flex;align-items:center;gap:8px;min-height:40px}
details.plieg>summary::-webkit-details-marker{display:none}
details.plieg>summary::before{content:"›";font-size:17px;color:var(--stone);
  transition:transform .15s ease;display:inline-block}
details.plieg[open]>summary::before{transform:rotate(90deg)}
details.plieg>summary:hover{color:var(--ink)}
.plieg-cuerpo{padding-top:18px}

@media(max-width:760px){
  .viaje,.acto-cuerpo,.ruta,.panel{padding-left:18px;padding-right:18px}
  .viaje-id h1{font-size:25px}
  .viaje-top .volver{margin-left:0}
  .linea{grid-template-columns:1fr;gap:0;padding-top:6px}
  .hito{text-align:left;padding:12px 0 12px 26px}
  .hito::before{left:5px;top:17px;transform:none}
  .hito::after{left:10px;top:0;bottom:0;right:auto;width:2px;height:auto;
    background:var(--stone-light)!important}
  .hito:first-child::after{top:50%;left:10px}
  .hito:last-child::after{bottom:50%;left:10px}
  .hito.hecho::after{background:var(--success)!important}
  .ruta-grid{grid-template-columns:1fr;gap:14px}
  .punto.der{text-align:left}
  .trecho{text-align:left;display:flex;align-items:center;gap:10px}
  .trecho .barra{flex:1 1 auto;margin:0}
  .btn-grande{width:100%}
}

/* EL PAR PRECIO + MONEDA DENTRO DE UNA TABLA (14-sep-2026, «Corregir el precio»).
   Ninguna pieza cubre un control de captura por RENGLÓN, y con una sola pantalla que
   lo necesita todavía no toca fabricarla (§4c). Va acotado a su clase para no tocar
   ningún otro formulario del ERP.

   ⚠️ SE DIMENSIONA CON `flex-basis`, NO CON `width` — lo cazó la foto del ensayo: la
   regla general de los controles (la del `:not()` largo, arriba) les pone `width:100%`
   con una especificidad que ningún `.clase input` alcanza, así que el precio ocupaba
   toda la columna y la moneda se le iba abajo. Dentro de un contenedor flex el
   `flex-basis` manda sobre el `width` para el tamaño principal: así se acota sin
   pelear con la especificidad ni usar `!important`.

   En teléfono la tabla ya se apila sola, así que el par se queda igual: los dos
   controles caben de sobra a 390 px. */
.precio-par{display:flex;gap:8px;align-items:center;margin:0;max-width:17em}
.precio-par input[type=text]{flex:1 1 8em;min-width:5em}
.precio-par select{flex:0 0 6em}

/* MIS REPORTES, el bloque de Mi día donde el reporte vuelve a quien lo escribió
   (R-200, 2026-09-14).

   Un renglón por reporte, separados por línea fina, dentro de una `.card acolchada`.
   Cada uno lleva cuatro cosas apiladas: folio y etiqueta, el eco de lo que escribió,
   la nota de cómo quedó, y los botones.

   Los botones van SIEMPRE en su propio renglón, no a la derecha del texto. Al caminar
   la maqueta a 390 px con un texto CORTO, la fila de botones se acomodaba al lado y se
   salía por la derecha —el texto largo era el que la empujaba abajo, o sea que el caso
   bonito escondía el defecto. Apilar siempre cuesta unos pixeles de alto y no tiene
   trampa a ningún ancho.

   ⚠️ Esta hoja se edita en paralelo por varias sesiones y ya tuvo un comentario partido
   en dos que la dejó INVÁLIDA de aquí para abajo: el bloque va COMPLETO y al final del
   archivo, nunca insertado dentro de otro. */
.reporte-vuelto { padding: 14px 0; border-top: 1px solid var(--hairline); }
.reporte-vuelto:first-child { padding-top: 0; border-top: 0; }
.reporte-vuelto:last-child { padding-bottom: 0; }
.reporte-vuelto-cab { display: flex; align-items: center; gap: 8px;
                      flex-wrap: wrap; margin: 0 0 6px; }
/* Van en `span`, no en `p`: son el APOYO de un dato (el eco de lo que escribió y
   cómo quedó), no párrafos de prosa. El filtro del estándar cuenta los `<p>` de cinco
   palabras o más como «frases en pantalla» y tiene razón — F12 pide ver un dato, no
   leer un texto. El `display:block` les da el renglón propio igual. */
.reporte-vuelto-eco { display: block; margin: 0 0 4px; font-size: 13px;
                      color: var(--ink-3); line-height: 1.5; overflow-wrap: anywhere; }
.reporte-vuelto-nota { display: block; margin: 0; font-size: 13px; color: var(--ink-2);
                       line-height: 1.5; overflow-wrap: anywhere; }
.reporte-vuelto-acc { display: flex; gap: 8px; align-items: center;
                      flex-wrap: wrap; margin-top: 10px; }
.reporte-vuelto-acc form { margin: 0; }
/* «Hay algo más» plegado: es la salida rara, no compite con «Listo». El triángulo
   propio del navegador se queda —es lo que le dice a la gente que ahí hay algo que
   abrir— y sólo se le da tamaño de dedo y el color de una liga. */
.reporte-vuelto-mas { margin-top: 10px; }
.reporte-vuelto-mas > summary { cursor: pointer; font-size: 13px; color: var(--ink-2);
                                padding: 6px 0; width: fit-content; }
.reporte-vuelto-mas > summary:hover { color: var(--ink); }
.reporte-vuelto-mas[open] > summary { margin-bottom: 6px; font-weight: 600; }
@media (max-width: 640px), (pointer: coarse) {
  .reporte-vuelto-mas > summary { padding: 12px 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MI TARJETA · comprobar un cargo, y varios cargos con una factura (15-sep-2026)
   ═══════════════════════════════════════════════════════════════════════════
   Hasta hoy esto vivía DENTRO de las dos plantillas de Mi tarjeta con la nota
   «suben al mueble cuando llegue la segunda pantalla». Llegó (R-199 de Luis:
   varios cargos con una factura), y subieron enteros — no se copiaron.
   ─────────────────────────────────────────────────────────────────────────── */

/* La lista: cada cargo es una tarjeta con su casilla al principio del renglón. */
.mt-cargo { margin-bottom: var(--e-3, 14px); }
.mt-cab { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; margin-bottom: 10px; }
.mt-fecha { color: var(--ink-2); font-size: .85rem; white-space: nowrap; }
/* La fecha y su pastilla no se parten, pero la nota que las sigue («vuelve a pedir
   comprobante», «no te cuesta nada») SÍ baja de renglón: a 390 px salía cortada
   por el borde de la tarjeta (R-257, 6-oct-2026). */
.mt-fecha .sub { white-space: normal; }
.mt-comercio { font-weight: 600; flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
.mt-monto { font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap; }
/* La pieza `palomita` ya trae el blanco del dedo (44 px) con margen negativo
   pensado para una celda de tabla; en una tarjeta ese margen la desalinea. */
.mt-cab .palomita { margin: -10px -8px -10px -12px; align-self: center; }
.marcar-todos { margin: 0 0 10px; }
.marcados-txt { font-size: 13.5px; }

/* ⚠️ HALLAZGO DE LA MAQUETA (15-sep): el mueble sólo pintaba de naranja el
   `.btn-manda` dentro de `.acciones` y `.cabecera`; en la barra pegada salía
   fantasma — y así salía TAMBIÉN «Guardar cambios» de editar producto,
   proveedor y cliente, que viven en esa barra. Misma regla, tercer sitio. */
.acciones-pegadas .btn-manda { background: var(--orange); color: #fff; border-color: var(--orange); }
.acciones-pegadas .btn-manda:hover { filter: brightness(.94); background: var(--orange); color: #fff; }

/* El cargo del banco (o la suma de los marcados): el número que NO se discute. */
.cargo-ancla { display: flex; gap: 18px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.ca-etq { color: var(--ink-2); font-size: 12.5px; margin-bottom: 2px; }
.ca-cifra { font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.ca-sub { color: var(--ink-2); font-size: 12.5px; margin-top: 4px; }
.ca-donde { color: var(--ink-3); font-size: 12.5px; text-align: right; }
.aire-arriba { margin-top: var(--e-3); }

/* LO QUE DICE EL PAPEL — tabla de dos columnas, no rejilla de columnitas. */
.pf { border: 1px solid var(--hairline); border-radius: 12px; overflow: hidden; background: var(--card); }
.pf-r { display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 2px 18px;
        padding: 9px 14px; border-bottom: 1px solid var(--hairline-2); align-items: baseline; }
.pf-r:last-child { border-bottom: 0; }
.pf-e { color: var(--ink-2); font-size: 12.5px; }
.pf-d { color: var(--ink); overflow-wrap: anywhere; }
.pf-r.fuerte { background: var(--card-2); font-weight: 700; }
.pf-r.fuerte .pf-d { font-variant-numeric: tabular-nums; }
.pf-mono { font-family: var(--mono); font-size: 11.5px; }

/* EL REPARTO — siempre remata en el cargo del banco, cuadre o no. */
.reparto { border: 1px solid var(--hairline); border-radius: 12px; overflow: hidden;
           background: var(--card); font-variant-numeric: tabular-nums; }
.reparto .rr { display: flex; align-items: baseline; gap: 12px; padding: 10px 14px;
               border-bottom: 1px solid var(--hairline-2); }
.reparto .rr:last-child { border-bottom: 0; }
.reparto .rp-et { flex: 1 1 auto; min-width: 0; }
.reparto .rp-et small { display: block; color: var(--ink-3); font-size: var(--t-apoyo); }
.reparto .rp-cif { white-space: nowrap; font-weight: 600; min-width: 120px; text-align: right; }
.reparto .rp-cif .campo { margin: 0; }
/* El control de una celda no puede pasarse del filo de la tarjeta: el ancho
   lo manda la celda, y el número —que es el dato— gana al prefijo. */
.reparto .rp-cif .con-moneda { max-width: 150px; margin-left: auto; }
.reparto .rp-cif input[type=number] { min-width: 0; width: 100%; text-align: right; }
.reparto .rr.tecleado { background: var(--orange-soft); }
/* El renglón del redondeo: gris, no naranja — no lo tecleó nadie, lo puso el ERP. */
.reparto .rr.redondeo { background: var(--card-2); }
.reparto .rr.remate { background: var(--card-2); border-top: 2px solid var(--ink);
                      font-weight: 700; padding-top: 12px; padding-bottom: 12px; }
.reparto .rr.remate .rp-cif { font-size: 1.15em; }
.reparto .rp-dice { font-size: var(--t-apoyo); font-weight: 600; white-space: nowrap; }
.reparto .rp-ok { color: var(--success-ink); }
.reparto .rp-mal { color: var(--critical-ink); }
.reparto .rp-fuente { font-size: var(--t-apoyo); color: var(--ink-3); font-weight: 400; }

/* ⚠️ A 390 px los tres pedazos del renglón NO caben en una línea: el «Total»
   se encimaba con su veredicto y la cifra se salía de la pantalla. Sólo lo
   vio el navegador — la suite no ejecuta CSS. */
@media (max-width: 640px), (pointer: coarse) {
  .reparto .rr { flex-wrap: wrap; row-gap: 4px; }
  .reparto .rp-et { flex: 1 1 100%; }
  .reparto .rp-et small { display: inline; }
  .reparto .rp-fuente { flex: 1 1 auto; }
  .reparto .rp-cif { flex: 0 0 auto; min-width: 0; margin-left: auto; text-align: right; }
  .reparto .rp-dice { flex: 1 1 100%; white-space: normal; }
  .pf-r { grid-template-columns: 1fr; gap: 1px; }
  .ca-donde { text-align: left; }
  .acciones-pegadas .btn-manda { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════════
   LA LISTA CON DUEÑOS (pieza `lista_con_duenos`, 2026-09-15). Nació como
   `ventas/_lo_que_falta.html` con su <style> adentro; al volverse pieza para
   la puesta en marcha del cliente, su CSS se mudó aquí, a la hoja compartida.
   ÁMBAR = te toca. GRIS = no te toca. El rojo sólo para «nadie tiene la casilla».
   ═══════════════════════════════════════════════════════════════════════ */
.titulillo-falta { margin: 0 0 8px; font-size: 12px; letter-spacing: .07em; text-transform: uppercase;
                   color: var(--ambar, #b26a00); font-weight: 700; }
.titulillo-falta .ajeno-n { color: var(--ink-3, #8a8a93); font-weight: 600; }
.tabla-falta tr.mia td { background: var(--ambar-bg, #fdf6e8); }
.tabla-falta tr.mia td:first-child { font-weight: 600; }
.tabla-falta tr.lista td { color: var(--ink-3, #8a8a93); }
.tabla-falta .yo { display: inline-block; background: var(--ink, #2b2b28); color: #fff; font-size: 10.5px;
                   padding: 1px 6px; border-radius: 4px; margin-left: 5px; vertical-align: 1px; font-weight: 700; }
.tabla-falta .donde { display: block; font-size: 12.5px; color: var(--ink-3, #8a8a93); }
/* El renglón de apoyo de una casilla y lo que traba: debajo del «qué», nunca en otra columna. */
.tabla-falta .ld-detalle { display: block; font-size: 12.5px; color: var(--ink-2, #6a6a63); font-weight: 400; margin-top: 2px; }
.tabla-falta .ld-traba { display: block; font-size: 12px; color: var(--rojo, #c0392b); font-weight: 600; margin-top: 2px; }
.tabla-falta tr.lista .ld-traba { display: none; }
/* La columna del documento (la lista del contador, 1-oct-2026): un folio no se parte en dos. */
.tabla-falta .ld-doc { white-space: nowrap; }
.sin-dueno { color: var(--rojo, #c0392b); }
.pie-falta { margin: 8px 0 0; color: var(--ink-3, #8a8a93); font-size: 13px; }
/* En el teléfono la tabla apila sus celdas: quedan a la IZQUIERDA (lo cazó la
   maqueta de la puesta en marcha a 390 px: alineadas a la derecha no se leían). */
@media (max-width: 640px), (pointer: coarse) {
  .tabla-falta td { text-align: left; }
  .tabla-falta td.der { text-align: left; }
  /* Un SKU largo («PT-CAJA-EXPORTACION-40X30X25-KRAFT-001») no se parte solo: en el
     botón y en la frase estiraba la tabla y cortaba el renglón a 390 px (lo cazaron
     los datos feos del cierre, 2-oct-2026). */
  .tabla-falta td, .tabla-falta .btn { overflow-wrap: anywhere; }
  /* Gana a `.tabla td.der .btn { nowrap }` de mely_piezas.css, que carga después. */
  .tabla.tabla-falta td.der .btn { white-space: normal; text-align: left; }
}

/* ═════════════════════════════════════════════════════════════════════════
   EL MARGEN · EL TABLERO DE ARRIBA (Pablo, 2026-09-23)
   Tres piezas: la principal (lo vendido, el ritmo del mes, lo ganado y el
   margen), «Quién compra» y el mapa de clientes. Versión CLARA, la que él
   eligió entre las dos de la maqueta. Los dibujos los hace margen_tablero.js.
   Colores validados con el verificador de daltonismo sobre fondo claro:
   azul #2F6FB5 ↔ naranja #FD6B00 (el naranja lleva siempre su rótulo).
   ═════════════════════════════════════════════════════════════════════════ */
.mt {
  --mt-azul: #2F6FB5;      /* la serie: lo vendido, el peso de un cliente */
  --mt-naranja: #FD6B00;   /* el periodo en curso; como TRAZO, nunca como letra */
  --mt-gris: #B9BCC3;      /* el contexto: el periodo anterior */
  --mt-rejilla: #EFEFF2;
  --mt-verde: #1C7C3C;     /* estado: arriba de tu margen (siempre con su cifra) */
  --mt-ambar: #B26A00;     /* estado: debajo de tu margen */
  --mt-rojo: #D93025;      /* estado: pierde (siempre con ▼ y su cifra) */
}
.mt-heroe { position: relative; overflow: hidden; border-radius: 22px; margin-bottom: 16px; padding: 26px 28px 22px;
            background: radial-gradient(760px 320px at 92% -20%, rgba(253,107,0,.10), transparent 62%),
                        radial-gradient(520px 260px at 0% 120%, rgba(47,111,181,.06), transparent 60%),
                        linear-gradient(180deg, #FFFFFF, #FCFCFD);
            box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 18px 40px -22px rgba(0,0,0,.18); }
.mt-rej { display: grid; grid-template-columns: 300px 1fr; gap: 28px; align-items: stretch; }
.mt-rot { font-size: 13px; color: var(--ink-2); font-weight: 500; }
.mt-num { font-size: 60px; line-height: 1; font-weight: 700; letter-spacing: -2.4px; margin: 10px 0 12px; white-space: nowrap; }
.mt-num small { font-size: 18px; letter-spacing: 0; color: var(--ink-2); font-weight: 600; margin-left: 6px; }
.mt-pastilla { display: inline-flex; gap: 6px; align-items: center; font-size: 12.5px; font-weight: 700; padding: 5px 10px; border-radius: 999px; }
.mt-pastilla span { font-weight: 500; color: var(--ink-2); }
.mt-pastilla.sube { background: #E7F5EC; color: var(--mt-verde); }
.mt-pastilla.baja { background: #FDE8E6; color: var(--mt-rojo); }
.mt-pastilla.igual { background: #F1F1F4; color: var(--ink-2); }
.mt-sep { height: 1px; background: var(--mt-rejilla); margin: 20px 0 16px; }
.mt-mini { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mt-mini .v { font-size: 26px; font-weight: 700; letter-spacing: -.8px; margin-top: 4px; white-space: nowrap; }
.mt-mini .v small { font-size: 12px; color: var(--ink-2); font-weight: 600; letter-spacing: 0; margin-left: 3px; }
.mt-mini .d { font-size: 12px; margin-top: 3px; font-weight: 600; }
.mt-mini .d.sube { color: var(--mt-verde); } .mt-mini .d.baja { color: var(--mt-rojo); } .mt-mini .d.igual { color: var(--ink-3); }
.mt-meses { display: flex; gap: 6px; align-items: flex-end; height: 30px; margin-top: 10px; }
.mt-meses div { flex: 1; border-radius: 4px 4px 0 0; background: #E4E5E9; min-height: 2px; }
.mt-meses div.ya { background: var(--mt-naranja); }
.mt-meses div.nada { background: transparent; border-bottom: 2px dotted #D5D6DB; }
.mt-meses-et { display: flex; gap: 6px; font-size: 10.5px; color: var(--ink-2); margin-top: 4px; }
.mt-meses-et span { flex: 1; text-align: center; white-space: nowrap; }
.mt-cab { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.mt-cab h2, .mt-cab h3 { margin: 0; font-size: 15px; font-weight: 650; color: var(--ink); letter-spacing: -.1px; }
.mt-cab .m { font-size: 12.5px; color: var(--ink-2); margin-top: 3px; }
.mt-ley { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--ink-2); }
.mt-ley span { display: inline-flex; align-items: center; gap: 6px; }
.mt-ley b { display: inline-block; width: 16px; height: 2px; border-radius: 2px; }
.mt-ley i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; }
.mt-svg { display: block; width: 100%; overflow: visible; }
.mt-svg text { font-family: inherit; }
#mt-ritmo { height: 250px; margin-top: 6px; }
.mt-par { display: grid; grid-template-columns: 1.15fr 1fr; gap: 16px; margin-bottom: 20px; }
.mt-tj { background: var(--card); border-radius: 20px; min-width: 0; padding: 20px 22px;
         box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 24px -12px rgba(0,0,0,.10); }
.mt-tj.mapa { display: flex; flex-direction: column; }
.mt-tj .mt-cab { margin-bottom: 14px; }
#mt-mapa { flex: 1; min-height: 320px; }
.mt-resumen { display: inline-flex; gap: 8px; align-items: baseline; background: #F4F4F6; border-radius: 12px; padding: 8px 12px; font-size: 12.5px; color: var(--ink-2); margin-bottom: 12px; }
.mt-resumen b { font-size: 18px; color: var(--ink); letter-spacing: -.4px; }
.mt-rank { list-style: none; margin: 0; padding: 0; }
.mt-rank li { display: grid; grid-template-columns: 22px 1fr 64px 76px; gap: 10px; align-items: center; padding: 9px 6px; border-radius: 12px; }
.mt-rank li:hover { background: #F7F7F9; }
.mt-rank .n { font-size: 12px; color: var(--ink-3); font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.mt-rank .nom { display: block; font-size: 13.5px; color: var(--ink); font-weight: 550; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mt-rank a.nom { text-decoration: none; }
.mt-rank a.nom:hover { color: var(--orange-ink); text-decoration: underline; }
.mt-rank .pista { height: 8px; background: #EFEFF2; border-radius: 99px; margin-top: 6px; overflow: hidden; }
.mt-rank .fill { height: 100%; border-radius: 99px; background: linear-gradient(90deg, #5B8FD0, var(--mt-azul)); width: 0; transition: width .9s cubic-bezier(.2,.7,.2,1); }
.mt-rank .fill.neg { background: linear-gradient(90deg, #F07A71, var(--mt-rojo)); }
.mt-rank .fill.otros { background: #C9CBD1; }
.mt-rank .pct { font-size: 15px; font-weight: 700; text-align: right; letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.mt-chip { justify-self: end; font-size: 12px; font-weight: 700; padding: 4px 9px; border-radius: 999px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.mt-chip.bien { background: #E7F5EC; color: var(--mt-verde); }
.mt-chip.bajo { background: #FFF1DB; color: var(--mt-ambar); }
.mt-chip.pierde { background: #FDE8E6; color: var(--mt-rojo); }
.mt-chip.nada { background: #F1F1F4; color: var(--ink-3); }
.mt-ley-chips { display: flex; gap: 12px; flex-wrap: wrap; font-size: 11.5px; color: var(--ink-2); margin-top: 12px; }
.mt-vacio { font-size: 13px; color: var(--ink-2); padding: 18px 0; }
/* CADA 100 VENDIDOS (Pablo, 3-oct): en qué se fue lo vendido; lo rayado es estimado. */
.mt-firme { font-size: 12px; color: var(--ink-2); margin-top: 3px; }
.mt-dolar { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--mt-rejilla); }
.mt-dolar-cab { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.mt-dolar-cab h3 { margin: 0; font-size: 15px; font-weight: 650; color: var(--ink); }
.mt-dolar-cab .m { font-size: 12.5px; color: var(--ink-2); }
.mt-barra { display: flex; height: 26px; border-radius: 8px; overflow: hidden; margin: 12px 0 10px; background: #EFEFF2; }
.mt-barra > div { height: 100%; }
.mt-barra > div + div:not(.est) { box-shadow: inset 2px 0 0 #fff; }
.mt .t-producto { background: #C9CBD1; }
.mt .t-traer { background: #5B8FD0; }
.mt .t-entregar { background: #8AB0DF; }
.mt .t-agencia { background: var(--mt-azul); }
.mt .t-comision { background: #7A5BB5; }
.mt .t-gano { background: var(--mt-verde); }
.mt-barra .est { background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.55) 0 3px, transparent 3px 7px); }
.mt-tramos { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px 10px; }
.mt-tramos > div { font-size: 12px; color: var(--ink-2); line-height: 1.35; }
.mt-tramos b { display: block; font-size: 17px; color: var(--ink); letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.mt-tramos i { display: inline-block; width: 9px; height: 9px; border-radius: 3px; margin-right: 5px; }
.mt-tramos .e { display: block; font-size: 11px; color: var(--ink-3); }
#mt-tip { position: fixed; pointer-events: none; z-index: 60; background: rgba(20,20,22,.94); color: #fff; border-radius: 12px;
          padding: 10px 12px; font-size: 12.5px; line-height: 1.55; box-shadow: 0 12px 30px rgba(0,0,0,.25);
          opacity: 0; transition: opacity .1s; max-width: 280px; }
#mt-tip .t { color: #B8B8BF; font-size: 11.5px; margin-bottom: 4px; }
#mt-tip .f { display: flex; gap: 14px; justify-content: space-between; align-items: center; }
#mt-tip .f b { font-size: 13.5px; font-variant-numeric: tabular-nums; }
#mt-tip .k { display: inline-block; width: 12px; height: 2px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.mt-aparece { animation: mt-aparece .6s cubic-bezier(.2,.7,.2,1) both; }
.mt-aparece.d1 { animation-delay: .08s; } .mt-aparece.d2 { animation-delay: .16s; }
@keyframes mt-aparece { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes mt-late { 0%, 100% { r: 5; opacity: .9; } 50% { r: 11; opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .mt-aparece { animation: none; } .mt-rank .fill { transition: none; } }
/* El total de «Costó» lleva sus notas (gastos, flete estimado) en un <div>: en
   teléfono cada nota va en su renglón, no amontonadas de lado. */
@media (max-width: 640px) {
  .tabla tfoot td > div { text-align: right; }
  .tabla tfoot td > div .callado { display: block; }
}
@media (max-width: 860px) {
  .mt-heroe { padding: 22px 18px 18px; border-radius: 18px; }
  .mt-rej { grid-template-columns: 1fr; gap: 18px; }
  .mt-num { font-size: 46px; letter-spacing: -1.6px; }
  .mt-par { grid-template-columns: 1fr; }
  .mt-rank li { grid-template-columns: 18px 1fr 54px 70px; gap: 8px; }
  .mt-rank .nom { white-space: normal; font-size: 13px; line-height: 1.3; }
  #mt-ritmo { height: 210px; }
}

/* ═════════════════════════════════════════════════════════════════════════
   TESORERÍA › FLUJO DE DINERO (Pablo, 17-oct-2026)
   Las piezas del tablero del margen (.mt-heroe, .mt-rank, #mt-tip) más lo que
   el flujo agrega: la gráfica entra/sale/queda (flujo_de_dinero.js), lo que
   sale en naranja, lo estimado rayado, el mínimo en rojo, y la tabla con las
   semanas en columnas que en el teléfono se recorre de lado con el concepto fijo.
   ═════════════════════════════════════════════════════════════════════════ */
.fl #fl-graf { height: 290px; margin-top: 8px; }
.fl-cifras .mt-num { font-size: 54px; }
/* Debajo de cero no se puede leer mal: en rojo, con su ▼ y el menos de verdad (Pablo, 18-oct). */
.fl-cifras .mt-num.neg, .fl-cifras .mt-mini .v.neg { color: var(--critical-ink); }
.fl-cifras .d.alerta { color: var(--mt-ambar); }
.fl-cifras .d.mal { color: var(--mt-rojo); }
.fl-ley b.rect { width: 10px; height: 10px; border-radius: 3px; }
.fl-ley b.raya { width: 12px; height: 10px; border-radius: 3px; background: repeating-linear-gradient(135deg, #FFB27A 0 2px, #fff 2px 4px); }
.fl-ley b.min { width: 16px; height: 0; border-top: 2px solid var(--mt-rojo); border-radius: 0; }
.mt-rank.fl-rank li { grid-template-columns: 22px minmax(0, 1fr) 54px auto; }
.mt-rank .fill.sale { background: linear-gradient(90deg, #FFA466, #FD6B00); }
.mt-rank .fill.sale.est { background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.55) 0 3px, transparent 3px 7px), linear-gradient(90deg, #FFA466, #FD6B00); }
.mt-rank .monto { display: block; font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; margin-top: 2px; }
.tabla.fl-tabla td .sub, .tabla.fl-tabla th .sub { display: block; font-size: 11.5px; color: var(--ink-3); font-weight: 400; }
.tabla.fl-tabla td.num .sub { white-space: nowrap; }
.tabla.fl-tabla .sub.falta { color: var(--critical-ink); font-weight: 600; }
.tabla.fl-tabla td.baja-min { color: var(--critical-ink); font-weight: 700; }
.tabla.fl-tabla td.izq { text-align: left; }
.tabla.fl-tabla .est-marca { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px;
                    background: repeating-linear-gradient(135deg, #9AA0AA 0 2px, #fff 2px 4px); }
/* Dentro de una liga (inline-flex en .tabla td a) la marca no se aprieta ni se centra entre
   dos líneas: va pegada a la primera, como en los renglones sin liga. */
.tabla.fl-tabla td a:has(.est-marca) { align-items: baseline; }
.tabla.fl-tabla td a .est-marca { flex: none; }
.tabla.fl-tabla tr.suma td { font-weight: 700; border-top: 1px solid var(--hairline); }
.tabla.fl-tabla tr.queda td { font-weight: 700; background: var(--card-2); }
.tabla.semanas td.num, .tabla.semanas th.num { white-space: nowrap; }
.tabla.semanas td, .tabla.semanas th { padding-left: 7px; padding-right: 7px; font-size: 13px; }
.tabla.semanas th .sub { white-space: normal; max-width: 92px; margin-left: auto; text-transform: none; letter-spacing: 0; }
.tabla.semanas th:first-child, .tabla.semanas td:first-child { position: sticky; left: 0; background: var(--card); z-index: 1;
                                                              min-width: 150px; max-width: 190px; white-space: normal; }
.tabla.semanas tr.queda td:first-child { background: var(--card-2); }
.tabla.semanas tr.tab-seccion td:first-child { position: static; max-width: none; }
@media (max-width: 860px) {
  .mt-rank.fl-rank li { grid-template-columns: 18px minmax(0, 1fr) 52px; row-gap: 4px; }
  .mt-rank.fl-rank li .mt-chip { grid-column: 2 / -1; justify-self: start; }
}
@media (max-width: 640px) {
  .fl #fl-graf { height: 240px; }
  .fl-cifras .mt-num { font-size: 42px; }
  /* La tabla de semanas NO se vuelve tarjetas: se recorre de lado, concepto fijo. */
  .tabla.semanas { display: table; width: auto; }
  .tabla.semanas thead { display: table-header-group; }
  .tabla.semanas tbody tr { display: table-row; box-shadow: none; border: 0; margin: 0; padding: 0; border-radius: 0; }
  .tabla.semanas tbody td, .tabla.semanas th { display: table-cell; padding: 8px 10px; }
  .tabla.semanas tbody td::before { content: none; }
  .tabla.semanas td:first-child, .tabla.semanas th:first-child { min-width: 150px; max-width: 150px; text-align: left; }
  .tabla.fl-tabla td > div { text-align: right; }
}
