/* Panel de ContáPLATA — pantalla Caja.
   CSS a mano, sin framework: son dos tablas y una botonera. */

/* --- Tokens ----------------------------------------------------------
   Dos temas, por clase en <html>: `tema-claro` y `tema-oscuro`. Sin clase
   rige el claro, que es el default de la cuenta (`usuarios.tema`). TODO
   color del panel sale de estas variables: abajo no hay ningún hex suelto.
   El significado es fijo y no cambia con el tema: `--in` es plata que entra,
   `--out` plata que sale, `--warn` falta un dato, `--info` pregunta pendiente
   o aceptado, `--mute` corregido o presupuestado. */

:root, html.tema-claro {
  color-scheme: light;
  --bg: #f1f5f3;  --surf: #ffffff;  --line: #c9d6d0;
  --tx: #13221c;  --tx2: #4f6159;
  --acc: #0f6b5c; --acc-tx: #ffffff;
  --in: #1f7a3f;   --in-bg: #dff3e5;
  --out: #a1352a;  --out-bg: #f8e2de;
  --warn: #7a5100; --warn-bg: #fdeec8;
  --info: #0f6b5c; --info-bg: #d8ede8;
  --mute: #4f6159; --mute-bg: #e2e9e5;
}

html.tema-oscuro {
  color-scheme: dark;
  --bg: #111917;  --surf: #1a2421;  --line: #2d3b36;
  --tx: #e9f1ed;  --tx2: #96a8a0;
  --acc: #4fd1b5; --acc-tx: #04211a;
  --in: #63d68a;   --in-bg: #173a25;
  --out: #ff8c7a;  --out-bg: #42221d;
  --warn: #ffd166; --warn-bg: #3f3110;
  --info: #4fd1b5; --info-bg: #143530;
  --mute: #96a8a0; --mute-bg: #26302d;
}

/* Derivados: se calculan sobre los de base con color-mix, así siguen al tema
   sin declararse dos veces. Y los ALIAS del vocabulario viejo, que siguen
   existiendo porque traza.css (el modo traza) los usa: acá adentro ya no se
   usan. */
:root {
  --radio: 10px;

  --surf2:     color-mix(in srgb, var(--surf) 90%, var(--tx));   /* cabecera de tabla, ítem activo */
  --hover:     color-mix(in srgb, var(--surf) 96%, var(--tx));   /* fila bajo el cursor */
  --hundido:   color-mix(in srgb, var(--bg) 60%, var(--surf));   /* evidencia desplegada */
  --tx3:       color-mix(in srgb, var(--tx2) 70%, var(--bg));    /* etiquetas, notas, datos que faltan */
  --line2:     color-mix(in srgb, var(--line) 60%, transparent); /* línea entre filas */
  --sombra:    color-mix(in srgb, var(--tx) 25%, transparent);
  --in-line:   color-mix(in srgb, var(--in) 40%, transparent);
  --out-line:  color-mix(in srgb, var(--out) 45%, transparent);
  --warn-line: color-mix(in srgb, var(--warn) 45%, transparent);
  --info-line: color-mix(in srgb, var(--info) 40%, transparent);
  --mute-line: color-mix(in srgb, var(--mute) 35%, transparent);

  --fondo: var(--bg);        --panel: var(--surf);     --panel-alto: var(--surf2);
  --borde: var(--line);      --texto: var(--tx);       --texto-suave: var(--tx2);
  --texto-tenue: var(--tx3); --entra: var(--in);       --sale: var(--out);
  --acento: var(--acc);
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--tx);
  font: 15px/1.45 Nunito, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.app {
  display: grid;
  grid-template-columns: 210px 1fr;
  height: 100%;
}

/* --- Lateral ------------------------------------------------------- */

.lateral {
  background: var(--surf);
  border-right: 1px solid var(--line);
  padding: 22px 14px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.marca {
  font-size: 18px;
  letter-spacing: .5px;
  padding-left: 10px;
  color: var(--tx2);
}
.marca strong { color: var(--tx); }

.lateral nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.seccion {
  appearance: none;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  padding: 9px 12px;
  text-align: left;
}
.seccion:disabled {
  color: var(--tx3);
  cursor: default;
  opacity: .55;
}
.seccion.activa {
  background: var(--surf2);
  color: var(--tx);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--acc);
}
/* La sección que contiene la vista abierta, cuando la vista es un sub-ítem:
   se prende el título del grupo, sin el fondo del ítem seleccionado — el
   destacado fuerte le corresponde al sub-ítem, que es lo que se está viendo. */
.seccion.en-seccion { color: var(--tx); font-weight: 600; }

/* Sub-ítems (Caja > Movimientos / Lo que viene): mismo botón, indentado y
   un punto más chico. La jerarquía se lee por sangría y tamaño. */
.subseccion {
  appearance: none;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  padding: 7px 12px 7px 26px;
  text-align: left;
}
.subseccion.activa {
  background: var(--surf2);
  color: var(--tx);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--acc);
}

/* El botón de tema: en el lateral, que es la única cabecera presente en las
   cuatro vistas (en angosto es literalmente la barra de arriba). El texto
   dice a qué modo PASA al tocarlo, no en cuál está. */
/* "Salir" comparte la forma del botón de tema: es la otra acción de cuenta
   del lateral. Texto explícito, sin ícono. */
.boton-tema, .boton-salir {
  appearance: none;
  align-self: flex-start;
  margin-left: 10px;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
}
.boton-tema:hover, .boton-salir:hover { color: var(--tx); border-color: var(--tx2); }
.boton-tema:disabled, .boton-salir:disabled { opacity: .55; cursor: default; }
.boton-salir { margin-top: 6px; }

.nota-lateral {
  margin: auto 0 0;
  padding: 0 12px;
  color: var(--tx3);
  font-size: 12px;
}

/* --- Principal ----------------------------------------------------- */

.principal {
  display: grid;
  grid-template-rows: auto auto auto minmax(0, 1fr) minmax(0, 1fr);
  height: 100%;
  min-width: 0;
  /* El ancla de `#vista-chat`, que se posiciona absoluto contra esta caja. */
  position: relative;
}

.cabecera {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding: 20px 26px 16px;
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: 14px;
}

.etiqueta {
  display: block;
  color: var(--tx3);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .8px;
  margin-bottom: 4px;
}

/* Las tres tarjetas: caja hoy es la principal, a cobrar / a pagar son el
   contraste — lo que hoy tenés contra lo que todavía falta que se mueva. */
.tarjetas {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  flex: 1;
}

.tarjeta {
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--radio);
  padding: 12px 20px;
  min-width: 148px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.tarjeta-hoy { padding: 14px 26px; }

