/* Sky Terra Gestión — capa visual v1
   ===================================================================
   Aplica el handoff de rediseño (16-sep-2026). Se carga DESPUÉS de styles.css
   y lo pisa por especificidad de orden: así el rediseño es reversible sacando
   un <link>, y las 2.000 líneas del CSS viejo siguen ahí como red.

   Cada decisión de acá viene del handoff, que a su vez replica un patrón de
   IBM Carbon, SAP Fiori o Atlassian. Lo que se anota abajo es el POR QUÉ, que
   es lo que no se deduce leyendo la regla.

   Lo que NO cambia: la paleta de marca, la funcionalidad, la arquitectura de
   información. Es capa visual.
   =================================================================== */

/* ── base ─────────────────────────────────────────────────────────────── */
body {
  font-family: var(--fuente);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  background: var(--bg);
  color: var(--ink);
}

/* Un solo estilo de foco en toda la app. El dorado no puede serlo: 2,79:1. */
:focus-visible { outline: var(--foco); outline-offset: var(--foco-offset); border-radius: 2px; }

/* ── tarjetas ─────────────────────────────────────────────────────────────
   Antes el <h3> de card competía con el título de pantalla: ambos grandes.
   Ahora hay un solo título de 20px por vista y las cards bajan a 16px. */
.card {
  background: var(--surface);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra-raised);
  padding: var(--e-4);
  margin-bottom: var(--e-3);
}
.card h3 {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  font-weight: var(--peso-med);
  margin-bottom: var(--e-3);
  gap: var(--e-2);
}
.card h3 .sub {
  font-weight: var(--peso-reg);
  font-size: var(--fs-caption);
  color: var(--ink-3);
}
.f-hint { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--ink-3); }

/* ── KPI / tiles ──────────────────────────────────────────────────────────
   Tile de Fiori: rótulo en mayúsculas arriba, cifra grande tabular, contexto
   abajo. La cifra baja de 23 a 24px pero gana interlínea y respiro. */
.grid-kpi { gap: var(--e-3); margin-bottom: var(--e-4); }
.tile {
  background: var(--surface);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra-raised);
  padding: var(--e-3) var(--e-4);
}
.tile .t-label {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--peso-med);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--e-1);
}
.tile .t-valor {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--peso-med);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
/* La moneda como chip fijo y no como texto suelto: la regla de doble moneda
   dice que el símbolo $ no alcanza para distinguir ARS de USD. */
.tile .t-valor small {
  display: inline-block;
  font-size: 11px;
  line-height: 16px;
  font-weight: var(--peso-med);
  letter-spacing: .04em;
  padding: 0 6px;
  border-radius: var(--radio-pill);
  background: var(--info-bg);
  color: var(--info-txt);
  vertical-align: middle;
  margin-right: var(--e-2);
}
.tile .t-pie { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--ink-3); margin-top: var(--e-1); }
.tile .t-pie.alerta { color: var(--warn-txt); font-weight: var(--peso-med); }

/* ── botones ──────────────────────────────────────────────────────────────
   Jerarquía de cuatro de Carbon. El primario es petróleo y no dorado porque
   el dorado no admite texto blanco (2,79:1). Una sola acción primaria por
   pantalla. Alturas fijas: 32 / 36 / 40. */
.btn-primary, .btn-principal, .btn-sec, .btn-borde, .btn-linea,
.btn-malo, .btn-plano, .btn-export, .guardar {
  height: var(--ctrl-m);
  padding: 0 14px;
  border-radius: var(--radio);
  font-size: var(--fs-body);
  font-weight: var(--peso-med);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  white-space: nowrap;
  transition: background .12s, border-color .12s;
}
.btn-primary, .btn-principal, .guardar {
  background: var(--petroleo);
  color: var(--ink-inv);
  border: none;
}
.btn-primary:hover, .btn-principal:hover, .guardar:hover { background: var(--petroleo-hover); filter: none; }
.btn-primary:active, .btn-principal:active, .guardar:active { background: var(--petroleo-active); }
.btn-primary:focus-visible, .btn-principal:focus-visible { box-shadow: inset 0 0 0 1px var(--ink-inv); }

