/* ══════════════════════════════════════════════════════════════════════════
   Fábrica O — el sistema.
   Marca ProfitView. Los tokens salen textuales de
   santiago-brain/_system/brand-profitview.md y no se bifurcan por cliente:
   el navy es del PRODUCTO. Lo que cambia por cliente son los módulos.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --paper: #fafafa;  --paper-warm: #f5f5f4;  --card: #ffffff;
  --ink: #0a0a0a;    --ink-light: #525252;
  --ink-muted: #737373;  --ink-subtle: #a3a3a3;
  --border: #ededed; --border-strong: #d4d4d4;

  --accent: #1e40af;  --accent-hover: #1e3a8a;  --accent-bright: #6b8eff;
  --accent-soft: #eff4ff;  --accent-soft-border: #dbe5ff;
  --accent-glow: rgba(30, 64, 175, 0.08);

  /* ── Verde y rojo con ojo de diseño (Santi, 14/9) ─────────────────────────
     «Más oscuros, sutiles, estéticos, menos chillones y genéricos… algo con
     más estilo para el ojo de diseñadoras». El verde y el rojo de semáforo
     (#2f9e63 / #d75f57) pasan a una familia terrosa: SALVIA para lo que suma,
     TERRACOTA para lo que resta, OCRE para «mirá esto». Más oscuros y con menos
     croma, y de paso legibles: los de antes daban 3,4 y 3,7 de contraste sobre
     blanco (debajo del 4,5 de texto); éstos, 5,8 y 5,7.
     Esta paleta es de Fábrica O: el archivo es de este sistema y Pretty tiene
     el suyo, así que no se toca a nadie más. El navy sigue siendo el de la
     marca. */
  --positive: #3e6f54;  --positive-soft: #eef4f0;  --positive-soft-border: #d2e0d7;
  --negative: #9c513c;  --negative-soft: #f8efeb;  --negative-soft-border: #ead3cb;
  --warn: #986a2f;      --warn-soft: #faf4eb;      --warn-soft-border: #ecdcc4;

  /* ── Gama del margen ─────────────────────────────────────────────────────
     Cinco tramos, y los cortes NO son números redondos: son los cuartiles de
     sus propios seis años — 0 · 32 · 55 · 94 — que reparten la cartera en
     7/17/26/24/26%. Un 40% es "normal" para Fábrica O aunque suene bajo, y un
     11% es malo aunque sea positivo. Ese juicio sale de su data, no de una
     convención.

     Se declaran en oklch para que la gama sea perceptual: dentro de cada
     familia sólo se mueven luminosidad y croma, el tono queda clavado. Por eso
     los dos verdes se leen como el mismo verde a dos intensidades y no como
     dos colores distintos. El tono de cada familia es el de la marca.

     Y el tramo del medio NO lleva color a propósito: si el 26% de la lista se
     pinta, el color deja de señalar. Sólo hablan los extremos.               */
  /* Dos tokens de SIGNIFICADO, no de componente. `--atencion` es «mirá esto,
     es recuperable»; `--perdida` es «esto ya pasó y no vuelve». Que un saldo
     negativo y un margen flojo compartan el ámbar no es reuso por comodidad:
     es que dicen lo mismo. Una caja en rojo NO es una pérdida — en su data
     pasa seguido y se cubre al mes siguiente (Luli quedó en −1.880.783 en
     dic 2025). Un proyecto con margen negativo, en cambio, ya perdió. */
  --atencion: oklch(0.56 0.095  70);    /* ocre       · 4,7 sobre blanco */
  --perdida:  oklch(0.49 0.115  32);    /* terracota honda · 6,6 */

  --m-perdida: var(--perdida);          /* < 0     · pierde plata */
  --m-flojo:   var(--atencion);         /* 0–32    · debajo del cuartil bajo */
  --m-normal:  var(--ink-light);        /* 32–55   · lo habitual, sin señal */
  --m-bueno:   oklch(0.54 0.055 158);   /* 55–94   · salvia · 4,8 */
  --m-optimo:  oklch(0.44 0.075 160);   /* ≥ 94    · bosque · 7,5 */

  --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --r-xl: 20px; --r-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(10,10,10,.05);
  --shadow-md: 0 4px 12px rgba(0,0,0,.05);
  --shadow-lg: 0 12px 32px rgba(10,10,10,.08);

  --display: "Plus Jakarta Sans", "Segoe UI", system-ui, sans-serif;
  --ui: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", "Cascadia Mono", ui-monospace, Consolas, monospace;

  /* ── Escala tipográfica. Antes había un rango de 0.78 a 1.75rem casi sin
     escalones intermedios, así que todo pesaba parecido y nada destacaba.
     Ocho pasos, y el salto grande está donde tiene que estar: entre el dato
     (--t3) y el título (--t6).

     ⚠️ LA ESCALA EXISTÍA Y MEDIO ARCHIVO NO LA USABA. Medido: 23 tamaños
     distintos en 59 declaraciones. `El mes` estaba escrito con la escala; el
     chrome, `Resolver` y `Explorar` con valores crudos —0.86, 0.73, 0.62— y
     `Resolver` además con estilos inline. Por eso la pantalla que tuvo la
     pasada fina se leía mejor que las otras dos: no era el criterio, era que
     las otras no estaban hechas con las mismas piezas.

     Ahora las 59 declaraciones salen de estos ocho pasos. Un tamaño nuevo se
     agrega ACÁ o no se agrega: si hace falta un valor que no está, la pregunta
     es qué paso falta, no cuánto mide este caso.                             */
  --t00: 0.6rem;   /* micro-etiquetas en mono: encabezado de tabla, chip, tipo */
  --t0: 0.68rem;   /* etiqueta de sección */
  --t1: 0.76rem;   /* subtítulo de fila, metadatos */
  --t2: 0.84rem;   /* números en tabla */
  --t3: 0.92rem;   /* nombre de fila, texto de lectura */
  --t4: 1.05rem;   /* título de panel */
  --t5: 1.3rem;    /* cifra ancla */
  /* 1.5rem y no 1.8: el título de pantalla se lee MÁS fuerte a 24px en negro
     pleno y peso 800 que a 28,8px en gris al 700, y encima deja lugar al lado
     para el contador y el filtro sin que la cabecera se amontone. Es el valor
     del sistema que ya está en producción en Pretty, que comparte estos
     tokens: dos productos del mismo chasis con dos escalas de título son dos
     productos. */
  --t6: 1.5rem;    /* título de pantalla */

  /* ── Espaciado. Un solo ritmo, para que la respiración sea deliberada.
     Seis pasos de LAYOUT: tarjetas, secciones, márgenes de pantalla. Más
     `--e0`, que es el único que faltaba de verdad y se usa seis veces.

     ⚠️ ESTA ESCALA NO CUBRE EL ESPACIADO DE CONTROLES, y es a propósito.
     Medido: 30 valores crudos distintos en 96 declaraciones de
     padding/margin/gap, casi todos abajo de 1rem — el padding de un botón, el
     gap de un chip. Redondearlos a estos seis pasos movería el layout entero
     en hasta ±1,6px, y el espaciado actual está bien: `El mes` se lee bien
     justamente por cómo respira.

     O sea que acá el problema NO es el mismo que con la tipografía. Allá había
     una escala y media pantalla no la usaba —eso se arregló—. Acá la escala
     nunca pretendió cubrir los controles. Definir esa segunda rampa es trabajo
     de la Fase 5, con la app real y sus componentes a la vista, no adivinando
     desde una maqueta. Queda anotado en el BACKLOG.                          */
  --e0: 0.15rem;
  --e1: 0.25rem; --e2: 0.5rem; --e3: 0.75rem;
  --e4: 1.1rem;  --e5: 1.6rem; --e6: 2.4rem;

  /* ── La segunda rampa: el espaciado DE CONTROL ───────────────────────────
     La de arriba mide layout —cuánto separa una tarjeta de la otra—. Ésta mide
     lo de adentro: el padding de un botón, el alto de una celda, el gap de un
     chip. Estaba anotada como pendiente arriba con la condición de definirla
     «con la app real y sus componentes a la vista»; esto es eso.

     Cinco pasos, y salen de medir los 30 valores crudos que ya había: el 68%
     caía en cuatro racimos (≈0.3 / ≈0.45 / ≈0.6 / ≈0.8) y el resto eran
     desviaciones de menos de 1px entre sí. O sea que la rampa ya existía de
     hecho; lo único que faltaba era escribirla para que la próxima celda no
     invente un sexto valor.

     ⚠️ No es la misma escala con otros números: es OTRO eje. Un botón con
     `--e4` de padding (1.1rem) es un botón gigante, y una tarjeta con `--k3`
     (0.6rem) de margen no separa nada. Mezclarlas es lo que hacía que algunas
     pantallas «respiraran» y otras no.                                       */
  --k1: 0.3rem;  /* gap de un chip · aire entre ícono y texto */
  --k2: 0.45rem; /* padding vertical de celda de tabla */
  --k3: 0.6rem;  /* padding vertical de control · gap de fila */
  --k4: 0.8rem;  /* padding horizontal de control */
  --k5: 1rem;    /* padding de contenedor chico */

  /* La barra de scroll es cromo, no contenido: descansa al tono del borde
     fuerte y sube a `--ink-subtle` recién cuando la agarrás. Van como tokens
     propios y no como `var(--border-strong)` suelto porque son una decisión
     con nombre — si mañana el borde cambia, la barra no tiene por qué. */
  --scroll: var(--border-strong);
  --scroll-activo: var(--ink-subtle);
}

/* El acento se ACLARA en oscuro: el navy da 2.2:1 sobre #0a0a0a. */
[data-theme='dark'] {
  --paper: #0a0a0a;  --paper-warm: #111111;  --card: #161616;
  --ink: #fafafa;    --ink-light: #d4d4d4;
  --ink-muted: #a3a3a3;  --ink-subtle: #737373;
  --border: #262626; --border-strong: #404040;
  --accent: #6b8eff; --accent-hover: #9ab4ff; --accent-bright: #9ab4ff;
  --accent-soft: rgba(107,142,255,.14);  --accent-soft-border: rgba(107,142,255,.32);
  --accent-glow: rgba(107,142,255,.12);
  --positive: #8fbea1;  --positive-soft: rgba(143,190,161,.12);  --positive-soft-border: rgba(143,190,161,.30);
  --negative: #da9884;  --negative-soft: rgba(218,152,132,.12);  --negative-soft-border: rgba(218,152,132,.30);
  --warn: #d9b480;      --warn-soft: rgba(217,180,128,.12);      --warn-soft-border: rgba(217,180,128,.30);
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow-md: 0 4px 12px rgba(0,0,0,.45);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.55);

  /* La gama sube de luminosidad y baja de croma sobre fondo oscuro. El tono no
     se mueve: es la misma gama, no otra paleta. */
  --atencion: oklch(0.79 0.080  75);
  --perdida:  oklch(0.71 0.100  34);

  --m-perdida: var(--perdida);
  --m-flojo:   var(--atencion);
  --m-normal:  var(--ink-light);
  --m-bueno:   oklch(0.72 0.050 158);
  --m-optimo:  oklch(0.83 0.070 160);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--paper); color: var(--ink);
  font-family: var(--ui); font-size: 15px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); }
/* Los checkboxes de Resolver y del wizard salían en el azul del navegador
   (#0d6efd en Chrome), al lado de botones y chips en navy: dos azules a 20px
   de distancia. `accent-color` los trae a la marca sin reemplazar el control
   nativo, que es el que ya sabe de foco y de teclado. */
input[type='checkbox'], input[type='radio'], progress { accent-color: var(--accent); }
[hidden] { display: none !important; }

/* ── barras de scroll ─────────────────────────────────────────────────────
   Las de Chrome en Windows miden 15px, pintan un canal gris de punta a punta y
   traen dos flechitas: al lado de una tarjeta con borde hairline se leen como
   parte del sistema operativo metida adentro del producto. Acá son finitas,
   sin canal, sin flechas, y sólo se ven cuando hay algo que scrollear.

   ⚠️ LOS DOS JUEGOS DE PROPIEDADES NO CONVIVEN, Y EL ORDEN IMPORTA.
   Desde Chrome 121, si el elemento declara `scrollbar-width` o
   `scrollbar-color`, las pseudo-clases `::-webkit-scrollbar` se IGNORAN por
   completo. Escribir las dos cosas planas no es «cinturón y tiradores»: gana
   la estándar y el bloque webkit no se aplica nunca.

   Y probadas las dos, la estándar da PEOR resultado en el navegador que ellas
   van a usar: `scrollbar-width: thin` en Windows adelgaza la barra pero deja
   las dos flechitas de Chrome, que son la mitad de lo que se venía a sacar.
   Entonces el webkit manda —Chrome, Edge, Safari— y la estándar queda para
   Firefox, que es el único que no entiende las pseudo-clases. Se lo pregunta
   con `selector()` y no con un hack de vendor: si el selector no existe, esa
   es exactamente la condición que define el caso.

   El pulgar se dibuja con `background-clip: padding-box` y un borde
   transparente: eso deja 6px de pulgar visible dentro de una pista de 10px,
   así el dedo tiene dónde agarrar sin que la barra pese 10px a la vista. */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--scroll); border-radius: var(--r-pill);
  border: 2px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--scroll-activo); background-clip: padding-box; }
/* Las flechas de los extremos: `display: none` las saca y el pulgar recupera
   el alto completo de la pista. */
::-webkit-scrollbar-button { display: none; }
/* La esquina donde se cruzan la barra vertical y la horizontal: sin esto queda
   un cuadradito gris opaco, que es justo lo que veníamos a sacar. */
::-webkit-scrollbar-corner { background: transparent; }

@supports not selector(::-webkit-scrollbar) {
  /* Heredan, así que una declaración en la raíz alcanza para todo el árbol.
     `transparent` en la pista es lo que saca el canal gris. */
  html { scrollbar-width: thin; scrollbar-color: var(--scroll) transparent; }
}

/* `stable` en los tres contenedores que scrollean adentro: el desplegable del
   buscador se redibuja en cada tecla, y los paneles de Explorar cambian de
   alto al navegar la pila. Sin gutter reservado la barra aparece y desaparece,
   y el contenido salta 10px en horizontal mientras se lee. Reservarlo siempre
   cuesta un renglón de aire; el salto cuesta la lectura. */
.sugerencias, .panel .contenido, .listaProy { scrollbar-gutter: stable; }

/* ── chrome ──────────────────────────────────────────────────────────────── */
.chrome {
  position: sticky; top: 0; z-index: 10;
  background: var(--paper); border-bottom: 1px solid var(--border);
}
/* ⚠️ Se llama `interior` y NO `fila`: ese nombre ya es el de la fila navegable
   de las listas, que trae cursor de mano, un borde arriba y fondo en :hover.
   El topbar se lo comía entero, y como el contenedor mide 76rem el hover
   pintaba un rectángulo que no llegaba a los bordes de la pantalla. Dos clases
   con el mismo nombre y semánticas distintas es el bug que más cuesta ver. */
.chrome .interior {
  max-width: 76rem; margin: 0 auto; padding: 0.7rem 1.25rem;
  display: flex; align-items: center; gap: 0.7rem;
}
.marca { display: flex; align-items: center; text-decoration: none; color: var(--ink); }
.marca .wordmark { height: 20px; width: auto; display: block; }
/* `nowrap`: sin esto «Fábrica O» parte en dos renglones en cuanto el topbar se
   aprieta, y el nombre del cliente cortado al medio es lo primero que se ve al
   entrar. Un nombre propio no envuelve. */
.cliente {
  color: var(--ink-light); font-size: var(--t2); font-weight: 600; white-space: nowrap;
  padding-left: 0.7rem; margin-left: 0.15rem; border-left: 1px solid var(--border-strong);
  /* Es un link a El mes, igual que el wordmark (Santi, 14/9): sin subrayado. */
  text-decoration: none;
}
.cliente:hover { color: var(--ink); }
.chrome .sp { flex: 1; }

/* Dos ítems de menú, no quince. Decisión 2 del plan. */
.menu { display: flex; gap: 0.35rem; align-items: center; }
.menu > a {
  font-size: var(--t2); text-decoration: none; padding: 0.35rem 0.8rem 0.35rem 0.7rem;
  border-radius: var(--r-pill); color: var(--ink-light); white-space: nowrap;
  display: inline-flex; align-items: center; gap: 0.42rem;
}
/* El ícono acompaña, no compite: un punto más chico que la palabra y un pelo
   más apagado. Al estar activo sube al mismo peso que el texto. */
.ico { width: 15px; height: 15px; flex: none; opacity: .72; }
.menu > a.on .ico, .menu > a:hover .ico { opacity: 1; }
/* ⚠️ ERA UN BLOQUE AZUL PLENO, Y ERA LO MÁS PESADO DE LA PANTALLA. El acento
   en `background` sobre un topbar claro pinta una pastilla de tinta saturada
   arriba a la izquierda que compite con el título, con el botón primario y con
   todo lo que de verdad tiene que llamar. Un ítem de menú activo no es una
   llamada a la acción: es un «estás acá».
   Lo dice igual con el fondo tibio, la tinta plena y el peso —tres señales, las
   tres baratas—, que es lo que ya hace Pretty del mismo chasis. El acento queda
   libre para lo que decide algo. */
.menu > a:hover { background: var(--paper-warm); color: var(--ink); }
.menu > a.on { background: var(--paper-warm); color: var(--ink); font-weight: 600; }
/* «Más» (8/10): el resto de las secciones, en un desplegable. El botón se ve
   como un ítem del menú —misma pastilla, mismo «estás acá»— y el panel es el de
   Registrar y el del avatar (`.menuRegistrar`), no un tercer menú distinto. */
.menuMas { position: relative; display: inline-flex; }
.menu .btnMas {
  font: inherit; font-size: var(--t2); cursor: pointer; background: none; border: 0;
  padding: 0.35rem 0.7rem; border-radius: var(--r-pill); color: var(--ink-light); white-space: nowrap;
  display: inline-flex; align-items: center; gap: 0.42rem;
}
.menu .btnMas:hover, .menu .btnMas[aria-expanded='true'] { background: var(--paper-warm); color: var(--ink); }
.menu .btnMas.on { background: var(--paper-warm); color: var(--ink); font-weight: 600; }
.menu .btnMas:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.flechaMas { font-size: 0.7em; opacity: .7; }
.menuMas .menuRegistrar [aria-current='page'] { background: var(--paper-warm); color: var(--ink); font-weight: 600; }
.menuMas .menuRegistrar .n { margin-left: auto; }
/* El inicio es el nombre del cliente al lado del logo: prendido cuando estás ahí. */
.cliente.on { color: var(--ink); }
.menu .btnMas .n, .menuMas .menuRegistrar .n,
.menu > a .n {
  font-family: var(--mono); font-size: var(--t0); margin-left: 0.3rem;
  padding: 0.05rem 0.35rem; border-radius: var(--r-pill);
  background: var(--warn-soft); color: var(--warn); border: 1px solid var(--warn-soft-border);
}
/* El badge ya no está sobre azul, así que conserva su propio color: un
   contador de pendientes en ámbar dice más que uno en blanco sobre blanco. */

/* `min-width` y no sólo `flex: 1`: el menú es `nowrap` y no cede, así que el
   único que cedía era éste. Entre 640px —donde el chrome se reordena— y
   ~960px el buscador se comprimía hasta quedar en un círculo vacío al lado del
   botón de tema: el control seguía ahí, clickeable, y no se veía que era una
   caja de búsqueda. Por debajo de 60rem se va a su propio renglón. */
.buscador { position: relative; flex: 1; min-width: 11rem; max-width: 24rem; }
/* La forma la fija el bloque compartido de más abajo (`.buscador input,
   .filtroL`). Acá queda sólo lo que es propio de estar en el topbar. */
.buscador input { width: 100%; padding-right: 2.4rem; }
.buscador input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* ── LA TECLA QUE DICE EL BUSCADOR TIENE QUE EXISTIR EN SU TECLADO ─────────
   El placeholder decía «Buscar…  ⌘/». El atajo es la barra SOLA —el handler
   descarta el evento si viene con meta o ctrl— así que «⌘/» era falso hasta en
   una Mac; y en Windows, que es donde esto se va a usar, ⌘ es una tecla que no
   está. Va como tecla y no como texto del placeholder: así se lee como un
   atajo, y desaparece apenas el campo se usa —mientras se escribe, un cartel
   diciendo cómo llegar acá es ruido. */
.buscador .atajo {
  position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: var(--t00); line-height: 1;
  color: var(--ink-subtle); background: var(--paper-warm);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 0.2rem 0.35rem; pointer-events: none;
}
.buscador input:focus ~ .atajo,
.buscador input:not(:placeholder-shown) ~ .atajo { display: none; }
.sugerencias {
  position: absolute; top: calc(100% + 0.35rem); left: 0; right: 0; z-index: 20;
  background: var(--card); border: 1px solid var(--border-strong);
  border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  max-height: 22rem; overflow-y: auto; padding: 0.3rem;
}
.sugerencias [data-i] {
  display: flex; width: 100%; gap: 0.6rem; align-items: baseline;
  background: none; border: 0; text-align: left; cursor: pointer;
  padding: 0.4rem 0.55rem; border-radius: var(--r-sm);
  font-family: var(--ui); font-size: var(--t2); color: var(--ink);
}
.sugerencias [data-i]:hover, .sugerencias [data-i].sel { background: var(--accent-soft); }
.sugerencias .nb { font-weight: 600; min-width: 0; }
.sugerencias .db {
  display: block; font-size: var(--t1); font-weight: 400; color: var(--ink-subtle);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sugerencias .tipo {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-subtle); margin-left: auto; white-space: nowrap;
}
.sugerencias .vacio { padding: 0.7rem; color: var(--ink-muted); font-size: var(--t2); }
.sugerencias .grupoSug {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-subtle); padding: 0.6rem 0.55rem 0.25rem;
}
/* ── el estado de inicio de la caja ───────────────────────────────────────
   Las filas de acción NO se ven como un resultado de búsqueda: llevan ícono,
   el nombre a tinta plena y más aire vertical. Un resultado se elige entre
   muchos; una acción se ofrece. Si se vieran igual, la caja abriría con dos
   renglones que parecen los dos primeros de una lista que no existe. */