.valor {
  font-size: 26px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.5px;
  font-variant-numeric: tabular-nums;
}
.tarjeta-hoy .valor { font-size: 40px; letter-spacing: -1px; }
.valor.negativo { color: var(--out); }

.tarjeta-cobrar .valor { color: var(--in); }

/* Por terminar es plata comprometida que todavía no se puede reclamar: se ve
   más apagada que "Te deben" a propósito. No son el mismo número y no se
   suman — ver §"Exigible != comprometido" en contratos/contrato_motor.md. */
.tarjeta-terminar .valor { color: var(--tx2); }

.pie-tarjeta {
  display: block;
  margin-top: 5px;
  color: var(--tx3);
  font-size: 11px;
  letter-spacing: .2px;
}

.aviso {
  align-self: center;
  background: var(--out-bg);
  border: 1px solid var(--out-line);
  border-radius: var(--radio);
  color: var(--out);
  font-size: 13px;
  padding: 8px 12px;
  max-width: 420px;
}

/* --- Períodos ------------------------------------------------------ */

.periodos {
  padding: 14px 26px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
}

.botonera { display: flex; gap: 6px; flex-wrap: wrap; }

.periodo {
  appearance: none;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  padding: 6px 14px;
}
.periodo:hover { color: var(--tx); border-color: var(--tx2); }
.periodo.activo {
  background: var(--acc);
  border-color: var(--acc);
  color: var(--acc-tx);
  font-weight: 600;
}

.rango { display: flex; gap: 12px; align-items: center; }
.rango label {
  color: var(--tx3);
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
  text-transform: uppercase;
  letter-spacing: .6px;
}
.rango input {
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--tx);
  font: inherit;
  font-size: 13px;
  padding: 5px 8px;
}

/* El rango que resolvió la botonera, al lado de ella. Los totales del período
   ya no viven acá: son la segunda fila de tarjetas. */
.rango-periodo {
  margin: 0 0 0 auto;
  align-self: center;
}

/* --- Segunda fila: las métricas DE PERÍODO -------------------------
   Arriba, las de hoy; acá abajo, las que siguen la botonera. La posición es
   lo que explica el alcance (§14): dos filas separadas por una línea, y la
   de abajo pegada a los botones que la controlan. Sin la separación, ocho
   números seguidos se leen como una sola cosa y nadie sabe cuál cambia al
   tocar "mes pasado". */
.tarjetas-periodo {
  padding: 4px 26px 18px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 14px;
}

/* Se colorea por signo desde el JS: puede ir para los dos lados y el color
   fijo mentiría la mitad de las veces. */
.valor.positivo { color: var(--in); }
.valor.negativo { color: var(--out); }

/* --- El resumen: una tabla en un cuadro ------------------------------
   Tres filas por tres columnas. Las reglas de abajo pisan las globales de
   `thead th` / `tbody td` (sticky, fondo, hover), que son de las tablas de
   movimientos y acá no corresponden. Entró en el color de la plata que
   entra, Salió en el de la que sale, Quedó por signo y en negrita. */
.tarjeta-resumen {
  padding: 4px 6px 2px;
  max-width: 560px;
  overflow-x: auto;
}
.resumen-caja { width: 100%; border-collapse: collapse; font-size: 14px; }
.resumen-caja th, .resumen-caja td {
  position: static;
  background: none;
  border-bottom: 1px solid var(--line2);
  padding: 8px 12px;
  vertical-align: baseline;
}
.resumen-caja thead th {
  color: var(--tx3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .8px;
  text-transform: uppercase;
  text-align: right;
}
.resumen-caja tbody th.res-rotulo {
  text-align: left;
  color: var(--tx);
  font-weight: 600;
  white-space: nowrap;
}
.res-bajada {
  display: block;
  color: var(--tx3);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .2px;
}
.resumen-caja td {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.resumen-caja tbody tr:hover td { background: none; }
.res-entro { color: var(--in); }
.res-salio { color: var(--out); }
/* `td.res-quedo` y no `.res-quedo`: tiene que ganarle al peso 600 de
   `.resumen-caja td`, que es más específico que una clase sola. */
.resumen-caja td.res-quedo { font-weight: 700; color: var(--tx); }
.resumen-caja td.res-quedo.positivo { color: var(--in); }
.resumen-caja td.res-quedo.negativo { color: var(--out); }
/* Desde el 5/9 hay una sola fila —El negocio—, así que la línea de abajo no
   separa de nada: colgaba suelta bajo la última cifra. Las reglas de la fila
   total (`.res-caja`) y de Lo tuyo se fueron con las filas que las usaban. */
.resumen-caja tbody th, .resumen-caja tbody td { border-bottom: 0; }

/* --- Las dos mitades ----------------------------------------------- */

.mitad {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0 26px 18px;
}

.mitad h2 {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--tx2);
  margin: 6px 0 8px;
}

.tabla-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--radio);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

