/* ==========================================================================
   fst-tesorería — identidad pos-v2 (monocromo brutalista)
   ==========================================================================
   Intención de diseño (portada literalmente de produce-pos/pos-v2/styles.css)
   ──────────────────────────────────────────────────────────────────────────
   Negro puro sobre blanco puro.  Sin color.  Sin radios.  Sin sombras.  Sin
   degradados.  Inter.  Etiquetas de sección en MAYÚSCULAS con tracking.
   Líneas negras de 1px como ÚNICO elemento estructural.  La tipografía hace
   todo el trabajo pesado.

   El POS no intenta verse amigable — se ve DECISIVO.  La tesorería es su
   hermana: mismo tema, misma tipografía, misma disciplina de color.  Lo que
   cambia es la ANATOMÍA: el POS tiene 5 pantallas simples, la tesorería 26
   densas, así que aquí hay además una capa de página (encabezado, tira de
   KPIs, secciones, panel de captura, prosa colapsable) que el POS no necesita.

   EL ROJO (#d00000) ES EL ÚNICO COLOR Y ESTÁ RESERVADO A PELIGRO/ERROR.
   El estado NUNCA se comunica solo con color: chip NEGRO relleno = requiere
   acción; chip con BORDE = neutral; chip ROJO = peligro/vencido. Siempre con
   texto legible dentro.

   Toda clase existente sigue viva: el retema vive en tokens y en las clases
   que las 26 pantallas ya usan, así que una pantalla NO tocada se ve coherente.
   ========================================================================== */

/* =========================  TOKENS (pos-v2, valores exactos)  ============= */

:root {
  --bg:          #ffffff;
  --bg-sunken:   #f0f0f0;
  --surface:     #ffffff;
  --surface-2:   #fafafa;

  --ink:         #000000;
  --ink-soft:    #000000;
  --ink-muted:   #666666;
  --ink-faint:   #999999;
  --ink-subtle:  #cccccc;

  --line:        #000000;
  --line-soft:   #cccccc;
  /* --line-strong existía en el tema anterior (inputs, chips, botones).
     En pos-v2 todo borde estructural es negro, así que apunta al mismo negro. */
  --line-strong: #000000;

  --accent:      #000000;
  --accent-ink:  #ffffff;

  --primary:       #000000;
  --primary-hover: #1a1a1a;
  --primary-ink:   #ffffff;
  /* Los tintes teal del tema anterior sobreviven como GRISES: la selección de
     fila y el resaltado de "vinculante" no pueden depender de color. */
  --primary-tint:   #f0f0f0;
  --primary-border: #000000;

  /* Semánticos. ok/warn son NEGROS a propósito (pos-v2): el énfasis lo hace el
     peso tipográfico, no el matiz. Solo danger conserva color. */
  --ok:      #000000;  --ok-soft:     #f0f0f0;  --ok-border:     #000000;
  --warn:    #000000;  --warn-soft:   #f0f0f0;  --warn-border:   #000000;
  --danger:  #d00000;  --danger-soft: #ffeeee;  --danger-border: #d00000;

  --ring:      0 0 0 2px #000000;
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: none;
  --shadow-card: none;

  --radius: 0;  --radius-sm: 0;  --radius-lg: 0;
  --r-sm:   0;  --r:          0;  --r-lg:     0;

  /* Inter desde Google Fonts (app/index.html), igual que pos-v2. La pila de
     respaldo queda intacta para el primer pintado y para un equipo sin red.
     pos-v2 NO usa monoespaciada: --num/--font-mono apuntan también a Inter y
     el ancho fijo lo da font-variant-numeric: tabular-nums. */
  --font:      "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --num:       "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* =========================  RESET + BASE  ================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; overflow-y: scroll; scrollbar-gutter: stable; }
body {
  font-family: var(--font); color: var(--ink); font-size: 13px; line-height: 1.5;
  background: var(--bg); letter-spacing: 0.01em; font-weight: 400;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, h5 { margin: 0; font-weight: 700; color: var(--ink); }
/* Regla base de pos-v2: sin esto, todo <button> sin clase .btn (el colapsar del
   sidebar, el cerrar sesión, los chips de filtro) cae a la fuente del navegador
   —Arial— y rompe la unidad tipográfica. */
button { font: inherit; color: inherit; cursor: pointer; }
::selection { background: #000; color: #fff; }

/* Todo lo numérico se alinea por columna. */
.td--num, .kpi__value, .clabe-big, .detail-head__total, .line-total,
.stat__value, .cont-stat__v, .totals__row, .totals__value, .cpq-cta,
.ciclo-hash, .ciclo-veto {
  font-variant-numeric: tabular-nums;
}

/* Foco visible SIEMPRE (anillo negro de 2px, el --ring de pos-v2). */
:focus-visible { outline: 2px solid var(--ink); outline-offset: -1px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ==========================================================================
   ANATOMÍA DE PÁGINA — las primitivas nuevas del sistema.
   Toda pantalla: encabezado → KPIs → secciones → tablas; la captura en panel
   aparte; la doctrina en <details>. Ver docs/UI_SYSTEM.md.
   ========================================================================== */

/* --- 1. Encabezado de página --------------------------------------------- */
.page-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding-bottom: 14px; border-bottom: 1px solid var(--line);
}
.page-header__text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.page-header__eyebrow {
  font-size: 9px; font-weight: 500; color: var(--ink-muted);
  text-transform: uppercase; letter-spacing: 0.16em;
}
.page-header__title {
  font-size: 20px; font-weight: 800; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.06em; line-height: 1.15;
  text-wrap: balance;
}
.page-header__sub { font-size: 12px; color: var(--ink-muted); max-width: 82ch; line-height: 1.55; margin: 0; }
/* `flex-shrink: 0` dejaba la tira de acciones a su ancho máximo aunque el
   `flex-wrap` de adentro pudiera repartirla: en teléfono, tres botones (los de
   Contabilidad miden 455px juntos) empujaban el <body> entero de lado. Ahora la
   tira se limita al ancho disponible y los botones bajan de renglón. */
.page-header__actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; flex-shrink: 1; max-width: 100%; }

/* --- 2. Tira de KPIs ------------------------------------------------------
   Celdas divididas por reglas negras de 1px.
   Técnica: `gap: 1px` + un anillo de 1px por celda (box-shadow, que no ocupa
   layout). Los anillos de celdas vecinas se solapan dentro del gap y producen
   UNA regla limpia, sobreviven cualquier salto de línea del auto-fit, y —a
   diferencia de pintar el contenedor de negro— un número IMPAR de celdas NO
   deja un hueco negro relleno al final de la rejilla. */
.kpi-row, .stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 1px; background: transparent; border: 0;
}
.kpi, .stat {
  display: flex; flex-direction: column; gap: 4px; justify-content: flex-start;
  padding: 14px 16px; background: var(--surface); border: 0; border-radius: 0;
  box-shadow: 0 0 0 1px var(--line); min-width: 0;
}
/* La etiqueta RESERVA dos renglones aunque solo ocupe uno.
   Sin esto, una etiqueta que se parte en dos ("Crédito no dispuesto · MXN")
   empuja SU valor 11px más abajo que los de sus vecinas y la tira de cifras
   —que en este tema solo está separada por hilos de 1px— se lee dentada.
   Reservar el alto alinea las cifras por su línea base en toda la tira. */