.sugerencias [data-i].accion {
  align-items: flex-start; gap: 0.55rem; padding: 0.55rem 0.55rem 0.6rem;
}
.sugerencias [data-i].accion .ico {
  color: var(--accent); opacity: 1; margin-top: 0.12rem; width: 16px; height: 16px;
}
.sugerencias [data-i].accion .nb { font-size: var(--t3); color: var(--ink); }
.sugerencias [data-i].accion .db {
  white-space: normal; margin-top: 0.05rem; color: var(--ink-muted); line-height: 1.35;
  /* Si igual llega a partirse, que no deje una palabra sola en el segundo
     renglón: en una caja de 24rem, un huérfano se lee como un error de armado. */
  text-wrap: pretty;
}

/* Los filtros quedan pegados arriba: se usan mientras se lee la lista. */
.filtros {
  position: sticky; top: 0; z-index: 1; display: flex; gap: 0.25rem; flex-wrap: wrap;
  padding: 0.15rem 0.15rem 0.45rem; margin-bottom: 0.1rem;
  background: var(--card); border-bottom: 1px solid var(--border);
}
/* En inicio los chips van abajo de las acciones, así que dejan de estar
   pegados —no hay lista arriba que leer mientras se filtra— y el borde se da
   vuelta: separa de lo de arriba, no de lo de abajo. */
.filtros.abajo {
  position: static; padding: 0.5rem 0.15rem 0.2rem; margin: 0.35rem 0 0;
  border-bottom: 0; border-top: 1px solid var(--border);
}
/* El rótulo ocupa el renglón entero: sin esto es un ítem más del flex y los
   chips se le sientan al lado. */
.filtros .grupoSug { flex: 0 0 100%; padding: 0 0.4rem 0.35rem; }
.filtros button {
  font-family: var(--ui); font-size: var(--t1); padding: 0.18rem 0.55rem;
  border: 1px solid var(--border-strong); background: var(--card); color: var(--ink-muted);
  border-radius: var(--r-pill); cursor: pointer;
}
.filtros button:hover { color: var(--ink); }
.filtros button.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.filtros .n { font-family: var(--mono); opacity: .7; }

/* ── layout ──────────────────────────────────────────────────────────────── */
.pantalla { max-width: 76rem; margin: 0 auto; padding: var(--e5) 1.25rem 5rem; }
/* ── LA CABECERA ES UNA BANDA CON SU LÍNEA, NO UN RENGLÓN SUELTO ───────────
   Medido: entre el borde de abajo del título y el primer contenido había
   **4px** (`margin-bottom: var(--e1)`). El título quedaba pegado a la tabla y
   las dos cosas se leían como un solo bloque apretado — que es exactamente lo
   que se ve mal sin poder nombrarlo.
   La estructura es la misma que ya usa Pretty, que sale del mismo chasis: el
   título vive en una banda propia, la banda cierra con una línea al ancho de la
   pantalla, y recién después arranca el contenido. La línea no es adorno: es lo
   que convierte «título y tabla» en «encabezado de la pantalla» + «contenido».
   Y el aire de abajo es `--e5`, el mismo que separa dos tarjetas: lo que está
   en otro nivel respira lo mismo que lo que está al lado. */
.cabecera {
  display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap;
  padding-bottom: var(--e4); border-bottom: 1px solid var(--border);
  margin-bottom: var(--e5);
}
/* Cuando el título trae una línea de dato abajo —hoy sólo el cierre: «Quedan
   $5.405.135 entre las tres cajas»— esa línea es PARTE del encabezado, no el
   principio del contenido. Sin esto quedaba del otro lado de la raya, flotando
   sola en el aire que separa la banda de la primera tarjeta.
   Va con `:has()` y no moviendo el marcado porque el encabezado se arma en seis
   pantallas y cinco no tienen bajada; y si un navegador no lo entiende, cae en
   el layout de antes — corrido, no roto. */
.cabecera:has(+ .bajada) {
  border-bottom: 0; padding-bottom: var(--e2); margin-bottom: var(--e2);
}
.cabecera + .bajada {
  padding-bottom: var(--e4); border-bottom: 1px solid var(--border);
  margin-bottom: var(--e5);
}
/* ⚠️ EL TÍTULO VUELVE A TINTA PLENA. Estaba en `--ink-light` para «sentarse en
   el tono del menú», y el efecto medido fue el contrario: el h1 quedó al mismo
   valor que los rótulos de las tarjetas y la pantalla perdió su primer nivel de
   jerarquía — no había nada más oscuro que un subtítulo. El menú se apaga solo
   desde que el ítem activo dejó de ser un bloque azul.
   800 y no 700: es el peso con el que Plus Jakarta cierra bien a 24px. */
h1 {
  font-family: var(--display); font-weight: 800; font-size: var(--t6);
  letter-spacing: -0.025em; line-height: 1.15; margin: 0; color: var(--ink);
}
/* El año, un escalón más apagado. El mes es el sujeto; el año, contexto. */
h1 .anio { font-weight: 400; color: var(--ink-muted); letter-spacing: -0.012em; }
/* El contador que reemplazó a la bajada de las secciones. No es un chip de
   estado —no lleva fondo ni borde, que es peso de señal y esto es contexto—:
   es el número al lado del nombre, un escalón más chico y apagado, alineado a
   la base del título para que se lea como parte de él y no como un badge. */
h1 .cuentaT {
  font-family: var(--mono); font-size: var(--t3); font-weight: 500;
  color: var(--ink-subtle); letter-spacing: 0; margin-left: var(--e1);
  font-variant-numeric: tabular-nums;
}

/* Las dos flechas son UN control, no dos botones sueltos: un contenedor con
   borde hairline y una división al medio. Sin contenedor los glifos flotaban
   y se perdían; con un contenedor cada uno serían dos puntos compitiendo.
   Agrupadas se leen como lo que son — un paso atrás y uno adelante sobre lo
   mismo. */
.navPeriodo {
  margin-left: auto; display: inline-flex; overflow: hidden;
  background: var(--paper-warm); border: 1px solid var(--border);
  border-radius: var(--r-pill);
}
.navPeriodo button {
  border: 0; background: none; color: var(--ink-muted); cursor: pointer;
  width: 2rem; height: 1.8rem; display: grid; place-items: center; padding: 0;
}
.navPeriodo button + button { border-left: 1px solid var(--border); }
.navPeriodo button:hover:not(:disabled) { background: var(--card); color: var(--ink); }
.navPeriodo button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.navPeriodo button:disabled { opacity: .3; cursor: default; }
.navPeriodo .ico { width: 14px; height: 14px; opacity: 1; }

/* El selector de moneda del cierre. Mismo cuerpo que `.navPeriodo`, pero con
   texto: ahí los botones son cuadrados de 2rem y «dólares» no entra.
   ⚠️ El estado elegido y el hover NO se pintan igual. Ya pasó una vez con
   `.opcion.on`: con el mouse encima, una opción sin elegir se veía exacto como
   la elegida, así que mirando la pantalla no se sabía cuál estaba activa — y
   acá lo que la pantalla está diciendo es en qué moneda se cierra. */
.selMoneda {
  margin-left: auto; display: inline-flex; overflow: hidden;
  background: var(--paper-warm); border: 1px solid var(--border);
  border-radius: var(--r-pill);
}
.selMoneda button {
  border: 0; background: none; color: var(--ink-muted); cursor: pointer;
  font: inherit; font-size: var(--t1); padding: .22rem .75rem;
}
.selMoneda button + button { border-left: 1px solid var(--border); }
.selMoneda button:hover:not(.on) { background: var(--card); color: var(--ink); }
/* ⚠️ Era `var(--ink)`: el ÚNICO control seleccionado de todo el sistema pintado
   en negro pleno. El ítem de menú activo, la cola de Resolver elegida y el
   botón primario son `--accent`; un cuarto estado «elegido» con otro color se
   lee como otra cosa, y encima el negro pesa más que el navy, así que el
   selector de moneda gritaba más que el botón de cerrar el mes. */
.selMoneda button.on { background: var(--accent); color: #fff; font-weight: 600; cursor: default; }
.selMoneda button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* La moneda de la vista (14/9). Santi eligió un botón como el del tema, no un
   selector: el mismo cuerpo gris y sin fondo, con la moneda en la que se está
   mirando. «ARS» y «USD» tienen tres letras las dos, así que el botón no cambia
   de ancho al alternar — `$ / u$s` sí, y fue lo primero que se vio mal. */
.btn.icono.vistaMoneda {
  width: auto; padding: 0 0.45rem; font-family: var(--mono); font-size: var(--t1);
  font-weight: 500; letter-spacing: 0.04em;
}
.btn.icono.vistaMoneda:hover { color: var(--ink); background: var(--paper-warm); }
/* Parado en Ajustes, su botón queda marcado como el ítem de menú activo. */
#ajustesBtn.on { color: var(--ink); background: var(--paper-warm); }
/* Los saldos tapados (14/9). Los puntos van en la letra de la interfaz y en
   gris: un «$ ••••••» en Display negro de 22px se lee como una cifra rota. */
/* ⚠️ Con la variable y con dos clases: esta regla está antes que `.cajaQ` en
   el archivo, y con `.tapado` sola perdía — los puntos salían en Display negro. */
.tapado { --tinta: var(--ink-subtle); color: var(--ink-subtle); letter-spacing: 0.08em; }
.cajaQ.tapado, .grupoM b.tapado, .totalT b.tapado { color: var(--ink-subtle); font-family: var(--ui); font-weight: 500; }
.cabCajas { display: inline-flex; align-items: center; gap: var(--k3); }
.tarjeta > header:has(.cabCajas) { align-items: center; }
.ojoSaldos[aria-pressed='true'] { color: var(--ink); }

/* ── Ajustes ───────────────────────────────────────────────────────────────
   Pares dato/valor: el rótulo en mono chico, el valor en el cuerpo. */
.pares { display: grid; grid-template-columns: minmax(9rem, 14rem) 1fr; gap: var(--k3) var(--e4); margin: 0; }
.pares dt { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); padding-top: 0.1rem; }
.pares dd { margin: 0; color: var(--ink); }
.pares dd .tenue { color: var(--ink-subtle); }
@media (max-width: 40rem) { .pares { grid-template-columns: 1fr; gap: var(--k1) 0; } .pares dd { margin-bottom: var(--k3); } }
.consultaFx { display: flex; flex-wrap: wrap; align-items: center; gap: var(--k3) var(--e3); }
.consultaFx input[type=date] { font: inherit; color: var(--ink); background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-md); padding: 0.35rem 0.55rem; }
.consultaFx .res { font-variant-numeric: tabular-nums; }
.tablaFx td, .tablaFx th { font-family: var(--mono); font-variant-numeric: tabular-nums; }
h2.seccion {
  font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-subtle); font-weight: 500; margin: 0 0 var(--e3);
}
.bajada { color: var(--ink-muted); font-size: var(--t3); margin: 0 0 var(--e5); max-width: 68ch; }
.bajada b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }

.dos { display: grid; grid-template-columns: 26rem 1fr; gap: var(--e4); align-items: start; }
/* ⚠️ `min-width: 0` no es decorativo. Un ítem de grid arranca en `min-width:
   auto`, o sea que NO puede achicarse por debajo del ancho mínimo de su
   contenido — y adentro hay tablas con `white-space: nowrap`. Sin esto, en
   angosto la columna se estira hasta donde pide la tabla y arrastra la página
   entera al scroll horizontal, aunque la tarjeta tenga su propio overflow.
   Es la misma familia que la columna `queda` que se cortaba: el contenedor
   parece tener la culpa y la tiene el default del hijo. */
.dos > * { min-width: 0; }
@media (max-width: 64rem) { .dos { grid-template-columns: 1fr; } }

/* ⚠️ NO LLEVABAN NINGÚN MARGEN. Medido en `El mes`: la tarjeta de las cajas
   terminaba en y=482 y la de los proyectos EMPEZABA en y=482 — dos bordes
   hairline pegados, que a la vista es una línea doble en el medio de la
   pantalla y dos tarjetas que parecen una partida al medio. Funcionaba de
   casualidad en las pantallas de una sola tarjeta.
   El margen va en la hija directa de `.pantalla` y no en `.tarjeta` a secas:
   adentro de `.dos` la separación la da el `gap` de la grilla, y sumar un
   margen ahí descuadraría las dos columnas entre sí. */
.tarjeta {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
}
.pantalla > .tarjeta, .pantalla > .dos, .pantalla > .vizFila { margin-bottom: var(--e5); }
.pantalla > :last-child { margin-bottom: 0; }
.tarjeta > header {
  padding: var(--e4) var(--e4) var(--e3); display: flex; justify-content: space-between;
  gap: var(--e4); align-items: baseline;
}
.tarjeta > header h2 {
  /* `--ink-muted` y 0.1em: a `--ink-subtle` con 0.14em de tracking, «LAS CAJAS»
     y «LOS PROYECTOS DEL MES» eran lo más apagado de la pantalla, o sea que el
     único nivel intermedio entre el título y el dato no existía. Sigue siendo
     un micro-rótulo —mono, versalita— y ahora se lee. */
  font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 500; margin: 0;
}
.tarjeta > header .aux { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); }
.tarjeta .cuerpo { padding: 0 var(--e4) var(--e4); }

/* ── etiquetas de estado ─────────────────────────────────────────────────── */
.chip {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.09em; text-transform: uppercase;
  padding: 0.2rem 0.55rem; border-radius: var(--r-pill); white-space: nowrap;
  border: 1px solid transparent; font-weight: 500;
}
.chip.abierto { background: var(--accent-soft); border-color: var(--accent-soft-border); color: var(--accent); }
.chip.cerrado { background: var(--positive-soft); border-color: var(--positive-soft-border); color: var(--positive); }
.chip.alerta  { background: var(--warn-soft); border-color: var(--warn-soft-border); color: var(--warn); }
/* ── UN CHIP TAN LARGO COMO UNA FRASE YA NO ES UN CHIP ─────────────────────
   `contiene un número partido` son 26 caracteres en mono-mayúscula con 0,09em
   de tracking: en la fila de `Levadura` la etiqueta medía más que el nombre del
   cliente y era lo más ruidoso de la tabla. La mayúscula y el tracking existen
   para que dos palabras se lean como rótulo; en una frase hacen lo contrario.
   En caja baja y con la familia de texto ocupa ~30% menos y se lee como lo que
   es: una nota al lado del nombre. El pastillón ámbar se queda —sigue siendo
   una señal— y la explicación entera sigue en el `title`. */
.chip.nota {
  font-family: var(--ui); font-size: var(--t1); text-transform: none;
  letter-spacing: 0; padding: 0.1rem 0.5rem;
}
.chip.malo    { background: var(--negative-soft); border-color: var(--negative-soft-border); color: var(--negative); }

/* ── botones ─────────────────────────────────────────────────────────────── */
.btn {
  font-family: var(--ui); font-size: var(--t2); font-weight: 600;
  padding: 0.55rem 1.05rem; border-radius: var(--r-md); cursor: pointer;
  border: 1px solid var(--border-strong); background: var(--card); color: var(--ink);
  text-decoration: none; display: inline-block; text-align: center;
}
.btn:hover { border-color: var(--ink-subtle); }
.btn.primario { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primario:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn.fantasma { border-color: transparent; color: var(--ink-muted); }
.btn.fantasma:hover { background: var(--paper-warm); border-color: transparent; }
.btn.ancho { width: 100%; }
.btn.chico { font-size: var(--t1); padding: 0.3rem 0.7rem; }
/* Botón de sólo glifo: cuadrado, sin texto, sin ruido. */
.btn.icono {
  padding: 0; width: 2rem; height: 2rem; display: inline-grid; place-items: center;
  color: var(--ink-muted); border-color: transparent; background: none;
}
.btn.icono:hover { color: var(--ink); background: var(--paper-warm); border-color: transparent; }
.btn.icono .ico { width: 16px; height: 16px; opacity: 1; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn:disabled { opacity: .5; cursor: default; }
.enlace {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--ui); font-size: var(--t2); color: var(--accent); font-weight: 500;
}
.enlace:hover { text-decoration: underline; }

.acciones { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; margin-top: 1.1rem; }
.acciones .sp { flex: 1; }

/* ── números ─────────────────────────────────────────────────────────────── */
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ── Las clases semánticas NO pintan: setean `--tinta` ──────────────────────
   Un saldo en negativo se veía NEGRO en la tarjeta de cajas de «El mes»: ahí
   el color lo fija `.tabla td.q` (0-2-1) y `.saldo-neg` (0-1-0) perdía la
   guerra de especificidad. Parchearlo con `.tabla td.q.saldo-neg` habría sido
   tapar agujeros de a uno.
   Seteando una variable el conflicto desaparece por construcción: la clase
   semántica declara QUÉ significa el dato, y cada componente decide DÓNDE se
   aplica leyendo `var(--tinta, <su color por defecto>)`. No compiten nunca,
   porque no declaran la misma propiedad.                                     */
.pos       { --tinta: var(--positive); }
.neg       { --tinta: var(--negative); }
.tenue     { --tinta: var(--ink-subtle); }
.m-perdida { --tinta: var(--m-perdida); }
.m-flojo   { --tinta: var(--m-flojo); }
.m-normal  { --tinta: var(--m-normal); }
.m-bueno   { --tinta: var(--m-bueno); }
.m-optimo  { --tinta: var(--m-optimo); }
/* Un saldo en negativo habla con la misma voz que un margen flojo: atención,
   no catástrofe. Es el mismo token porque es el mismo significado. */
.saldo-neg { --tinta: var(--atencion); }

/* Los slots sin color propio simplemente la aplican. */
.pos, .neg, .tenue, .saldo-neg,
.m-perdida, .m-flojo, .m-normal, .m-bueno, .m-optimo { color: var(--tinta); }

/* ── tablas ──────────────────────────────────────────────────────────────── */
.tabla { width: 100%; border-collapse: collapse; }
.tabla th {
  /* Micro-label, así que la mono-mayúscula se queda (es su rol en el handoff).
     Mismo arreglo que `.kpiK`: a 9,6px el tracking de `0.1em` hacía ilegible
     justo la fila que explica qué es cada columna. */
  font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 500; text-align: right;
  padding: 0 0 var(--k3); border-bottom: 1px solid var(--border-strong);
}
.tabla th:first-child { text-align: left; }
.tabla th + th, .tabla td + td { padding-left: var(--e4); }
.tabla tbody tr:first-child td { padding-top: var(--k3); }
.tabla td {
  padding: var(--k2) 0; font-size: var(--t2); text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tabla td:first-child { text-align: left; font-weight: 600; white-space: normal; }
/* ── Por qué las filas llevan línea ───────────────────────────────────────
   Con ocho columnas y el ancho completo, el ojo tiene que viajar de «ALO JUNIN»
   hasta «$17.932.486» sin nada que lo sostenga, y se salta de fila. La
   alternativa clásica es el cebrado, y acá está VEDADO: el fondo de fila alterna
   sería `--paper-warm`, que es exactamente el que usa `tr.nav:hover`. Una fila
   par sin el mouse encima se vería igual que la fila que estás señalando — la
   trampa del estado y el hover pintados igual, que ya se pagó una vez. */
.tabla tbody tr + tr td { border-top: 1px solid var(--border); }
/* Lo que se compara (vino, movió) es contexto; lo que queda es el ancla. */
.tabla td.n { font-family: var(--mono); font-size: var(--t1); color: var(--tinta, var(--ink-muted)); }
/* Un metadato no es plata. `MOVS` pesaba igual que `FACTURÓ` y no dice lo
   mismo: uno cuenta filas y el otro cuenta dinero. */
.tabla td.meta { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); }
.tabla td.q {
  /* Peso 600 y no 700: de JetBrains Mono la marca define 400/500/600. */
  font-family: var(--mono); font-size: var(--t3); font-weight: 600;
  color: var(--tinta, var(--ink)); letter-spacing: -0.01em;
}
/* La columna por la que está ordenada la tabla gobierna lo que ves: no puede
   ser la que menos pesa. Se marca en el encabezado y en la celda. */
.tabla th.ord { color: var(--ink); font-weight: 600; }
.tabla td.ord { color: var(--tinta, var(--ink-light)); }
/* Una caja que NO se movió en el mes. En febrero 2021 la SRL e Inviu no tenían
   nada, y su `queda` igual salía en `0` negro y negrita: el mismo peso que los
   $25,8M reales de Inviu en junio 2026. Un cero que significa «acá no pasó
   nada» no puede pesar como un número.
   Se resuelve con el mismo patrón de siempre — la fila setea `--tinta` y cada
   celda la lee — así no hay que pelear especificidad celda por celda. */
.tabla tr.suave { --tinta: var(--ink-subtle); }
.tabla tr.suave td:first-child { font-weight: 400; color: var(--ink-muted); font-size: var(--t2); }
.tabla tr.suave td.q { font-weight: 400; }
.tabla tr.total td { border-top: 1px solid var(--border-strong); padding-top: 0.55rem; font-weight: 700; }
/* Toda entidad es una puerta, también en tabla. El chevron aparece al pasar. */
.tabla tr.nav { cursor: pointer; }
.tabla tr.nav:hover td { background: var(--paper-warm); }
.tabla tr.nav:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.tabla tr.nav .ir { color: var(--ink-subtle); opacity: 0; font-size: var(--t1); }
.tabla tr.nav:hover .ir, .tabla tr.nav:focus-visible .ir { opacity: 1; }

/* ── listas de filas navegables: el corazón de Explorar ──────────────────── */
.filas { display: flex; flex-direction: column; }
.fila {
  display: grid; grid-template-columns: 1fr auto auto 0.9rem;
  gap: var(--e4); align-items: center; width: 100%;
  padding: 0.6rem 0.55rem; border: 0; border-top: 1px solid var(--border);
  background: none; text-align: left; cursor: pointer;
  font-family: var(--ui); font-size: var(--t3); color: var(--ink);
  border-radius: var(--r-sm); transition: background .1s;
}
.filas .fila:first-child { border-top: 0; }
.fila:hover { background: var(--paper-warm); }
.fila:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.fila .et { font-weight: 600; letter-spacing: -0.005em; line-height: 1.3; }
.fila .sub2 {
  display: block; font-size: var(--t1); color: var(--ink-subtle);
  font-weight: 400; letter-spacing: 0; margin-top: 0.1rem;
}
.fila .v {
  font-family: var(--mono); font-size: var(--t2); font-variant-numeric: tabular-nums;
  color: var(--tinta, var(--ink-light));
}
/* El margen es el número que se busca: más grande y más pesado que el resto. */
.fila .m {
  font-family: var(--mono); font-size: var(--t3); font-weight: 700;
  min-width: 3.6rem; text-align: right; font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
/* El chevron aparece al pasar: si estuviera siempre, 40 filas serían 40 flechas. */
.fila .ir { color: var(--ink-subtle); font-size: var(--t1); opacity: 0; transition: opacity .1s; }
.fila:hover .ir, .fila:focus-visible .ir { opacity: 1; }
.fila.plano { cursor: default; }
.fila.plano:hover { background: none; }

/* ── Explorar: paneles apilados ──────────────────────────────────────────── */
/* ── La pila ES el título de Explorar ──────────────────────────────────────
   No es una miga de pan debajo de un encabezado: es el encabezado. Antes había
   un `<h1>Explorar</h1>` —la única pantalla cuyo título no decía qué estabas
   mirando— y abajo, en gris chico, la miga con la información de verdad. La
   jerarquía estaba dada vuelta, y el plan ya decía lo contrario: «el título de
   arriba ES la navegación».
   Hereda de h1 y vive en `.cabecera`, como «junio 2026» en El mes. Baja un paso
   de tamaño porque una pila de cuatro nodos a --t6 no entra en una línea.    */
h1.pila {
  display: flex; align-items: baseline; gap: var(--e0); flex-wrap: wrap;
  font-size: var(--t5); font-weight: 400; color: var(--ink-muted);
}
h1.pila button {
  background: none; border: 0; cursor: pointer; color: inherit;
  font-family: inherit; font-size: inherit; font-weight: inherit;
  letter-spacing: inherit; padding: 0 var(--e1); border-radius: var(--r-sm);
}
h1.pila button:hover { background: var(--paper-warm); color: var(--ink-light); }
h1.pila button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
h1.pila .sep { color: var(--ink-subtle); font-size: var(--t4); }
/* El nodo actual es el sujeto: peso pleno, y el mismo tono que cualquier otro
   título de pantalla. */
h1.pila .actual { color: var(--ink-light); font-weight: 700; letter-spacing: -0.02em; }

.paneles {
  display: flex; gap: 0.85rem; overflow-x: auto; padding-bottom: 0.5rem;
  scroll-snap-type: x proximity; margin-top: var(--e5);
}
.panel {
  flex: 0 0 22rem; max-width: 22rem; scroll-snap-align: end;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; max-height: 34rem;
}
/* El panel activo CRECE para llenar lo que sobra. Con uno o dos paneles la
   pantalla quedaba tres cuartos vacía a la derecha —el caso más común, porque
   toda exploración empieza con uno— mientras `El mes`, al lado, llena los
   76rem. Con `flex: 1 1` el último toma el espacio libre y con cuatro paneles
   vuelve a su ancho y la tira scrollea, que era el comportamiento bueno. */
.panel.ultimo {
  flex: 1 1 26rem; max-width: 42rem; min-width: 26rem;
  border-color: var(--accent-soft-border); box-shadow: var(--shadow-md);
}
.panel > header { padding: var(--e4) var(--e4) var(--e3); border-bottom: 1px solid var(--border); }
.panel .tipo {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--accent); display: block; margin-bottom: var(--e1);
}
.panel h3 {
  font-family: var(--display); font-size: var(--t4); font-weight: 800;
  margin: 0; letter-spacing: -0.025em; line-height: 1.2;
}
.panel .resumen {
  display: flex; gap: var(--e3) var(--e4); flex-wrap: wrap;
  margin-top: var(--e3); font-size: var(--t1); color: var(--ink-subtle);
}
.panel .resumen b {
  font-family: var(--mono); color: var(--tinta, var(--ink)); font-weight: 700;
  font-size: var(--t2); letter-spacing: -0.02em; margin-left: 0.15rem;
}
.panel .contenido { overflow-y: auto; padding: var(--e2) var(--e3) var(--e3); }
.panel .grupo {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink-subtle); padding: var(--e4) 0.55rem var(--e1);
}
.panel .grupo:first-child { padding-top: var(--e2); }
/* Dentro de un panel de 22rem el ritmo de la fila general es demasiado ancho:
   el nombre se parte en tres líneas. Se aprieta el gap y se achican las cifras,
   que acá son contexto — el nombre es lo que se lee. */