thead th {
  position: sticky;
  top: 0;
  background: var(--surf2);
  border-bottom: 1px solid var(--line);
  color: var(--tx3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .8px;
  text-align: left;
  text-transform: uppercase;
  padding: 9px 14px;
  z-index: 1;
}

tbody td {
  border-bottom: 1px solid var(--line2);
  padding: 9px 14px;
  vertical-align: top;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: var(--hover); }

.col-fecha  { width: 132px; white-space: nowrap; }

/* Montos y fechas en cifras tabulares: las columnas de números quedan
   alineadas dígito a dígito aunque Nunito sea proporcional. */
.col-fecha, .col-monto, .hora, .rango-periodo, .rango input,
.chat-dia, .chat-meta, .evidencia-meta, .saldo-pedido, .cambio-linea,
.cambio-impacto, .baja-linea {
  font-variant-numeric: tabular-nums;
}
.col-tipo   { width: 128px; }
.col-monto  { width: 150px; text-align: right; white-space: nowrap; }
.col-estado { width: 130px; }

td.col-monto {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.hora { color: var(--tx3); margin-left: 6px; font-size: 12px; }
.suma { color: var(--in); }
.resta { color: var(--out); }
.sin-dato { color: var(--tx3); font-style: italic; font-weight: 400; }
.medio { color: var(--tx3); font-size: 12px; }

/* Anulado: se ve, tachado. Nunca se esconde. */
tr.anulado td { color: var(--tx3); text-decoration: line-through; }
tr.anulado .suma, tr.anulado .resta { color: var(--tx3); }
.marca-anulado {
  text-decoration: none;
  display: inline-block;
  margin-left: 8px;
  background: var(--out-bg);
  border-radius: 5px;
  color: var(--out);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .6px;
  padding: 1px 6px;
  text-transform: uppercase;
  vertical-align: 1px;
}

.estado {
  background: var(--mute-bg);
  border: 1px solid var(--mute-line);
  border-radius: 5px;
  color: var(--mute);
  font-size: 11px;
  letter-spacing: .4px;
  padding: 2px 7px;
  text-transform: uppercase;
  white-space: nowrap;
}
.estado.exigible { color: var(--info); background: var(--info-bg); border-color: var(--info-line); }

.vacio {
  color: var(--tx3);
  font-size: 13px;
  margin: 0;
  padding: 18px 14px;
}

/* --- Lo que se viene: es proyección, no plata movida, y se ve más apagado
   que los movimientos a propósito. --------------------------------------- */

.mitad-proyectada .tabla-scroll {
  background: color-mix(in srgb, var(--surf) 60%, var(--bg));
  border-color: var(--line2);
}
.mitad-proyectada thead th {
  background: color-mix(in srgb, var(--surf2) 60%, var(--bg));
  color: var(--tx3);
}
.mitad-proyectada tbody td { color: var(--tx2); }
.mitad-proyectada tbody tr:hover td { background: var(--hover); }
.mitad-proyectada .suma { color: color-mix(in srgb, var(--in) 65%, var(--tx2)); }
.mitad-proyectada .resta { color: color-mix(in srgb, var(--out) 65%, var(--tx2)); }

/* El filtro de contraparte de Movimientos (la vieja sección Proveedores,
   §14): mismo look que los selects de la corrección, misma paleta. */
.filtro-contraparte { margin: 6px 0 10px; display: flex; align-items: center; gap: 8px; }
.filtro-contraparte select {
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--tx);
  font: 13px/1.4 Nunito, system-ui, sans-serif;
  padding: 5px 8px;
  min-width: 130px;
}

/* La línea de ajuste de "Te deben": no es un trabajo, es plata que ya entró y
   que baja el total sin colgar de ninguna fila. Se lee como un renglón de
   cierre —atenuada, en itálica— no como un compromiso más. */
.fila-ajuste td {
  color: var(--tx3);
  font-style: italic;
  border-top: 1px dashed var(--line);
}
.fila-ajuste:hover td { background: none; }

/* --- Evidencia: la fila desplegable ---------------------------------
   Es respaldo, no protagonista (§14): el chevron es tenue, el desplegado se
   hunde un escalón respecto de la tabla y el texto va en el gris suave de
   siempre. Estas reglas van al final a propósito: empatan especificidad con
   las de .mitad-proyectada y gana el orden. */

/* Etiqueta solo para lectores de pantalla: el th del chevron no lleva texto. */
.oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.col-desplegar { width: 34px; text-align: center; }

tr.desplegable { cursor: pointer; }
.chevron {
  display: inline-block;
  color: var(--tx3);
  font-size: 11px;
  transition: transform .15s ease;
}
tr.abierta .chevron { transform: rotate(90deg); }
tbody tr.abierta td { background: var(--hover); }

tbody tr.evidencia td,
tbody tr.evidencia:hover td {
  background: var(--hundido);
  cursor: default;
  padding: 12px 16px 14px 46px;
}

.evidencia-caja {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 680px;
  font-size: 13px;
  color: var(--tx2);
}
.evidencia-meta { margin: 0; color: var(--tx3); font-size: 12px; }
.evidencia-texto {
  margin: 0;
  padding: 2px 0 2px 12px;
  border-left: 2px solid var(--line);
  font-style: italic;
}
.evidencia-caja audio {
  width: 100%;
  max-width: 420px;
  height: 36px;   /* los controles nativos siguen al color-scheme del tema */
}
.evidencia-multi { margin: 0; color: var(--tx3); font-size: 12px; }

/* --- Corrección inline: los controles dentro de la evidencia ----------
   Mismo tono discreto que el resto del desplegable; el único botón que grita
   es el de anular, y grita bajito (borde, no relleno). */

.evidencia-acciones { display: flex; gap: 8px; margin-top: 2px; }
/* `display` le gana al [hidden] del navegador: sin esto, la botonera sigue
   viéndose abajo del delta que abrió. */
.evidencia-acciones[hidden] { display: none; }

.btn-evidencia {
  appearance: none;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  padding: 5px 12px;
}
.btn-evidencia:hover:not(:disabled) { color: var(--tx); border-color: var(--tx2); }
/* Mientras un pedido viaja: misma convención que el sidebar (.seccion:disabled)
   — se atenúa y deja de ofrecerse al cursor. No hay estilo nuevo acá. */
.btn-evidencia:disabled { opacity: .55; cursor: default; }
.btn-primario {
  background: var(--acc);
  border-color: var(--acc);
  color: var(--acc-tx);
  font-weight: 600;
}
.btn-primario:hover:not(:disabled) { color: var(--acc-tx); }
.btn-anular { color: var(--out); border-color: var(--out-line); }
.btn-anular:hover:not(:disabled) { color: var(--out); border-color: var(--out); }

.form-correccion {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  align-items: flex-end;
}
.campo-correccion {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--tx3);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .6px;
}
.campo-correccion input,
.campo-correccion select {
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--tx);
  font: 13px/1.4 Nunito, system-ui, sans-serif;
  padding: 5px 8px;
  min-width: 130px;
}
.botones-correccion { display: flex; gap: 8px; margin-top: 4px; width: 100%; }
.form-correccion .botones-correccion { width: auto; }