.btn-sec, .btn-borde, .btn-linea, .btn-export {
  background: var(--surface);
  color: var(--ink);
  /* borde-fuerte y no --borde: un borde de control necesita 3:1, y #DED7CC da 1,43:1 */
  border: 1px solid var(--borde-fuerte);
}
.btn-sec:hover, .btn-borde:hover, .btn-linea:hover, .btn-export:hover {
  background: var(--surface-3);
  border-color: var(--borde-fuerte);
  color: var(--ink);
}
.btn-sec:active, .btn-borde:active, .btn-linea:active { background: var(--gris); }

.btn-plano { background: transparent; color: var(--petroleo-2); border: none; }
.btn-plano:hover { background: var(--surface-3); }

.btn-malo { background: var(--err); color: var(--ink-inv); border: none; }
.btn-malo:hover { background: var(--err-txt); }

/* El destructivo de fila es un enlace, no un botón: no compite con la acción
   primaria de la pantalla. Subrayado siempre, para no depender del color. */
.btn-peligro {
  height: auto; padding: 2px; border: none; background: none;
  color: var(--err-txt); font-size: var(--fs-caption); font-weight: var(--peso-med);
  text-decoration: underline; border-radius: 2px; display: inline;
}
.btn-peligro:hover { color: var(--err); }

.btn-primary:disabled, .btn-principal:disabled, .btn-sec:disabled, .guardar:disabled {
  background: var(--gris); color: var(--ink-disabled); border-color: var(--borde);
  opacity: 1; cursor: not-allowed;
}
/* botón chico, el de dentro de las tablas */
.tabla-envuelta .btn-sec, td .btn-sec, th .btn-sec { height: var(--ctrl-s); padding: 0 12px; font-size: var(--fs-caption); }

/* El buscador vive DENTRO del menú petróleo: es translúcido, no un secundario
   sobre blanco. Se lo trata como ítem de navegación, que es lo que parece. */
.btn-buscar {
  height: var(--ctrl-m);
  padding: 0 12px;
  border-radius: var(--radio);
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .14);
  color: var(--nav-txt);
  font-size: var(--fs-body);
  font-weight: var(--peso-reg);
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-2);
  width: 100%;
}
.btn-buscar:hover { background: rgba(255, 255, 255, .14); color: var(--nav-txt-activo); }
.btn-buscar kbd {
  font-size: 11px; font-family: var(--fuente-mono);
  background: rgba(255, 255, 255, .12); border-radius: 4px; padding: 2px 6px; color: var(--nav-txt);
}

/* Los campos del buscador global y del menú NO son campos de formulario:
   viven sobre superficies propias y se dejan como estaban. */
.buscador-caja input { height: var(--ctrl-l); border: none; }

/* ── formularios ──────────────────────────────────────────────────────────
   Carbon Form: etiqueta ARRIBA del campo, ayuda debajo, error con icono.
   Se usa el borde completo de Fiori y no el subrayado de Carbon porque acá
   hay campos sobre blanco y sobre crema, y el subrayado se pierde en tonal. */
.f-grid { gap: var(--e-3); }
.f-field { gap: var(--e-1); }
.f-field label, .lbl {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--peso-med);
  color: var(--ink-2);
}
.f-field input, .f-field select, .f-field textarea,
input[type=text], input[type=number], input[type=date], input[type=search],
input[type=password], input[type=tel], input[type=email], select, textarea, .campo {
  height: var(--ctrl-m);
  padding: 0 10px;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-body);
  width: 100%;
}
textarea, .f-field textarea { height: auto; padding: 8px 10px; resize: vertical; line-height: var(--lh-body); }
.f-field input:hover, .f-field select:hover, .campo:hover { border-color: var(--ink-3); }
.f-field input:focus-visible, .f-field select:focus-visible, .campo:focus-visible { border-color: var(--borde-fuerte); }
.f-field input:disabled, .f-field select:disabled, .campo:disabled {
  background: var(--gris); border-color: var(--borde); color: var(--ink-disabled);
}
::placeholder { color: var(--ink-3); }
/* los importes se comparan de arriba abajo: a la derecha y tabulares */
input[type=number], .campo.num, input.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── tablas ───────────────────────────────────────────────────────────────
   Carbon Data Table en densidad sm. Se saca la cebra: con filas de 36px y
   montos tabulares el hairline alcanza, y el fondo alterno peleaba con el
   hover y con la fila seleccionada (una sola señal por estado). */