.panel .fila {
  grid-template-columns: 1fr auto auto 0.7rem;
  gap: var(--e2); padding: 0.5rem 0.5rem;
}
.panel .fila .et { font-size: var(--t2); line-height: 1.25; }
.panel .fila .sub2 { font-size: var(--t0); }
.panel .fila .v { font-size: var(--t1); }
.panel .fila .m { font-size: var(--t2); min-width: 2.8rem; }
.panel .vacio { padding: 1rem 0.6rem; color: var(--ink-subtle); font-size: var(--t2); }

/* ── P4 · Preguntar (15/9) ────────────────────────────────────────────────
   Con las piezas de la ficha: la cabecera de siempre, la pregunta como un
   formulario del sistema (no un campo gigante suelto), la frase que contesta
   como bajada destacada y, abajo, las KPI y el cuerpo de la ficha. */
.preguntaF {
  position: relative; display: flex; gap: var(--e2); align-items: center;
  max-width: 48rem; margin-bottom: var(--e5);
}
.preguntaF .campoTexto { flex: 1; padding: 0.75rem 0.9rem 0.75rem 2.6rem; font-size: 1rem; border-radius: var(--r-lg); }
.preguntaF .btn { padding: 0.72rem 1.2rem; border-radius: var(--r-lg); }
.preguntaIco {
  position: absolute; left: 0.85rem; top: 50%; transform: translateY(-50%);
  color: var(--ink-subtle); display: flex; pointer-events: none;
}
.preguntaIco .ico { width: 17px; height: 17px; opacity: 1; }
.preguntaGuia { margin-bottom: var(--e3); }

/* La frase que contesta: lo primero que se lee y lo único que puede leerse
   solo. Los números van en negrita adentro del texto: sacarlos del renglón
   obliga a cruzar la vista para saber qué mide cada uno. */
.respuestaR {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: var(--e3) var(--e4); margin-bottom: var(--e5);
  padding: var(--e4) var(--e5); background: var(--card);
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
}
.fraseR { margin: 0; font-size: var(--t4); line-height: 1.5; color: var(--ink-light); max-width: 68ch; }
.fraseR b { color: var(--ink); font-weight: 700; }
.respuestaR .btn { flex: none; display: inline-flex; align-items: center; gap: 0.35rem; }
.respuestaR .btn .ico { width: 14px; height: 14px; }
/* Lo que la pregunta pidió y la respuesta no pudo aplicar (15/9): ámbar, arriba
   de la frase, y la frase pierde el filo azul — no es una respuesta limpia. */
.avisoR { margin: 0 0 var(--e2); max-width: none; }
.respuestaR.conAviso { border-left-color: var(--atencion); }
.tituloR { font-family: var(--display); font-size: var(--t4); font-weight: 700; margin: 0 0 var(--e3); }
.respuestaDatos .kpis { margin-bottom: var(--e4); }

.preguntaNo { margin: 0 0 var(--e5); max-width: 48rem; }
.otrasR { margin-top: var(--e6); }
.otrasR h2.seccion { margin-bottom: var(--e3); }
/* Las preguntas de ejemplo son puertas: chips con el borde de los controles. */
.preguntasSug { display: flex; flex-wrap: wrap; gap: var(--e2); }
.chipPregunta {
  font-family: var(--ui); font-size: var(--t2); color: var(--ink-light); cursor: pointer;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-pill);
  padding: 0.45rem 0.9rem; text-align: left;
}
.chipPregunta:hover { color: var(--ink); border-color: var(--accent-soft-border); background: var(--accent-soft); }
.chipPregunta:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (max-width: 40rem) {
  .preguntaF { flex-wrap: wrap; }
  .preguntaF .btn { width: 100%; }
  .preguntaIco { top: 1.45rem; }
  .respuestaR { padding: var(--e3) var(--e4); }
}

/* La fila de preguntar dentro de la caja. Va con el mismo dibujo que las
   acciones de inicio —es una acción— pero el texto es lo tipeado, así que se
   deja respirar en varias líneas en vez de cortarse con puntos suspensivos. */
.sugerencias [data-i].accion.pregunta .nb { white-space: normal; }

/* ── P5 · Registrar ────────────────────────────────────────────────────────
   No hay lenguaje visual nuevo: la tarjeta, la pregunta, el porqué, la
   consecuencia y las acciones son las de `Resolver`. Lo único propio son las
   piezas de formulario, que ahí no existían. */

/* Los pasos, como puntos y no como «3 de 7»: el número invita a contar cuánto
   falta, que es justo lo que hace que un formulario se sienta largo. */
.pasosW { display: flex; gap: 0.3rem; margin: 0 0 var(--e4); }
.pasoW {
  width: 1.6rem; height: 3px; border-radius: var(--r-pill);
  background: var(--border-strong); transition: background .15s;
}
.pasoW.hecho { background: var(--accent); opacity: .45; }
.pasoW.on { background: var(--accent); }

.opciones { display: grid; gap: 0.4rem; }
.opciones.lista { margin-top: 0.55rem; max-height: 15rem; overflow-y: auto; scrollbar-gutter: stable; }
.opcion {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem;
  width: 100%; text-align: left; cursor: pointer; font-family: var(--ui);
  padding: 0.6rem 0.85rem; border-radius: var(--r-md);
  border: 1px solid var(--border-strong); background: var(--card); color: var(--ink);
  /* La opción puede ser un <button> o un <a> —la de elegir qué registrar navega—
     y el <a> se traía el azul y el subrayado de la regla global. Un control que
     cambia de aspecto según el tag que le tocó es el mismo bug de especificidad
     de siempre: la clase manda, no el elemento. */
  text-decoration: none;
}
/* ⚠️ `:hover` y `.on` NO pueden pintarse igual, y la primera versión los pintó
   idénticos: pasando el mouse por encima, una opción sin elegir se veía exacto
   como la elegida, así que mirando la pantalla no se podía saber qué estaba
   contestado. Es la familia de siempre —dos reglas que están bien por separado
   y se pelean— pero acá el costo no es estético: es no saber qué elegiste.
   Ahora el hover sólo insinúa (borde y papel tibio) y la elegida es la única
   que se llena de acento. */
.opcion:hover { border-color: var(--accent); background: var(--paper-warm); }
.opcion:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* La elegida se marca con el borde y el fondo del acento, no con un tilde: el
   glifo agrega un elemento a leer para decir lo que el color ya dijo. */
.opcion.on, .opcion.on:hover { border-color: var(--accent); background: var(--accent-soft); }
.opcion .ot { font-size: var(--t3); font-weight: 600; }
.opcion.on .ot { color: var(--accent); }
.opcion .od { font-size: var(--t1); color: var(--ink-muted); line-height: 1.35; }
/* «Crear X» va en borde punteado: dice «esto todavía no existe» sin una
   palabra de más, y es el mismo recurso que `.nombreEditable`. */
.opcion.nuevo { border-style: dashed; }

.campoTexto {
  font-family: var(--ui); font-size: var(--t3); color: var(--ink);
  background: var(--card); border: 1px solid var(--border-strong);
  border-radius: var(--r-md); padding: 0.55rem 0.8rem; width: 100%;
}
.campoTexto:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.campoTexto.num {
  font-family: var(--mono); font-size: var(--t5); font-weight: 700;
  letter-spacing: -0.02em; text-align: right; font-variant-numeric: tabular-nums;
}
.campos { display: flex; gap: var(--e4); flex-wrap: wrap; }
.campos label {
  display: grid; gap: 0.3rem; flex: 1 1 11rem;
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-subtle);
}
.elegido { font-size: var(--t1); color: var(--ink-muted); margin: 0.5rem 0 0; }
/* «Todavía no sé» es hijo directo del cuerpo y no de `.acciones`, así que no
   heredaba el aire de arriba y quedaba pegado al borde de la lista scrolleable
   —parecía el último ítem cortado, no una salida. El selector no toca al
   «Dejarlo acá», que vive adentro de `.acciones`. */
.decision .cuerpo > .btn.fantasma { margin-top: var(--e3); }
.elegido b { color: var(--ink); }

/* El resumen del último paso: pares clave/valor en dos columnas, alineados, sin
   bordes. Es una lectura, no una tabla — nada que comparar entre filas. */
.resumenW {
  display: grid; grid-template-columns: auto 1fr; gap: 0.45rem var(--e4);
  align-items: baseline;
}
.resumenW .rk {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-subtle);
}
.resumenW .rv { font-size: var(--t3); color: var(--ink); font-weight: 600; }

/* Lo que falta se DICE al lado del botón que igual te deja pasar. Un botón
   apagado que no explica qué le falta es un cuelgue, no un guardrail. */
.faltaW { font-size: var(--t1); color: var(--ink-muted); }

/* La entrada contextual: un renglón discreto al pie de lo que estás mirando.
   No compite con el contenido — es una salida, no una llamada a la acción. */
.sumar {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-family: var(--ui); font-size: var(--t2); font-weight: 500;
  background: none; border: 1px dashed var(--border-strong); border-radius: var(--r-md);
  color: var(--ink-muted); cursor: pointer; padding: 0.4rem 0.75rem; margin-top: var(--e3);
  text-decoration: none;
}
.sumar:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.sumar:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.sumar .ico { width: 14px; height: 14px; opacity: 1; }

@media (max-width: 720px) {
  .campos label { flex: 1 1 100%; }
  .resumenW { grid-template-columns: 1fr; gap: 0.1rem var(--e4); }
  .resumenW .rv { margin-bottom: 0.5rem; }
}

/* ── avisos ──────────────────────────────────────────────────────────────── */
.aviso {
  margin-top: 1rem; padding: 0.75rem 1rem; border-radius: var(--r-md);
  font-size: var(--t2); display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  background: var(--warn-soft); border: 1px solid var(--warn-soft-border);
}
.aviso.info { background: var(--accent-soft); border-color: var(--accent-soft-border); }
.aviso.ok { background: var(--positive-soft); border-color: var(--positive-soft-border); }
.aviso .sp { flex: 1; }
/* «Ya hay uno igual» (8/10): el que ya está, en tres renglones — qué pasa, cuál
   es, y sus datos en mono para que el monto se compare de un vistazo. */
/* «A revisar»: lo que entró por la planilla y ya tenía un igual. La marca en la
   fila y la píldora del filtro comparten el tono de aviso, que es el del cartel. */
.pillMv.revisar { background: var(--warn-soft); border-color: var(--warn-soft-border); color: var(--ink); text-decoration: none; }
/* ── La pantalla «A revisar» ───────────────────────────────────────────────
   Una tarjeta por diferencia, todas con la misma forma: encabezado (qué pasó a
   la izquierda, las dos salidas a la derecha) y una tabla de dos filas —«en el
   sistema» y «en la planilla»— con las mismas columnas y los mismos anchos en
   todas las tarjetas, así los conceptos, las fechas y los montos caen en la
   misma vertical de arriba abajo de la pantalla. Lo que difiere se marca en la
   fila de la planilla; el resto es tinta tranquila. */
/* ── LOS NIVELES (Santi, 8/10: «se ve como mucho texto plano») ─────────────
   1 · título de la pantalla (Display)
   2 · la frase que importa, en tinta plena · el título de cada tarjeta (Display)
   3 · la explicación y la frase de cada tarjeta, apagadas y un punto más chicas
   4 · los rótulos de la tabla, en mono-mayúscula
   5 · el dato: lo de la planilla en tinta plena (es lo que se revisa), lo del
       sistema un tono abajo (es la referencia) */
.revIntro { margin: 0 0 var(--e5); padding-bottom: var(--e4); border-bottom: 1px solid var(--border); }
.cabecera:has(+ .revIntro) { border-bottom: 0; padding-bottom: var(--e2); margin-bottom: var(--e2); }
.revLead { margin: 0; font-size: var(--t4); font-weight: 600; color: var(--ink); }
.revNota { margin: var(--k1) 0 0; font-size: var(--t2); color: var(--ink-muted); max-width: 72ch; }
.revLista { display: grid; gap: var(--e4); }
.revTarjeta > header { align-items: center; padding: var(--e3) var(--e4); border-bottom: 1px solid var(--border); }
.revCab { min-width: 0; }
.revTitFila { display: flex; align-items: center; gap: var(--k3); flex-wrap: wrap; }
/* El título de la tarjeta NO es el micro-rótulo en mono de las demás tarjetas:
   acá cada tarjeta es una decisión, y su título es lo primero que se lee. */
.tarjeta > header h2.revTit {
  font-family: var(--display); font-size: var(--t4); font-weight: 700; letter-spacing: -0.01em;
  text-transform: none; color: var(--ink); margin: 0;
}
.revSub { margin: 0.15rem 0 0; font-size: var(--t2); color: var(--ink-muted); }
.revAcc { display: inline-flex; gap: var(--k2); flex-wrap: wrap; justify-content: flex-end; }
/* Los dos botones miden lo mismo: ninguno pesa más que el otro. */
.revAcc .btn { min-width: 13.5rem; justify-content: center; text-align: center; }
.revTarjeta > .cuerpo { padding: var(--e2) var(--e4) var(--e3); }
.revT { width: 100%; border-collapse: collapse; table-layout: fixed; }
.revT .cRot { width: 9.5rem; }
.revT .cProy { width: 22%; }
.revT .cCaja { width: 11rem; }
.revT .cFecha { width: 7.5rem; }
.revT .cMonto { width: 10rem; }
.revT th, .revT td { text-align: left; padding: var(--k3) var(--k4) var(--k3) 0; vertical-align: baseline; }
.revT thead th {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-subtle); font-weight: 500; padding-top: var(--k2); padding-bottom: var(--k1);
}
.revT tbody th {
  font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 500; white-space: nowrap;
}
.revT tbody tr + tr > * { border-top: 1px solid var(--border); }
.revT td {
  font-size: var(--t2); color: var(--ink-light);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.revT .revN { text-align: right; padding-right: 0; }
.revT td.revN { font-family: var(--mono); font-variant-numeric: tabular-nums; }
/* La fila de la planilla es el sujeto: tinta plena, concepto y monto con peso.
   La del sistema es la referencia: mismo tamaño, un tono abajo, sin negrita. */
.revT tr.revPla td { color: var(--ink); }
.revT tr.revPla td.revC { font-weight: 600; font-size: var(--t3); }
.revT tr.revPla td.revN { font-weight: 600; font-size: var(--t3); }
.revT tr.revPla td.revN.pos { color: var(--positive); }
.revT tr.revPla td.revN.neg { color: var(--negative); }
.revT tr.revPla th { color: var(--ink); }
.revT tr.revSis td { color: var(--ink-muted); }
.revT td.revVacio, .revT tr.revPla td.revVacio { color: var(--ink-subtle); font-weight: 400; font-size: var(--t2); }
/* La diferencia: el texto que cambió va en ámbar oscuro y subrayado, sólo el
   texto. Sin fondo: un bloque de color en una celda rompe la grilla. */
.revT tr.revPla td.dif > span { color: var(--warn); box-shadow: inset 0 -2px 0 var(--warn-soft-border); padding-bottom: 2px; }
/* ── Saldos iniciales: la misma tabla y los mismos niveles que «A revisar» ──
   Caja a la izquierda (nombre con peso, tipo en mono chico); a la derecha tres
   columnas de plata del mismo ancho —lo que el sistema tenía, lo declarado y
   el campo para escribir— y la acción. Lo declarado es el dato: tinta plena. */
.salTarjeta { margin-bottom: var(--e4); }
.salTarjeta > header { align-items: center; padding: var(--e3) var(--e4); border-bottom: 1px solid var(--border); }
/* La fecha a la que vale el saldo: rótulo en mono a la izquierda del campo,
   como una celda más del encabezado. */
.salFecha { display: inline-flex; align-items: center; gap: var(--k3); }
.salFecha > span { font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); }
.salFecha .campoTexto { font-size: var(--t2); padding: 0.3rem 0.6rem; width: auto; }
.salT .cDif { width: 10rem; }
.salT .cQuien { width: 14rem; }
.salT .cSal { width: 12rem; }
.salT .cAcc { width: 9rem; }
.salT tbody th { text-transform: none; letter-spacing: 0; font-family: var(--ui); vertical-align: middle; }
.salNombre { display: inline-flex; align-items: baseline; gap: var(--k3); }
.salCaja { font-size: var(--t3); font-weight: 600; color: var(--ink); }
.salTipo { font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-subtle); }
.salT td { vertical-align: middle; }
.salT td.salRef { color: var(--ink-muted); }
.salT td.salDecl { color: var(--ink); font-weight: 600; font-size: var(--t3); }
.salT td.salCampo { padding-left: var(--k4); padding-right: 0; overflow: visible; }
/* El campo mide lo que un botón chico: en la tabla es una celda más, no un
   formulario. `.campoTexto.num` viene en cuerpo grande para el wizard. */