.delta-banner {
  border-left: 2px solid var(--acc);
  padding: 4px 0 4px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.delta-banner p { margin: 0; }
.delta-titulo { color: var(--tx); font-weight: 600; font-size: 13px; }

.correccion-error { margin: 4px 0 0; color: var(--out); font-size: 12px; }

/* --- Clientes: lista y ficha --------------------------------------
   Misma paleta que Caja, mismo significado: verde = plata que entra o ya es
   tuya, gris = comprometido pero no exigible todavía (igual que "Por
   terminar" en Caja), rojo/naranja = plata que vos debés. El
   celeste de acento no tenía un significado de plata todavía: acá se usa
   para "aceptado" (comprometido y en curso), un estado intermedio entre el
   gris de "presupuestado" y el verde de "cobrado". */

.cabecera-clientes {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding: 20px 26px 16px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.titulo-vista {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: var(--tx);
}

.volver {
  appearance: none;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  padding: 7px 14px;
}
.volver:hover { color: var(--tx); border-color: var(--tx2); }

.mitad-clientes { padding-top: 4px; }

/* --- Chips grandes, texto explícito, sin símbolos -------------------
   Cada chip toma el par color/fondo de la variable que significa lo suyo:
   cobrado = entra, aceptado/terminado = info, presupuestado/corregido = mute,
   "le debés vos" = sale, "falta el monto" = warn. Ningún ícono. */

.chip-grande {
  display: inline-block;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .2px;
  padding: 4px 12px;
  white-space: nowrap;
}

.chip-cobrado    { color: var(--in);   border-color: var(--in-line);   background: var(--in-bg); }
.chip-por-cobrar { color: var(--info); border-color: var(--info-line); background: var(--info-bg); }
.chip-en-curso   { color: var(--mute); border-color: var(--mute-line); background: var(--mute-bg); }

/* "Le debés vos": el color de la plata que sale — es la misma idea,
   plata de tu bolsillo, sólo que todavía no se movió. */
.chip-le-debes-vos {
  color: var(--out);
  border-color: var(--out-line);
  background: var(--out-bg);
}

/* Compromiso incompleto ("Falta el monto", "a cuenta"): es el par `--warn`,
   "falta algo". No es una alarma, es un dato que falta, y por eso el ámbar
   y no el rojo de la plata que sale. */
.chip-incompleto {
  color: var(--warn);
  border-color: var(--warn-line);
  background: var(--warn-bg);
}

.chips-cliente { display: inline-flex; gap: 6px; margin-left: 10px; vertical-align: middle; }

/* --- Fila de cliente ------------------------------------------------- */

td.col-cliente { font-weight: 600; }
.col-monto.chip-te-debe { color: var(--in); }

/* Plano: saldo cero y nada abierto. Se ve, pero apagado — nunca se
   esconde (ni toggle ni paginado). */
tr.fila-plana td { color: var(--tx3); }
tr.fila-plana td.col-cliente { font-weight: 400; }
tr.fila-plana .col-monto.chip-te-debe { color: var(--tx3); }

/* --- Tarjetas de la ficha -------------------------------------------- */

.tarjetas-ficha {
  padding: 4px 26px 18px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 14px;
}
.tarjeta-a-favor .valor { color: var(--out); }

/* --- Pedidos: reusa .estado pero con las clases de chip de arriba ---- */

#ficha-pedidos td.col-estado { white-space: nowrap; }

/* El saldo pendiente del pedido: es el número que se mira, así que va en el
   texto pleno y en negrita. Sin color de signo — lo que falta cobrar no es
   ni una ganancia ni una pérdida. */
.saldo-pedido { color: var(--tx); font-weight: 600; }

/* --- Historial de correcciones: arriba de la evidencia vigente ---------
   El chip "Corregido" reusa el mismo componente de chip de Clientes (texto
   llano, sin ícono). El historial en sí se ve tachado/atenuado — es
   evidencia de lo que YA NO VALE, la vigente sigue abajo sin cambios. */

.chip-corregido {
  color: var(--mute);
  border-color: var(--mute-line);
  background: var(--mute-bg);
}

.historial-correcciones {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px dashed var(--line);
}
.historial-titulo {
  margin: 0;
  color: var(--tx3);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
}
.historial-version {
  display: flex;
  flex-direction: column;
  gap: 4px;
  opacity: .65;
}
.historial-version .evidencia-meta { color: var(--tx3); }
.historial-version .evidencia-texto.version-vieja {
  text-decoration: line-through;
  border-left-color: var(--tx3);
}
.audio-viejo { opacity: .8; }

/* --- Qué cambió + impacto, dentro de cada versión del historial -------- */

.version-cambios {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 2px;
  font-size: 12px;
}
.cambio-linea { margin: 0; color: var(--tx3); }
.cambio-impacto {
  margin: 4px 0 0;
  color: var(--tx2);
  font-weight: 600;
}

/* --- Anulado / reactivado: el otro eje del historial -------------------
   No son versiones del movimiento, son cosas que le pasaron, así que van
   abajo de la evidencia vigente y no dentro del bloque de correcciones. Se
   colorean con los mismos dos colores que ya usa toda la caja: salir es
   rojo, volver es verde. */

.historial-bajas {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  font-size: 12px;
}
.baja-linea { margin: 0; font-weight: 600; }
.baja-anulado { color: var(--out); }
.baja-reactivado { color: var(--in); }

/* ======================================================================
   Chat — la conversación, los dos canales en un solo hilo.

   Los dos canales no toman los colores de la plata: `--in` es plata que
   entró y `--out` plata que salió, y un mensaje de WhatsApp no es un cobro.
   WhatsApp va en `--info` y el Panel en `--mute`, los dos pares de la paleta
   que no significan plata.

   Y van en el BORDE y en la pill, nunca en el relleno de la burbuja: el
   relleno saturado convierte la conversación en dos paredes de color y hace
   pelear al texto, que es lo único que importa acá.
   ====================================================================== */

/* Absoluto y no un item mas de la grilla de `.principal`, a proposito. Como
   item, el hilo entero contaba para el alto de las filas: con 40 mensajes la
   grilla crecia a 12.000px, `.principal` se desbordaba, y el area de scroll
   —que se calcula sobre ese alto— quedaba mas alta que la ventana. El
   resultado era una conversacion completa en el DOM y una pantalla en blanco.
   Sacandolo del flujo, `.principal` vuelve a medir lo que mide la ventana y
   `inset: 0` le da al chat exactamente ese alto, que es contra lo que el
   `overflow-y: auto` de adentro tiene que trabajar. */
#vista-chat {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* `display: flex` puesto sobre un id le gana al `display: none` que el
   navegador aplica por `[hidden]`, asi que sin esta linea la vista del chat
   se quedaba encima de Caja para siempre. Las otras vistas no lo necesitan
   porque no declaran `display` propio. */
#vista-chat[hidden] { display: none; }

.cabecera-chat {
  align-items: center;
  justify-content: space-between;
}

.leyenda-canales { display: flex; gap: 8px; }

.pill {
  display: inline-block;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .3px;
  padding: 3px 10px;
  white-space: nowrap;
}
.pill-whatsapp {
  color: var(--info);
  border-color: var(--info-line);
  background: var(--info-bg);
}
.pill-panel {
  color: var(--mute);
  border-color: var(--mute-line);
  background: var(--mute-bg);
}
/* "🎤 Voz" / "⌨️ Texto" en la pill de un mensaje de WhatsApp. Nunito no trae
   emojis: sin las fuentes de emoji nombradas al final de la pila, el ⌨️ (que
   lleva variation selector) queda a merced del fallback del sistema, que en
   algún navegador lo pinta como el glifo de texto monocromo. */
.pill-origen {
  font-family: Nunito, system-ui, sans-serif,
               "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji";
}

/* Una columna hoy, dos en la tanda que viene. El minmax(0, 1fr) está para
   que la columna del hilo pueda encogerse: sin eso, una burbuja larga estira
   la grilla y aparece scroll horizontal en toda la página.

   Tope de ancho y centrado: en un monitor grande la conversación a pantalla
   completa deja líneas que hay que barrer de punta a punta. 720px de columna
   más los 26px de padding de cada lado (border-box). El pie con el input está
   adentro de `.chat-columna`, así que queda alineado con la misma columna. El
   `margin: 0 auto` centra dentro del flex vertical de `#vista-chat`; por
   debajo del tope el `width: 100%` la deja fluida como siempre. Sólo el Chat:
   Caja, Clientes y la Planilla no pasan por acá. */
.chat-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  min-height: 0;
  flex: 1;
  padding: 0 26px 18px;
  width: 100%;
  max-width: 772px;
  margin: 0 auto;
}

.chat-columna {
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative;
}

.chat-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 4px 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.chat-anteriores { display: flex; justify-content: center; padding-bottom: 8px; }

.chat-vacio { text-align: center; margin: auto; }

/* --- Separador de día -------------------------------------------------- */

.chat-dia {
  align-self: center;
  color: var(--tx3);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  margin: 14px 0 6px;
  padding: 3px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surf);
}