.tabla-envuelta { overflow: auto; border-radius: var(--radio); }
table { font-size: var(--fs-body); }
th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-3);
  color: var(--ink-2);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--peso-med);
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 0 14px;
  height: var(--fila-compacta);
  border-bottom: 1px solid var(--borde-fuerte);
  white-space: nowrap;
}
td {
  padding: 0 14px;
  height: var(--fila-compacta);
  border-bottom: 1px solid var(--hairline);
  vertical-align: middle;
  color: var(--ink);
}
/* la celda que envuelve varias líneas necesita aire vertical propio */
td:has(> .pill), td:has(> button) { padding-top: 0; padding-bottom: 0; }
tbody tr:hover { background: var(--surface-hover); }
tbody tr.clic { cursor: pointer; }
tbody tr.sel, tbody tr[aria-selected="true"] {
  background: var(--surface-sel);
  box-shadow: inset 3px 0 0 var(--petroleo);
}
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
/* sin cebra: si styles.css la pintaba, acá se apaga */
tbody tr:nth-child(even) { background: transparent; }
tbody tr:nth-child(even):hover { background: var(--surface-hover); }

/* ── badges de estado ─────────────────────────────────────────────────────
   Lozenge de Atlassian. Llevan borde además del fondo para sobrevivir en
   impresión y en escala de grises, donde el color no existe. */
.pill {
  display: inline-flex; align-items: center;
  height: 22px; padding: 0 9px;
  border-radius: var(--radio-pill);
  font-size: var(--fs-caption); line-height: 1; font-weight: var(--peso-med);
  border: 1px solid transparent;
}
.pill.ok     { background: var(--ok-bg);   color: var(--ok-txt);   border-color: var(--ok-txt); }
.pill.warn   { background: var(--warn-bg); color: var(--warn-txt); border-color: var(--warn-txt); }
.pill.err    { background: var(--err-bg);  color: var(--err-txt);  border-color: var(--err-txt); }
.pill.neutro { background: var(--gris);    color: var(--ink-2);    border-color: var(--borde-fuerte); }
.pill.dir, .pill.info { background: var(--info-bg); color: var(--info-txt); border-color: var(--info-txt); }
.pill.estim  { background: var(--warn-bg); color: var(--warn-txt); border-color: var(--warn-txt); }

/* ── semáforo contable ────────────────────────────────────────────────────
   El rojo y el verde de esta app significan plata, no decoran. Se usan las
   variantes -txt, que son las que pasan 4,5:1 sobre fondo claro. */
.rojo, .neg { color: var(--err-txt); }
.verde, .pos { color: var(--ok-txt); }

/* ── alertas inline ───────────────────────────────────────────────────────
   Notification de Carbon: barra lateral de 3px + icono + texto. Nunca solo
   color: el mensaje tiene que leerse en escala de grises. */
.aviso, .alerta-inline {
  display: flex; gap: var(--e-2); align-items: flex-start;
  padding: 10px 14px;
  border: 1px solid var(--borde);
  border-left-width: 3px;
  border-radius: var(--radio);
  font-size: var(--fs-body);
  color: var(--ink-2);
}
.aviso.ok   { background: var(--ok-bg);   border-color: var(--ok-txt); }
.aviso.warn { background: var(--warn-bg); border-color: var(--warn-txt); }
.aviso.err  { background: var(--err-bg);  border-color: var(--err-txt); }
.aviso.info { background: var(--info-bg); border-color: var(--info-txt); }

/* ── toast ────────────────────────────────────────────────────────────────
   Abajo a la derecha, petróleo sobre blanco (14,57:1), sombra de overlay. */
#toast {
  background: var(--petroleo);
  color: var(--ink-inv);
  border-radius: var(--radio);
  box-shadow: var(--sombra-overlay);
  font-size: var(--fs-body);
  max-width: 360px;
  padding: 10px 14px;
  gap: var(--e-2);
}
#toast .ok { color: #8FD79A; }
#toast .err { color: #F2A9A0; }

/* ── modal ────────────────────────────────────────────────────────────────
   El pie va sobre surface-2 para separar la decisión del contenido. */