.salT td.salCampo .campoTexto {
  width: 100%; text-align: right; font-family: var(--mono); font-size: var(--t2); font-weight: 500;
  padding: 0.3rem 0.6rem; height: auto; min-height: 0;
}
.salT td.salAcc { text-align: right; padding-right: 0; overflow: visible; }
.salT td.salAcc .btn { min-width: 6.5rem; justify-content: center; }
.salMsg { font-size: var(--t1); color: var(--ink-muted); white-space: normal; }
.salMsg.ok { color: var(--positive); font-weight: 600; }
.revOtros { margin: var(--e2) 0 0; font-size: var(--t1); color: var(--ink-muted); }
.revTarjeta .aviso { margin-top: var(--e3); }
@media (max-width: 62rem) {
  /* Sin lugar para seis columnas: las acciones bajan y la tabla se desliza
     adentro de su tarjeta, nunca empuja la página. */
  .revTarjeta > .cuerpo { overflow-x: auto; }
  .revT { min-width: 46rem; }
  .revAcc { width: 100%; justify-content: flex-start; }
  .revAcc .btn { min-width: 0; flex: 1 1 12rem; }
}
.repetidoTxt { display: grid; gap: 0.2rem; min-width: 0; }
.repetidoCual { color: var(--ink); overflow-wrap: anywhere; }
.repetidoDatos {
  display: flex; flex-wrap: wrap; gap: 0.15rem 0.9rem;
  font-family: var(--mono); font-size: var(--t1); color: var(--ink-muted);
}

/* «Hay números nuevos» (A6, 29/9): flota abajo porque aparece cuando hay algo
   abierto encima de la pantalla, y ahí es donde no se puede meter en el flujo. */
.avisoGrafo {
  position: fixed; left: 50%; bottom: 1.25rem; transform: translateX(-50%); z-index: 60;
  display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
  max-width: calc(100vw - 2rem); padding: 0.6rem 0.75rem 0.6rem 1rem;
  font-size: var(--t2); border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  background: var(--accent-soft); border: 1px solid var(--accent-soft-border);
}

/* ── cierre ──────────────────────────────────────────────────────────────── */
/* ⚠️ EL `padding-right` DE ACÁ DESALINEA LA COLUMNA CON LA FILA DE ARRIBA.
   En el cierre, «Disponible» son celdas de texto pegadas al borde de la columna
   y «Repartir» / «Al mes que viene» son inputs: el texto del input arranca 1px
   de borde + 7px de padding más adentro, así que la columna de LULI mostraba
   −260.339 y, once píxeles a la izquierda, su propio 0. Tres filas que se leen
   de arriba abajo tienen que caer sobre la misma vertical.
   Se resuelve pagándolo del otro lado: la celda de dato lleva el mismo margen
   que el input se come (`.tabla td.q` de más abajo), así los dos textos caen a
   la misma distancia del borde de la columna. */
.entrada {
  font-family: var(--mono); font-size: var(--t2); text-align: right;
  width: 7.2rem; padding: 0.26rem 0.45rem; color: var(--ink);
  background: var(--paper-warm); border: 1px solid var(--border-strong); border-radius: var(--r-sm);
}
.entrada:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* El otro lado del arreglo de arriba: 0.45rem de padding + 1px de borde es lo
   que el input mete hacia adentro, y es lo que la celda de dato tiene que
   dejar libre para caer sobre la misma vertical. */
#tablaCierre td.q, #tablaCierre th { padding-right: calc(0.45rem + 1px); }
tr.resto td { border-top: 2px solid var(--border-strong); padding-top: 0.8rem; font-weight: 700; }
tr.resto.ok td { color: var(--positive); }
tr.resto.pendiente td { color: var(--warn); }

.barras { display: grid; gap: 0.45rem; margin: 0.9rem 0; }
.filaBarra { display: grid; grid-template-columns: 6.5rem 1fr 8.5rem; align-items: center; gap: 0.7rem; }
.filaBarra .bn { font-size: var(--t2); color: var(--ink-light); }
.filaBarra .bn.otra { color: var(--ink-subtle); font-size: var(--t1); }
/* Pista anclada en cero: las barras crecen desde la marca del cero para el lado
   que corresponda. Una caja debiendo se ve debiendo. */
.pista { height: 1.1rem; background: var(--paper-warm); border-radius: var(--r-sm); position: relative; overflow: hidden; }
.pista .trozo { position: absolute; top: 0; bottom: 0; background: var(--accent); border-radius: 2px; }
.pista .trozo.baja { background: var(--atencion); }
.pista .trozo.neg  { background: var(--atencion); }
/* ⚠️ A `.45` esto NO SE VEÍA. `--ink-subtle` al 45% sobre `--paper-warm` da un
   #d6d6d5 contra un #f5f5f4: 1,1:1. O sea que la caja más grande del cierre
   —Inviu, $27,8M, la única que se sale de la escala por arriba— dibujaba una
   barra que se leía como pista vacía: el número más grande de la pantalla con
   el trazo más débil. Sigue siendo gris (no es una caja de socia y no compite
   con ellas) pero se ve. */
.pista .trozo.otra { background: var(--ink-subtle); opacity: .8; }
/* ── Una barra que se sale de la escala tiene que VERSE saliéndose ──────────
   La escala la fijan las socias a propósito: si entraran los $25,8M de Inviu,
   la comparación entre las tres cajas —que es para lo que existe esta
   pantalla— quedaría aplastada contra el cero. Eso está bien y no se toca.
   Lo que estaba mal era el resultado: Luli (2.634.771), la SRL (3.919.621) e
   Inviu (25.813.345) recibían las TRES el mismo `width: 78.10%`, porque todo
   lo que pasa el máximo se recorta al mismo largo. O sea que la barra más
   larga legítima y una que se pasa diez veces se dibujaban idénticas.
   El borde desvanecido es la convención de corte de eje de toda la vida: dice
   «esto sigue» sin agregar un control ni un cartel. El número exacto ya está
   al lado, que es donde se compara de verdad.                               */
.pista .trozo.corta-der {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 14px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 14px), transparent);
}
.pista .trozo.corta-izq {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 14px), transparent);
          mask-image: linear-gradient(to left, #000 calc(100% - 14px), transparent);
}
/* El cero es una hendidura, no una línea encima: divide la pista. */
.pista .cero { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border-strong); }
.pista .obj  { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink-subtle); opacity: .55; }
.filaBarra .bv { font-family: var(--mono); font-size: var(--t2); text-align: right; font-variant-numeric: tabular-nums; }
.delta { font-family: var(--mono); font-size: var(--t0); }

.traspaso {
  display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap;
  padding: 0.45rem 0.65rem; margin-bottom: 0.4rem; font-size: var(--t2);
  background: var(--accent-soft); border: 1px solid var(--accent-soft-border); border-radius: var(--r-md);
}
.traspaso.invalido { background: var(--negative-soft); border-color: var(--negative-soft-border); }
.traspaso select {
  font-family: var(--ui); font-size: var(--t2); padding: 0.18rem 0.3rem;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  background: var(--card); color: var(--ink);
}
.traspaso .flecha { color: var(--accent); font-weight: 700; }
.traspaso .quitar { margin-left: auto; border: 0; background: none; color: var(--ink-muted); cursor: pointer; font-size: var(--t4); padding: 0 var(--e1); }
.traspaso .quitar:hover { color: var(--negative); }
.traspaso .nota { width: 100%; font-size: var(--t1); color: var(--negative); }

/* ── resolver ────────────────────────────────────────────────────────────── */
.colas { display: flex; gap: 0.4rem; margin-bottom: 1rem; flex-wrap: wrap; }
.colas button {
  font-family: var(--ui); font-size: var(--t2); padding: 0.42rem 0.9rem;
  border: 1px solid var(--border-strong); background: var(--card); color: var(--ink-light);
  border-radius: var(--r-pill); cursor: pointer;
}
.colas button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.colas .num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.colas .soloLectura {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-subtle); margin-left: 0.5rem;
}
.colas button[aria-pressed="true"] .soloLectura { color: rgba(255,255,255,.72); }
/* El progreso y el «1 de 15» son el mismo dato dicho de dos formas, y estaban a
   media pantalla de distancia: la barra acá arriba y el contador adentro de la
   tarjeta, arriba a la derecha. Van juntos. */
.avance { display: flex; align-items: center; gap: var(--e3); margin-bottom: var(--e4); max-width: 48rem; }
/* La pista iba en `--border` (#ededed sobre un papel #fafafa: 1,03:1). Con la
   cola recién abierta el relleno mide 0, así que no se veía NADA — ni barra ni
   pista— y el «1 de 35» de al lado quedaba flotando sin nada que lo explicara.
   Una barra vacía tiene que verse vacía, no ausente. */
.progreso { flex: 1; height: 4px; background: var(--border-strong); border-radius: var(--r-pill); overflow: hidden; }
.progreso i { display: block; height: 100%; background: var(--accent); transition: width .25s; }
.avance .cuenta {
  font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* ── La tarjeta de decisión ─────────────────────────────────────────────────
   Acotada a 48rem, y no es cosmética. A 1440px la comparación se estiraba a los
   76rem completos de la pantalla, así que entre «Rabanne Nieve» y su margen
   —los dos datos que deciden— había novecientos píxeles de blanco. Comparar dos
   cosas requiere que las dos entren en una mirada.
   Es el mismo criterio por el que las cajas de `El mes` viven en 26rem: el
   ancho lo pide el contenido, no la ventana.                                 */
.decision { max-width: 48rem; }
.decision .cuerpo { padding-top: var(--e4); }
.pregunta {
  font-family: var(--display); font-size: var(--t4); font-weight: 700;
  letter-spacing: -0.02em; margin: 0 0 var(--e4); color: var(--ink-light);
}
.candidatos { display: grid; grid-template-columns: 1fr auto auto auto; gap: var(--e2) var(--e4); align-items: baseline; }
.candidatos > div { display: contents; }
/* El nombre y el margen son el par que decide; movs y «entró» son contexto y
   pesan como contexto. Antes los cuatro venían casi del mismo tamaño. */
.candidatos .cn { font-weight: 600; font-size: var(--t3); }
/* ── La letra que diferencia a los dos candidatos ──────────────────────────
   Ámbar y no rojo, por la razón de siempre en este repo: no es un error, es
   justamente lo que hay que mirar para poder contestar. Va con fondo Y con
   subrayado, y el subrayado no es adorno: cuando la diferencia es un ESPACIO,
   un fondo solo se lee como un hueco más entre palabras.
   `mark` trae amarillo de fábrica, así que las dos propiedades se declaran. */
.candidatos .cn .dif {
  background: var(--warn-soft); color: var(--warn); font-weight: 700;
  border-bottom: 2px solid var(--warn); border-radius: 2px; padding: 0 1px;
}
.candidatos .cd { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); font-variant-numeric: tabular-nums; }
.candidatos .cm {
  font-family: var(--mono); font-size: var(--t4); font-weight: 700;
  letter-spacing: -0.02em; text-align: right; min-width: 3.4rem;
  font-variant-numeric: tabular-nums; color: var(--tinta, var(--ink));
}
.consecuencia {
  margin-top: 1rem; padding: 0.75rem 1rem; border-radius: var(--r-md); font-size: var(--t2);
  background: var(--accent-soft); border: 1px solid var(--accent-soft-border);
}
.consecuencia.neutra { background: var(--paper-warm); border-color: var(--border); color: var(--ink-muted); }
.consecuencia b { font-family: var(--mono); }
.porque { font-size: var(--t1); color: var(--ink-subtle); margin-top: 0.55rem; }
.nombreEditable {
  font-family: var(--display); font-size: var(--t4); font-weight: 700;
  padding: 0.28rem 0.5rem; border: 1px dashed var(--border-strong); border-radius: var(--r-sm);
  background: var(--paper-warm); color: var(--ink); width: 15rem; max-width: 100%;
}
.nombreEditable:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-style: solid; }
.listaProy { display: grid; gap: 0.25rem; margin-top: 0.85rem; max-height: 17rem; overflow-y: auto; }
.filaProy {
  display: grid; grid-template-columns: 1.1rem 1fr auto auto; gap: 0.65rem;
  align-items: baseline; padding: 0.3rem 0.45rem; border-radius: var(--r-sm); cursor: pointer;
}
.filaProy:hover { background: var(--paper-warm); }
/* Filas que se muestran y no se eligen (Resolver → «Fuera de la lista»): sin
   la columna del checkbox el concepto caía debajo de la fecha (28/9). */
.filaProy.sinCheck { grid-template-columns: 1fr auto auto; cursor: default; }
.filaProy.sinCheck:hover { background: none; }
.filaProy input { margin: 0; accent-color: var(--accent); }
.filaProy.off .pn { color: var(--ink-subtle); text-decoration: line-through; }
.filaProy .pv { font-family: var(--mono); font-size: var(--t1); color: var(--ink-muted); font-variant-numeric: tabular-nums; }
/* Ediciones (B4): qué edición es, y el nombre que va a llevar, editable. */
.listaEdicion { max-height: none; }
.filaEdicion { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.35rem; padding: 0.6rem 0.75rem; border: 1px solid var(--border); border-radius: var(--r-md); }
.filaEdicion .edQue { font-size: var(--t2); color: var(--ink-muted); }
.filaEdicion .edQue b { color: var(--ink); }
.nomEdicion { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.nomEdicion .tenue { font-size: var(--t1); display: inline-flex; align-items: center; gap: 0.35rem; }
.nomEdicion .campoTexto { flex: 1 1 14rem; min-width: 0; }
/* El marcador sólo aparece cuando hay algo que marcar. Con las cuatro cifras en
   cero —o sea, siempre que alguien entra por primera vez— era una fila de ruido
   que no decía nada. El progreso ya lo cuenta la barra. */
.marcador { display: flex; gap: var(--e5); flex-wrap: wrap; margin-top: var(--e4); font-size: var(--t2); color: var(--ink-muted); }
.marcador b { font-family: var(--mono); color: var(--ink); }

/* ── Estado vacío ───────────────────────────────────────────────────────────
   Con título y explicación, no una línea suelta. Un vacío sin explicar deja a
   la persona sin saber si terminó, si algo falló o si nunca hubo nada — y las
   tres cosas se ven igual. Acá siempre dice cuál de las tres es y qué se puede
   hacer a continuación.                                                      */
.nada { text-align: center; padding: var(--e6) var(--e4); }
.nada .simbolo { font-size: var(--t6); line-height: 1; color: var(--positive); display: block; margin-bottom: var(--e3); }
.nada h2 {
  font-family: var(--display); font-size: var(--t4); font-weight: 700;
  letter-spacing: -0.02em; margin: 0 0 var(--e1); color: var(--ink-light);
}
.nada p { margin: 0 auto var(--e4); color: var(--ink-muted); font-size: var(--t3); max-width: 42ch; }

.pie {
  max-width: 76rem; margin: 0 auto; padding: 1rem 1.25rem 3rem;
  font-size: var(--t1); color: var(--ink-subtle); border-top: 1px solid var(--border);
}
.pie b { font-family: var(--mono); font-weight: 600; color: var(--ink-muted); }
/* Que los datos estén viejos habla con la misma voz que un saldo en negativo
   —atención, no catástrofe— y por eso usa el mismo token. Va en un `span` y no
   en un `b` a propósito: `.pie b` fija color y fuente mono, y dos reglas que
   están bien por separado peleándose por el mismo elemento ya nos costó tres
   veces. El nombre es tan específico como su significado. */
.pie .desactualizado { color: var(--atencion); font-weight: 600; }

/* ── LA PORTADA (15/9) ────────────────────────────────────────────────────
   Lo único que se dibuja ANTES de que exista la aplicación: «entrando», el
   login y el error de conexión. Hasta el 15/9 era una tarjeta de 34rem pegada
   arriba, con la cabecera de la aplicación encima —logo, «Fábrica O» y un
   buscador que sin sesión no busca nada—. Santi: «parece medio improvisada».
   Ahora es una pantalla propia: sin chrome ni pie, la marca arriba y la caja
   centrada en la ventana. `body.enPortada` lo pone el HTML y lo saca
   `sesion.js::arrancarApp`. */
body.enPortada .chrome, body.enPortada .pie { display: none; }
body.enPortada .pantalla { max-width: none; padding: 0 16px; }
.portada {
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--e5); padding-block: var(--e6);
}
.portadaMarca { display: flex; align-items: center; gap: var(--e3); color: var(--ink); }
.portadaMarca .wordmark { height: 36px; width: auto; display: block; }
.portadaCliente {
  font-family: var(--display); font-weight: 700; font-size: var(--t4); letter-spacing: -0.01em;
  padding-left: var(--e3); border-left: 1px solid var(--border-strong); line-height: 1.2;
}
.portadaCaja {
  width: min(24rem, 100%); background: var(--card);
  border: 1px solid var(--border); border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg); padding: var(--e6) var(--e5) var(--e5);
}
.portadaTitulo {
  font-family: var(--display); font-weight: 800; font-size: var(--t6);
  letter-spacing: -0.02em; line-height: 1.15; margin: 0 0 var(--e5);
}
.portadaCaja .bajada { margin-bottom: var(--e3); }
.portadaCaja .porque { margin: 0 0 var(--e4); }
.portadaAcciones { display: flex; flex-wrap: wrap; gap: var(--e2); }
/* «Entrando…», «Trayendo los datos…»: sin caja, en el lugar donde va a
   aparecer. Un poco de respiración en la opacidad dice «estoy trabajando» sin
   un spinner. */
.portadaEspera { margin: 0; min-height: 3rem; color: var(--ink-muted); font-size: var(--t3); animation: respirar 1.6s ease-in-out infinite; }
@keyframes respirar { 0%, 100% { opacity: 1 } 50% { opacity: .55 } }
@media (prefers-reduced-motion: reduce) { .portadaEspera { animation: none; } }

/* ══════════════════════════════════════════════════════════════════════════
   FOCO — que se pueda recorrer con el teclado sin adivinar dónde estás
   ══════════════════════════════════════════════════════════════════════════
   Varios controles tenían su `:focus-visible` y varios no —`.colas`, los
   filtros, las filas de proyecto de Resolver—, así que tabulando la pantalla
   el anillo aparecía y desaparecía. Una regla de base los cubre a todos y las
   específicas siguen mandando donde el anillo tiene que ir por dentro.       */
.colas button:focus-visible,
.filtros button:focus-visible,
.filaProy:focus-within,
.migas button:focus-visible,
.enlace:focus-visible,
.traspaso select:focus-visible,
.traspaso .quitar:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm);
}

/* Quien pidió menos movimiento no debería recibir ninguno. Son cuatro
   transiciones y ninguna comunica nada que el estado final no diga. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   VISTA ANGOSTA
   ══════════════════════════════════════════════════════════════════════════
   No había ni una media query salvo el colapso de `.dos`. Medido a 390px: las
   cuatro pantallas con scroll horizontal de página, el chrome partido en dos
   líneas con el buscador fuera de pantalla, y `Explorar` directamente
   inusable — el panel activo mide 26rem y no entra.

   Y no es hipotético: el link de la maqueta se comparte por WhatsApp, o sea
   que la primera vez que una socia la abra va a ser en el celular.

   El criterio es uno solo: **el scroll horizontal se permite DENTRO de un
   contenedor, nunca en la página.** Una tabla de caja con tres columnas de
   monospace no entra en 350px y no hay forma de que entre; lo que no puede
   pasar es que arrastre a toda la pantalla con ella.                        */
/* ── EL CHROME SE REORDENA MUCHO ANTES QUE EL RESTO ───────────────────────
   Estaba adentro del bloque de 40rem, y hasta ahí no llegaba: medido, el
   topbar no entra desde los ~960px. Cinco ítems de menú con `nowrap` (~505px)
   + el wordmark + «Fábrica O» + el botón de tema + los espacios dan ~810px
   ANTES del buscador, así que entre 640 y 960 el menú se quedaba con todo, el
   buscador se estrujaba hasta un círculo y «Fábrica O» partía en dos
   renglones. 960px no es un tamaño raro: es un portátil con la pantalla al
   150%, que es cómo ve Windows por defecto.
   Acá el buscador baja a su propio renglón, a lo ancho. El nombre del cliente
   sólo se va más abajo (40rem): mientras entre, es de las primeras cosas que
   tiene que decir la pantalla.
   62rem y no 60: medido en la pantalla, lo fijo del topbar (wordmark + «Fábrica
   O» + los cinco ítems + el botón de tema + gaps + padding) da 792px, y el
   buscador no baja de 11rem, así que la línea necesita 968px para entrar. Entre
   968 y 992 el `min-width` ya no deja encoger nada: en vez de estrujarse,
   desbordaría. El corte va arriba del número medido, no encima. */
@media (max-width: 62rem) {
  .chrome .interior { flex-wrap: wrap; padding: var(--e2) var(--e3); gap: var(--e2); }
  .buscador { order: 10; flex: 1 0 100%; max-width: none; min-width: 0; }
}