.kpi__label, .stat__label {
  font-size: 9px; font-weight: 500; color: var(--ink-muted);
  text-transform: uppercase; letter-spacing: 0.14em; line-height: 1.3;
  min-height: calc(2 * 1.3em);
}
.kpi__value, .stat__value {
  font-size: 23px; font-weight: 700; color: var(--ink);
  letter-spacing: -0.02em; line-height: 1.05;
}
.kpi__hint, .stat__hint {
  font-size: 10px; color: var(--ink-muted);
  text-transform: uppercase; letter-spacing: 0.06em; line-height: 1.35;
}
/* Acento = celda negra: el número que gobierna la pantalla. */
.kpi--accent, .stat--accent { background: var(--ink); }
.kpi--accent .kpi__value, .stat--accent .stat__value,
.kpi--accent .kpi__label, .stat--accent .stat__label,
.kpi--accent .kpi__hint,  .stat--accent .stat__hint { color: #fff; }
/* DOS grados de alarma, no uno.
   `--warn` vale #000000 en este tema (pos-v2), así que mandar .kpi--warn al
   tinte rojo colapsaba los dos grados: "3 pagos por aprobar" (una cola de
   trabajo rutinaria) se pintaba EXACTAMENTE igual que "$199,500 sin conciliar"
   (un hueco real). Cuando todo grita, nada grita.
   AVISO = énfasis NEGRO (barra izquierda + cifra en tinta plena).
   PELIGRO = el único rojo. */
.kpi--warn { background: var(--surface); box-shadow: 0 0 0 1px var(--line), inset 4px 0 0 var(--ink); }
.kpi--warn .kpi__value { color: var(--ink); }
.kpi--warn .kpi__label { color: var(--ink); font-weight: 700; }

.kpi--danger, .stat--danger { background: var(--danger-soft); }
.kpi--danger .kpi__value, .stat--danger .stat__value { color: var(--danger); }
.kpi--danger .kpi__label, .stat--danger .stat__label { color: var(--danger); }
.kpi--link { cursor: pointer; }
.kpi--link:hover { background: var(--bg-sunken); }
.kpi--accent.kpi--link:hover { background: var(--primary-hover); }
.kpi--warn.kpi--link:hover { background: var(--bg-sunken); }
.kpi--danger.kpi--link:hover { background: #ffdede; }

/* Una tira de 3 o 5 celdas cae en 2 columnas al angostarse: sin esto la última
   queda huérfana y su media fila vacía rompe el rectángulo de la tira. */
@media (max-width: 640px) {
  .kpi-row .kpi:last-child:nth-child(odd),
  .stat-row .stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
/* SEIS celdas (Cartera cuando hay crédito detenido) caben 5 + 1 en el auto-fit
   y la sexta queda sola en una fila a un quinto de ancho: la tira se ve rota.
   En escritorio se reparten 3 × 2, que además agrupa solo el dinero arriba y
   las alarmas abajo. En pantallas angostas mandan el auto-fit y la regla de la
   huérfana de arriba. */
@media (min-width: 901px) {
  .kpi-row:has(> .kpi:nth-child(6):last-child),
  .stat-row:has(> .stat:nth-child(6):last-child) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- 3. Sección ----------------------------------------------------------- */
.section { display: flex; flex-direction: column; gap: 12px; }
.section + .section { margin-top: 12px; }
.section__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.section__title, .card__subtitle, .cont-subtitle, .ciclo-h, .cpq-lab,
.cont-export-group__h, .cot-headline__lab, .ciclo-accion__t {
  font-size: 11px; font-weight: 700; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.14em; margin: 0;
}
.card__subtitle, .cont-subtitle, .ciclo-h { margin: 14px 0 2px; }
.cpq-lab, .cot-headline__lab, .cont-export-group__h, .ciclo-accion__t {
  font-size: 9px; letter-spacing: 0.14em; font-weight: 500; color: var(--ink-muted);
}
.section__hint { font-size: 11px; color: var(--ink-muted); }
.section__actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.section__body { display: flex; flex-direction: column; gap: 12px; }

/* --- 4. Panel de captura --------------------------------------------------
   Visualmente distinto del contenido de lectura: fondo hundido + borde negro. */
.form-panel, .inline-form, .wcp-subform, .panel {
  border: 1px solid var(--line); border-radius: 0; background: var(--surface-2);
  padding: 16px 18px; display: flex; flex-direction: column; gap: 14px;
}
.form-panel__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin: -4px 0 2px;
}
.form-panel__title {
  font-size: 10px; font-weight: 700; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.16em;
}
.form-panel__hint { font-size: 11px; color: var(--ink-muted); }
.form-panel__grid, .form-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px;
}
.inline-form__actions, .form-panel__actions {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
}

/* --- 5. Prosa de método / doctrina colapsable ----------------------------- */
details.method, .wcp-details, details.cont-method {
  border: 0; border-left: 2px solid var(--line); background: var(--bg-sunken);
  border-radius: 0; padding: 0;
}
details.method > summary, .wcp-details > summary {
  cursor: pointer; list-style: none; padding: 8px 14px;
  font-size: 10px; font-weight: 700; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.12em;
}
details.method > summary::-webkit-details-marker,
.wcp-details > summary::-webkit-details-marker { display: none; }
details.method > summary::before, .wcp-details > summary::before {
  content: "+ "; font-weight: 700;
}
details.method[open] > summary::before, .wcp-details[open] > summary::before { content: "− "; }
details.method > summary:hover, .wcp-details > summary:hover { background: var(--ink); color: #fff; }
details.method[open] > summary, .wcp-details[open] > summary { border-bottom: 1px solid var(--line-soft); }
.method__body, .wcp-details > *:not(summary) { padding: 0 14px; }
.method__body {
  padding: 12px 14px; font-size: 11.5px; color: var(--ink-muted); line-height: 1.65;
}
.method__body p { margin: 0 0 8px; }
.method__body p:last-child { margin-bottom: 0; }
.wcp-details > *:not(summary):last-child { padding-bottom: 12px; }
/* La tabla dentro de un details ocupa todo el ancho del bloque. */
.wcp-details > .table-wrap, .method__body > .table-wrap { padding: 0; margin: 0; }

/* --- 6. Envoltura de tabla (scroll propio; el <body> jamás scrollea al lado) */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); background: var(--surface); }
.table-wrap .table { border: 0; }
.table-wrap > .table th { border-top: 0; }

/* --- 7. Lista de pares etiqueta/valor -------------------------------------
   El reemplazo estructural de "N datos unidos por ' · ' en un span". */
.meta-list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; background: transparent; border: 0;
}
.meta-list__item {
  display: flex; flex-direction: column; gap: 3px; padding: 9px 12px;
  background: var(--surface); min-width: 0; box-shadow: 0 0 0 1px var(--line);
}
.meta-list__label { font-size: 9px; font-weight: 500; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.14em; }
.meta-list__value { font-size: 12px; font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.meta-list__value.is-danger { color: var(--danger); }
.meta-list--plain { border: 0; background: none; gap: 12px 22px; }
.meta-list--plain .meta-list__item { padding: 0; box-shadow: none; }

/* =========================  SHELL: sidebar  ============================== */

.shell--saas { display: grid; grid-template-columns: 240px minmax(0, 1fr); min-height: 100vh; }
.shell__content { min-width: 0; display: flex; flex-direction: column; }
.shell__main { flex: 1; padding: 26px 30px 60px; max-width: 1440px; width: 100%; }
.shell__notice { width: 100%; padding: 16px 30px 0; cursor: pointer; max-width: 1440px; }

.sidebar {
  background: var(--surface); color: var(--ink);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  border-right: 1px solid var(--line);
}
.sidebar__brand {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 16px 14px; border-bottom: 1px solid var(--line);
}
/* La marca recarga la app: se ve como botón al pasar el puntero, se hunde al pulsar. */
.sidebar__brand--reload { cursor: pointer; user-select: none; transition: background 120ms ease; }
.sidebar__brand--reload:hover { background: var(--surface-2, rgba(0, 0, 0, 0.04)); }
.sidebar__brand--reload:active .sidebar__logo { transform: scale(0.94); }
.sidebar__brand--reload:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.sidebar__logo {
  width: 30px; height: 30px; border-radius: 0; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ink); color: #fff; font-weight: 700; font-size: 15px;
  letter-spacing: 0.04em; box-shadow: none;
}
.sidebar__brand-text { display: flex; flex-direction: column; gap: 2px; line-height: 1.2; min-width: 0; }
.sidebar__name {
  font-weight: 700; font-size: 12px; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.12em; white-space: nowrap;
}
/* La versión se lee de un vistazo (petición del operador): etiqueta sólida,
   no letra chica gris. Cuando la app detecta módulos viejos (index dice una
   versión y config.js otra), la etiqueta se pone en rojo y lo dice. */
.sidebar__version {
  display: inline-block; align-self: flex-start; margin-top: 2px;
  font-size: 11px; font-weight: 700; color: #fff; background: var(--ink);
  padding: 2px 7px; letter-spacing: 0.1em; text-transform: uppercase;
  font-variant-numeric: tabular-nums; line-height: 1.3;
}
.sidebar__version--stale { background: #d00000; }
.login__version--stale { color: #d00000; }
/* Enlaces externos del menú (sección Retail): mismo aspecto que un botón de
   navegación, sin subrayado ni color de enlace. */
a.nav-item--link { text-decoration: none; color: inherit; }
a.nav-item--link:visited { color: inherit; }
.login__version--big { font-size: 12px; font-weight: 700; color: var(--ink); letter-spacing: 0.14em; }

/* ---------------------------------------------------------------------------
   INICIO — la página principal. Misma identidad (negro sobre blanco, reglas
   de 1px, mayúsculas con tracking); el «impacto» es tipográfico: un título
   grande y una sola celda negra (la acción principal), nada más.
   --------------------------------------------------------------------------- */
.inicio-hero { display: flex; flex-direction: column; gap: 12px; padding: 22px 0 26px; border-bottom: 1px solid var(--line); }
/* En INICIO el título de cada sección queda CENTRADO entre la regla que lo
   precede y la suya: el mismo aire arriba que abajo (operador, 2026-09-03;
   medido en el arnés: 9px / 9px). */
.inicio .section__head { padding-top: 9px; padding-bottom: 8px; }
.inicio .section + .section { margin-top: 18px; }
.inicio-hero__eyebrow { font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-muted); }
.inicio-hero__title { margin: 0; font-size: clamp(26px, 3.6vw, 40px); font-weight: 800; letter-spacing: 0.02em; line-height: 1.08; text-transform: uppercase; max-width: 22ch; }
.inicio-hero__sub { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink); max-width: 72ch; }
.inicio-hero__actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 6px; }
.inicio-intro { margin: 0; font-size: 13px; line-height: 1.6; max-width: 80ch; }
/* Aviso de «ya está subido»: énfasis en negro (borde izquierdo), no en color. */
.inicio-nota { margin: 0; font-size: 13px; line-height: 1.55; max-width: 80ch; padding: 8px 12px; border: 1px solid var(--line); border-left: 6px solid var(--ink); background: var(--surface-2); font-weight: 500; }