.modal-caja, .modal > div, dialog {
  border-radius: var(--radio);
  box-shadow: var(--sombra-overlay);
  border: 1px solid var(--borde);
}
.modal-fondo, .modal { background: rgba(27, 42, 59, .45); }
.modal .acciones, .acciones-form {
  display: flex; gap: var(--e-2); justify-content: flex-end;
  padding-top: var(--e-3);
}

/* ── navegación lateral ───────────────────────────────────────────────────
   UI Shell de Carbon. El ítem activo suma una barra dorada de 3px: el color
   solo nunca marca el estado. El dorado acá sí funciona, es fondo/barra. */
#nav button {
  height: var(--ctrl-m);
  border-radius: var(--radio);
  font-size: var(--fs-body);
  font-weight: var(--peso-reg);
  color: var(--nav-txt);
  gap: var(--e-2);
  padding: 0 12px;
}
#nav button:hover { background: rgba(255, 255, 255, .08); color: var(--nav-txt-activo); }
#nav button.activo {
  background: rgba(255, 255, 255, .12);
  color: var(--nav-txt-activo);
  font-weight: var(--peso-med);
  box-shadow: inset 3px 0 0 var(--dorado);
}
#nav .grupo {
  font-size: 11px; font-weight: var(--peso-med);
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--nav-rotulo);
  margin: var(--e-4) 0 var(--e-1);
  padding: 0 12px;
}

/* ── cabecera de página ───────────────────────────────────────────────────
   Dynamic Page Header de Fiori: un solo título de pantalla, subtítulo con el
   contexto del dato, acciones a la derecha. */
header.top #titulo-vista {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--peso-med);
}
header.top .miga { font-size: var(--fs-body); color: var(--ink-3); }
header.top .fecha { font-size: var(--fs-caption); color: var(--ink-3); }

/* ── el bloque del tablero financiero ─────────────────────────────────────
   La curva y las palancas del piso de caja: mismos tokens que el resto. */
.veredicto .piso .rot { font-size: var(--fs-caption); color: var(--ink-3); letter-spacing: .06em; }
.veredicto .piso .n { font-size: 42px; line-height: 1.05; font-weight: var(--peso-med); }
.veredicto .piso .n small { font-size: var(--fs-h4); color: var(--ink-3); }
.veredicto .piso .cuando { font-size: var(--fs-body); color: var(--ink-3); }
.palanca { border-left: 3px solid var(--borde-fuerte); padding: 3px 0 3px 10px; font-size: var(--fs-body); }
.palanca.mejor { border-left-color: var(--ok-txt); }
.palanca.peor { border-left-color: var(--err-txt); }
.palanca b { font-size: var(--fs-lead); font-variant-numeric: tabular-nums; }
.palanca .que { color: var(--ink-3); }
.capa { padding: var(--e-2) 0; border-bottom: 1px solid var(--hairline); }
.capa .nom { font-weight: var(--peso-med); }
.capa .val { font-variant-numeric: tabular-nums; font-weight: var(--peso-med); }
.capa .txt { font-size: var(--fs-caption); color: var(--ink-3); }

/* ── PNL: tres roles de fila, no catorce tonos ────────────────────────────
   El CSS original tenía 14 variables --pnl-*. Se reducen a ingreso / egreso /
   resultado; el signo del monto se escribe además de colorearse. */
.pnl-ingreso, tr.ingreso { background: var(--ok-bg); }
.pnl-egreso, tr.egreso { background: var(--warn-bg); }
.pnl-resultado, tr.resultado {
  background: var(--info-bg);
  border-top: 2px solid var(--petroleo);
  font-weight: var(--peso-med);
}

/* ── responsive ───────────────────────────────────────────────────────────
   Bajo 600px la densidad cede: es el único lugar donde lo hace. El que carga
   una compra está parado en una obra, con una mano. */