/* ── LA CABECERA (15/9, dos vueltas) ──────────────────────────────────────
   1 · «La home y toda la app tiene un scroll horizontal». El corte de arriba se
   midió con CINCO ítems de menú; eran siete más el contador de Resolver y
   Registrar, y la cabecera pedía 1.446px en una caja de 1.216 (la página medía
   1.537 a 1.430 de ventana, y 891 en un celular de 390). Desde entonces la
   cabecera ENVUELVE: si algo no entra baja un renglón adentro de ella, y nunca
   ensancha la página.
   2 · «Perdiste los íconos del nav, queda mal sin ellos». El primer arreglo
   sacaba los íconos entre 84 y 100rem, que es justo su pantalla. Ahora el
   orden es el que pidió Santi: marca y cliente a la izquierda, el menú, el
   buscador ocupando TODO el espacio que sobra, y a la derecha moneda, tema y
   avatar (Ajustes adentro del avatar). Los íconos van siempre; con poco ancho
   se esconde el TEXTO de los ítems, no el ícono, salvo el de la sección
   actual. El corte sale de medir cuándo entra en un renglón (ver abajo). */
.chrome .interior { max-width: 92rem; flex-wrap: wrap; row-gap: var(--e2); gap: 0.6rem; }
.chrome .interior > .sp { display: none; }
/* Con tope (30/9, Santi: «la barra de buscar se fue muy larga hasta la mitad
   de la pantalla»). Sin `max-width` se comía todo lo que sobraba; lo que sobra
   ahora queda entre el buscador y los controles de la derecha. */
.buscador { flex: 1 1 14rem; min-width: 10rem; max-width: 22rem; }
.derechaChrome { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
.menu { gap: 0.1rem; flex-wrap: wrap; }
.menu > a { padding: 0.35rem 0.65rem 0.35rem 0.55rem; }

/* 92rem (29/9): con «Estructura», ocho ítems y Resolver en dos cifras, la
   cabecera con texto pide 1.441px medidos; el corte viejo (86,5rem = 1.384)
   la partía en dos renglones justo en un portátil común. Otra vez el corte
   medido con los ítems de ayer: al sumar un ítem, se vuelve a medir.
   86rem (30/9): Actividad pasó a Ajustes y quedan siete. Medido: la línea con
   texto pide 1.400px con el buscador a 14rem y 1.336 con el buscador en su
   mínimo, así que a partir de 1.376 entra con texto. Con 92rem una pantalla de
   1.440 —la de Santi— quedaba en íconos sin necesidad. */
/* 8/10: el menú quedó en Movimientos + «Más», así que el corte de 86rem que
   pasaba los ítems a ícono ya no hace falta: con dos entra con texto hasta el
   celular. Se sacó la regla en vez de dejarla medida para siete ítems. */
@media (max-width: 62rem) {
  /* En su propio renglón va a lo ancho: el tope de 22rem es para compartir línea. */
  .buscador { order: 10; flex: 1 0 100%; min-width: 0; max-width: none; }
}
/* En el celular: la marca y los controles arriba, el menú de íconos en su
   renglón (Registrar como «+»), y el buscador abajo. */
@media (max-width: 40rem) {
  .chrome .interior > .marca { order: 0; }
  .derechaChrome { order: 2; }
  .menu { order: 5; flex: 1 0 100%; justify-content: flex-start; gap: 0.4rem; flex-wrap: nowrap; }
  .menuMas .menuRegistrar { left: 0; right: auto; }
  .menu > a > span:not(.n), .registrarNav .btn > span {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .menu > a, .menu > a:not(.on) { padding: 0.45rem 0.5rem; gap: 0; }
  .registrarNav .btn { padding: 0.4rem 0.55rem; }
  .buscador { order: 10; }
}

@media (max-width: 40rem) {
  .pantalla { padding: var(--e4) var(--e3) 4rem; }
  .pie { padding: var(--e4) var(--e3) 2rem; }

  /* En 390px cada palabra del topbar compite con el menú, y la marca ya dice
     de quién es el sistema. */
  .chrome .cliente { display: none; }

  /* La tabla scrollea adentro de su tarjeta, no arrastrando la página. */
  .tarjeta .cuerpo { overflow-x: auto; }

  /* Un panel por pantalla, y se pasa deslizando. La pila sigue viviendo en la
     URL, así que «atrás» sigue funcionando igual. */
  .paneles { scroll-snap-type: x mandatory; gap: var(--e3); }
  .panel, .panel.ultimo { flex: 0 0 100%; max-width: 100%; min-width: 0; scroll-snap-align: center; }

  h1 { font-size: var(--t5); }
  h1.pila { font-size: var(--t4); }
  .filaBarra { grid-template-columns: 4.5rem 1fr 6.5rem; gap: var(--e2); }
  .filaBarra .bv { font-size: var(--t1); }
}

/* Los dos candidatos de Resolver: el nombre toma su línea y los tres datos
   fluyen debajo, con el margen —el que decide— anclado a la derecha. */
@media (max-width: 34rem) {
  .candidatos { display: block; }
  .candidatos > div {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--e0) var(--e3);
    padding: var(--e3) 0; border-top: 1px solid var(--border);
  }
  .candidatos > div:first-child { border-top: 0; }
  .candidatos .cn { flex: 1 0 100%; }
  .candidatos .cm { margin-left: auto; }
}


/* ══════════════════════════════════════════════════════════════════════════
   ETAPA 2 — jerarquía, KPI, la ficha y lo visual
   ══════════════════════════════════════════════════════════════════════════ */

/* `.sp` empuja lo que sigue al otro extremo. Estaba definido dentro de
   `.chrome` y de `.aviso` nada mas, asi que en la cabecera de una pantalla no
   hacia nada y el boton quedaba pegado al titulo. Se declara donde se usa. */
.cabecera .sp { flex: 1; }

/* ── El margen en plata, debajo del porcentaje ─────────────────────────────
   «En vez de porcentaje también el número». El % se queda como ancla —es lo
   comparable entre proyectos de tamaños distintos— y la plata va debajo, un
   escalón más abajo de peso y en `--ink-subtle`: si las dos cifras pesaran
   igual, la columna dejaría de tener un ancla y el ojo no sabría dónde caer.
   El color del margen NO baja a la segunda línea, por lo mismo: la banda pinta
   el juicio, y un juicio pintado dos veces en el mismo renglón es ruido.      */
.fila .m { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; }
.fila .m2 {
  font-size: var(--t0); font-weight: 500; letter-spacing: 0;
  color: var(--ink-subtle); margin-top: 0.05rem;
}

/* ── KPI cards ─────────────────────────────────────────────────────────────
   El mismo `resumen` del descriptor que en el panel se dibuja como un renglón
   de texto chico. Acá cada dato es una tarjeta: rótulo arriba en micro-mono, la
   cifra grande abajo. Es lo que pidieron —«unas KPI cards de ese proyecto o
   cliente»— y lo que hace que la pantalla arranque con los números y no con una
   lista.
   `auto-fit` + `minmax` y no un número fijo de columnas: los descriptores tienen
   entre tres y cinco datos según la entidad, y una grilla de cinco con tres
   tarjetas deja dos huecos que se leen como que falta algo.                   */
.kpis {
  /* 11rem y no 9,5: en mono `$41.161.000` mide ~137px y la tarjeta de 9,5rem
     dejaba 120px útiles, así que la cifra ancla partía en dos líneas. El piso
     de una tarjeta de KPI lo fija el número más largo que va a caer adentro. */
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--e3); margin-bottom: var(--e5);
}
.kpi {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--k5) var(--k5) var(--k4); display: flex; flex-direction: column;
  gap: var(--k1); min-width: 0;
}
.kpiK {
  /* Mono-mayúscula ES el rol de micro-label del handoff, así que la familia se
     queda. Lo que estaba mal era el tamaño: `--t00` son 9,6px, y a ese cuerpo
     `0.1em` de tracking pelea contra las mayúsculas — grita y no se lee. Un
     paso más grande y menos tracking dicen lo mismo sin costar legibilidad. */
  font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--ink-muted); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ══════════════════════════════════════════════════════════════════════════
   DÓNDE VA CADA FAMILIA EN UN NÚMERO
   ══════════════════════════════════════════════════════════════════════════
   Esto se movió tres veces, así que queda escrito como regla y no como ajuste:

   · **Cifra ancla suelta** —la de una tarjeta de KPI, la de una tarjeta de
     caja, el total de un bloque— va en **Display (Plus Jakarta)**. Es una sola
     por tarjeta, no se compara con nada que esté abajo, y a 20px el mono en
     bold con tracking negativo junta glifos que ya nacen anchos: se lee
     apelmazado, y grande se nota. `tabular-nums` conserva lo único que el mono
     aportaba acá, que es que los dígitos midan igual.

   · **Número en columna** —tabla, lista de filas, el eje de un dibujo— va en
     **mono**. Ahí sí hay algo debajo con lo que alinear, el cuerpo es chico
     (--t1/--t2/--t3) y la grilla fija del mono es exactamente para eso.

   Lo que NO puede pasar —y pasó— es que dos cifras del mismo rango, en la misma
   pantalla y a 60px de distancia, salgan en familias distintas: la fila de KPI
   en Display y las tarjetas de caja de abajo en mono. El criterio no es la
   familia, es el ROL del número.                                              */
.kpiV {
  /* Cifra ancla: Display. Ver la regla de arriba. */
  font-family: var(--display); font-size: var(--t5); font-weight: 700;
  letter-spacing: -0.015em; font-variant-numeric: tabular-nums;
  color: var(--tinta, var(--ink)); line-height: 1.15;
  /* Una cifra larga (`−$1.234.567.890`) no puede empujar la grilla: se achica
     antes de romper el layout. */
  overflow-wrap: anywhere;
}
/* ── Por qué el valor YA NO se ancla al pie ────────────────────────────────
   Anclarlo (`margin-top: auto` en `.kpiV`) alineaba cuatro de las cinco y
   rompía la quinta: donde hay `.kpiV2`, el `auto` empuja al pie la SUBLÍNEA y
   la cifra sube justo lo que mide. En la ficha de un proyecto se veía derecho
   —`ENTRÓ`, `SALIÓ` y `MOVIMIENTOS` a una altura y `MARGEN` 26px más arriba—,
   que es exactamente lo que la regla venía a evitar.
   Al tope, en cambio, alinea siempre: el rótulo abre la tarjeta y la cifra va
   pegada abajo, midan lo que midan las de al lado. La sublínea se ancla al pie
   pegada abajo. Y la sublínea va pegada A SU CIFRA y no al pie de la tarjeta:
   «$13.511.737» anota al «33%» de arriba, no cierra la tarjeta — separados por
   40px de aire se leen como dos datos y no como uno. */
.kpiV2 {
  font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle);
  font-variant-numeric: tabular-nums; padding-top: var(--e0);
}
/* Un rango de fechas NO es una cifra. A `--t5` en Display bold pesaba como los
   $41.161.000 de al lado, no entraba en una línea y arrastraba el alto de las
   cinco tarjetas. Es metadato: se escribe como metadato. */
/* Un rango de fechas no es una cifra: entra en una línea y no arrastra el alto
   de las otras cuatro tarjetas. La familia ya es la de Display por `.kpiV`; lo
   que cambia acá es el cuerpo y el peso. */
.kpiV.txt { font-size: var(--t3); font-weight: 600; letter-spacing: -0.005em; }

/* ── Lo visual ─────────────────────────────────────────────────────────────
   Dos figuras chicas, no un dashboard. Comparten cejilla: título a la
   izquierda, leyenda a la derecha, y ninguna lleva ejes con números — lo que se
   lee en cifra ya está en las KPI cards de arriba, y repetirlo dentro del
   dibujo es la mitad de lo que hace que un gráfico se vea recargado.          */
.vizFila {
  display: flex; flex-direction: column; gap: var(--e4);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: var(--e4); margin-bottom: var(--e5);
}
.viz { margin: 0; }
.viz figcaption {
  display: flex; align-items: baseline; gap: var(--e3); flex-wrap: wrap;
  margin-bottom: var(--e2);
}
.vizT {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-subtle); font-weight: 500;
  margin-right: auto;
}
.vizL {
  font-size: var(--t1); color: var(--ink-muted);
  display: inline-flex; align-items: center; gap: 0.3rem;
}
.vizL b { font-family: var(--mono); font-weight: 700; color: var(--tinta, var(--ink)); }
.vizPct { font-family: var(--mono); font-size: var(--t1); color: var(--tinta, var(--ink-muted)); }
/* La muestra de color. Va SIEMPRE al lado de su palabra: el color no identifica
   solo — es la regla de accesibilidad y además es lo que hace que la leyenda se
   entienda sin buscar a qué corresponde cada tono. */
/* El contorno interior no es decoración: `costó` se pinta con
   `--border-strong` (#d4d4d4) sobre la tarjeta blanca, o sea 1,3:1 — en un
   cuadrado de 9px eso no se ve, y la leyenda quedaba con una sola muestra
   visible de dos. La muestra TIENE que llevar el color del segmento que
   identifica, así que no se puede oscurecer: lo que se agrega es el borde. Con
   la muestra oscura no se nota y con la clara la hace existir. */
.sw {
  width: 9px; height: 9px; border-radius: 2px; flex: none;
  background: var(--tinta, var(--ink-subtle));
  box-shadow: inset 0 0 0 1px rgba(10,10,10,.14);
}
[data-theme='dark'] .sw { box-shadow: inset 0 0 0 1px rgba(255,255,255,.18); }
.sw.costo { background: var(--border-strong); }
.sw.queda { background: var(--accent); }

/* La barra de margen: part-to-whole. Un hue y un gris — «emphasis», no una
   paleta categórica, así que no hay dos colores compitiendo por atención. */
.barraM svg { width: 100%; height: 24px; display: block; }
.pista { fill: var(--paper-warm); }
.segCosto { fill: var(--border-strong); }
/* ⚠️ EL SEGMENTO DEL MARGEN NO USA EL COLOR DE LA BANDA, y la primera version
   si lo hacia. El problema no era de gusto: la banda del medio —`--m-normal`,
   donde cae el 26% de la cartera— es `--ink-light` A PROPOSITO, porque «sólo
   hablan los extremos». Asi que en el caso mas frecuente la barra quedaba
   gris claro contra gris oscuro: dos grises, ninguno diciendo nada, y encima
   el margen pesando mas que el costo por ser el mas oscuro.
   Ademas era doble codificacion: el juicio sobre el margen ya lo pinta el
   PORCENTAJE, que esta al lado. La barra contesta otra pregunta —cuanto de lo
   que entro quedo— y para eso alcanza con un hue y un gris, que es la forma
   «emphasis»: separa siempre, valida siempre, y no compite con el numero. */
.segQueda { fill: var(--accent); }

/* La línea de tiempo. Los trazos son finos a propósito: con 5 unidades de ancho
   sobre 1000, treinta movimientos siguen respirando y no se tocan. */
.linea .lienzo { position: relative; }
.linea svg { width: 100%; height: 104px; display: block; overflow: visible; }
.eje { stroke: var(--border-strong); stroke-width: 1; }
.tz { fill: var(--tinta, var(--ink-subtle)); transition: opacity .1s; }
.tz.pos { --tinta: var(--positive); }
.tz.neg { --tinta: var(--negative); }
/* El hover se marca bajando TODO lo demás y no subiendo el trazo apuntado: así
   el que se está mirando queda solo, en vez de brillar entre iguales. */
.linea .lienzo:hover .tz { opacity: .3; }
.linea .lienzo .tz:hover { opacity: 1; }
.tz.vaA { cursor: pointer; }
.linea .tip {
  position: absolute; z-index: 3; pointer-events: none;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-md);
  box-shadow: var(--shadow-md); padding: 0.4rem 0.6rem;
  display: flex; flex-direction: column; gap: 0.05rem;
  max-width: 15rem; white-space: nowrap;
}
.linea .tip b {
  font-family: var(--mono); font-size: var(--t2); font-weight: 700;
  color: var(--tinta, var(--ink)); font-variant-numeric: tabular-nums;
}
.linea .tipC {
  font-size: var(--t1); color: var(--ink); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis;
}
.linea .tipF { font-size: var(--t0); color: var(--ink-subtle); }
.vizPie {
  display: flex; justify-content: space-between; margin-top: var(--e1);
  font-family: var(--mono); font-size: var(--t00); color: var(--ink-subtle);
}

/* ── La ficha ──────────────────────────────────────────────────────────────
   El desglose ocupa la columna ancha y el contexto queda al costado: «todo lo
   que está arriba debería estar mucho más grande y quizá lo otro es una
   pestañita abajo». No es una pestaña —esconder el contexto detrás de un clic
   lo mata— pero sí pierde la mitad del ancho, que es lo mismo dicho en layout. */
.fichaCab { align-items: baseline; }
.tipoF {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-subtle); font-weight: 500;
}
.fichaCab h1 { font-size: var(--t6); }
.fichaCuerpo { display: grid; grid-template-columns: 1fr 21rem; gap: var(--e4); align-items: start; }
.fichaCuerpo.sola { grid-template-columns: 1fr; }
/* ⚠️ Lo mismo que en `.dos`: un ítem de grid arranca en `min-width: auto`, así
   que una fila larga adentro empuja la columna y desborda la pantalla. */
.fichaCuerpo > * { min-width: 0; }
.colAncha { display: flex; flex-direction: column; }
.colLado { display: flex; flex-direction: column; gap: var(--e4); }
.colLado .tarjeta > header h2 { font-size: var(--t3); }
.colLado .fila { padding: 0.5rem 0.4rem; font-size: var(--t2); }
.colLado .fila .sub2 { font-size: var(--t0); }
.colLado .fila .v, .colLado .fila .m { font-size: var(--t2); }
/* La lista principal es larga por definición —la ficha existe para eso— así que
   scrollea adentro de su tarjeta en vez de estirar la página a diez pantallas.
   El tope es alto: cortar en 20rem sería devolverle el problema del panel. */
.principalF .cuerpo { max-height: 46rem; overflow-y: auto; scrollbar-gutter: stable; }
.corte {
  font-size: var(--t1); color: var(--ink-subtle); padding: var(--e3) 0.55rem 0;
  border-top: 1px solid var(--border); margin-top: var(--e2);
}
.sumar.suelto { align-self: flex-start; }
/* La puerta a la ficha, en la cejilla del panel de Explorar. Va arriba a la
   derecha, alineada con el chip de tipo: es sobre la entidad entera, no sobre
   una fila. */
.panel > header { position: relative; }
.abrirF {
  position: absolute; top: var(--e4); right: var(--e4);
  font-size: var(--t0); color: var(--ink-subtle); text-decoration: none;
  border: 1px solid var(--border); border-radius: var(--r-pill); padding: 0.1rem 0.5rem;
  background: var(--paper-warm);
}
.abrirF:hover { color: var(--accent); border-color: var(--accent-soft-border); background: var(--accent-soft); }

/* ── El mes: las cajas como tarjetas ───────────────────────────────────────
   «Darle un poco más de protagonismo a la caja y menos a lo otro», y «tipo Luli
   y la plata que tiene, algo medio rápido para visualizar». Una tabla de cinco
   filas a lo ancho de la pantalla es mucha grilla para poca información; una
   tarjeta por caja con el saldo en cuerpo grande se lee de un vistazo, que es
   literalmente lo que pidió Angie.                                            */
.tarjeta.destacada { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.bloqueCaja + .bloqueCaja { margin-top: var(--e5); }
.grupoM {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-subtle); font-weight: 500;
  margin-bottom: var(--e2);
}
/* `auto-fill`, no `auto-fit`: con `auto-fit` las columnas vacías colapsan y
   las tarjetas se estiran a llenar la fila, así que un grupo de una sola caja
   (Isa, en Archivadas) ocupaba el ancho entero y pesaba más que las cinco de
   pesos. Con `auto-fill` todos los grupos tienen las mismas columnas y las
   tarjetas miden lo mismo en toda la pantalla (Santi, 14/9: «simétricos y
   parejos»). */
.cajasGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: var(--e3); }
/* Archivadas y quietas, colapsadas: están para quien las busca. */
details.bloqueCaja > summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: flex-start; gap: 0.4rem; }
details.bloqueCaja > summary::-webkit-details-marker { display: none; }
details.bloqueCaja > summary::before { content: '›'; font-family: var(--ui); font-size: var(--t2); color: var(--ink-subtle); transition: transform .12s; }
details.bloqueCaja[open] > summary::before { transform: rotate(90deg); }
details.bloqueCaja > summary:hover { color: var(--ink); }
details.bloqueCaja > summary.grupoM { margin-bottom: 0; }
details.bloqueCaja[open] > summary.grupoM { margin-bottom: var(--e2); }
.caja {
  display: flex; flex-direction: column; gap: 0.1rem; text-align: left;
  padding: var(--e3) var(--e4); border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--paper-warm); cursor: pointer; font-family: var(--ui);
  transition: border-color .1s, background .1s; min-width: 0;
}
.caja:hover { border-color: var(--accent-soft-border); background: var(--accent-soft); }
.caja:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cajaN {
  font-size: var(--t2); font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Cifra ancla de tarjeta, igual que `.kpiV`: viven a 60px una de otra en
   `El mes` y tienen que ser la misma letra. */
.cajaQ {
  font-family: var(--display); font-size: var(--t5); font-weight: 700;
  letter-spacing: -0.015em; font-variant-numeric: tabular-nums;
  color: var(--tinta, var(--ink)); line-height: 1.2; overflow-wrap: anywhere;
}
.cajaD { font-size: var(--t0); color: var(--ink-subtle); font-family: var(--mono); }
/* Una caja que este mes no se movió sigue siendo información («Luli no movió»),
   pero no puede pesar como una que sí. Mismo criterio que `tr.suave`. */
.caja.quieta { background: none; --tinta: var(--ink-subtle); }
.caja.quieta .cajaN { font-weight: 400; color: var(--ink-muted); }
.caja.quieta .cajaQ { font-weight: 400; font-size: var(--t4); }
.totalCaja {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: var(--e3); padding-top: var(--e3); border-top: 1px solid var(--border-strong);
  font-size: var(--t1); color: var(--ink-muted);
}
/* El total del bloque cierra la misma tarjeta que las cifras de arriba: si sale
   en otra letra, la tarjeta tiene dos. */
.totalCaja b {
  font-family: var(--display); font-size: var(--t4); font-weight: 700;
  color: var(--tinta, var(--ink)); font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
}

/* ── El selector de período ────────────────────────────────────────────── */
.selPeriodo select {
  font-family: var(--ui); font-size: var(--t2); color: var(--ink);
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-md);
  padding: 0.3rem 0.5rem; max-width: 13rem;
}
.selPeriodo select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ── Las secciones fijas: la lista ─────────────────────────────────────── */
/* ⚠️ ERAN DOS CONTROLES DE BÚSQUEDA CON DOS CRITERIOS, EN LA MISMA PANTALLA.
   Medido: el del topbar 33px de alto, radio 999px, padding 6,7/14,4; el filtro
   de la lista 30px, radio 6px, padding 5,1/9,6. Se ven los dos a la vez en
   `Proyectos` —uno arriba a la izquierda, el otro arriba a la derecha— y no hay
   ninguna razón por la que uno sea una píldora y el otro un rectángulo: los dos
   hacen lo mismo, filtrar escribiendo.
   La forma compartida se declara UNA vez y la usan los dos. El alto va
   explícito y no derivado del padding: es lo único que garantiza que midan
   igual aunque el cuerpo de letra cambie. */
.buscador input, .filtroL {
  font-family: var(--ui); font-size: var(--t2); text-align: left;
  height: 2.15rem; padding: 0 var(--k4); line-height: 1;
  border: 1px solid var(--border-strong); border-radius: var(--r-pill);
  background: var(--card); color: var(--ink);
}
.filtroL { width: 14rem; }
/* El tope era 42rem fijas. En una pantalla de portátil (~700px de alto) eso
   deja la tarjeta más alta que la ventana, así que scrollean LAS DOS cosas: la
   página hasta que la tarjeta llega al tope y la tabla después. Dos scrolls
   encimados en el mismo gesto es de lo que más desorienta — la rueda no hace lo
   mismo dos veces seguidas. Con el `min`, en una pantalla corta la tarjeta entra
   entera y lo único que se mueve es la tabla; en una larga manda el tope de
   42rem, que es lo que evita una lista de 442 filas ocupando toda la ventana. */
.cuerpoL { max-height: min(42rem, calc(100vh - 15rem)); overflow-y: auto; scrollbar-gutter: stable; }
/* El encabezado queda pegado arriba: en una lista de 442 filas, perder los
   nombres de las columnas al scrollear obliga a volver hasta el principio para
   saber qué se está mirando. */
/* ⚠️ CON `border-collapse: collapse` EL BORDE DE UN `th` PEGAJOSO NO VIAJA CON
   ÉL. El borde colapsado lo pinta la tabla, no la celda, así que se queda
   arriba de todo y scrollea: el encabezado quedaba flotando sin línea y las
   filas le pasaban por debajo pegadas al texto, cortadas al medio. Se ve como
   un bug de render y es esto. La sombra interior SÍ la pinta la celda.
   Y el `padding-top`: sin él la fila que sube toca el texto del encabezado
   antes de desaparecer. La banda tiene que ser una banda. */
/* La banda es simétrica: mismo aire arriba que abajo, y el rótulo centrado de
   verdad en vez de apoyado contra el techo. */
.listaT thead th {
  position: sticky; top: 0; background: var(--card); z-index: 2;
  padding: var(--k5) 0; border-bottom: 0; vertical-align: middle;
  box-shadow: inset 0 -1px 0 var(--border-strong);
}
/* ── EL ENCABEZADO DE UNA COLUMNA DE PLATA SE ALINEA CON LA PLATA ──────────
   `.ordena` reserva el lugar de la flecha SIEMPRE (si apareciera sólo en la
   columna activa, ordenar movería los encabezados). Pero la reservaba a la
   derecha del rótulo dentro de una caja alineada a la derecha, así que el
   rótulo quedaba 11px a la izquierda del borde de la columna mientras las
   cifras caían pegadas a ese borde: siete columnas de números con su título
   corrido. En una columna alineada a la derecha la flecha va ANTES del
   rótulo —es lo que hace cualquier planilla— y el reservado se come el
   canalón, que está vacío. */
.listaT th.n .ordena { flex-direction: row-reverse; justify-content: flex-start; }
/* Y el rótulo no envuelve: es lo que le fija el ancho mínimo a su columna. Sin
   esto, con la columna ancha pidiendo todo el sobrante, «ÚLTIMO MOVIMIENTO» se
   partía en dos renglones, la flecha de orden quedaba sola contra el borde
   —despegada del rótulo que ordena— y la fila de encabezados medía el doble
   por una sola columna. Un encabezado de tabla es un rótulo, no un párrafo. */
.listaT th .ordena { white-space: nowrap; }
.listaT td { font-size: var(--t2); }
.listaT td:not(.n) { text-align: left; }
/* ⚠️ `meta` NO LLEVA `n`, ASÍ QUE SE ESTABA ALINEANDO A LA IZQUIERDA. La celda
   de un contador («movs») se marca `meta` y no `n` —a propósito: un contador de
   filas no es plata y no tiene por qué pesar como plata—, pero eso la sacaba de
   `td.n` y la agarraba el `:not(.n)` de acá arriba. Resultado: una columna de
   números pegados a la izquierda debajo de un encabezado pegado a la derecha,
   con «2» y «46» arrancando en la misma x. El peso es otra cosa que la
   alineación: sigue siendo `--ink-subtle` y un cuerpo más chico, y se alinea
   como lo que es, un número. */
.listaT td.meta { text-align: right; }
.listaT th:not(.n) { text-align: left; }
.listaT th:not(.n) .ordena { justify-content: flex-start; }
.listaT td.n { font-family: var(--mono); color: var(--tinta, var(--ink-light)); }
.listaT td[data-ancha], .listaT td:first-child { white-space: normal; }
/* ── QUIÉN SE QUEDA CON EL ANCHO QUE SOBRA ─────────────────────────────────
   La tabla mide 100% y `table-layout: auto` reparte el sobrante entre TODAS
   las columnas en proporción a su contenido. Con seis columnas cortas —el caso
   de `Cajas`— eso abre un canalón de 350px entre «último movimiento» y
   «quedó», y el ojo tiene que cruzarlo en cada fila. Dándole `width: 100%` a
   la columna ancha, ella pide todo y las demás se ajustan a su contenido: los
   números quedan juntos y el aire va al nombre, que es el único que lo usa. */
.listaT th[data-ancha] { width: 100%; }
/* ⚠️ EL `padding-bottom` DE ACÁ ERA LO QUE DEJABA EL RÓTULO A MEDIO CENTRAR.
   La celda daba 9,6px arriba y 9,6px abajo, y el botón sumaba 8px más abajo:
   9,6 contra 17,6, o sea el texto subido ~4px respecto del centro de una banda
   de 47px. Desde afuera se lee como «casi alineado», que es peor que
   claramente arriba — parece un error de render y no una decisión.
   Ahora el espaciado vertical lo pone la celda y sólo la celda; el botón ocupa
   su línea y nada más. Una medida en un solo lugar. */
.ordena {
  font: inherit; font-family: var(--mono); font-size: var(--t00);
  letter-spacing: 0.1em; text-transform: uppercase; font-weight: 500;
  color: var(--ink-subtle); background: none; border: 0; cursor: pointer;
  padding: 0; display: inline-flex; align-items: center; gap: 0.25rem;
  width: 100%; justify-content: flex-end; line-height: 1;
}
.ordena:hover { color: var(--ink); }
.ordena.on { color: var(--ink); }
.ordena:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* La flecha ocupa su lugar siempre, aunque esté vacía: si apareciera sólo en la
   columna activa, cambiar de orden movería los encabezados de lugar. */
.flecha { display: inline-block; min-width: 0.7em; text-align: center; }
.vacioT { text-align: center !important; color: var(--ink-subtle); padding: var(--e5) 0; }

/* ── Corregir un movimiento, en el lugar ───────────────────────────────────
   El lápiz va AL LADO de la fila y no adentro (un botón dentro de otro no
   existe), así que el borde que separa filas pasa de la fila al envoltorio. */
.filaEd { display: flex; align-items: center; border-top: 1px solid var(--border); border-radius: var(--r-sm); }
.filas > .filaEd:first-child { border-top: 0; }
.filaEd > .fila { border-top: 0; flex: 1; min-width: 0; }
/* Tenue en reposo y no invisible: un lápiz que sólo aparece al pasar el mouse
   no existe para quien no sabe que está ahí. */
.filaEd .lapiz { flex: none; opacity: .35; }
.filaEd:hover .lapiz, .filaEd .lapiz:focus-visible, .filaEd.abierta .lapiz { opacity: 1; }
.filaEd.abierta { background: var(--paper-warm); }
.filaEd.recien { animation: recien 2.6s ease-out; }
@keyframes recien { from { background: var(--positive-soft); } to { background: transparent; } }

.editorMov {
  margin: 0.2rem 0 0.8rem; padding: 0.9rem 1rem; display: grid; gap: 0.75rem;
  background: var(--paper-warm); border: 1px solid var(--border-strong); border-radius: var(--r-md);
}
.editorMov .campos label { font-size: var(--t1); color: var(--ink-muted); }
.editorMov .campos label.ancho2 { flex: 2 1 16rem; }
.editorMov .campoTexto { background: var(--card); }
.editorMov .campoTexto.num { font-size: var(--t3); }
.editorMov .aviso, .editorMov .acciones { margin-top: 0; }
.conflictoEd { display: grid; gap: 0.5rem; }
.reciboF { margin: 0.3rem 0 0.6rem; }
.fichaCab + .reciboF { margin: 0 0 1rem; }

/* ── La entrada con contraseña, y cambiarla desde el pie ─────────────────── */
/* El formulario de entrar (15/9). Rótulo arriba de cada campo —el placeholder
   como rótulo desaparece al escribir y no se sabe qué campo era cuál—, todo a
   lo ancho de la caja, y el botón también: es la única acción de la pantalla. */
.entrarF { display: grid; gap: var(--e4); }
.campoEntrar { display: grid; gap: 0.4rem; }
.campoEntrar > span:first-child { font-size: var(--t2); font-weight: 600; color: var(--ink-light); }
.entrarF .campoTexto { padding: 0.7rem 0.85rem; font-size: 1rem; }
.conOjo { position: relative; display: block; }
.conOjo .campoTexto { padding-right: 2.8rem; }
.verClave {
  position: absolute; top: 50%; right: 0.35rem; transform: translateY(-50%);
  width: 2.1rem; height: 2.1rem; display: grid; place-items: center;
  border: 0; border-radius: var(--r-sm); background: transparent; color: var(--ink-subtle); cursor: pointer;
}
.verClave:hover { color: var(--ink); background: var(--paper-warm); }
.verClave[aria-pressed="true"] { color: var(--accent); }
.verClave:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.entrarB { width: 100%; padding: 0.75rem 1rem; font-size: var(--t3); margin-top: var(--e1); }
.entrarB:disabled { opacity: .7; cursor: progress; }
.avisoEntrar {
  font-size: var(--t2); line-height: 1.45; padding: 0.65rem 0.8rem; border-radius: var(--r-md);
  background: var(--accent-soft); border: 1px solid var(--accent-soft-border); color: var(--ink);
}
.avisoEntrar.mal { background: var(--negative-soft); border-color: var(--negative-soft-border); }
/* El widget de Cloudflare, a lo ancho y alineado con el botón. Mientras carga
   reserva su alto (65px) para que la caja no salte. */
.captchaEntrar { min-height: 65px; margin-top: calc(var(--e1) * -1); }
.captchaEntrar iframe { display: block; }
.claveF { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; margin-top: 0.6rem; }
.claveF .campoTexto { width: 13rem; padding: 0.35rem 0.6rem; font-size: var(--t2); }

@media (max-width: 900px) {
  .fichaCuerpo { grid-template-columns: 1fr; }
  .principalF .cuerpo { max-height: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   14/9 — PEDIDOS DE SANTI: la caja filtra, el pie se va, el perfil sube
   ══════════════════════════════════════════════════════════════════════════ */

/* ── El pie: sólo si está al día, chico y a la derecha ─────────────────── */
.pie {
  border-top: 0; text-align: right; padding: var(--e4) 1.25rem var(--e5);
  font-size: var(--t0); color: var(--ink-subtle);
}

/* ── El perfil: un círculo con la inicial, al lado del tema ─────────────── */
.perfil { position: relative; display: flex; }
.avatar {
  width: 2rem; height: 2rem; border-radius: 50%; padding: 0; cursor: pointer;
  display: grid; place-items: center; overflow: hidden;
  font-family: var(--display); font-weight: 700; font-size: var(--t2);
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid var(--accent-soft-border);
}
.avatar:hover, .avatar[aria-expanded='true'] { border-color: var(--accent); }
.avatar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* El panel y los ítems los comparten los dos desplegables del chrome —el del
   avatar y el de Registrar—: dos copias de «cómo se ve un menú» se separan
   igual que dos copias de una regla (15/9). */
.menuPerfil, .menuRegistrar {
  position: absolute; top: calc(100% + 0.45rem); right: 0; z-index: 30; min-width: 15rem;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); padding: var(--k1);
}
.menuPerfil .quien {
  display: flex; flex-direction: column; padding: var(--k3) var(--k4) var(--k3);
  border-bottom: 1px solid var(--border); margin-bottom: var(--k1);
}
.menuPerfil .quien b { font-size: var(--t2); color: var(--ink); }
.menuPerfil .quien span { font-size: var(--t1); color: var(--ink-muted); overflow-wrap: anywhere; }
/* Con ícono y en la misma columna los tres —Ajustes, Cambiar contraseña,
   Salir— (15/9). Era `display: block` y sin íconos quedaban corridos. */
.menuPerfil [role='menuitem'], .menuRegistrar [role='menuitem'] {
  display: flex; align-items: center; gap: 0.5rem;
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  /* Ajustes es un <a> y los otros dos <button>: sin esto el link venía
     subrayado y 5px más alto (interlineado del body contra el del botón). */
  text-decoration: none; line-height: 1.4;
  font-family: var(--ui); font-size: var(--t2); color: var(--ink-light);
  padding: var(--k2) var(--k4); border-radius: var(--r-sm);
}
.menuPerfil [role='menuitem']:hover, .menuRegistrar [role='menuitem']:hover { background: var(--paper-warm); color: var(--ink); }
.menuPerfil [role='menuitem'] .ico, .menuRegistrar [role='menuitem'] .ico { opacity: .72; }
.menuPerfil [role='menuitem']:hover .ico, .menuRegistrar [role='menuitem']:hover .ico { opacity: 1; }
.menuPerfil [role='menuitem']:focus-visible, .menuRegistrar [role='menuitem']:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.menuPerfil .claveF { flex-direction: column; align-items: stretch; margin: var(--k1) var(--k4) var(--k3); }
.menuPerfil .claveF .campoTexto { width: 100%; }

/* ── Las KPI que filtran ───────────────────────────────────────────────────
   Se ven como tarjetas —son las mismas— y se leen como controles por tres
   señales baratas: mano, borde al pasar, y el acento cuando están elegidas. */
.kpi.filtra {
  font: inherit; text-align: left; cursor: pointer; color: inherit;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.kpi.filtra:hover { border-color: var(--accent-soft-border); box-shadow: var(--shadow-md); }
.kpi.filtra.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.kpi.filtra:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.kpiX { margin-left: 0.4rem; color: var(--accent); font-family: var(--ui); font-size: var(--t2); line-height: 0; }

/* Una fila elegida (el período que filtra) no se confunde con el hover. */
.fila.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.fila.on .et { color: var(--accent); }

/* ── El saldo de la caja, al costado ─────────────────────────────────────── */
.saldoT .cuerpo { padding-bottom: var(--e3); }
.saldoCuando { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); }
.saldoCifra {
  font-family: var(--display); font-size: var(--t5); font-weight: 700; letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums; color: var(--tinta, var(--ink)); line-height: 1.15;
  margin-bottom: var(--e3);
}
.saldoLienzo { position: relative; height: 96px; cursor: crosshair; }
.saldoLienzo svg { width: 100%; height: 100%; display: block; overflow: visible; }
.saldoArea { fill: var(--accent); opacity: .08; }
.saldoLinea { fill: none; stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.saldoCero { stroke: var(--border-strong); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.saldoGuia {
  position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border-strong);
  transform: translateX(-0.5px); pointer-events: none;
}
.saldoPunto {
  position: absolute; width: 9px; height: 9px; border-radius: 50%; pointer-events: none;
  background: var(--accent); box-shadow: 0 0 0 2px var(--card); transform: translate(-50%, -50%);
}
.saldoPunto.fijo { background: var(--card); box-shadow: 0 0 0 2px var(--accent); }

/* La lista de períodos acompaña al gráfico y no estira la columna. */
.periodosT .cuerpo { max-height: 26rem; overflow-y: auto; scrollbar-gutter: stable; }
.periodosT .fila .m { font-size: var(--t2); font-weight: 600; }

/* Llegar a algo desde un aviso: un pulso corto que dice «es esto». */
.seniala { animation: seniala 1.6s ease-out; }
@keyframes seniala {
  0%, 30% { box-shadow: 0 0 0 3px var(--accent-soft-border); border-color: var(--accent); }
  100% { box-shadow: var(--shadow-sm); }
}

/* Un chip de aviso que lleva a resolverlo se ve tocable. */
.chip.accionable { cursor: pointer; }
.chip.accionable:hover { border-color: var(--warn); }

/* ── Explorar: el panel con jerarquía ──────────────────────────────────────
   La cabecera se separa del contenido con papel tibio: es la identidad del
   panel, y la lista de abajo es lo que se recorre. El resumen es una tira de
   datos —rótulo chico, cifra abajo— en vez de un renglón corrido. */
.panel > header { background: var(--paper-warm); border-radius: var(--r-lg) var(--r-lg) 0 0; }
.panel.ultimo > header { background: var(--accent-soft); }
.panel .resumen { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); gap: var(--k3) var(--k4); }
.panel .resumen .dato { display: flex; flex-direction: column; min-width: 0; }
.panel .resumen .dato i {
  font-style: normal; font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-subtle); white-space: nowrap;
}
.panel .resumen .dato b { margin-left: 0; font-size: var(--t3); overflow-wrap: anywhere; }
.panel .grupo { color: var(--ink-muted); font-weight: 500; }

/* El aviso: una franja, arriba, y cada renglón es la salida. */
.panelAviso {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--e0);
  margin: var(--e2) 0 var(--e1); padding: var(--k3) var(--k4); border-radius: var(--r-md);
  background: var(--warn-soft); border: 1px solid var(--warn-soft-border); font-size: var(--t1);
}
.panelAviso b { color: var(--warn); font-weight: 600; }
.panelAviso button {
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left;
  font-family: var(--ui); font-size: var(--t1); color: var(--ink-light);
}
.panelAviso button:hover { color: var(--ink); text-decoration: underline; }

.panel .resumen .dato b.txt { font-family: var(--ui); font-size: var(--t1); font-weight: 600; letter-spacing: 0; }

/* ── Explorar: solapas y alto de pantalla ──────────────────────────────────
   Las relaciones del panel van como solapas en la cejilla —todas a la vista,
   con su cantidad— y se ve una lista a la vez. El panel usa el alto de la
   ventana: a 34rem quedaba media pantalla vacía debajo y un scroll dentro de
   otro. */
.panel { height: calc(100vh - 12.5rem); min-height: 24rem; max-height: none; }
.pestanas {
  display: flex; gap: var(--k1); flex-wrap: wrap; margin-top: var(--k4);
}
.pestanas button {
  font-family: var(--ui); font-size: var(--t1); color: var(--ink-muted); cursor: pointer;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-pill);
  padding: 0.18rem 0.6rem; display: inline-flex; align-items: center; gap: 0.3rem;
}
.pestanas button:hover:not(.on) { color: var(--ink); border-color: var(--border-strong); }
.pestanas button.on { background: var(--ink); border-color: var(--ink); color: var(--card); font-weight: 600; cursor: default; }
.pestanas button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pestanas .n { font-family: var(--mono); font-size: var(--t00); opacity: .7; }
/* La fila que abrió el panel siguiente: el hilo de la pila, marcado. */
.panel .fila.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.panel .fila.on .et { color: var(--accent); }
.panel .fila.on .ir { opacity: 1; color: var(--accent); }
.panel .corte a { color: var(--accent); text-decoration: none; }
.panel .corte a:hover { text-decoration: underline; }