.inicio-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.inicio-step { display: grid; grid-template-columns: 40px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
.inicio-step:last-child { border-bottom: 0; }
.inicio-step__n { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; background: var(--ink); color: #fff; font-weight: 800; font-size: 13px; }
.inicio-step__body { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.inicio-step__title { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.inicio-step__text { margin: 0; font-size: 13px; line-height: 1.55; max-width: 80ch; }

.inicio-progress { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding: 10px 12px; border: 1px solid var(--line); }
.inicio-progress__label { font-size: 10px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-muted); }
.inicio-progress__value { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.inicio-progress__sep { width: 1px; height: 18px; background: var(--line); align-self: center; margin: 0 6px; }

.inicio-grid { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.inicio-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.inicio-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
a.inicio-tool--link { text-decoration: none; color: inherit; }
a.inicio-tool--link:visited { color: inherit; }
.inicio-tile, .inicio-tool { background: var(--surface); padding: 12px 14px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.inicio-tile__head { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.inicio-tile__title { font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.inicio-tile__count { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; }
.inicio-tile__count--on { color: var(--ink); font-weight: 700; }
.inicio-list { margin: 0; padding-left: 16px; font-size: 12.5px; line-height: 1.55; }
.inicio-list li + li { margin-top: 2px; }

.inicio-tool { text-align: left; border: 0; font: inherit; color: inherit; cursor: pointer; align-items: flex-start; }
.inicio-tool:hover { background: var(--surface-2); }
/* Ficha informativa: se lee, no se abre. Relleno: celda blanca que completa la
   última fila (sin él, la rejilla enseñaba su fondo negro). */
.inicio-tool--info { cursor: default; }
.inicio-tool--info:hover { background: var(--surface); }
.inicio-tile--relleno { padding: 0; }
.inicio-tool:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.inicio-tool__name { font-size: 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.inicio-tool__state { font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); border: 1px solid var(--line-soft); padding: 1px 6px; }
.inicio-tool__state--on { color: #fff; background: var(--ink); border-color: var(--ink); }
.inicio-tool__text { font-size: 12.5px; line-height: 1.5; color: var(--ink); }

/* Mensajes (139): dos columnas, burbujas monocromas, redactor abajo. */
.chat { display: grid; grid-template-columns: 250px minmax(0, 1fr); border: 1px solid var(--line); min-height: 60vh; }
.chat--general { grid-template-columns: minmax(0, 1fr); }
.chat__list { border-right: 1px solid var(--line); display: flex; flex-direction: column; overflow: auto; max-height: 72vh; }
.chat__list-title { font-size: 10px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); padding: 10px 12px 4px; }
.chat__item { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; text-align: left; background: var(--surface); border: 0; border-bottom: 1px solid var(--line-soft); font: inherit; color: inherit; cursor: pointer; padding: 9px 12px; }
.chat__item:hover { background: var(--surface-2); }
.chat__item--on { background: var(--ink); color: #fff; }
.chat__item--on:hover { background: var(--ink); }
.chat__item-name { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; }
.chat__item-sub { font-size: 11px; color: var(--ink-muted); width: 100%; }
.chat__item--on .chat__item-sub { color: #ccc; }
.chat__badge { margin-left: auto; min-width: 20px; padding: 1px 6px; text-align: center; font-size: 11px; font-weight: 800; background: var(--ink); color: #fff; }
.chat__item--on .chat__badge { background: #fff; color: var(--ink); }
.chat__pane { display: flex; flex-direction: column; min-width: 0; }
.chat__head { display: flex; align-items: baseline; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }
.chat__msgs { flex: 1; overflow: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; max-height: 58vh; background: var(--surface-2); }
.chat__more { align-self: center; }
.msg { max-width: 76%; align-self: flex-start; background: var(--surface); border: 1px solid var(--line); padding: 8px 10px; display: flex; flex-direction: column; gap: 4px; }
.msg--mine { align-self: flex-end; background: var(--ink); color: #fff; border-color: var(--ink); }
.msg__meta { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); }
.msg--mine .msg__meta { color: #cfcfcf; }
.msg__body { white-space: pre-wrap; word-break: break-word; font-size: 13px; line-height: 1.5; }
.msg__doc { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; border-top: 1px solid var(--line-soft); padding-top: 6px; font-size: 12px; }
.msg--mine .msg__doc { border-top-color: #444; }
.msg--mine .btn { border-color: #fff; color: #fff; background: transparent; }
.msg__doc-title { font-weight: 600; }
.chat__composer { border-top: 1px solid var(--line); padding: 10px 14px; display: flex; flex-direction: column; gap: 6px; }
.chat__composer-row { display: flex; gap: 8px; align-items: flex-end; }
.chat__input { flex: 1; min-height: 44px; resize: vertical; font: inherit; }
.chat__adjunto { display: flex; align-items: center; gap: 8px; font-size: 12px; border: 1px solid var(--line); padding: 4px 8px; align-self: flex-start; }
.chat__hint { font-size: 11px; }
@media (max-width: 920px) {
  .chat { grid-template-columns: 1fr; }
  .chat__list { border-right: 0; border-bottom: 1px solid var(--line); max-height: 180px; }
  .msg { max-width: 92%; }
}

/* Banner de versión nueva (v96): franja negra arriba de todo, en cualquier
   pantalla (login incluido). No bloquea: avisa y ofrece recargar. */
.version-banner {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap;
  padding: 10px 16px; background: var(--ink); color: #fff;
  font-size: 12px; font-weight: 600; letter-spacing: 0.04em;
}
.version-banner__text strong { font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; margin-right: 8px; }
.version-banner .btn { border-color: #fff; color: #fff; background: transparent; }
.version-banner .btn--primary { background: #fff; color: var(--ink); }
.version-banner .btn:hover { background: rgba(255,255,255,0.12); }
.version-banner .btn--primary:hover { background: #e6e6e6; }

/* Archivo (v90): carpetas por mes y por grupo, buscador, tabla. */
.archivo-meses { display: flex; flex-wrap: wrap; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.archivo-mes { background: var(--surface); border: 0; font: inherit; color: inherit; cursor: pointer; padding: 10px 14px; display: flex; flex-direction: column; gap: 2px; min-width: 120px; text-align: left; }
.archivo-mes:hover { background: var(--surface-2); }
.archivo-mes--on { background: var(--ink); color: #fff; }
.archivo-mes--on:hover { background: var(--ink); }
.archivo-mes__label { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.archivo-mes__n { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.archivo-grupos { display: flex; flex-wrap: wrap; gap: 6px; }
.archivo-grupo { background: var(--surface); border: 1px solid var(--line); font: inherit; font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: inherit; cursor: pointer; padding: 5px 10px; }
.archivo-grupo:hover { background: var(--surface-2); }
.archivo-grupo--on { background: var(--ink); color: #fff; border-color: var(--ink); }
.archivo-grupo--empty { color: var(--ink-faint); border-color: var(--line-soft); }
.archivo-q { max-width: 420px; }

/* Alta de contraparte (137): dentro del modal de subida y por fila del lote. */
.alta-cp { display: flex; flex-direction: column; gap: 8px; margin: -4px 0 8px; }
.alta-cp__form { border: 1px solid var(--line); padding: 10px 12px; display: flex; flex-direction: column; gap: 10px; background: var(--surface-2); }
.lote-alta { display: flex; gap: 6px; align-items: center; margin-top: 4px; }
.lote-alta .input--sm { width: auto; min-width: 110px; }

.inicio-rules { margin: 0; padding-left: 20px; font-size: 13px; line-height: 1.6; max-width: 84ch; }
.inicio-rules li + li { margin-top: 6px; }
.inicio-cierre { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; padding: 20px 0 8px; border-top: 1px solid var(--line); margin-top: 12px; }
.inicio-cierre__text { margin: 0; font-size: 14px; line-height: 1.6; font-weight: 500; max-width: 76ch; }

@media (max-width: 920px) {
  .inicio-grid--3, .inicio-grid--2 { grid-template-columns: 1fr; }
  .inicio-hero__title { max-width: none; }
}

.sidebar__nav { flex: 1; padding: 8px 0 14px; display: flex; flex-direction: column; gap: 10px; }
.sidebar__section { display: flex; flex-direction: column; gap: 0; }
.sidebar__section-title {
  font-size: 9px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-faint); padding: 10px 16px 5px;
}
.nav-item {
  appearance: none; background: none; border: 0; width: 100%; text-align: left;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px; border-radius: 0; cursor: pointer;
  font: inherit; font-size: 10.5px; font-weight: 500; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.09em;
  transition: background 80ms, color 80ms;
}
.nav-item:hover { background: var(--bg-sunken); color: var(--ink); }
.nav-item--active { background: var(--ink); color: #fff; font-weight: 700; }
.nav-item--active:hover { background: var(--ink); color: #fff; }
/* Los iconos lucide son de trazo con stroke="currentColor": heredan el
   monocromo (negro sobre blanco, blanco sobre la fila activa) sin tocarlos. */
.nav-item__icon { display: inline-flex; width: 16px; height: 16px; flex-shrink: 0; }
.nav-item__icon svg { width: 100%; height: 100%; }
.nav-item__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item__mini { display: none; }

.sidebar__user {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-top: 1px solid var(--line);
  position: sticky; bottom: 0; background: var(--surface);
}
.sidebar__avatar {
  width: 28px; height: 28px; border-radius: 0; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ink); color: #fff; font-weight: 700; font-size: 12px;
  text-transform: uppercase;
}
.sidebar__user-meta { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.3; }
.sidebar__user-role {
  font-size: 10px; font-weight: 700; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.1em;
}
.sidebar__user-email { font-size: 10px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar__signout {
  appearance: none; background: none; border: 1px solid transparent; cursor: pointer; color: var(--ink-muted);
  padding: 6px; border-radius: 0; display: inline-flex; transition: background 80ms, color 80ms;
}
.sidebar__signout:hover { background: var(--danger); border-color: var(--danger); color: #fff; }

/* ---------------- riel colapsable (escritorio) --------------------------- */
.shell--nav-collapsed { grid-template-columns: 58px minmax(0, 1fr); }

.sidebar__collapse {
  position: absolute; top: 0; right: 0; width: 12px; height: 100%;
  background: none; border: 0; border-right: 2px solid transparent;
  cursor: pointer; padding: 0; z-index: 5;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-faint);
}
.sidebar__collapse:hover { background: var(--bg-sunken); border-right-color: var(--ink); color: var(--ink); }
.sidebar__collapse:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.sidebar__collapse-chevron { font-size: 12px; line-height: 1; user-select: none; }

.sidebar--collapsed .sidebar__brand { padding: 16px 0 14px; justify-content: center; }
.sidebar--collapsed .sidebar__brand-text { display: none; }
.sidebar--collapsed .sidebar__section-title { display: none; }
.sidebar--collapsed .sidebar__nav { padding: 8px 0 12px; align-items: stretch; }
.sidebar--collapsed .sidebar__section { align-items: stretch; gap: 0; }
.sidebar--collapsed .nav-item { padding: 9px; justify-content: center; }
.sidebar--collapsed .nav-item__label { display: none; }
.sidebar--collapsed .nav-item__icon { width: 18px; height: 18px; }
.sidebar--collapsed .sidebar__user { padding: 10px 6px; flex-direction: column; gap: 6px; }
.sidebar--collapsed .sidebar__user-meta { display: none; }

/* Móvil: el riel se vuelve una tira superior con scroll horizontal. */
@media (max-width: 920px) {
  .shell--saas { grid-template-columns: 1fr; }
  .sidebar {
    position: sticky; top: 0; height: auto; flex-direction: row; align-items: center;
    gap: 4px; z-index: 60; padding-right: 6px;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  .sidebar__brand { padding: 10px 12px; border-bottom: 0; border-right: 1px solid var(--line); }
  .sidebar__brand-text { display: none; }
  .sidebar__nav { flex-direction: row; padding: 6px 4px; gap: 2px; overflow-x: auto; scrollbar-width: none; }
  .sidebar__nav::-webkit-scrollbar { display: none; }
  .sidebar__section { flex-direction: row; gap: 2px; }
  .sidebar__section-title { display: none; }
  .nav-item { padding: 5px 8px 4px; white-space: nowrap; flex-direction: column; gap: 3px; letter-spacing: 0.06em; }
  .nav-item__label { display: none; }
  .nav-item__icon { width: 18px; height: 18px; }
  .nav-item__mini {
    display: block; font-size: 8.5px; line-height: 1; font-weight: 500;
    text-transform: uppercase; letter-spacing: 0.06em;
    max-width: 74px; overflow: hidden; text-overflow: ellipsis;
  }
  .nav-item--active .nav-item__mini { font-weight: 700; }
  .sidebar__collapse { display: none; }
  .sidebar__user { border-top: 0; border-left: 1px solid var(--line); padding: 6px 8px; position: static; }
  .sidebar__user-meta { display: none; }
  .shell__main { padding: 16px 14px 48px; }
  .shell__notice { padding: 12px 14px 0; }
  .page-header__title { font-size: 17px; }
  .kpi__value, .stat__value { font-size: 20px; }

  /* RED DE SEGURIDAD MÓVIL. Las tablas anchas (cartera 9 columnas,
     cuentaCorriente 10, nómina 13) no viven dentro de .split ni .grid-2, así que
     ningún breakpoint las alcanzaba: en teléfono empujaban el <body> entero de
     lado (medido: 713px de desborde). Mientras una pantalla no adopte
     tableWrap(), su contenedor se vuelve el scroll horizontal.
     El arreglo REAL por pantalla sigue siendo tableWrap() — esto solo evita que
     una pantalla sin migrar sea inusable en el teléfono del operador. */
  .card__body, .split__list, .split__detail, .pay-scroll, .section__body { overflow-x: auto; }
}

/* =========================  LOGIN  ======================================= */

.login {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px; background: var(--bg);
}
.login__split {
  display: grid; grid-template-columns: 1fr 1fr; width: 100%; max-width: 800px;
  border-radius: 0; overflow: hidden; box-shadow: none;
  border: 1px solid var(--line); background: var(--bg);
}
/* El panel deja de ser una landing de marketing: negro sólido, sin degradados. */
.login__panel {
  background: var(--ink); color: #fff; padding: 40px 34px;
  display: flex; flex-direction: column; justify-content: center; gap: 14px;
  border-right: 1px solid var(--line);
}
.login__panel-logo {
  width: 40px; height: 40px; border-radius: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: #fff; color: var(--ink); font-weight: 700; font-size: 20px;
  margin-bottom: 4px; box-shadow: none;
}
.login__panel-title {
  margin: 0; font-size: 18px; font-weight: 800; color: #fff;
  text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.2;
}
.login__panel-sub { margin: 0; font-size: 11px; line-height: 1.6; color: #999; }
.login__panel-points { margin: 8px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.login__panel-points li {
  font-size: 10px; color: #ccc; padding-left: 16px; position: relative;
  text-transform: uppercase; letter-spacing: 0.1em;
}
.login__panel-points li::before { content: "—"; position: absolute; left: 0; top: 0; color: #fff; font-weight: 700; }
.login__card {
  background: var(--bg); padding: 40px 34px; width: 100%;
  display: flex; flex-direction: column; gap: 16px; justify-content: center;
}
.login__title { margin: 0; font-size: 18px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; }
.login__subtitle {
  margin: 0; color: var(--ink-muted); font-size: 9px;
  text-transform: uppercase; letter-spacing: 0.16em; font-weight: 500;
}
.login__version {
  margin: 0; color: var(--ink-faint); font-size: 9px; text-align: center;
  text-transform: uppercase; letter-spacing: 0.12em; font-variant-numeric: tabular-nums;
}

@media (max-width: 760px) {
  .login { padding: 12px; }
  .login__split { grid-template-columns: 1fr; max-width: 420px; }
  .login__panel { padding: 24px; gap: 8px; border-right: 0; border-bottom: 1px solid var(--line); }
  .login__panel-points { display: none; }
}

.boot-error {
  max-width: 640px; margin: 40px auto; padding: 20px; border: 1px solid var(--danger);
  border-radius: 0; background: var(--bg); color: var(--danger); box-shadow: none;
  font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em;
}

/* =========================  PANTALLAS / CARDS  =========================== */

.screen { display: flex; flex-direction: column; gap: 22px; }
/* .screen__title sigue existiendo para las pantallas que aún no adoptan
   pageHeader(): se ve igual que el título del encabezado nuevo. */
.screen__title {
  margin: 0; font-size: 20px; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.06em; text-wrap: balance;
}
.screen__titlebar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
/* Un .screen anidado en otro (fleteros L288) no debe duplicar el ritmo. */
.screen .screen { gap: 18px; }

.card {
  border: 1px solid var(--line); background: var(--bg); border-radius: 0;
  box-shadow: none; overflow: visible;
}
.card__header {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  padding: 12px 18px; border-bottom: 1px solid var(--line); background: var(--surface);
}
.card__title {
  margin: 0; font-size: 11px; font-weight: 700; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.14em; text-wrap: balance;
}
/* Contador/monto que acompaña al título sin fundirse con él. */
.card__count {
  display: inline-block; margin-left: 10px; padding: 2px 7px;
  border: 1px solid var(--line); background: var(--ink); color: #fff;
  font-size: 9px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; font-variant-numeric: tabular-nums; vertical-align: 1px;
}
.card__meta {
  font-size: 10px; color: var(--ink-muted); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.1em; font-variant-numeric: tabular-nums;
}
.card__body { padding: 18px; display: flex; flex-direction: column; gap: 14px; }
.card__actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.card__body h4 { margin: 6px 0 0; font-size: 11px; font-weight: 700; color: var(--ink); text-transform: uppercase; letter-spacing: 0.14em; }
/* Una card dentro de otra pierde el marco: no se apilan dos bordes. */
.card__body > .card { border-left: 0; border-right: 0; margin: 0 -18px; }
.card__body > .card:last-child { border-bottom: 0; margin-bottom: -18px; }

/* `1fr` NO es `minmax(0, 1fr)`: el tamaño mínimo automático de un ítem de
   rejilla es su min-content, así que una card con tabla ancha ESTIRA su pista
   y empuja la página entera a scroll horizontal (tablero medía 1417px de ancho
   con la ventana en 1280). Con `minmax(0, …)` la pista puede encogerse y el
   scroll se queda dentro de .table-wrap, que es donde debe vivir.
   Lo mismo para .split: los suelos de 340/360px sumaban 720px + gap y hacían
   desbordar el contenido en anchos intermedios; el suelo se conserva como
   preferencia vía las fracciones, no como mínimo duro. */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.split { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); gap: 20px; align-items: start; }
.grid-2 > *, .split > * { min-width: 0; }
.split__list, .split__detail { min-width: 0; overflow-x: auto; }

@media (max-width: 900px) {
  .grid-2, .split { grid-template-columns: minmax(0, 1fr); }
  .shell__main { padding: 16px 14px 48px; }
}

/* =========================  FORMULARIOS  ================================= */

.field { display: flex; flex-direction: column; gap: 5px; font-size: 12px; min-width: 0; }
.field__label {
  font-weight: 700; font-size: 10px; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.12em; line-height: 1.35;
}
.field__req { color: var(--danger); font-weight: 700; margin-left: 3px; }
.field__hint { color: var(--ink-muted); font-size: 10.5px; line-height: 1.45; }

.input, .field__input {
  font: inherit; font-size: 13px; padding: 9px 11px; border: 1px solid var(--line);
  border-radius: 0; background: var(--bg); color: var(--ink);
  width: 100%; min-width: 0; transition: none; appearance: auto;
}
.input::placeholder, .field__input::placeholder { color: var(--ink-subtle); }
.input:focus, .field__input:focus { outline: 2px solid var(--ink); outline-offset: -2px; box-shadow: none; }
.input:disabled, .field__input:disabled { background: var(--bg-sunken); color: var(--ink-faint); cursor: not-allowed; }
.input--textarea { resize: vertical; font-family: var(--font); }
.input--sm, .ws-amt, .pay-cell-input { padding: 6px 8px; font-size: 12px; }
select.input, select.field__input { cursor: pointer; }
input[type="checkbox"], input[type="radio"] {
  width: 14px; height: 14px; min-width: 14px; padding: 0; margin: 0;
  border: 1px solid var(--line); accent-color: var(--ink); cursor: pointer; flex-shrink: 0;
}
input[type="file"] { padding: 7px 9px; font-size: 12px; }

.filters {
  display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: 0; padding: 12px 14px; background: var(--surface-2);
}
.filters .field { min-width: 140px; }
.filters__actions { padding-bottom: 2px; }

/* =========================  BOTONES  ===================================== */

.btn {
  appearance: none; font: inherit; font-weight: 700; font-size: 11px; cursor: pointer;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  padding: 9px 14px; border-radius: 0; box-shadow: none;
  text-transform: uppercase; letter-spacing: 0.1em; white-space: nowrap;
  transition: background 80ms, color 80ms;
  display: inline-flex; align-items: center; gap: 6px;
}
.btn:hover:not(:disabled) { background: var(--ink); color: #fff; }
.btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; box-shadow: none; }
.btn:disabled { opacity: 0.35; cursor: not-allowed; box-shadow: none; }

.btn--primary { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn--primary:hover:not(:disabled) { background: var(--bg); color: var(--ink); }

/* Ghost/quiet: la acción de consulta dentro de una tabla — no compite con la
   acción real de la sección. Sin él, "Ver" pesa lo mismo que "Eliminar". */
/* Acción principal de una pantalla: se ve como lo que es. `small` empequeñece
   los botones de fila; `large` es para el verbo que la gente vino a hacer —en
   Documentos, «Subir documento». Mismo lenguaje visual, otra escala. */
.btn--large {
  font-size: 11px; letter-spacing: 0.14em; padding: 11px 22px; font-weight: 800;
}

/* El vacío con llamada a la acción: el botón dentro del hueco, no una
   instrucción que manda a buscarlo a la otra punta. */
.field__hint--warn { min-height: 1.2em; margin-top: 4px; font-size: 11px; font-weight: 700; color: var(--ink); }
.field__hint--warn:empty { display: none; }

/* Subida por lote: cada fila reporta su suerte. */
.input--sm { padding: 4px 7px; font-size: 11.5px; }
.table--compact td, .table--compact th { padding: 6px 8px; }
.row--error td { background: var(--bg-sunken); }
.chip--ok { background: var(--ink); color: #fff; border-color: var(--ink); }
.chip--duplicado { border-style: dashed; }
.chip--subiendo { opacity: 0.6; }
.muted { color: var(--ink-soft, #666); font-size: 10.5px; margin-top: 2px; }

.empty--cta { padding: 34px 16px; }

/* Vista previa: una herramienta construida que todavía no se habilita para
   este rol. Se ve como pieza del sistema —no como error ni como hueco. */
.preview { border: 1px solid var(--line); background: var(--bg-sunken); padding: 26px 22px; }
.preview__badge {
  display: inline-block; font-size: 9.5px; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; background: var(--ink); color: #fff; padding: 4px 9px; margin-bottom: 12px;
}
.preview__title { margin: 0 0 8px; font-size: 15px; font-weight: 800; letter-spacing: -0.01em; }
.preview__body { margin: 0; max-width: 62ch; line-height: 1.55; color: var(--ink-soft, inherit); }
.empty__action { margin-top: 14px; display: flex; justify-content: center; }

.btn--ghost, .btn--quiet {
  border-color: var(--line-soft); color: var(--ink-muted); font-weight: 500; background: var(--bg);
}
.btn--ghost:hover:not(:disabled), .btn--quiet:hover:not(:disabled) { background: var(--bg-sunken); color: var(--ink); border-color: var(--line); }

.btn--danger { border-color: var(--danger); color: var(--danger); background: var(--bg); }
.btn--danger:hover:not(:disabled) { background: var(--danger); color: #fff; border-color: var(--danger); }

/* warn ya no es ámbar: es un botón normal con más peso. */
.btn--warn { border-color: var(--ink); background: var(--bg); color: var(--ink); font-weight: 700; }
.btn--warn:hover:not(:disabled) { background: var(--ink); color: #fff; }

.btn--small { padding: 5px 9px; font-size: 9.5px; letter-spacing: 0.08em; }

/* Un botón DENTRO de una tabla se pone a la medida de la fila: con el tamaño
   normal, la columna de acciones se salía del panel (en Clientes, "Editar" y
   "Desactivar" quedaban cortados a media palabra dentro del .table-wrap) y
   además engordaba cada fila. Misma métrica que .btn--small, sin tocar un solo
   llamador. */
.table td .btn { padding: 5px 9px; font-size: 9.5px; letter-spacing: 0.08em; }

.confirm-pair { display: inline-flex; gap: 4px; align-items: center; flex-wrap: wrap; }

/* =========================  TABLAS  ====================================== */

.table { width: 100%; border-collapse: collapse; font-size: 12.5px; background: var(--surface); }
.table th {
  text-align: left; font-size: 9.5px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-muted);
  padding: 9px 12px; border-bottom: 1px solid var(--line);
  background: var(--surface); position: sticky; top: 0; z-index: 1; white-space: nowrap;
}
.table td { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
/* Primera columna = identidad de la fila: pesa más. */
.table tbody td:first-child { font-weight: 700; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-2); }
.table--clickable tbody tr { cursor: pointer; }
.table--clickable tbody tr:hover, .table--clickable-row:hover { background: var(--bg-sunken); }
.table--clickable-row { cursor: pointer; }
.row--selected { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); }
.row--selected td:first-child { font-weight: 800; }
.row--inactive { color: var(--ink-faint); }
.row--inactive td:first-child { font-weight: 500; }
.td--num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.td--num--strong { font-weight: 700; }
.td--neg { color: var(--danger); }
.td--actions { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
/* Columna de TEXTO LIBRE (notas, motivos): necesita un ancho mínimo legible.
   Sin él, el reparto automático le daba lo que sobraba —a veces 60px— y una
   nota de báscula salía en ocho renglones de dos palabras. La tabla prefiere
   desplazarse dentro de su .table-wrap antes que volver ilegible una columna. */
.td--text { min-width: 150px; }
/* Tabla dentro de un panel estrecho (mitad de un split o de una rejilla de 2):
   el `nowrap` del encabezado + 12px de padding empujaban la última columna
   fuera del .table-wrap y la acción de cada fila salía cortada a media palabra
   (Clientes: "Editar" / "Desactivar"). Aquí el encabezado puede partirse en dos
   renglones —son 9.5px en mayúsculas, se lee igual— y el aire se reduce a 10px:
   con eso las tablas de Clientes dejan de desbordar y no se pierde ni una
   columna. Las tablas anchas a pantalla completa no cambian. */
.split__detail .table th, .split__list .table th, .grid-2 .table th { white-space: normal; }
.split__detail .table :is(th, td),
.split__list .table :is(th, td),
.grid-2 .table :is(th, td) { padding-left: 10px; padding-right: 10px; }
.table--lines .input { min-width: 80px; }
/* La fila de totales de un tbody/tfoot: regla negra arriba y peso alto. */
.row--total td, .table tfoot td, .cpq-foot td {
  border-top: 1px solid var(--line); font-weight: 700; background: var(--surface-2);
}
.cpq-foot--diff td { border-top: 0; }
/* Fila crítica: el único rojo de una tabla. */
.row--critical { background: var(--danger-soft); box-shadow: inset 3px 0 0 var(--danger); }
.row--critical:hover { background: #ffdede; }
.row--critical td:first-child { color: var(--danger); }

/* =========================  AVISOS / CHIPS  ============================== */

.notice {
  padding: 11px 14px; border: 1px solid var(--line); border-radius: 0;
  font-size: 12px; background: var(--surface); box-shadow: none; line-height: 1.55;
}
.notice--ok   { background: var(--bg); border-color: var(--line); color: var(--ink); font-weight: 500; }
.notice--warn { background: var(--bg); border-color: var(--line); color: var(--ink); font-weight: 700; border-left-width: 4px; }
.notice--error {
  background: var(--bg); border-color: var(--danger); color: var(--danger);
  font-weight: 700; border-left-width: 4px;
}
/* notice--info EXISTE ahora: 21 llamadas a noticeBox("info") salían sin estilo
   propio, indistinguibles del contenedor genérico. Es el aviso más tenue. */
.notice--info { background: var(--bg-sunken); border-color: var(--line-soft); color: var(--ink-muted); }
.notice--alcance { border-style: dashed; background: var(--surface-2); color: var(--ink-muted); }

/* --- Chips: TRES especies, jamás color solo ------------------------------
   Las especies están ORDENADAS por volumen visual y ese orden es la mitad del
   sistema:  ROJO RELLENO  >  NEGRO RELLENO  >  BORDE.
   Importa porque la app usa escaleras de severidad (crítica > aviso > info)
   sobre estas clases. Con el rojo en tinte claro, "Aviso" (negro relleno) se
   leía MÁS fuerte que "Crítica" (rojo tenue) — la escalera al revés, en el
   Tablero, que es la primera pantalla que el operador abre. El rojo relleno
   la endereza para TODO llamador viejo sin tocar un solo render.
   (#d00000 con texto blanco = 5.7:1 de contraste; pasa AA.) */
.chip {
  display: inline-block; padding: 2px 8px; border: 1px solid var(--line);
  border-radius: 0; font-size: 9.5px; font-weight: 700; white-space: nowrap;
  color: var(--ink); background: var(--bg);
  text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.6;
}
/* (a) NEGRO RELLENO — requiere acción / crítico operativo. */
.chip--solid, .chip--pending, .chip--warn { background: var(--ink); color: #fff; border-color: var(--ink); }
/* (b) BORDE — neutral / informativo / cerrado. */
.chip--neutral, .chip--captured, .chip--shipped, .chip--invoiced, .chip--settled {
  background: var(--bg); color: var(--ink); border-color: var(--line);
}
/* (c) ROJO RELLENO — peligro / vencido / anulado / rechazado. La especie más
   fuerte del sistema: nada debe verse más alto que esto. */
.chip--danger, .chip--cancelled {
  background: var(--danger); color: #fff; border-color: var(--danger);
}
/* Chip clicable (filtros de Documentos). */
.chip--button { cursor: pointer; font: inherit; font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; padding: 4px 10px; }
.chip--button:hover { background: var(--bg-sunken); }
.chip--button.is-active, .chip--button[aria-pressed="true"] { background: var(--ink); color: #fff; border-color: var(--ink); }
.chip__count { font-variant-numeric: tabular-nums; opacity: 0.65; margin-left: 5px; }
.chip--button.is-active .chip__count { opacity: 0.75; }

.empty {
  padding: 30px 20px; text-align: center; color: var(--ink-muted);
  border: 1px dashed var(--line-soft); border-radius: 0; font-size: 12px; line-height: 1.6;
}
.empty__next { display: block; margin-top: 6px; font-size: 10px; text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700; color: var(--ink); }
.loading { padding: 16px; color: var(--ink-muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; font-weight: 500; }
.loading--page { padding: 60px; text-align: center; }
.muted { color: var(--ink-muted); font-size: 11.5px; margin: 0; line-height: 1.55; }
.cont-tiny { font-size: 11px; margin: 6px 0 0; }

/* =========================  DETALLE / TIMELINE  ========================== */

.info-row { display: flex; gap: 12px; font-size: 12.5px; padding: 5px 0; border-bottom: 1px solid var(--line-soft); }
.info-row:last-child { border-bottom: 0; }
.info-row__label {
  min-width: 168px; color: var(--ink-muted); font-size: 9px; padding-top: 3px;
  text-transform: uppercase; letter-spacing: 0.12em; font-weight: 500; flex-shrink: 0;
}
.info-row__value { flex: 1; min-width: 0; font-weight: 500; overflow-wrap: anywhere; }

.detail-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.detail-head__total { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }

.timeline { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
.timeline__item {
  display: flex; gap: 10px; flex-wrap: wrap; font-size: 11.5px;
  border-bottom: 1px solid var(--line-soft); padding: 8px 0;
}
.timeline__item:last-child { border-bottom: 0; }
.timeline__when { color: var(--ink-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.timeline__type { font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; }
.timeline__transition { color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.timeline__actor { color: var(--ink-muted); }
.timeline__reason { flex-basis: 100%; color: var(--ink-muted); }

/* Zona de riesgo REAL: era `display:flex; justify-content:flex-end` y se usaba
   como CONTENEDOR de bloques completos (ventas L331, facturar L546,
   aprobaciones L830) — un bug de maquetado silencioso. Ahora es un marco. */
.danger-zone {
  display: flex; flex-direction: column; gap: 10px; align-items: stretch;
  border: 1px solid var(--danger); border-radius: 0; padding: 14px 16px; background: var(--bg);
}
.danger-zone::before {
  content: "Zona de riesgo"; display: block;
  font-size: 9px; font-weight: 700; color: var(--danger);
  text-transform: uppercase; letter-spacing: 0.16em;
}
.danger-zone p { margin: 0; font-size: 11.5px; }
/* Un aviso DENTRO de la zona de riesgo no repite el marco: la zona ya lo pone.
   Dos marcos rojos anidados eran la tercera caja de §2 (card › danger-zone ›
   notice) y además restaban fuerza al de fuera. Se conserva la regla izquierda
   gruesa y el peso, que es lo que hace legible el aviso. */
.danger-zone > .notice,
.panel > .notice { border-width: 0 0 0 4px; padding: 2px 0 2px 12px; background: transparent; }
/* La variante de una sola acción alineada a la derecha conserva el gesto viejo. */
.danger-zone--inline { flex-direction: row; justify-content: flex-end; border: 0; padding: 0; }
.danger-zone--inline::before { content: none; }

/* =========================  NUEVA VENTA  ================================= */

.refs-banner {
  margin: 0; padding: 10px 14px; background: var(--bg); border: 1px solid var(--line);
  border-left-width: 4px; border-radius: 0; font-weight: 700; font-size: 11px;
  color: var(--ink); text-transform: uppercase; letter-spacing: 0.06em;
}
/* `display: block` porque el `margin-top` ya declaraba la intención: es una
   línea de apoyo DEBAJO del dato, no texto pegado a su derecha. Catálogo la
   escribe como <span> y la celda salía como "01010101Sin capturar", chocando
   además con la columna siguiente. Todos los demás llamadores ya usan <div>,
   así que para ellos no cambia nada. */
.line-hint { display: block; font-size: 10.5px; color: var(--ink-muted); margin-top: 3px; }
/* line-hint--warn era SOLO color ámbar (moría en monocromo) y es el único
   marcador de alerta en tablero/nuevaVenta/cartera/posRecon. Ahora tiene FORMA:
   mayúsculas, peso 700 y tinta plena — que es exactamente lo que §2 pide (la
   jerarquía la hacen el peso y las mayúsculas). El triángulo que llevaba delante
   se quitó: §4 lo nombra entre los glifos que NO son estado, y en un tema
   monocromo era la única mancha con forma de emoji de la línea. */
.line-hint--warn {
  color: var(--ink); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
}
.line-hint--danger { color: var(--danger); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.line-total { font-weight: 700; }

.totals { display: flex; flex-direction: column; gap: 0; max-width: 460px; border: 1px solid var(--line); }
.totals__row {
  display: flex; justify-content: space-between; gap: 20px; font-size: 11px;
  padding: 8px 12px; border-bottom: 1px solid var(--line-soft);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-muted); font-weight: 500;
}
.totals__row:last-child { border-bottom: 0; }
.totals__value { font-weight: 700; color: var(--ink); letter-spacing: 0; }
.totals__row--grand {
  font-size: 15px; font-weight: 700; color: var(--ink);
  border-top: 1px solid var(--line); border-bottom: 0; padding: 12px;
  letter-spacing: 0.04em;
}
.totals__row--grand .totals__value { font-size: 20px; letter-spacing: -0.02em; }

.panel h3 { margin: 0; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; }
.panel p { margin: 0; font-size: 12px; }
/* Éxito y bloqueo ya no se distinguen por color de fondo (verde/rojo suave):
   el éxito es un marco negro grueso, el bloqueo el único marco rojo. */
.panel--ok { background: var(--bg); border: 2px solid var(--ink); }
.panel--lockout { background: var(--bg); border: 2px solid var(--danger); }
.panel--lockout h3 { color: var(--danger); }
.panel__figure { font-size: 30px; font-weight: 700; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }

.override-row {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  border-top: 1px solid var(--line-soft); padding-top: 8px; font-size: 11.5px;
}
.override-row .input { max-width: 240px; }

/* =========================  TABLERO  ===================================== */

.tablero-banner {
  border: 1px solid var(--line); border-left: 4px solid var(--line);
  border-radius: 0; padding: 18px 20px; display: flex; flex-direction: column; gap: 5px;
  background: var(--bg); box-shadow: none;
}
.tablero-banner__headline {
  font-size: 18px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; text-wrap: balance;
}
.tablero-banner__sub { font-size: 12px; color: var(--ink-muted); line-height: 1.55; }
.tablero-banner__meta { font-size: 10px; color: var(--ink-faint); margin-top: 4px; text-transform: uppercase; letter-spacing: 0.1em; }
/* El semáforo deja de ser color de fondo: el peso del borde izquierdo y el
   color del titular hacen la jerarquía. Rojo = ciego/peligro. */
.tablero-banner--red { border-left: 6px solid var(--danger); border-color: var(--danger); background: var(--bg); }
.tablero-banner--red .tablero-banner__headline { color: var(--danger); }
.tablero-banner--amber { border-left: 6px solid var(--ink); background: var(--bg); }
.tablero-banner--amber .tablero-banner__headline { color: var(--ink); }
.tablero-banner--green { border-left: 2px solid var(--line-soft); background: var(--bg); }
.tablero-banner--green .tablero-banner__headline { color: var(--ink); font-weight: 700; }

/* =========================  MODAL  ======================================= */

.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0, 0, 0, 0.6); backdrop-filter: none;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 48px 16px; overflow-y: auto;
}
.modal-card {
  background: var(--bg); border: 1px solid var(--line); border-radius: 0;
  box-shadow: none; width: 100%; max-width: 620px;
  display: flex; flex-direction: column; max-height: calc(100vh - 96px); overflow: hidden;
}
.modal-card--wide { max-width: 780px; }
.modal-card--full { max-width: 1180px; }
.modal-card__header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--line); background: var(--surface);
  flex-shrink: 0;
}
.modal-card__title { margin: 0; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; }
/* El glifo de cierre necesita cuerpo propio: heredando el 9.5px de .btn--small
   quedaba un aspa diminuta en un botón de 27px. Mismas medidas que el cierre de
   pos-v2 (.modal__close). */
.modal-card__close { font-size: 16px; line-height: 1; padding: 4px 10px; letter-spacing: 0; }
.modal-card__body { padding: 18px; display: flex; flex-direction: column; gap: 14px; overflow-y: auto; }

@media (max-width: 640px) {
  .modal-overlay { padding: 12px 8px; }
  .modal-card { max-height: calc(100vh - 24px); }
}

/* =========================  CLABE  ======================================= */

.clabe-panel {
  border: 1px solid var(--line); border-radius: 0; padding: 16px; text-align: center;
  display: flex; flex-direction: column; gap: 8px; background: var(--surface-2);
}
.clabe-panel--pay { background: var(--bg); border: 2px solid var(--ink); }
.clabe-panel__caption {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--ink-muted); font-weight: 500;
}
.clabe-panel__headline { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; }
.clabe-big {
  font-size: 26px; font-weight: 700; letter-spacing: 0.14em; font-family: var(--num);
  font-variant-numeric: tabular-nums; word-break: break-all; line-height: 1.25; color: var(--ink);
}
.clabe-panel__meta { font-size: 12px; }
.clabe-panel__actions { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.clabe-missing { color: var(--danger); font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; }
/* La advertencia antifraude: el ÚNICO bloque rojo del modal de aprobación. */
.clabe-warning {
  border: 2px solid var(--danger); background: var(--danger-soft); color: var(--danger);
  padding: 12px 14px; font-size: 12px; font-weight: 700; line-height: 1.5; text-align: left;
}

/* =========================  PAGOS A PROVEEDORES (029)  =================== */

.ws-txn-list { display: flex; flex-direction: column; gap: 0; margin: 6px 0 4px; max-height: 340px; overflow-y: auto; border: 1px solid var(--line); }
.ws-txn-filter {
  width: 100%; max-width: 420px; padding: 8px 11px; border: 1px solid var(--line);
  border-radius: 0; margin: 4px 0 6px; font: inherit; font-size: 13px; background: var(--bg);
}
.ws-txn-filter:focus { outline: 2px solid var(--ink); outline-offset: -2px; box-shadow: none; }
.ws-txn-row {
  /* La columna del importe era de 120px fijos, pero su contenido va en nowrap y
     una parcial ("$96,000.00 MXN (de $120,000.00 MXN)") mide el doble: se salía
     de la pista y empujaba el chip del proveedor fuera de la lista, que lo
     recortaba. Con `auto` el importe toma lo que necesita y quien cede es el
     nombre del beneficiario, que ya trunca con elipsis. */
  display: grid; grid-template-columns: 92px minmax(0, 1fr) auto auto; gap: 12px; align-items: center;
  text-align: left; padding: 9px 12px; border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0;
  background: var(--bg); cursor: pointer; font-size: 12.5px;
}
.ws-txn-row:last-child { border-bottom: 0; }
.ws-txn-row:hover { background: var(--surface-2); }
.ws-txn-row.is-selected { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); }
.ws-txn-date { font-variant-numeric: tabular-nums; color: var(--ink-muted); font-size: 11px; }
.ws-txn-benef { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }
.ws-txn-amt { font-weight: 700; white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; }
.ws-txn-guess {
  font-size: 9px; color: var(--ink); background: var(--bg); border: 1px solid var(--line);
  padding: 2px 7px; border-radius: 0; white-space: nowrap;
  text-transform: uppercase; letter-spacing: 0.1em; font-weight: 700;
}
.ws-supplier-block { border: 1px solid var(--line); border-radius: 0; padding: 12px 14px; margin: 8px 0; background: var(--surface-2); }
.ws-supplier-head { margin-bottom: 6px; }
.ws-po-row { display: grid; grid-template-columns: minmax(0, 1fr) auto 120px; gap: 12px; align-items: center; padding: 6px; border-radius: 0; }
.ws-po-row.is-checked { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); }
.ws-po-check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.ws-po-folio { font-weight: 700; }
.ws-po-rest { font-variant-numeric: tabular-nums; color: var(--ink-muted); font-size: 11px; }
.ws-amt { width: 110px; border: 1px solid var(--line); border-radius: 0; text-align: right; font: inherit; font-variant-numeric: tabular-nums; }
.ws-pay-footer { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.ws-owe { display: flex; flex-direction: column; gap: 0; }
.ws-owe-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 14px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); font-variant-numeric: tabular-nums; }

/* --- Señales: mini-gráficas ---------------------------------------------- */
.spark-row { display: flex; align-items: center; gap: 12px; margin: 4px 0 10px; flex-wrap: wrap; }
.spark { position: relative; }
.spark svg { display: block; }
.spark__caption { font-size: 11px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.spark__tip {
  position: absolute; transform: translate(-50%, -135%);
  background: var(--ink); color: var(--bg);
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
  padding: 3px 8px; border-radius: 0; white-space: nowrap;
  pointer-events: none; box-shadow: none; z-index: 5;
}

/* --- Comparativo multi-cadena -------------------------------------------- */
.cmp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 22px; }
.cmp-block { min-width: 0; }
.cmp-block__title { font-size: 11px; font-weight: 700; color: var(--ink); margin: 0 0 6px; text-transform: uppercase; letter-spacing: 0.12em; }
.cmp-chart { margin: 2px 0 4px; }
.cmp-legend { display: flex; gap: 16px; flex-wrap: wrap; margin: 0 0 6px; }
.cmp-legend__item { display: inline-flex; align-items: center; gap: 6px; font-size: 10px; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 500; }
.cmp-legend__sw { width: 14px; height: 0; border-top: 2px solid var(--ink); border-radius: 0; display: inline-block; }
.cmp-legend__sw--dash { border-top-style: dashed; }
.cmp-plot { position: relative; }
.cmp-plot svg { display: block; width: 100%; height: auto; }
.cmp-tip {
  position: absolute; transform: translate(-50%, 0);
  background: var(--ink); color: var(--bg);
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
  padding: 5px 9px; border-radius: 0; white-space: nowrap;
  pointer-events: none; box-shadow: none; z-index: 5; line-height: 1.5;
}
.cmp-tip__d { font-weight: 700; margin-bottom: 2px; opacity: 0.7; }
.cmp-tip__sw { display: inline-block; width: 8px; height: 8px; border-radius: 0; margin-right: 4px; vertical-align: middle; }

/* --- Documentos: fila de filtros por categoría --------------------------- */
.doc-filter { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 14px; }
.doc-filter .chip {
  cursor: pointer; border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  font: inherit; font-size: 9.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.1em; padding: 5px 10px; line-height: 1.4;
}
.doc-filter .chip:hover { background: var(--bg-sunken); }
.doc-filter .chip--invoiced, .doc-filter .chip.is-active { background: var(--ink); color: #fff; border-color: var(--ink); }

/* ==========================================================================
   Contabilidad (061) — pólizas ContPAQi + XML SAT + modal estilo ContPAQi.
   ========================================================================== */
.cont-controls { display: flex; flex-wrap: wrap; gap: 12px; }
.cont-controls .field { flex: 1 1 160px; }
.cont-typerow { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.cont-typechk {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--ink);
  cursor: pointer; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 500;
  border: 1px solid var(--line-soft); padding: 5px 9px;
}
.cont-typechk:hover { border-color: var(--line); background: var(--surface-2); }
.cont-typechk input { accent-color: var(--ink); }

.cont-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; background: transparent; border: 0; margin-bottom: 12px; }
.cont-stat {
  background: var(--surface); border: 0; border-radius: 0; padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px; min-width: 0; box-shadow: 0 0 0 1px var(--line);
}
.cont-stat__k { display: block; font-size: 9px; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.14em; font-weight: 500; }
.cont-stat__v { display: block; font-size: 19px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
/* cont-ok / cont-bad eran SOLO color (verde/rojo). En monocromo el "ok" es
   tinta normal y el "bad" conserva el único rojo, con marca textual. */
.cont-ok  { color: var(--ink); font-weight: 700; }
.cont-bad { color: var(--danger); font-weight: 700; }

.cont-actionbar { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; justify-content: space-between; margin-bottom: 14px; }
.cont-rfc { flex: 0 1 240px; }
.cont-rfc input { text-transform: uppercase; }
.cont-exports { display: flex; flex-wrap: wrap; gap: 14px; }
.cont-export-group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; border: 1px solid var(--line-soft); border-radius: 0; }
.cont-grp { max-width: 90px; }
.cont-chip-pend { margin-left: 0.5rem; }
.cont-row-pend > td:first-child { border-left: 3px solid var(--ink); }
.cont-muted-v { color: var(--ink-muted); }
.cont-table td--num, .cont-table .td--num { font-variant-numeric: tabular-nums; }
.cont-file { font-size: 11.5px; word-break: break-all; font-variant-numeric: tabular-nums; }

/* Badges de tipo de póliza (Ingreso / Egreso / Diario) — tres FORMAS. */
.poliza-badge {
  display: inline-block; font-size: 9px; font-weight: 700; padding: 2px 7px;
  border-radius: 0; border: 1px solid var(--line); letter-spacing: 0.12em; text-transform: uppercase;
  background: var(--bg); color: var(--ink);
}
.poliza-badge--ing { background: var(--ink); color: #fff; border-color: var(--ink); }
.poliza-badge--egr { background: var(--bg); color: var(--ink); border-color: var(--line); }
.poliza-badge--dia { background: var(--bg); color: var(--ink-muted); border-color: var(--line-soft); }

/* ---- Modal de captura estilo ContPAQi ---- */
.cpq-head { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; padding: 0; margin-bottom: 12px; background: transparent; border: 0; }
.cpq-head__cell {
  display: flex; flex-direction: column; gap: 3px; padding: 9px 12px;
  background: var(--surface); min-width: 0; box-shadow: 0 0 0 1px var(--line);
}
.cpq-head__cell--wide { grid-column: span 2; }
.cpq-grid th, .cpq-grid td { padding: 6px 10px; }
.cpq-grid .cpq-cta { font-family: var(--num); font-variant-numeric: tabular-nums; font-size: 12px; color: var(--ink); white-space: nowrap; font-weight: 700; }
.cpq-grid .cpq-cargo, .cpq-grid .cpq-abono { font-variant-numeric: tabular-nums; }
.cpq-uuid, .cpq-uuidchip {
  display: inline-block; font-size: 8.5px; font-weight: 700; color: var(--ink);
  background: var(--bg); border: 1px solid var(--line); border-radius: 0;
  padding: 0 5px; cursor: help; letter-spacing: 0.06em; text-transform: uppercase;
}

/* ---- Nómina (063) ---- */
.pay-scroll { overflow-x: auto; border: 1px solid var(--line); }
.pay-scroll .table { border: 0; }
.pay-cell-input { width: 6rem; min-width: 4.5rem; text-align: right; font-variant-numeric: tabular-nums; }
.pay-form-row { display: flex; flex-wrap: wrap; gap: 12px; }
.pay-form-row .field { flex: 1 1 160px; }
/* Encabezado de grupo sobre las columnas (PERCEPCIONES | DEDUCCIONES). */
.pay-group th {
  text-align: center; border-bottom: 1px solid var(--line); background: var(--bg-sunken);
  font-size: 9px; letter-spacing: 0.16em;
}

/* ---- Cotizador (070) ---- */
.cot-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
.cot-field .input { width: 100%; }
.cot-headline {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 8px 20px; padding: 12px 0; border-bottom: 1px solid var(--line);
}
.cot-headline__big { font-size: 34px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }
.cot-headline__unit { font-size: 14px; color: var(--ink-muted); margin-left: 2px; }
.cot-headline__margins { font-size: 12px; color: var(--ink); }
/* La fila "vinculante" era solo fondo teal: ahora la marca el peso + una regla. */
.cot-binding td { background: var(--bg-sunken); font-weight: 700; box-shadow: inset 3px 0 0 var(--ink); }
.cot-tag {
  font-size: 9px; font-weight: 700; color: #fff; background: var(--ink);
  text-transform: uppercase; letter-spacing: 0.12em; padding: 2px 7px; margin-left: 6px;
}

/* --- Políticas contables (081) ------------------------------------------- */
.pol-block { border-top: 1px solid var(--line-soft); padding: 14px 0 4px; }
.pol-block:first-of-type { border-top: 0; }
.pol-block__q {
  font-size: 12px; font-weight: 700; color: var(--ink); margin: 0 0 4px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.pol-opts { display: flex; flex-direction: column; gap: 0; margin: 8px 0 0; border: 1px solid var(--line-soft); }
.pol-opt {
  display: flex; gap: 9px; align-items: flex-start; padding: 9px 11px;
  border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0; cursor: pointer; background: var(--bg);
}
.pol-opt:last-child { border-bottom: 0; }
.pol-opt:hover { background: var(--surface-2); }
.pol-opt--chosen { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); }
.pol-opt input { margin-top: 2px; accent-color: var(--ink); }
.pol-opt__body { display: flex; flex-direction: column; gap: 2px; }
.pol-opt__label { font-size: 12px; font-weight: 700; color: var(--ink); }
.pol-opt__now { font-weight: 700; color: var(--ink); text-transform: uppercase; letter-spacing: 0.08em; font-size: 10px; }
.pol-opt__detail { font-size: 11.5px; color: var(--ink-muted); line-height: 1.5; }

/* --- Ciclo contable (F7 · 080/100) --------------------------------------- */
/* SIN marco (deuda §12 del contrato): estos tres envoltorios viven DENTRO de la
   card del ciclo y cada uno traía su propio borde negro, así que un aviso o una
   tabla adentro ya era la tercera caja y la pantalla más densa de la app se leía
   como una pila de marcos iguales. Se quedan con el espaciado y un fondo hundido
   —suficiente para agrupar— y el único borde de la zona vuelve a ser el de la
   card. */
.ciclo-corte, .ciclo-apert, .ciclo-pf {
  display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-start;
  justify-content: space-between; padding: 12px 14px; margin: 4px 0 12px;
  background: var(--surface-2); border: 0; border-radius: 0;
}
.ciclo-pf { display: block; }
.ciclo-corte__txt, .ciclo-apert__txt { flex: 1 1 320px; }
.ciclo-corte__txt p, .ciclo-apert__txt p { margin: 0 0 4px; font-size: 12px; line-height: 1.55; color: var(--ink); }
.ciclo-apert__t { display: block; font-size: 11px; font-weight: 700; color: var(--ink); margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.12em; }
.ciclo-pf .notice { margin: 8px 0 0; }
.ciclo-pf > p { margin: 8px 0 0; }

.ciclo-pol { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.ciclo-pol .notice { flex: 1 1 320px; margin: 0; }

.ciclo-mes { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; margin-bottom: 10px; }
.ciclo-mes .field { flex: 0 1 220px; margin: 0; }

/* "Qué procede ahora" tampoco lleva marco: una regla izquierda gruesa —el mismo
   gesto que usan los avisos y los <details> de método— lo destaca sin sumar una
   caja más dentro de .ciclo-pf. */
.ciclo-accion {
  display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center;
  justify-content: space-between; margin-top: 10px; padding: 11px 13px;
  background: var(--bg); border: 0; border-left: 4px solid var(--line); border-radius: 0;
}
.ciclo-accion__txt { flex: 1 1 320px; display: flex; flex-direction: column; gap: 2px; }
.ciclo-accion__txt p { margin: 2px 0 0; }

.ciclo-mesvivo { margin-top: 6px; }
.ciclo-veto { font-family: var(--num); font-size: 11px; font-variant-numeric: tabular-nums; }
.ciclo-secuencia {
  margin: 6px 0 0; padding-left: 22px; display: flex; flex-direction: column; gap: 3px;
  font-size: 11.5px; color: var(--ink-muted);
}
.ciclo-secuencia li::marker { font-weight: 800; color: var(--ink); }
.ciclo-rescate {
  margin-top: 8px; padding: 10px 12px; border: 1px solid var(--line);
  background: var(--bg-sunken); border-radius: 0;
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
}
.ciclo-rescate p { margin: 0; }
.ciclo-rescate-sel td { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); }
/* La declaración de la apertura: checkbox EXPLÍCITO, nunca pre-marcado. */
.ciclo-declaracion {
  display: flex; gap: 10px; align-items: flex-start; margin: 10px 0;
  padding: 12px 14px; border: 2px solid var(--ink); background: var(--bg);
  border-radius: 0; font-size: 12px; line-height: 1.5; cursor: pointer; font-weight: 500;
}
.ciclo-declaracion input { margin-top: 2px; flex: 0 0 auto; width: 16px; height: 16px; }

.ciclo-closefix { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 8px; }
.ciclo-closefix .notice { margin: 0; }

.ciclo-flow { display: flex; flex-direction: column; gap: 0; margin: 4px 0 6px; border: 1px solid var(--line-soft); }
.ciclo-step {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px;
  border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0; background: var(--bg);
}
.ciclo-step:last-child { border-bottom: 0; }
.ciclo-step--ok { background: var(--bg); }
.ciclo-step--warn { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--ink); }
.ciclo-step__n {
  flex: 0 0 20px; height: 20px; border-radius: 0; display: inline-flex;
  align-items: center; justify-content: center; font-size: 10px; font-weight: 700;
  color: #fff; background: var(--ink); border: 1px solid var(--ink);
}
.ciclo-step__body { display: flex; flex-direction: column; gap: 2px; }
.ciclo-step__t { font-size: 11px; font-weight: 700; color: var(--ink); text-transform: uppercase; letter-spacing: 0.1em; }
.ciclo-step__who { font-weight: 500; color: var(--ink-muted); text-transform: none; letter-spacing: 0; }
.ciclo-step__d { font-size: 11.5px; color: var(--ink-muted); line-height: 1.5; }

/* Sin marco, por lo mismo que .ciclo-pf: vive dentro de una card y suele llevar
   un aviso adentro; con borde eran tres cajas anidadas. El fondo hundido basta. */
.ciclo-bar {
  display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center;
  justify-content: space-between; padding: 11px 13px; margin-bottom: 14px;
  border: 0; background: var(--bg-sunken); border-radius: 0;
}
.ciclo-bar__txt { display: flex; flex-direction: column; gap: 2px; flex: 1 1 260px; }
.ciclo-bar__t { font-size: 11px; font-weight: 700; color: var(--ink); text-transform: uppercase; letter-spacing: 0.12em; }
.ciclo-bar__d { font-size: 11.5px; color: var(--ink-muted); }
.ciclo-bar .notice { flex: 1 1 100%; margin: 4px 0 0; }

/* Deriva: el hallazgo grave — una póliza asentada dejó de coincidir. Alarma. */
.ciclo-drift { border: 2px solid var(--danger); background: var(--bg); border-radius: 0; padding: 12px 14px; margin-bottom: 14px; }
.ciclo-drift__t { margin: 0 0 6px; font-size: 12px; font-weight: 800; color: var(--danger); text-transform: uppercase; letter-spacing: 0.12em; }
.ciclo-drift p { margin: 0 0 6px; font-size: 12px; line-height: 1.55; color: var(--ink); }
.ciclo-drift__tbl { margin-top: 8px; }
.ciclo-row-drift > td:first-child { border-left: 3px solid var(--danger); }
.ciclo-src { font-size: 11.5px; word-break: break-all; }
.ciclo-hash {
  font-family: var(--num); font-size: 10px; letter-spacing: 0.02em;
  word-break: break-all; max-width: 220px; color: var(--ink-muted);
}
.ciclo-hash--live { color: var(--danger); font-weight: 700; }

/* --- Cuenta corriente / anulación en línea ------------------------------- */
.cxc-void { display: inline-flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.cxc-void .input { width: 180px; }
.cont-subtitle, .card__subtitle { display: block; }

/* --- Ruta / migas -------------------------------------------------------- */
.route-hint { font-size: 9px; color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.16em; font-weight: 500; }