@media (max-width: 600px) {
  body { font-size: var(--fs-lead); line-height: var(--lh-lead); }
  .f-field input, .f-field select, .f-field textarea, .campo,
  input[type=text], input[type=number], input[type=date], input[type=search] {
    height: var(--ctrl-l); font-size: var(--fs-lead);
  }
  .btn-primary, .btn-principal, .guardar, .btn-sec {
    height: var(--toque-min); width: 100%; font-size: var(--fs-lead);
  }
  .acciones-form { flex-direction: column-reverse; }
  .acciones-form .btn-primary, .acciones-form .guardar { order: -1; }
  td, th { padding: 0 10px; }
  /* Área táctil sin cambiar el aspecto: el "borrar" de fila sigue siendo un
     enlace de 12px y el badge sigue midiendo 22px, pero el dedo tiene 44px
     donde apoyar. Material 3 pide 48dp; con el padding vertical se llega. */
  .btn-peligro { padding: 10px 6px; display: inline-block; }
  /* Nueve filtros apilados en 390px son 484px de alto: media pantalla antes de
     ver el primer dato. En dos columnas entran en la mitad. El buscador se queda
     a ancho completo porque es el que más se usa. */
  /* Con los filtros de columna ya en la cabecera, acá arriba queda poco: el
     buscador, el período y los botones. Tres columnas y entra en dos renglones. */
  .filtros { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e-2); }
  .filtros input, .filtros select, .filtros .campo { width: 100%; max-width: none; min-width: 0; height: var(--ctrl-l); }
  .filtros input[type=search] { grid-column: 1 / -1; max-width: none; }
  .filtros .resumen { grid-column: 1 / -1; }
  .filtros button { grid-column: span 3; height: var(--ctrl-l); }
  .filtros button + button { grid-column: span 3; }
  button.pill { min-height: var(--toque-min); padding-top: 11px; padding-bottom: 11px; }
  .tile .t-valor { font-size: var(--fs-h3); line-height: var(--lh-h3); }
  .veredicto .piso .n { font-size: 32px; }
}

/* Sin animaciones decorativas: solo cambios de estado y el spinner. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ── bloqueo de accesibilidad #1: el dorado como tinta ────────────────────
   #B8973E da 2,79:1 sobre blanco — no llega ni a 3:1. El CSS viejo lo usaba
   para los códigos de obra, para el anillo de foco de los campos y para el
   borde de hover de los botones. Sobre fondo oscuro el dorado sí funciona
   (7,48:1 sobre petróleo), así que ahí se queda; sobre claro pasa a
   --dorado-txt #8F722A, que da 4,56:1.
   Esto no es cosmética: son 314 enlaces de obra por pantalla en Cajas. */
a.ref, td .mono, a.ref:hover { color: var(--dorado-txt); }
a.ref:hover { text-decoration: underline; }

/* El foco NUNCA es dorado. Uno solo para toda la app, el de Carbon. */
.f-field input:focus, .f-field select:focus, .f-field textarea:focus,
input:focus, select:focus, textarea:focus, .campo:focus {
  outline: none;
  border-color: var(--borde-fuerte);
}
.f-field input:focus-visible, .f-field select:focus-visible, .f-field textarea:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible, .campo:focus-visible {
  outline: var(--foco);
  outline-offset: var(--foco-offset);
  border-color: var(--borde-fuerte);
}

/* El wordmark del login está sobre blanco; el de la lateral, sobre petróleo. */
.login-caja .wordmark small { color: var(--dorado-txt); }
aside .wordmark small, #menu .wordmark small { color: var(--dorado); }

/* El chip del TC vive en la lateral oscura: el dorado ahí es legible. */
.tc-chip b { color: var(--dorado); }

/* ── el área de trabajo usa TODA la pantalla ──────────────────────────────
   styles.css tenía `.vista { max-width: 1140px }`, y el PNL ya se lo anulaba
   por su cuenta. En un monitor de 1920 eso dejaba media pantalla vacía y las
   tablas cortadas al medio, que es justo lo que este ERP no puede permitirse:
   son 14 columnas de importes que se leen de corrido.
   Carbon: el área de trabajo no lleva ancho máximo. */
.vista { max-width: none; }

/* La excepción son las grillas de formulario. Sin tope, `auto-fit` a 210px
   arma ocho columnas en un monitor ancho y el formulario se vuelve ilegible:
   la etiqueta queda a un metro de su campo. Los datos se leen anchos; los
   formularios, no. */
.f-grid { max-width: 1180px; }
.dos-col { max-width: 1600px; }

/* Los DATOS se leen anchos; la PROSA no. Al liberar el ancho, las explicaciones
   de cada fila pasaron a ocupar 1.200 px de una línea y el ojo se pierde al
   volver al renglón. Se les pone tope de medida (~90 caracteres); las tablas y
   los importes siguen usando todo el viewport. */