/* --- Un intercambio: lo que dijo el usuario, lo que se ejecutó, lo que se
   contestó. Siempre en ese orden. ---------------------------------------- */

.chat-intercambio {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 18px;
}

.chat-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--tx3);
}

/* La respuesta quedó escrita pero el WhatsApp falló los tres intentos: acá
   es el único lugar donde se puede leer, y el aviso no puede pasar por meta
   más del montón. Va después de .chat-meta: misma especificidad, gana el
   último. */
.chat-no-entregado {
  color: var(--out);
}

.chat-burbuja {
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--radio);
  background: var(--surf);
  padding: 10px 14px;
  max-width: 62ch;
  /* La respuesta del motor viene con saltos de línea y hay que respetarlos.
     pre-wrap los muestra sin que nadie tenga que convertir texto en HTML. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Derecha = lo que escribió o dijo el usuario, por el canal que sea;
   izquierda = lo que respondió Contáplata. El filete de canal va del lado
   derecho de la burbuja, acompañando la alineación. */
.chat-usuario { align-items: flex-end; }
.chat-usuario .chat-burbuja {
  border-left-width: 1px;
  border-right-width: 3px;
}
.chat-usuario.canal-whatsapp .chat-burbuja { border-right-color: var(--info); }
.chat-usuario.canal-panel    .chat-burbuja { border-right-color: var(--mute); }

/* Lo que contesta el motor: a la izquierda, con el borde neutro — de quién
   es el mensaje ya lo dice la etiqueta de arriba. */
.chat-motor .chat-burbuja {
  background: var(--surf2);
  border-left-color: var(--line);
}

.chat-audio { width: 100%; max-width: 320px; margin-bottom: 8px; display: block; }

/* --- Chips de movimientos ejecutados ------------------------------------ */

.chat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chat-chip {
  appearance: none;
  display: inline-block;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surf2);
  color: var(--tx);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  text-align: left;
}
.chat-chip:hover { border-color: var(--tx2); }
.chat-chip-caja        { box-shadow: inset 2px 0 0 var(--in); }
.chat-chip-compromisos { box-shadow: inset 2px 0 0 var(--acc); }
.chat-chip-anulado { color: var(--tx3); text-decoration: line-through; }

/* --- Pensando: tres puntos, sin texto que haya que leer -------------- */

.chat-pensando { display: inline-flex; gap: 4px; align-items: center; height: 1.45em; }
.chat-pensando span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--tx3);
  animation: chat-latido 1.2s infinite ease-in-out;
}
.chat-pensando span:nth-child(2) { animation-delay: .18s; }
.chat-pensando span:nth-child(3) { animation-delay: .36s; }

@keyframes chat-latido {
  0%, 60%, 100% { opacity: .25; transform: translateY(0); }
  30%           { opacity: 1;   transform: translateY(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  .chat-pensando span { animation: none; opacity: .6; }
}

/* --- Volver al final ---------------------------------------------------- */

.chat-bajar {
  position: absolute;
  right: 14px;
  bottom: 120px;
  z-index: 3;
  appearance: none;
  background: var(--surf2);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--tx);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 7px 14px;
  box-shadow: 0 4px 14px var(--sombra);
}
.chat-bajar:hover { border-color: var(--tx2); }

/* --- El pie: error, input, leyenda -------------------------------------- */

.chat-pie {
  border-top: 1px solid var(--line);
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.chat-envio { display: flex; gap: 10px; align-items: flex-end; }

#chat-texto {
  flex: 1;
  min-width: 0;
  resize: none;
  max-height: 140px;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--radio);
  color: var(--tx);
  font: inherit;
  padding: 11px 14px;
}
#chat-texto:focus { outline: none; border-color: var(--acc); }
#chat-texto:disabled { opacity: .55; cursor: not-allowed; }
#chat-texto::placeholder { color: var(--tx3); }

.chat-enviar {
  appearance: none;
  background: var(--acc);
  border: 1px solid var(--acc);
  border-radius: var(--radio);
  color: var(--acc-tx);
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  padding: 11px 20px;
}
.chat-enviar:disabled { opacity: .45; cursor: not-allowed; }

.chat-leyenda { margin: 0; color: var(--tx3); font-size: 12px; }

.chat-error {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  color: var(--out);
  font-size: 13px;
  border: 1px solid var(--out-line);
  background: var(--out-bg);
  border-radius: var(--radio);
  padding: 10px 14px;
}
/* Mismo caso que `#vista-chat[hidden]`: el `display: flex` de esta clase le
   gana al del navegador y la caja de error quedaba visible y vacia. */
.chat-error[hidden] { display: none; }

.chat-reintentar {
  appearance: none;
  background: none;
  border: 1px solid var(--out-line);
  border-radius: 8px;
  color: var(--out);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 12px;
}