/* ── Ficha: filtros puestos, en la cejilla de la lista ───────────────────── */
.tarjeta > header { flex-wrap: wrap; }
.filtrosT { display: inline-flex; gap: var(--k1); flex-wrap: wrap; }
.chipFiltro {
  font-family: var(--ui); font-size: var(--t1); cursor: pointer;
  background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent-soft-border);
  border-radius: var(--r-pill); padding: 0.1rem 0.55rem;
}
.chipFiltro:hover { border-color: var(--accent); }
.chipFiltro:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* El aviso al costado habla en ámbar, como el chip que lleva hasta él. */
.tarjeta.avisoT { background: var(--warn-soft); border-color: var(--warn-soft-border); }
.tarjeta.avisoT > header h2 { color: var(--warn); }
.tarjeta.avisoT .fila:hover { background: var(--card); }
.saldoLienzo { cursor: default; }
.saldoLienzo.clic { cursor: pointer; }
.saldoT .barraM { margin-top: var(--e4); }
.colLado .tarjeta:not(.saldoT):not(.avisoT) .cuerpo { max-height: 22rem; overflow-y: auto; scrollbar-gutter: stable; }
.tarjeta.listaMes > header { align-items: center; }
.tarjeta > header .pestanas { margin-top: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   14/9 (3) — PASADA GLOBAL
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Una columna vacía no ocupa lugar ──────────────────────────────────────
   La celda del margen reserva 3.6rem aunque la fila no tenga margen (un
   movimiento, un período): el importe quedaba flotando en el medio de la fila,
   lejos del borde donde el ojo lo busca. */
.fila .m:empty { min-width: 0; }

/* ── El costado no puede pesar más que la lista ────────────────────────────
   Los rótulos del costado estaban a --t3 en mono versalita: «PROVEEDORES (9)»
   pesaba más que «MOVIMIENTOS (43)», que es la lista por la que se vino. Todos
   los rótulos de tarjeta son el mismo micro-rótulo; la jerarquía la da el
   ancho, no la letra. */
.colLado .tarjeta > header h2 { font-size: var(--t0); }
.colLado .fila { gap: var(--e2); grid-template-columns: 1fr auto auto 0.7rem; }
.colLado .fila .et { font-size: var(--t2); font-weight: 500; }
.colLado .fila .v { white-space: nowrap; }

/* ── La cabecera con bajada: la raya a todo el ancho ───────────────────────
   La bajada tiene `max-width: 68ch` para que el texto no se estire, y la raya
   de abajo heredaba ese ancho: en Cerrar quedaba cortada a media pantalla. */
.cabecera + .bajada { max-width: none; }

/* ── El pie, cerca del contenido ───────────────────────────────────────────── */
.pantalla { padding-bottom: var(--e5); }

/* ── Cerrar: una columna ───────────────────────────────────────────────────── */
.cierreUno { max-width: 62rem; }

/* ── El mes: el total en la cejilla, y los grupos por moneda con el suyo ──── */
.totalT { font-size: var(--t1); color: var(--ink-muted); }
.totalT b {
  font-family: var(--display); font-size: var(--t4); font-weight: 700; margin-left: var(--e1);
  color: var(--tinta, var(--ink)); font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
}
.grupoM { display: flex; justify-content: space-between; align-items: baseline; }
.grupoM b {
  font-family: var(--display); font-size: var(--t3); font-weight: 700; letter-spacing: -0.01em;
  text-transform: none; color: var(--tinta, var(--ink)); font-variant-numeric: tabular-nums;
}
/* A5: lo que venía más lo del mes = el total. Números en renglón → mono. */
.desgloseCajas { margin: 0 0 var(--e2); font-size: var(--t1); color: var(--ink-muted); }
.desgloseNota { color: var(--ink-subtle); }
.desgloseCajas b { font-family: var(--mono); font-weight: 600; color: var(--tinta, var(--ink)); font-variant-numeric: tabular-nums; }
.listaMes > header { gap: var(--e3); justify-content: flex-start; }
.listaMes > header .filtrosT { margin-left: auto; }

/* ── Cajas: tarjetas ───────────────────────────────────────────────────────── */
.cuerpoCajas { padding-top: var(--e4); }

/* ── Listas: filtros rápidos al lado del título, y el margen con su plata ─── */
.cabecera .rapidos { margin-top: 0; }
.listaT td .m2 {
  display: block; font-size: var(--t0); color: var(--ink-subtle); font-weight: 500; margin-top: 0.05rem;
}

/* La cejilla de las listas: `padding: var(--k5) 0` le sacaba al encabezado el
   `padding-left` que sí tienen las celdas, así que cada rótulo quedaba 18px a
   la izquierda de su columna. Y la flecha reservada vacía bajaba los rótulos
   numéricos medio renglón: el botón mide lo mismo con o sin flecha. */
.listaT thead th + th { padding-left: var(--e4); }
.ordena { height: 1rem; }
.flecha { line-height: 1; }
.tarjeta .cuerpo.cuerpoCajas { padding-top: var(--e4); }
.cierreUno { max-width: none; }

/* En oscuro `--paper-warm` (#111) es MÁS oscuro que la tarjeta (#161616): la
   caja que se movió quedaba más apagada que la quieta, que es transparente.
   La que tiene plata tiene que ser la que se levanta. */
[data-theme='dark'] .caja:not(.quieta) { background: var(--border); }

/* ══════════════════════════════════════════════════════════════════════════
   14/9 (5) — LAS LISTAS, CON LA ESTÉTICA DEL MOCKUP
   ══════════════════════════════════════════════════════════════════════════
   Cada fila es un bloque en papel tibio con aire entre uno y otro: el ojo
   agarra la fila entera sin cebrado y sin líneas. El cebrado estaba vedado
   porque el tibio es el hover; acá TODAS las filas son tibias y el hover es el
   acento suave, así que estado y hover no se confunden.                      */
.listaT { border-collapse: separate; border-spacing: 0 6px; margin-top: -6px; }
.listaT tbody tr + tr td { border-top: 0; }
.listaT tbody td {
  background: var(--paper-warm); padding-top: 0.85rem; padding-bottom: 0.85rem;
  vertical-align: middle; transition: background .1s;
}
.listaT tbody tr:first-child td { padding-top: 0.85rem; }
.listaT tbody td:first-child { border-radius: var(--r-md) 0 0 var(--r-md); padding-left: var(--k5); }
.listaT tbody td:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; padding-right: var(--k5); }
.listaT thead th:first-child { padding-left: var(--k5); }
.listaT thead th:last-child { padding-right: var(--k5); }
.listaT thead th { box-shadow: none; }
.tabla.listaT tr.nav:hover td { background: var(--accent-soft); }
[data-theme='dark'] .listaT tbody td { background: var(--border); }
[data-theme='dark'] .tabla.listaT tr.nav:hover td { background: var(--accent-soft); }

/* El nombre ancla la fila: más cuerpo y peso que el resto. */
.listaT .nomL { font-size: var(--t3); font-weight: 650; color: var(--ink); letter-spacing: -0.005em; }
.listaT td.n { font-size: var(--t2); color: var(--ink-light); }
.listaT td.meta { color: var(--ink-subtle); }

/* ── La pastilla del margen ─────────────────────────────────────────────── */
.pillM {
  display: inline-block; min-width: 3.6rem; text-align: center;
  font-family: var(--mono); font-size: var(--t2); font-weight: 600;
  padding: 0.2rem 0.5rem; border-radius: var(--r-sm);
  color: var(--tinta, var(--ink-light));
  background: color-mix(in oklch, var(--tinta, var(--ink-light)) 13%, transparent);
}
.pillM.m-normal { background: var(--card); color: var(--ink-light); box-shadow: inset 0 0 0 1px var(--border-strong); }
.plM {
  display: inline-block; min-width: 4.4rem; margin-left: var(--k3); text-align: right;
  font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle);
}

/* ── Badges ─────────────────────────────────────────────────────────────── */
.badge {
  display: inline-block; font-family: var(--ui); font-size: var(--t1); font-weight: 500;
  color: var(--ink-light); background: var(--card); border: 1px solid var(--border-strong);
  border-radius: var(--r-pill); padding: 0.08rem 0.55rem; margin-right: var(--k1);
  white-space: nowrap; line-height: 1.5;
}
.badge.alerta { color: var(--warn); background: var(--warn-soft); border-color: var(--warn-soft-border); }
.badge.accionable { cursor: pointer; }
.badge.accionable:hover { border-color: var(--warn); }
.masN { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); }
.listaT td .chip { margin-left: var(--k2); vertical-align: 1px; }

/* ── El resumen al pie ─────────────────────────────────────────────────── */
.resumenL {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--e4); flex-wrap: wrap;
  margin: var(--e2) var(--e4) var(--e4); padding: var(--k4) var(--k5);
  background: var(--accent-soft); border: 1px solid var(--accent-soft-border); border-radius: var(--r-md);
  font-size: var(--t3); color: var(--ink-light);
}
.resumenM { font-family: var(--mono); color: var(--accent); font-size: var(--t2); }
.resumenM b { font-weight: 700; margin-left: var(--k1); }
.flecha.oculta { visibility: hidden; }
/* Las columnas de plata respiran: pegadas, «$ 70,7M $ 30,7M» se leía como un
   solo número. */
.listaT td.n, .listaT th.n { min-width: 6.2rem; }
.listaT td.meta, .listaT th.n:has(+ th.n) { min-width: 3.4rem; }
.plM { margin-left: 0; margin-right: var(--k3); }

/* ══════════════════════════════════════════════════════════════════════════
   14/9 (6) — CARGAR DESDE EL SISTEMA
   ══════════════════════════════════════════════════════════════════════════ */
.wMoneda { margin: 0 0 var(--e3); display: inline-flex; }
/* Las cubetas de estructura, a un clic y arriba del buscador. */
.rapidosW { display: flex; gap: var(--k2); flex-wrap: wrap; margin-bottom: var(--e3); }
.opcion.chica { width: auto; padding: 0.35rem 0.8rem; flex-direction: row; }
.wPeriodo { margin-top: var(--e3); }
.wPeriodo select { max-width: 16rem; }
/* El recibo: lo que quedó, lado por lado. */
.reciboW ul { margin: var(--e2) 0 0; padding: 0; list-style: none; display: grid; gap: var(--k2); }
.reciboW li {
  padding: var(--k3) var(--k4); border-radius: var(--r-md); font-size: var(--t2);
  background: var(--positive-soft); border: 1px solid var(--positive-soft-border); color: var(--ink);
}
.reciboW li.medio { background: var(--warn-soft); border-color: var(--warn-soft-border); }
.reciboW li.mal { background: var(--negative-soft); border-color: var(--negative-soft-border); }
.reciboW li.tenue { background: none; border-color: var(--border); color: var(--ink-muted); }

/* ══════════════════════════════════════════════════════════════════════════
   14/9 (7) — REGISTRAR A MANO Y EL EDITOR
   ══════════════════════════════════════════════════════════════════════════ */
.btn.conIco { display: inline-flex; align-items: center; gap: var(--k1); }
.btn.conIco .ico { width: 13px; height: 13px; opacity: 1; }
.registrarNav { position: relative; margin-left: var(--k3); display: inline-flex; }
.registrarNav .btn { white-space: nowrap; }
/* ⚠️ El desplegable vive ADENTRO de `.menu` y heredaba las reglas de los ítems
   de sección —centrado, pastilla, y el texto escondido con poco ancho—. Desde
   el 15/9 esas reglas son `.menu > a`; el panel y los ítems son los del avatar
   (arriba). Acá sólo lo propio: arranca en el borde del botón, y el
   movimiento —lo de todos los días— separado de las altas. */
.menuRegistrar { left: 0; right: auto; min-width: 12rem; }
.menuRegistrar[hidden] { display: none; }
.menuRegistrar .sep { display: block; height: 1px; background: var(--border); margin: var(--k1) var(--k2); }
@media (max-width: 40rem) {
  /* En el celular Registrar es el último ícono del renglón: se abre hacia adentro. */
  .menuRegistrar { left: auto; right: 0; }
}
.fichaCab .btn.chico, .cabecera .btn.chico { align-self: center; }

/* ── Volver ─────────────────────────────────────────────────────────────── */
.volver {
  display: inline-grid; place-items: center; width: 2rem; height: 2rem; flex: none;
  border-radius: var(--r-pill); border: 1px solid var(--border); background: var(--card);
  color: var(--ink-muted); cursor: pointer; padding: 0; align-self: center;
}
.volver:hover { color: var(--ink); border-color: var(--border-strong); }
.volver:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.volver .ico { width: 15px; height: 15px; opacity: 1; }

/* ── El panel lateral ────────────────────────────────────────────────────
   A la derecha, sobre la ficha, con un velo apenas perceptible: se sigue
   viendo lo que se edita. */
.panelFondo { position: fixed; inset: 0; z-index: 40; background: rgba(10,10,10,.12); }
[data-theme='dark'] .panelFondo { background: rgba(0,0,0,.35); }
.panelLat {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 41; width: min(30rem, 100vw);
  background: var(--card); border-left: 1px solid var(--border-strong); box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; animation: panelEntra .16s ease-out;
}
@keyframes panelEntra { from { transform: translateX(1.5rem); opacity: 0; } to { transform: none; opacity: 1; } }
.panelLat > header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e3);
  padding: var(--e4) var(--e4) var(--e3); border-bottom: 1px solid var(--border);
}
.panelLat > header h2 { font-family: var(--display); font-size: var(--t4); font-weight: 700; margin: 0; letter-spacing: -0.015em; }
.panelLat > header .btn.icono { font-size: 1.3rem; line-height: 1; }
.cuerpoPanel { overflow-y: auto; padding: var(--e4); display: flex; flex-direction: column; gap: var(--e3); }
.cuerpoPanel .editorMov { margin: 0; background: none; border: 0; padding: 0; }
.campos.colW { flex-direction: column; gap: var(--e3); }
.campos.colW label { flex: none; }
.bloqueP { border-top: 1px solid var(--border); padding-top: var(--e4); margin-top: var(--e2); }
.bloqueP h3 {
  font-family: var(--mono); font-size: var(--t0); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-muted); font-weight: 500; margin: 0 0 var(--e2);
}
.btn.peligro { color: var(--negative); }
.btn.peligro:hover { background: var(--negative-soft); border-color: var(--negative-soft-border); }
.btn.chico.peligro { border-color: var(--negative-soft-border); }

/* El historial: qué, quién y cuándo; y el gesto que lo deshace. */
.historial { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--k1); }
.historial li {
  display: grid; grid-template-columns: 1fr auto; gap: 0 var(--e3); align-items: baseline;
  padding: var(--k2) var(--k3); border-radius: var(--r-sm); background: var(--paper-warm); font-size: var(--t1);
}
.historial li.deshecha { opacity: .6; }
.historial li.en_curso, .historial li.con_conflictos { background: var(--warn-soft); }
.historial .hQue { color: var(--ink); }
.historial .hQuien { grid-column: 1; color: var(--ink-subtle); font-size: var(--t0); }
.historial .hAcc { grid-column: 2; grid-row: 1 / span 2; display: flex; gap: var(--e3); }
.historial .enlace { font-size: var(--t1); }
/* La lista de vínculos del panel (proyectos de una marca, marcas de un
   cliente) usa la forma del historial, sin la segunda línea. */
.historial.vinculos { margin-bottom: var(--e3); max-height: 16rem; overflow-y: auto; }
.historial.vinculos li { grid-template-columns: 1fr auto; }
.historial.vinculos .hAcc { grid-row: 1; }

/* Lo que quedó a medias, abajo a la izquierda, con su gesto. */
.enCurso {
  position: fixed; left: 1rem; bottom: 1rem; z-index: 35; max-width: min(34rem, calc(100vw - 2rem));
  display: flex; align-items: center; gap: var(--e3); padding: var(--k3) var(--k4);
  background: var(--warn-soft); border: 1px solid var(--warn-soft-border); border-radius: var(--r-md);
  box-shadow: var(--shadow-md); font-size: var(--t2);
}

/* ── El mes partido ──────────────────────────────────────────────────────── */
.mesCuerpo { grid-template-columns: 1fr 22rem; }
.mesLado { position: sticky; top: 4.5rem; }
.mesLado .kpis { grid-template-columns: 1fr 1fr; margin-bottom: 0; gap: var(--e2); }
.mesLado .kpi { padding: var(--k4); }
.mesLado .kpiV { font-size: var(--t4); }
.mesLado .tarjeta.destacada > header { padding-bottom: var(--e2); }
.mesLado .cajasGrid { grid-template-columns: 1fr; gap: var(--k1); }
.mesLado .caja { flex-direction: row; justify-content: space-between; align-items: baseline; padding: var(--k3) var(--k4); }
.mesLado .cajaQ { font-size: var(--t3); }
.mesLado .caja.quieta .cajaQ { font-size: var(--t2); }
.mesLado .grupoM { margin-bottom: var(--k1); }
.mesLado .bloqueCaja + .bloqueCaja { margin-top: var(--e3); }
.mesCuerpo .listaMes .cuerpo { max-height: none; }
@media (max-width: 900px) {
  .mesCuerpo { grid-template-columns: 1fr; }
  .mesLado { position: static; order: -1; }
}
.mesLado { position: static; }
.mesLado .tarjeta .cuerpo, .colLado.mesLado .tarjeta:not(.saldoT):not(.avisoT) .cuerpo { max-height: none; overflow: visible; }

/* ══════════════════════════════════════════════════════════════════════════
   14/9 (8) — LAS FILAS DE EL MES
   ══════════════════════════════════════════════════════════════════════════
   El mismo lenguaje que Proyectos y Clientes: bloques en papel tibio con aire
   entre uno y otro; tres zonas fijas —qué · cuánto · cómo le fue— para que el
   ojo baje por columnas y no zigzaguee; el hover en acento suave. */