.capa .txt, .palanca .que, .card > .f-hint, .aviso { max-width: 92ch; }

/* El naranja de aviso (#D4830A) da 2,98:1 sobre blanco: como tinta no llega.
   Sobre la lateral oscura sí, por eso .tc-chip se deja. */
.chk-ico.no { color: var(--warn-txt); }

/* ── barra de filtros ─────────────────────────────────────────────────────
   ⚠ Los campos de un formulario van a ancho completo; los de una barra de
   filtros, NO. `.filtros` es una fila que envuelve, y al heredar el
   `width:100%` de los formularios cada filtro se comía un renglón entero:
   nueve filtros apilados empujaban la tabla abajo del pliegue y había que
   scrollear para ver el primer dato. Acá el ancho lo pone el contenido. */
.filtros input, .filtros select, .filtros .campo {
  width: auto;
  height: var(--ctrl-s);
  padding: 0 10px;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio);
  background: var(--surface);
  font-size: var(--fs-caption);
  /* el select se estira al texto de su opción más larga y el flex no lo frena:
     con nombres de proveedor largos medía 492px en una pantalla de 390 */
  max-width: 230px;
}
.filtros input[type=search] { min-width: 200px; max-width: 360px; flex: 1 1 200px; }
.filtros { gap: var(--e-2); align-items: center; }
.filtros .resumen { font-size: var(--fs-caption); color: var(--ink-3); }

/* Lo mismo para las otras barras de herramientas que viven arriba de una tabla. */
.li-barra input, .li-barra select, .buscador-pie input {
  width: auto; height: var(--ctrl-s); max-width: 260px;
}

/* ── menú de columna: ordenar y filtrar desde la cabecera ─────────────────
   Como en una planilla, que es donde la gente lo busca. El ▾ aparece al pasar
   por encima —o siempre, si esa columna está filtrada— para no ensuciar una
   cabecera de catorce columnas con catorce flechitas. */
th .th-in { display: flex; align-items: center; gap: 4px; justify-content: inherit; }
th.num .th-in { justify-content: flex-end; }
th .th-t { cursor: pointer; user-select: none; }
th .th-m {
  /* Tenue pero presente: si aparece solo al pasar el mouse, nadie descubre que
     la columna se puede filtrar. Se insinúa siempre y se afirma al acercarse. */
  opacity: .35;
  transition: opacity .12s, background .12s, color .12s;
  width: 22px; height: 22px;
  border-radius: 4px;
  color: var(--ink-2); background: transparent; border: none;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  padding: 0;
}
th:hover .th-m { opacity: .75; }
th .th-m:hover, th .th-m:focus-visible {
  opacity: 1;
  background: var(--petroleo);
  color: var(--ink-inv);
}
th .th-m svg { display: block; }

/* Una columna filtrada se reconoce de un vistazo: el embudo en petróleo, sólido,
   y una barra abajo. Dos señales, ninguna dependiente solo del color. */
th.filtrada { box-shadow: inset 0 -3px 0 var(--petroleo); background: var(--surface-sel); }
th.filtrada .th-m { opacity: 1; color: var(--petroleo); background: transparent; }
th.filtrada .th-m:hover { background: var(--petroleo); color: var(--ink-inv); }
th.filtrada .th-t { color: var(--petroleo); }

/* El menú abierto deja el botón marcado, para saber de dónde salió el panel. */
th .th-m[aria-expanded=true] { opacity: 1; background: var(--petroleo); color: var(--ink-inv); }