/* ======================================================================
   Planilla — las tres hojas crudas, sólo lectura, con cara de planilla.

   Que se parezca a una planilla no es decoración: la planilla es el
   elemento que Contáplata reemplaza, y esta pantalla es la prueba de que
   lo hace. De ahí sale todo lo de abajo — cuadrícula en cada celda,
   numeración de filas, encabezado congelado, pestañas de hoja abajo — y de
   ahí sale también lo que NO tiene: ni tarjetas, ni sombras, ni bordes
   redondeados, ni el cuadro flotante que usan las otras vistas. La hoja
   ocupa el área y llega a los bordes.

   Lo único que se pinta distinto de una celda son los chips de estado y de
   "saldado", que se quedan (decisión del 08/09) porque son las dos cosas
   que el usuario viene a buscar. Están achatados a la altura de la línea
   de texto para no romper el alto de fila ni la cuadrícula.

   **Ninguna fila de totales, en ninguna hoja, a propósito.** Un total que
   cambia al filtrar es exactamente el número que no queremos que exista.
   Lo que sí hay es el renglón de "Mostrando N de M filas", que dice con
   todas las letras cuánto se está escondiendo.
   ====================================================================== */

/* Absoluto e `inset: 0` por el mismo motivo que `#vista-chat`, y con el
   mismo comentario largo allá arriba: la hoja no está paginada, así que como
   item de la grilla de `.principal` el alto de la tabla entera contaría para
   el alto de la fila, `.principal` se desbordaría, y el `overflow` de la caja
   de scroll —que se calcula contra ese alto— dejaría de scrollear. Sacada
   del flujo, la vista mide exactamente la ventana; de eso depende que el
   encabezado congelado tenga contra qué congelarse. */
#vista-planilla {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg);

  /* Los tres colores de la hoja, derivados del tema como todo el resto.
     `--celda` es el papel, `--cuadricula` la línea fina de la grilla y
     `--encabezado` la banda gris de arriba y de la columna de números. */
  --celda: var(--surf);
  --cuadricula: color-mix(in srgb, var(--line) 75%, transparent);
  --encabezado: color-mix(in srgb, var(--bg) 55%, var(--surf));
  --alto-fila: 34px;
}
/* Mismo caso que `#vista-chat[hidden]`: el `display: flex` puesto sobre un id
   le gana al `display: none` del navegador y la vista quedaría encima de las
   demás para siempre. */
#vista-planilla[hidden] { display: none; }

/* --- Cabecera y rótulo ---------------------------------------------- */

.planilla-cabecera {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 20px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}

/* Sobrio y fijo: dice de dónde salen estas filas y que acá no se tocan.
   No es un aviso ni una alerta — es el rótulo de la pantalla. */
.planilla-rotulo {
  margin: 0;
  color: var(--tx3);
  font-size: 12.5px;
}

/* --- El renglón que impide que un filtro esconda plata ---------------- */

.planilla-estado {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 8px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
  font-size: 12.5px;
  min-height: 38px;
}

.planilla-cuenta {
  color: var(--tx);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.planilla-orden { color: var(--tx2); }
.planilla-orden[hidden] { display: none; }

.planilla-quitar {
  appearance: none;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 10px;
}
.planilla-quitar:hover { color: var(--tx); border-color: var(--tx2); }
.planilla-quitar[hidden] { display: none; }

.planilla-aviso { color: var(--out); font-weight: 600; }
.planilla-aviso[hidden] { display: none; }

/* --- Las hojas ------------------------------------------------------- */

.planilla-hojas {
  flex: 1;
  min-height: 0;
  display: flex;
}

.hoja {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* `display: flex` sobre la clase le gana al `[hidden]` del navegador. */
.hoja[hidden] { display: none; }

/* La caja de scroll ES la hoja: sin borde, sin radio, sin sombra, llega a
   los cuatro bordes del área. Scrollea en las dos direcciones. */
.hoja-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--celda);
}

/* `separate` y no `collapse`: con `collapse` el navegador se queda con los
   bordes de las celdas `sticky` y la fila congelada aparece sin cuadrícula.
   Con `separate` + `border-spacing: 0` cada celda dibuja los suyos y la
   grilla sobrevive al congelado. `fixed` es lo que hace que los anchos NO
   bailen: salen del `<colgroup>` y no del contenido, así que son los mismos
   con la hoja filtrada y sin filtrar. */
.hoja-tabla {
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  font-size: 13px;
}

/* La cuadrícula: una línea fina en cada celda, sin zebra. La de arriba y la
   de la izquierda las pone la propia celda de la primera fila / columna. */
.hoja-tabla th,
.hoja-tabla td {
  border-right: 1px solid var(--cuadricula);
  border-bottom: 1px solid var(--cuadricula);
  padding: 0 8px;
  height: var(--alto-fila);
  /* Como en una planilla: una línea por celda y lo que no entra se corta.
     El texto completo va en el `title` de la celda, que lo pone el JS. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
  background: var(--celda);
}

.hoja-tabla tbody tr:hover td { background: var(--hover); }

/* --- Encabezado congelado -------------------------------------------- */

.hoja-tabla thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--encabezado);
  border-bottom: 1px solid var(--line);
  color: var(--tx2);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .4px;
  text-align: left;
  text-transform: uppercase;
  padding: 0;
  height: 46px;
}

/* El encabezado entero es el control de autofiltro: se clickea en cualquier
   parte, como en una planilla. La flechita es la manija; lo que dice que la
   columna está filtrada es la palabra, abajo. */
.filtro-boton {
  appearance: none;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  height: 100%;
  padding: 0 8px;
  text-align: left;
  width: 100%;
}
.filtro-boton:hover { background: color-mix(in srgb, var(--encabezado) 80%, var(--tx)); }

/* Dos renglones: el nombre de la columna arriba, entero, y la marca abajo.
   En una sola línea la marca se comía el nombre en las columnas angostas. */
.filtro-textos {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
}

.filtro-rotulo {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La marca de columna filtrada u ordenada: TEXTO, no una flechita pintada
   de otro color. "No alcanza con pintar la flechita" es el requisito. */
.filtro-marca {
  color: var(--acc);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}

.filtro-flecha {
  border: 1px solid var(--line);
  border-radius: 3px;
  color: var(--tx2);
  font-size: 9px;
  line-height: 1;
  padding: 3px 3px 4px;
}
.filtro-boton[aria-expanded="true"] .filtro-flecha,
th.columna-activa .filtro-flecha {
  border-color: var(--acc);
  color: var(--acc);
}

/* --- Columna de números de fila --------------------------------------
   Angosta, gris y congelada al scrollear horizontal. Numera la POSICIÓN en
   la hoja ordenada, no el orden de aparición: con un filtro puesto los
   números quedan salteados, y ese salteo es la segunda prueba —además del
   renglón de arriba— de que hay filas escondidas. Es lo mismo que hace una
   planilla de verdad. */

.celda-nro {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--encabezado);
  color: var(--tx3);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  text-align: right;
  border-right: 1px solid var(--line);
}
.hoja-tabla tbody tr:hover td.celda-nro { background: var(--encabezado); }