.listaMes .filas { display: grid; gap: 6px; }
.filaMes {
  display: grid; grid-template-columns: minmax(0, 1fr) 8rem 5rem 0.9rem; gap: var(--e4);
  align-items: center; width: 100%; text-align: left; cursor: pointer;
  padding: 0.8rem var(--k5); border: 0; border-radius: var(--r-md);
  background: var(--paper-warm); font-family: var(--ui); color: var(--ink);
  transition: background .1s;
}
.filaMes.mov { grid-template-columns: minmax(0, 1fr) auto 8.5rem 0.9rem; }
.filaMes:hover:not(:disabled) { background: var(--accent-soft); }
.filaMes:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.filaMes:disabled { cursor: default; }
[data-theme='dark'] .filaMes { background: var(--border); }
[data-theme='dark'] .filaMes:hover:not(:disabled) { background: var(--accent-soft); }
.fmQue { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.fmNom {
  font-size: var(--t3); font-weight: 650; letter-spacing: -0.005em; line-height: 1.25;
  display: flex; align-items: center; gap: var(--k2); flex-wrap: wrap;
}
.fmNom .chip { margin: 0; }
.fmCtx { display: flex; align-items: center; gap: var(--k2); flex-wrap: wrap; font-size: var(--t1); color: var(--ink-muted); }
.fmCtx .badge { margin: 0; font-size: var(--t0); padding: 0.02rem 0.5rem; }
.fmFecha { font-family: var(--mono); font-size: var(--t0); color: var(--ink-subtle); }
.fmTxt { color: var(--ink-muted); }
.fmTxt.tenue { color: var(--ink-subtle); }
.fmPlata {
  font-family: var(--mono); font-size: var(--t2); font-variant-numeric: tabular-nums;
  text-align: right; color: var(--ink-light); white-space: nowrap;
}
.filaMes.mov .fmPlata { font-size: var(--t3); font-weight: 600; color: var(--ink); }
.filaMes.mov .fmPlata.entra { color: var(--positive); }
.fmMargen { text-align: right; }
.fmMargen .pillM { min-width: 3.4rem; }
.fmCaja { text-align: right; }
.badge.caja { background: var(--card); color: var(--ink-muted); }
.filaMes .ir { color: var(--ink-subtle); opacity: 0; transition: opacity .1s; }
.filaMes:hover .ir { opacity: 1; }
.listaMes > .cuerpo { padding-top: var(--e2); }
@media (max-width: 40rem) {
  .filaMes { grid-template-columns: minmax(0, 1fr) auto; }
  .filaMes .fmMargen, .filaMes .fmCaja, .filaMes .ir { display: none; }
}

/* ── Resultados (14/9) ───────────────────────────────────────────────────────
   La cascada: el signo va en su propia columna visual, delante del rótulo, para
   que «−», «=» y «+» se lean en fila y el ojo baje por la resta. Los renglones
   de total ya tienen `.tabla tr.total`; las categorías abiertas, `tr.suave`. */
.tablaRes .signoRes {
  display: inline-block; width: 1.1rem; font-family: var(--mono);
  color: var(--ink-subtle); font-weight: 500;
}
.tablaRes tr.suave td:first-child { padding-left: 1.1rem; }
.tablaRes td.ir { width: 1rem; color: var(--ink-subtle); }
.tablaRes .abreRes {
  display: inline-block; margin-left: var(--k1); color: var(--ink-subtle);
  transition: transform .12s; font-weight: 400;
}
.tablaRes .abreRes.on { transform: rotate(90deg); }
/* `.tablaScroll` se usaba desde el 14/9 y no existía en el CSS: la tabla de
   Resultados siempre entró, así que nunca se notó. La de Estructura (nueve
   meses de columnas) empujaba la página a 977px en una ventana de 960. Una
   tabla ancha scrollea ADENTRO de su tarjeta, nunca ensancha la página. */
.tablaScroll { overflow-x: auto; max-width: 100%; }
.tarjeta .cuerpo:has(> .tablaScroll) { min-width: 0; }
/* Estructura (B5): el rubro queda a la vista cuando la grilla de meses se
   desplaza. Sticky en la celda, con fondo propio, o las cifras le pasan por
   debajo. */
.tablaEst th:first-child, .tablaEst td:first-child { position: sticky; left: 0; background: var(--card); z-index: 1; min-width: 11rem; }
/* Y con `border-collapse` la línea de fila la pinta la TABLA, no la celda: el
   fondo de la celda fija la tapaba (la trampa del `th` pegajoso, de costado).
   La línea va en la celda, con sombra. */
.tablaEst th:first-child { box-shadow: inset 0 -1px 0 var(--border-strong); }
.tablaEst tbody tr + tr td:first-child { box-shadow: inset 0 1px 0 var(--border); }
.tablaEst td.n, .tablaEst th.n { white-space: nowrap; }
.tablaEst td[data-celda] { cursor: pointer; }
.tablaEst td[data-celda]:hover { background: var(--accent-soft); }
.tablaRes tr.total.neg td.q { --tinta: var(--negative); }
.cabecera .pestanas { margin: 0; }

/* Los movimientos detrás de un renglón, en el panel lateral. */
.movsRes { list-style: none; margin: 0; padding: 0; }
.movsRes li {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--e3);
  padding: var(--k2) 0; border-top: 1px solid var(--border);
}
.movsRes .mrQue { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.movsRes .mrQue b { font-weight: 600; font-size: var(--t2); }
.movsRes .mrQue .tenue { font-size: var(--t1); }
.movsRes .mrPlata { font-family: var(--mono); font-size: var(--t2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.movsRes .mrCat { display: inline-flex; align-items: center; gap: var(--k2); margin-top: 0.3rem; font-size: var(--t1); flex-wrap: wrap; }
.movsRes .mrCat select {
  font: inherit; font-size: var(--t1); color: var(--ink); background: var(--card);
  border: 1px solid var(--border-strong); border-radius: var(--r-md); padding: 0.15rem 0.4rem; max-width: 100%;
}
.movsRes .mrCat select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.movsRes .mrAviso { font-size: var(--t1); color: var(--ink-muted); }
.movsRes .mrAviso:empty { display: none; }

/* Estructura (30/9): el rubro abierto en la tabla, por concepto o proveedor.
   Un nivel más adentro que `tr.suave`, y más chico. */
.tablaRes tr.detalleRub td:first-child {
  padding-left: 2rem; font-weight: 400; color: var(--ink-muted); font-size: var(--t1);
  max-width: 16rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tablaRes tr.detalleRub td { font-size: var(--t1); --tinta: var(--ink-subtle); }
.tablaEst td[data-celda-det] { cursor: pointer; }
.tablaEst td[data-celda-det]:hover { background: var(--accent-soft); }
.porDetalle { display: inline-flex; align-items: center; gap: var(--k2); font-size: var(--t1); }
.porDetalle .pestanas { margin: 0; }
/* El lote del panel: tildar y pasar a una categoría. */
.loteCat {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--k2);
  padding: var(--k2) 0 var(--k3); font-size: var(--t1);
}
.loteCat label { display: inline-flex; align-items: center; gap: var(--k1); }
.loteCat select {
  font: inherit; color: var(--ink); background: var(--card);
  border: 1px solid var(--border-strong); border-radius: var(--r-md); padding: 0.15rem 0.4rem; max-width: 100%;
}
.movsRes li:has(> .mrTilde) { justify-content: flex-start; }
.movsRes li > .mrTilde { flex: none; align-self: center; }
.movsRes li:has(> .mrTilde) > .mrPlata { margin-left: auto; }

/* ── Actividad (15/9) ────────────────────────────────────────────────────────
   Tres columnas fijas —hora, quién, qué— para que el ojo baje por la hora y
   encuentre a la persona sin leer las frases. En el panel la hora lleva el día
   y la grilla se afina. */
.actLista { list-style: none; margin: 0; padding: 0; }
.actLista li {
  display: grid; grid-template-columns: 3.2rem 8.5rem minmax(0, 1fr); gap: var(--e3);
  align-items: baseline; padding: var(--k3) 0; border-top: 1px solid var(--border);
}
.actLista li:first-child { border-top: 0; }
.actLista li[role="button"] { cursor: pointer; }
.actLista li[role="button"]:hover { background: var(--paper-warm); }
.actLista li[role="button"]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.actHora { font-family: var(--mono); font-size: var(--t1); color: var(--ink-subtle); font-variant-numeric: tabular-nums; }
.actQuien { font-weight: 600; font-size: var(--t2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.actQue { font-size: var(--t2); color: var(--ink-light); display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.actObj { color: var(--ink-muted); font-size: var(--t1); }
.actObj .pos, .actObj .neg { font-family: var(--mono); }
.actLista.enPanel li { grid-template-columns: 6.5rem 6rem minmax(0, 1fr); }
@media (max-width: 40rem) {
  .actLista li { grid-template-columns: 2.8rem minmax(0, 1fr); }
  .actLista li .actQue { grid-column: 1 / -1; }
}

/* La estructura del mes en el home (B5): rubro y monto, en columna → mono. */
.estMes header .enlace { font-size: var(--t1); }
.estLista { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.estLista li { display: flex; justify-content: space-between; gap: 0.75rem; font-size: var(--t2); }
.estLista li b { font-family: var(--mono); font-weight: 600; font-variant-numeric: tabular-nums; }
.estLista li.estTotal { border-top: 1px solid var(--border); padding-top: 0.4rem; margin-top: 0.2rem; font-weight: 600; }

/* ── Movimientos: la mesa de trabajo (5/10) ────────────────────────────────
   Todos los movimientos en una tabla: buscar, filtrar, tildar, pasar, cargar.
   Reusa `.tabla.listaT` (encabezado pegajoso, orden por columna) y `.cuerpoL`
   (un solo scroll). Lo de acá es lo que esa tabla no tenía: filtros en
   píldoras con su desplegable, una columna de tildes, filas nuevas con celdas
   y una barra de acción pegada al pie. */
.registrarMov { position: relative; display: inline-flex; }
/* El botón está contra el borde derecho: el desplegable abre hacia adentro. */
.registrarMov .menuRegistrar { left: auto; right: 0; }

/* Las vistas a la izquierda, el buscador a la derecha: un renglón. */
.vistasMov { margin: 0 0 var(--e3); align-items: center; }
.vistasMov .sp { flex: 1; }
.vistasMov .filtroL { width: 19rem; max-width: 100%; }
/* Guardar o borrar una vista es una ACCIÓN, no una vista más: dentro de
   `.pestanas` heredaba la píldora y se leía como otro filtro para elegir. */
.pestanas.vistasMov button.mvAccionVista {
  border: 0; background: none; padding: 0; margin-left: var(--k2);
  color: var(--accent); font-weight: 500; font-size: var(--t1);
}
.pestanas.vistasMov button.mvAccionVista:hover { text-decoration: underline; color: var(--accent); }
.nombrarMv { display: inline-flex; align-items: center; gap: var(--k1); margin-left: var(--k2); }
/* El texto se queda con el ancho y los botones no bajan de renglón. */
.reciboMv { margin-bottom: var(--e3); flex-wrap: nowrap; align-items: center; }
.reciboMv > span:first-child { flex: 1; min-width: 0; }
.reciboMv .sp { display: none; }
.reciboMv .btn { flex: none; }

/* ── los filtros ───────────────────────────────────────────────────────────
   Una píldora por campo, del idioma de `.pestanas`. Apagada dice el campo;
   prendida dice el VALOR, en el acento, y trae su ×. El desplegable es el
   menú de siempre (`.menuPerfil`), no un control del sistema operativo: los
   `<select>` y las fechas nativas rompían la pantalla (Santi, 6/10). */
.barraMov {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--k2);
  padding: var(--k4) var(--e4);
}
.barraMov .sp { flex: 1; }
.pillMvCaja { position: relative; display: inline-flex; align-items: center; }
.pillMv {
  font-family: var(--ui); font-size: var(--t1); color: var(--ink-muted); cursor: pointer;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-pill);
  padding: 0.22rem 0.7rem; display: inline-flex; align-items: center; gap: 0.35rem;
  line-height: 1.4; max-width: 16rem;
}
.pillMv:hover { color: var(--ink); border-color: var(--border-strong); }
.pillMv:focus-visible, .pillMvX:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pillMv[aria-expanded='true'] { border-color: var(--accent); color: var(--ink); }
.pillMvT { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pillMvV { font-size: 0.85em; opacity: 0.55; margin-right: -0.1rem; }
.pillMv.on {
  background: var(--accent-soft); border-color: var(--accent-soft-border);
  color: var(--accent); font-weight: 600;
}
.pillMv.on:hover { border-color: var(--accent); color: var(--accent); }
/* Prendida y con ×: la flecha le deja el lugar a la ×, que es lo que se usa. */
.pillMvCaja .pillMv.on { padding-right: 1.55rem; }
.pillMvCaja .pillMv.on .pillMvV { display: none; }
.pillMvX {
  position: absolute; right: 0.3rem; top: 50%; transform: translateY(-50%);
  width: 1.05rem; height: 1.05rem; border-radius: 50%; border: 0; padding: 0;
  background: none; color: var(--accent); cursor: pointer; font-size: var(--t2); line-height: 1;
}
.pillMvX:hover { background: var(--accent); color: var(--card); }
.pillMvSep { width: 1px; height: 1.1rem; background: var(--border); margin: 0 var(--k1); }
.mvLimpiar { font-size: var(--t1); }

.menuMv {
  position: absolute; top: calc(100% + 0.4rem); left: 0; z-index: 30; min-width: 13.5rem;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-md);
  box-shadow: var(--shadow-lg); padding: var(--k1); display: flex; flex-direction: column;
}
.menuMvLista { display: flex; flex-direction: column; max-height: 19rem; overflow-y: auto; }
.itemMv {
  display: flex; align-items: center; justify-content: space-between; gap: var(--k3);
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  font-family: var(--ui); font-size: var(--t2); color: var(--ink-light); line-height: 1.4;
  padding: var(--k2) var(--k4); border-radius: var(--r-sm); white-space: nowrap;
}
.itemMv:hover { background: var(--paper-warm); color: var(--ink); }
.itemMv:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.itemMv.on { color: var(--accent); font-weight: 600; }
.itemMv.on::after { content: '✓'; font-size: var(--t1); }
.menuMvQ {
  font-family: var(--ui); font-size: var(--t2); color: var(--ink);
  border: 0; border-bottom: 1px solid var(--border); background: none; outline: none;
  padding: var(--k2) var(--k4) var(--k3); margin-bottom: var(--k1); width: 100%; min-width: 17rem;
}
.menuMvGrupo {
  font-family: var(--mono); font-size: var(--t00); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-subtle); padding: var(--k3) var(--k4) var(--k1);
}
.menuMvSep { display: block; height: 1px; background: var(--border); margin: var(--k1) var(--k2); }
.menuMvCampo {
  display: flex; align-items: center; justify-content: space-between; gap: var(--k4);
  font-size: var(--t1); color: var(--ink-muted); padding: var(--k1) var(--k4);
}
.menuMvCampo input {
  font-family: var(--ui); font-size: var(--t1); color: var(--ink);
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  padding: 0.18rem 0.4rem;
}
.menuMvNota { font-size: var(--t1); color: var(--ink-subtle); padding: var(--k2) var(--k4); }

/* Un control de la barra de lo tildado: la forma del buscador, sin el ancho fijo. */
.campoMv {
  font-family: var(--ui); font-size: var(--t1); color: var(--ink);
  height: 2.15rem; padding: 0 var(--k3); max-width: 100%;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-md);
}
.campoMv:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
input.campoMv { width: 11rem; }

/* ── la tabla ──────────────────────────────────────────────────────────────
   `.listaT` hace de cada fila un bloque con aire, que es lo que pide una lista
   de 40 entidades donde se elige una. Acá se recorren cientos de filas
   buscando un grupo: van planas, apretadas y con línea, como una planilla. Los
   selectores llevan las tres clases para ganarle a `.listaT` sin `!important`. */
.tabla.listaT.movT { border-spacing: 0; margin-top: 0; }
.tabla.listaT.movT thead th { box-shadow: inset 0 -1px 0 var(--border-strong); padding-top: var(--k3); padding-bottom: var(--k3); }
.tabla.listaT.movT tbody td {
  background: transparent; border-radius: 0; vertical-align: baseline;
  padding-top: 0.42rem; padding-bottom: 0.42rem;
  box-shadow: inset 0 -1px 0 var(--border);
}
.tabla.listaT.movT tr.nav:hover td { background: var(--paper-warm); }
.movT th.mvTilde, .movT td.mvTilde { width: 1.5rem; padding-right: 0; white-space: nowrap; }
.movT .mvTilde input { cursor: pointer; vertical-align: middle; margin: 0; }
.movT td.mvFecha { white-space: nowrap; color: var(--ink-muted); font-size: var(--t1); }
.movT td.mvConcepto { font-weight: 600; min-width: 10rem; color: var(--ink); }
/* Los textos de columna no parten la fila en dos renglones: se cortan, y el
   editor muestra el valor entero. */
.movT td.mvTexto { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; color: var(--ink-light); }
.movT td.mvProv { color: var(--ink-muted); }
.movT td.mvMonto { color: var(--tinta, var(--ink)); }
/* Tildada y señalada no se pintan igual (la trampa del estado y el hover): la
   tildada va en el acento suave, el hover en `--paper-warm`. */
.tabla.listaT.movT tr.tildada td, .tabla.listaT.movT tr.nav.tildada:hover td { background: var(--accent-soft); }
.movT tr.recien td { animation: recien 2.6s ease-out; }

/* ── los chips de la fila ──────────────────────────────────────────────────
   Proyecto, categoría y caja son valores Y puertas: tocarlos filtra por
   ellos. Cada uno con su forma, para que la fila se lea de un golpe: el
   proyecto es texto, la categoría una pastilla llena, la caja una pastilla
   de borde. */
.chipMv {
  font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer;
  display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; text-align: left; vertical-align: bottom;
}
.chipMv:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.chipMv.texto:hover { color: var(--accent); text-decoration: underline; }
.chipMv.vacio { color: var(--ink-subtle); }
.chipMv.cat, .chipMv.caja {
  font-size: var(--t1); line-height: 1.5; border-radius: var(--r-pill); padding: 0.02rem 0.55rem;
}
/* Mezcla sobre la tinta y no `--paper-warm`: ése es el fondo del hover de la
   fila, y la pastilla desaparecería justo al señalarla. */
.chipMv.cat { background: color-mix(in oklch, var(--ink) 7%, transparent); color: var(--ink-light); }
.chipMv.cat.aMano { box-shadow: inset 0 0 0 1px var(--border-strong); }
.chipMv.caja { box-shadow: inset 0 0 0 1px var(--border-strong); color: var(--ink-muted); }
.chipMv.cat:hover, .chipMv.caja:hover { box-shadow: inset 0 0 0 1px var(--accent); color: var(--accent); }

/* ── las filas nuevas ──────────────────────────────────────────────────────
   Acá sí hay celdas: una por columna, alineadas con la tabla. */
.tabla.listaT.movT tr.mvAgregar td { padding-top: 0.3rem; padding-bottom: 0.3rem; }
.mvMas {
  width: 1.15rem; height: 1.15rem; border-radius: 50%; padding: 0; cursor: pointer;
  border: 1px dashed var(--border-strong); background: none; color: var(--ink-muted);
  font-size: var(--t1); line-height: 1; display: inline-flex; align-items: center; justify-content: center;
}
.mvAgregarTexto {
  font-family: var(--ui); font-size: var(--t1); color: var(--ink-subtle); cursor: pointer;
  background: none; border: 0; padding: 0; width: 100%; text-align: left;
}
tr.mvAgregar:hover .mvMas, .mvMas:hover { border-style: solid; border-color: var(--accent); color: var(--accent); }
tr.mvAgregar:hover .mvAgregarTexto { color: var(--accent); }
.tabla.listaT.movT tr.mvNueva td {
  background: var(--accent-soft); box-shadow: none; vertical-align: middle;
  padding-top: 0.28rem; padding-bottom: 0.28rem;
}
.tabla.listaT.movT tr.mvNueva td + td { padding-left: var(--k2); }
.tabla.listaT.movT tr.mvNueva td:nth-child(2) { padding-left: var(--e4); }
.celdaMv {
  font-family: var(--ui); font-size: var(--t2); color: var(--ink); width: 100%; min-width: 0;
  height: 1.95rem; padding: 0 0.45rem;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-sm);
}
.celdaMv:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.celdaMv:disabled { background: transparent; border-color: var(--border); color: var(--ink-subtle); }
/* Los anchos los pone la COLUMNA, no la celda: un input trae su ancho propio
   (el `size`) y con cuatro en una fila la tabla se salía de la tarjeta y
   dejaba el monto afuera. `width: 0; min-width: 100%` hace que la celda no
   le pida nada a la columna y después la llene. */
.celdaMv:not(.num):not([type='date']) { width: 0; min-width: 100%; }
.celdaMv.num { font-family: var(--mono); text-align: right; width: 5.4rem; }
input[type='date'].celdaMv { width: 6.9rem; font-size: var(--t1); padding: 0 0.25rem; }
select.celdaMv { padding: 0 0.2rem; }
.movT td.mvNuevaAuto { font-size: var(--t1); color: var(--ink-subtle); text-align: left; }
.movT td.mvNuevaMonto { white-space: nowrap; }
/* El lado: un botón redondo con el signo, en el color de entró o salió. Se
   toca, o se escribe «+» o «−» adelante del monto. */
.ladoMv {
  font-family: var(--mono); font-size: var(--t2); font-weight: 600; cursor: pointer; margin-right: var(--k1);
  width: 1.6rem; height: 1.6rem; padding: 0; line-height: 1; vertical-align: middle;
  color: var(--tinta); background: var(--card); border: 1px solid currentColor; border-radius: 50%;
}
.ladoMv:hover { background: var(--tinta); color: var(--card); }
.ladoMv:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mvQuitar {
  background: none; border: 0; padding: 0; cursor: pointer; width: 1.15rem;
  color: var(--ink-subtle); font-size: var(--t3); line-height: 1;
}
.mvQuitar:hover { color: var(--negative); }
.tabla.listaT.movT tr.mvNuevaAviso td {
  background: var(--warn-soft); box-shadow: none; text-align: left;
  font-size: var(--t1); color: var(--ink-light); padding-top: 0.3rem; padding-bottom: 0.3rem;
}
.tabla.listaT.movT tr.mvNuevaPie td {
  background: var(--accent-soft); text-align: left; padding-top: var(--k2); padding-bottom: var(--k3);
  box-shadow: inset 0 -1px 0 var(--border-strong);
}
tr.mvNuevaPie .btn { margin-right: var(--k1); }
.mvNuevaTip { font-size: var(--t1); color: var(--ink-subtle); margin-left: var(--k2); }

.masMv { margin: var(--k3) var(--e4) 0; font-size: var(--t1); color: var(--ink-muted); }
.pieMv {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--e4); flex-wrap: wrap;
  padding: var(--k4) var(--e4) var(--e4); font-size: var(--t1); color: var(--ink-muted);
}
.pieMvSumas, .loteMvSumas { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: pre-wrap; }

/* La barra de lo tildado, pegada al pie de la ventana mientras haya tildes:
   con 200 filas, la acción no puede quedar debajo de todo. */
.loteMov {
  position: sticky; bottom: 0; z-index: 3;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--k2) var(--k3);
  padding: var(--k4) var(--e4); font-size: var(--t1);
  background: var(--card); border-top: 1px solid var(--border-strong);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  box-shadow: 0 -6px 14px -10px rgba(0, 0, 0, 0.25);
}
.loteMov[hidden] { display: none; }
.loteMov .sp { flex: 1; }
.loteMvN { font-size: var(--t2); }
.loteMvSumas { color: var(--ink-muted); }
.loteMvAccion { display: inline-flex; align-items: center; gap: var(--k1); }
.loteMvEstado { flex-basis: 100%; color: var(--ink-light); }
.loteMvEstado:empty { display: none; }

/* ── Extracto del banco (9/10): la tabla de «Saldos» con una tilde adelante ──
   Lo tildado va en tinta plena (`revPla`) y lo que no, apagado (`revSis`): se
   ve qué se va a cargar sin leer la columna de la tilde. */
.extT .cTilde { width: 2rem; }
.extT .cLin { width: 8rem; }
.extT .cEst { width: 16rem; }
.extT td.extTilde { padding-right: 0; }
.extT td.extTilde input { cursor: pointer; vertical-align: middle; margin: 0; }
.extT td.extTilde input:disabled { cursor: default; }
.extLineas {
  border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--ink-muted); white-space: nowrap;
}
.extLineas:hover { color: var(--ink); }
.extLineas:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* El detalle: las líneas del banco que suma la fila de arriba, en mono chico
   y en las mismas columnas — cada importe debajo del total. */
.extT tbody tr.extDetalle > td {
  border-top: 0; padding-top: 0.1rem; padding-bottom: 0.1rem;
  font-family: var(--mono); font-size: var(--t1); font-weight: 400; color: var(--ink-muted);
}
.extT tbody tr.extDetalle + tr:not(.extDetalle) > * { border-top: 1px solid var(--border); }
/* Lo que no está tildado se apaga entero, también el nombre. */
.extT tr.revSis .salCaja { color: var(--ink-muted); font-weight: 500; }
.extNotas { margin: var(--e3) 0 0; padding: 0; list-style: none; font-size: var(--t1); color: var(--ink-muted); }
.extNotas li + li { margin-top: 0.2rem; }
.extNotas .enlace { font: inherit; }
.extVacio { margin: var(--e3) 0 0; }
.extPie {
  display: flex; align-items: center; justify-content: flex-end; gap: var(--e3); flex-wrap: wrap;
  margin-top: var(--e3); padding-top: var(--e3); border-top: 1px solid var(--border);
}
.extSuma { font-family: var(--mono); font-size: var(--t2); color: var(--ink); }
.extPie .btn { min-width: 7rem; justify-content: center; }
@media (max-width: 62rem) {
  .salTarjeta > .cuerpo:has(.extT) { overflow-x: auto; }
  .extT { min-width: 48rem; }
}