.th-menu {
  position: fixed; z-index: 90;
  min-width: 240px; max-width: min(92vw, 320px);
  background: var(--surface);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra-overlay);
  padding: var(--e-1);
  font-size: var(--fs-body);
}
.thm-op {
  display: block; width: 100%; text-align: left;
  padding: 0 10px; height: var(--ctrl-m);
  border-radius: 4px; color: var(--ink); background: none; border: none;
  font-size: var(--fs-body);
}
.thm-op:hover { background: var(--surface-3); }
.thm-quitar { color: var(--err-txt); }
.thm-sep { height: 1px; background: var(--hairline); margin: var(--e-1) 0; }
.thm-busca { padding: var(--e-1); }
.thm-busca input {
  width: 100%; height: var(--ctrl-s); padding: 0 9px;
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio);
  font-size: var(--fs-caption); background: var(--surface); color: var(--ink);
}
.thm-lista { max-height: 260px; overflow: auto; }
.thm-val {
  display: block; width: 100%; text-align: left;
  padding: 6px 10px; border-radius: 4px;
  color: var(--ink); background: none; border: none;
  font-size: var(--fs-caption); line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.thm-val:hover { background: var(--surface-3); }
.thm-val.elegida { background: var(--surface-sel); font-weight: var(--peso-med); }
.thm-val.elegida::after { content: " ✓"; }

/* En el celular el menú se apoya abajo, a lo ancho: un panel flotante de 240px
   al lado de una columna es imposible de tocar con el pulgar. */
@media (max-width: 600px) {
  .th-menu {
    left: 8px !important; right: 8px;
    top: auto !important; bottom: 8px;
    max-width: none; width: calc(100vw - 16px);
  }
  .thm-lista { max-height: 44vh; }
  .thm-val { padding: 10px; font-size: var(--fs-body); }
  /* En el celular el ▾ está siempre visible (no hay hover) y necesita dedo:
     32px de botón más un área invisible alrededor para llegar a los 44 reales. */
  th .th-m { opacity: 1; width: 32px; height: 32px; position: relative; }
  th .th-m::after { content: ""; position: absolute; inset: -6px; }
  th { height: var(--ctrl-l); }
}

/* ── cabecera de tabla fija de verdad ─────────────────────────────────────
   El `position: sticky` del <th> no alcanzaba: cuando un ancestro tiene
   `overflow` distinto de visible, el sticky se ancla A ESE CONTENEDOR. Como
   `.tabla-envuelta` tenía `overflow:auto` pero ninguna altura máxima, nunca
   scrolleaba por dentro — scrolleaba la página, y la cabecera se iba igual.

   Con un alto máximo la tabla scrollea adentro y los títulos quedan quietos,
   que es lo que hace falta para leer 42.746 filas de catorce columnas.
   Las tablas cortas no se enteran: `max-height` solo actúa si sobra contenido. */
/* Solo las tablas de listado, que son las largas de verdad (Compras, Ingresos,
   Cajas: decenas de miles de filas con su paginación). Las tablas embebidas en
   una tarjeta suelen tener diez o quince filas: ahí un recuadro con scroll
   propio es peor que dejarlas fluir con la página. */
#ts-tabla .tabla-envuelta, #li-tabla .tabla-envuelta {
  max-height: calc(100vh - 230px);
  overscroll-behavior: contain;   /* al llegar al final no arrastra la página */
}
/* La cabecera tiene que tapar las filas que pasan por debajo: fondo sólido y
   una línea que la despegue del contenido. */
thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--surface-3);
  box-shadow: inset 0 -1px 0 var(--borde-fuerte);
}
th.filtrada { box-shadow: inset 0 -3px 0 var(--petroleo); }

@media (max-width: 600px) {
  /* En el celular el límite va en proporción y no en píxeles: con un valor fijo,
     una tabla de trece filas quedaba con scroll interno sin necesidad, y hacer
     scroll dentro de un recuadro chico con el pulgar es peor que scrollear la
     página. Así solo scrollean adentro las que de verdad son largas. */
  #ts-tabla .tabla-envuelta, #li-tabla .tabla-envuelta { max-height: 72vh; }
}

/* El lápiz de la fila: chico, discreto, del alto de la celda. No compite con el
   dato — es una acción de corrección, no la principal de la pantalla. */
.btn-editar {
  height: 22px; width: 22px; padding: 0;
  font-size: 11px; border-radius: 4px;
  color: var(--ink-3); background: transparent; border: 1px solid transparent;
  display: inline-flex; align-items: center; justify-content: center;
}
tr:hover .btn-editar { border-color: var(--borde-fuerte); color: var(--ink); background: var(--surface); }
.btn-editar:hover { background: var(--petroleo); color: var(--ink-inv); border-color: var(--petroleo); }
@media (max-width: 600px) {
  .btn-editar { height: 30px; width: 30px; position: relative; border-color: var(--borde-fuerte); }
  .btn-editar::after { content: ""; position: absolute; inset: -7px; }
}