/* La esquina: congelada en las dos direcciones a la vez, así que va por
   encima de las dos. */
.hoja-tabla thead th.celda-nro {
  z-index: 3;
  border-bottom: 1px solid var(--line);
}

/* --- Alineación por tipo de dato -------------------------------------- */

/* Números y fechas a la derecha y en cifras tabulares: las columnas quedan
   alineadas dígito a dígito aunque Nunito sea proporcional. Texto a la
   izquierda, que es el default. */
.hoja-tabla .celda-monto,
.hoja-tabla .celda-fecha {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.hoja-tabla td.celda-monto { font-weight: 600; }
.hoja-tabla thead th.celda-monto .filtro-boton,
.hoja-tabla thead th.celda-fecha .filtro-boton { flex-direction: row-reverse; }
.hoja-tabla thead th.celda-monto .filtro-textos,
.hoja-tabla thead th.celda-fecha .filtro-textos { text-align: right; }

.hoja-tabla .suma  { color: var(--in); }
.hoja-tabla .resta { color: var(--out); }
.hoja-tabla .sin-dato { color: var(--tx3); font-style: italic; font-weight: 400; }
.hoja-tabla .hora { color: var(--tx3); margin-left: 6px; font-size: 11px; }

/* Fila anulada: tachada, y sigue ahí. Nunca se esconde ni se filtra sola. */
.hoja-tabla tr.anulado td { color: var(--tx3); text-decoration: line-through; }
.hoja-tabla tr.anulado .suma, .hoja-tabla tr.anulado .resta { color: var(--tx3); }
/* Al chip y a la nota de corrección se les saca el tachado: un chip tachado
   que dice "Anulada" se lee dos veces peor que uno derecho, y la nota que
   explica la corrección tiene que poder leerse. */
.hoja-tabla tr.anulado .chip-hoja,
.hoja-tabla tr.anulado .nota-fila { text-decoration: none; }

/* Las notas de corrección van en texto llano y explícito, al lado del chip.
   Nunca un símbolo: "→" no le dice a nadie cuál de las dos filas reemplazó
   a cuál. */
.nota-fila { color: var(--tx3); font-size: 11.5px; margin-left: 8px; }

/* --- Los chips de estado ---------------------------------------------
   Se quedan como chips (decisión del 08/09): el estado y el "saldado" son
   las dos cosas que se vienen a buscar acá y tienen que saltar sin leer la
   columna. Van achatados —`line-height` corto y padding vertical de 1px—
   para entrar en el alto de fila y no empujar la cuadrícula. Texto entero,
   ningún ícono, y el color acompaña a la palabra, nunca la reemplaza. */

.chip-hoja {
  display: inline-block;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .2px;
  line-height: 15px;
  padding: 0 9px;
  vertical-align: middle;
  white-space: nowrap;
}

.chip-vigente      { color: var(--mute); border-color: var(--mute-line); background: var(--mute-bg); }
.chip-anulada      { color: var(--out);  border-color: var(--out-line);  background: var(--out-bg); }
.chip-saldado      { color: var(--in);   border-color: var(--in-line);   background: var(--in-bg); }
.chip-falta-cobrar { color: var(--info); border-color: var(--info-line); background: var(--info-bg); }
.chip-falta-monto  { color: var(--warn); border-color: var(--warn-line); background: var(--warn-bg); }

/* Los seis estados de `compromiso_eventos`, cada uno con el color de lo que
   significa para la plata: presupuestado y previsto todavía no son nada
   (mute), aceptado está en curso (info), realizado ya es exigible (el verde
   de la plata que entra), pendiente es un dato que falta (warn) y anulado es
   el rojo de siempre. */
.chip-estado-presupuestado { color: var(--mute); border-color: var(--mute-line); background: var(--mute-bg); }
.chip-estado-previsto      { color: var(--mute); border-color: var(--mute-line); background: var(--mute-bg); }
.chip-estado-aceptado      { color: var(--info); border-color: var(--info-line); background: var(--info-bg); }
.chip-estado-realizado     { color: var(--in);   border-color: var(--in-line);   background: var(--in-bg); }
.chip-estado-pendiente     { color: var(--warn); border-color: var(--warn-line); background: var(--warn-bg); }
.chip-estado-anulado       { color: var(--out);  border-color: var(--out-line);  background: var(--out-bg); }

/* --- Hoja vacía ------------------------------------------------------- */

/* `sticky` a la izquierda para que el cartel se lea aunque la hoja esté
   corrida a la derecha. */
.hoja-vacia {
  position: sticky;
  left: 0;
  margin: 0;
  padding: 18px 20px;
  color: var(--tx3);
  font-size: 13px;
}
.hoja-vacia[hidden] { display: none; }

/* --- Las pestañas de hoja, abajo -------------------------------------- */

.planilla-pestanas {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  padding: 0 14px;
  border-top: 1px solid var(--line);
  background: var(--bg);
  min-height: 34px;
}

/* Forma de pestaña de planilla: esquinas de abajo redondeadas, la activa en
   el color del papel y unida a la hoja. */
.pestana {
  appearance: none;
  background: color-mix(in srgb, var(--bg) 70%, var(--tx3));
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 7px 7px;
  color: var(--tx2);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 5px 18px 6px;
  margin-top: -1px;
}
.pestana:hover { color: var(--tx); }
.pestana.activa {
  background: var(--celda);
  color: var(--tx);
  font-weight: 700;
  box-shadow: inset 0 -2px 0 var(--acc);
}

/* --- El menú de autofiltro -------------------------------------------
   Uno solo para todas las columnas, armado de nuevo cada vez que se abre y
   posicionado contra el encabezado que lo pidió. Es el único flotante de
   esta pantalla, así que sí lleva borde, radio y sombra: tiene que
   despegarse de la hoja. */

.filtro-menu {
  position: absolute;
  z-index: 20;
  width: 250px;
  max-height: 60vh;
  display: flex;
  flex-direction: column;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 10px 26px var(--sombra);
  font-size: 13px;
  overflow: hidden;
}
/* Mismo caso que `.chat-error[hidden]`: el `display: flex` de la clase le
   gana al `display: none` del navegador. */
.filtro-menu[hidden] { display: none; }

.filtro-menu-titulo {
  margin: 0;
  padding: 9px 12px 7px;
  border-bottom: 1px solid var(--line2);
  color: var(--tx3);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
}

.filtro-bloque {
  display: flex;
  flex-direction: column;
  padding: 6px;
  border-bottom: 1px solid var(--line2);
}

.filtro-opcion {
  appearance: none;
  background: none;
  border: 0;
  border-radius: 5px;
  color: var(--tx);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  padding: 6px 8px;
  text-align: left;
}
.filtro-opcion:hover { background: var(--hover); }
.filtro-opcion.elegida { color: var(--acc); font-weight: 700; }

/* La lista de valores presentes, con casillas. Scrollea sola cuando la
   columna tiene muchos valores distintos. */
.filtro-lista {
  overflow-y: auto;
  max-height: 190px;
  padding: 2px 6px 6px;
  border-bottom: 1px solid var(--line2);
}
.filtro-valor {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px;
  border-radius: 5px;
  cursor: pointer;
}
.filtro-valor:hover { background: var(--hover); }
.filtro-valor span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filtro-valor.filtro-todo {
  border-bottom: 1px solid var(--line2);
  border-radius: 0;
  font-weight: 700;
  margin-bottom: 2px;
}
.filtro-valor input { accent-color: var(--acc); margin: 0; }

.filtro-rango {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line2);
}
.filtro-rango label {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--tx2);
  font-size: 12px;
}
.filtro-rango input {
  flex: 1;
  min-width: 0;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--tx);
  font: inherit;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  padding: 4px 7px;
}

.filtro-pie {
  display: flex;
  gap: 8px;
  padding: 8px 10px;
}
.filtro-pie button {
  appearance: none;
  border-radius: 6px;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  padding: 5px 10px;
}
.filtro-limpiar {
  flex: 1;
  background: var(--surf);
  border: 1px solid var(--line);
  color: var(--tx2);
}
.filtro-limpiar:hover { color: var(--tx); border-color: var(--tx2); }
.filtro-aplicar {
  flex: 1;
  background: var(--acc);
  border: 1px solid var(--acc);
  color: var(--acc-tx);
}

/* --- Angosto: una sola columna, y el lateral arriba --------------------- */

@media (max-width: 860px) {
  .app { grid-template-columns: 1fr; height: auto; }
  .lateral { flex-direction: row; align-items: center; flex-wrap: wrap; gap: 10px; }
  .lateral nav { flex-direction: row; flex-wrap: wrap; }
  .boton-tema { margin-left: auto; align-self: center; }
  .boton-salir { margin-top: 0; align-self: center; }
  .nota-lateral { display: none; }
  /* El resumen NO se apila: entran las cuatro columnas achicando padding y
     letra. El cuadro ocupa todo el ancho. */
  .tarjeta-resumen { max-width: none; padding: 2px 0 0; }
  .resumen-caja { font-size: 12px; }
  .resumen-caja th, .resumen-caja td { padding: 6px 7px; }
  .resumen-caja tbody th.res-rotulo { white-space: normal; }
  .res-bajada { font-size: 10px; }
  /* En angosto el lateral es una barra que envuelve, y cuánto mide depende de
     cuántos ítems entren por fila: cualquier alto fijo para el chat deja el
     input abajo del borde de la pantalla en algún ancho. Así que en vez de
     adivinarlo, con el chat abierto la app pasa a medir una pantalla exacta y
     `.principal` se queda con lo que sobra — el chat, que es `inset: 0` sobre
     ella, hereda esa medida sea cual sea. Se limita a esta vista con la clase
     del body: Caja y Clientes siguen scrolleando la página entera como antes. */
  body.en-chat .app {
    height: 100dvh;
    grid-template-rows: auto minmax(0, 1fr);
  }
  body.en-chat .principal { min-height: 0; }
  .chat-layout { padding: 0 14px 14px; grid-template-columns: minmax(0, 1fr); }
  .chat-burbuja { max-width: 100%; }
  .chat-bajar { bottom: 132px; }
  /* La planilla es `inset: 0` sobre `.principal` igual que el chat, asi que
     necesita lo mismo que el: que la app mida una pantalla exacta y le deje a
     `.principal` lo que sobra del lateral, que en angosto envuelve y no tiene
     alto fijo. Sin esto la hoja se dibuja encima del lateral. */
  body.en-planilla .app {
    height: 100dvh;
    grid-template-rows: auto minmax(0, 1fr);
  }
  body.en-planilla .principal { min-height: 0; }
  /* La hoja no se apila ni se achica: en angosto scrollea al costado, que es
     lo que hace una planilla. Lo unico que cede es el margen de los rotulos. */
  .planilla-cabecera { padding: 12px 14px 8px; }
  .planilla-estado { padding: 8px 14px; }
  .planilla-pestanas { padding: 0 8px; }
  .filtro-menu { width: 220px; }
}

/* En un teléfono la pill de origen se queda sin el "Enviado por ": dice
   "WhatsApp — 🎤 Voz" / "WhatsApp — ⌨️ Texto" entera en una línea, en vez de
   truncarse o partirse en dos. Sólo la de los mensajes de WhatsApp; la del
   panel no tiene el span y no cambia. */
@media (max-width: 480px) {
  .chat-usuario .pill-prefijo { display: none; }
}

/* --- Pantalla de ingreso (/panel sin sesión) --------------------------- */

.ingreso-body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.ingreso {
  width: 100%;
  max-width: 380px;
  background: var(--surf);
  border: 1px solid var(--line);
  border-radius: var(--radio);
  padding: 28px 26px 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ingreso .marca { padding: 0; margin-bottom: 4px; }
.ingreso h1 { margin: 0; font-size: 18px; font-weight: 700; color: var(--tx); }
/* Cinco casilleros: 3 dígitos · separación · 2 letras. Grandes, para
   tipear en el celular; el ancho se reparte con flex y `min-width: 0` para
   que entren en 320px. */
.ingreso-casilleros {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.ingreso-casillero {
  flex: 1 1 0;
  min-width: 0;
  max-width: 56px;
  height: 60px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radio);
  color: var(--tx);
  font: inherit;
  font-size: 26px;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  padding: 0;
  caret-color: var(--acc);
}
.ingreso-casillero:focus { outline: none; border-color: var(--acc); box-shadow: 0 0 0 3px var(--info-bg); }
.ingreso-separador {
  width: 12px;
  height: 2px;
  background: var(--tx3);
  border-radius: 1px;
  flex: 0 0 auto;
}
.ingreso-entrar {
  appearance: none;
  background: var(--acc);
  border: 1px solid var(--acc);
  border-radius: var(--radio);
  color: var(--acc-tx);
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  padding: 12px 20px;
}
.ingreso-entrar:disabled { opacity: .45; cursor: not-allowed; }
.ingreso-error { margin: 0; color: var(--out); font-size: 13px; }
.ingreso-error[hidden] { display: none; }
.ingreso-ayuda { margin: 4px 0 0; color: var(--tx3); font-size: 13px; line-height: 1.5; }
