/* Componentes base sancionados de Cristal.  v1.1.0
 *
 * FUENTE: platform/cristal-casa/public/styles.css del board de Cristal en
 * produccion, que es el manual de marca de facto (decision de Sam, 31-08-2026).
 * Cada bloque declara "origen: styles.css:N-M". Un bloque sin origen es una
 * DECISION CRISTAL y lo dice en su propio comentario.
 *
 * Todo color sale de un token. Ningun valor hexadecimal literal aca abajo que
 * no sea ya un valor de tokens.css: si aparece uno, el test de paleta lo
 * rechaza igual que en una extension.
 *
 * LO QUE NO SE EXTRAJO, A PROPOSITO: el pipeline NBB, el roadmap, la valuacion,
 * la hoja de impresion y las superficies de la casa (chips del muro, buscador,
 * bloqueo). Este paquete cubre las diez piezas del dashboard de empresa y nada
 * mas.
 */

/* ══ 1. Piezas originales v1.0.0, intactas ══════════════════════════════════
 * En uso por la extension Cobranza de demo-casa. No se tocan. */
.c-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 16px;
}
.c-tabla { width: 100%; border-collapse: collapse; }
.c-tabla thead th {
  background: var(--slate); color: var(--card);
  text-align: left; padding: 8px 10px; font-weight: 700;
}
.c-tabla tbody tr:nth-child(even) { background: var(--soft); }
.c-tabla td { padding: 8px 10px; border-top: 1px solid var(--line); }
.c-cifra { font-variant-numeric: tabular-nums; color: var(--ink); }
.c-cifra--neg { color: var(--neg); }
.c-cifra--pos { color: var(--pos); }
.c-eyebrow {
  color: var(--grey); letter-spacing: .08em;
  text-transform: uppercase; font-size: 12px;
}
.c-sello { color: var(--muted); font-size: 12px; }

/* ══ 2. Base de pagina ══════════════════════════════════════════════════════ */

/* origen: styles.css:7 y :14
 * [hidden] con !important: el board lo aprendio a los golpes, cualquier regla
 * de autor que fije display le gana al user agent y el elemento marcado
 * hidden se queda en pantalla sin decir nada. */
* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }

/* origen: styles.css:18-20
 * 14px de base y 1.5 de interlineado, fondo --soft, tinta --ink. */
body {
  font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.5;
  color: var(--ink); background: var(--soft); -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
}

/* ══ 3. Encabezado de pagina con indicador de periodo ════════════════════════
 * Componente 1 de 10. */

/* origen: styles.css:193-199 (.sthead). El encabezado formal del board:
 * tarjeta propia, no una banda suelta. h1 de 19px, razon social debajo, y la
 * metaline que lleva el periodo y la unidad monetaria. */
.enc {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 22px 26px; margin-bottom: 12px;
}
.enc h1 { font-size: 19px; margin-bottom: 2px; }
.enc .enc-legal { font-size: 12.5px; color: var(--slate); }
.enc .enc-meta {
  font-size: 12px; color: var(--slate); margin-top: 10px;
  display: flex; flex-wrap: wrap; gap: 6px 18px;
}

/* origen: styles.css:215-227 (.strip). La tira de confianza: veredicto,
 * frescura, version de contrato. Va bajo el encabezado. El fondo cambia solo
 * cuando el veredicto es no-go, y usa la semantica universal, nunca identidad. */
.tira-estado {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 26px; margin-bottom: 14px; font-size: 12px; color: var(--slate);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
}
.tira-estado .sep { color: var(--muted); }
.tira-estado .veredicto { font-weight: 700; letter-spacing: .03em; }
.tira-estado .veredicto.ok { color: var(--pos); }
.tira-estado .veredicto.no { color: var(--warn); }
.tira-estado .nota { color: var(--muted); }
.tira-estado[data-veredicto="no"] { background: var(--warn-bg); border-color: var(--warn-bg); }

/* origen: styles.css:2284-2291 (.snchip). La pastilla de periodo. En el board
 * vive en la cabecera de la vista Snapshot y dice la ventana que se esta
 * mirando. Es el indicador de PERIODO CERRADO. */
.periodo {
  display: inline-flex; align-items: center; height: 26px;
  padding: 0 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--card); font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--slate);
  white-space: nowrap;
}
/* origen: styles.css:2282-2283 (.snbandhead). Dos pastillas en una linea y
 * ninguna se estira. */
.periodo-fila {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px;
}
/* origen: styles.css:359-361 (.colbadge.validated / .open / .pending).
 * El estado de cierre que acompana al periodo. Semantica universal. */
.periodo-estado {
  display: inline-flex; align-items: center; height: 26px; padding: 0 12px;
  border-radius: 999px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; white-space: nowrap;
  line-height: 1; border: 1px solid transparent;
}
.periodo-estado.cerrado { color: var(--pos); background: var(--pos-bg); }
.periodo-estado.abierto { color: var(--warn); background: var(--warn-bg); }
.periodo-estado.pendiente { color: var(--slate); background: var(--soft); border-color: var(--line); }

/* DECISION CRISTAL v1.0.0, sin origen en el board.
 * Indicador de PERIODO EN CURSO, para las cuatro vistas de GESTION. El board
 * solo publica periodos cerrados y por eso no tiene esta forma. Se construye
 * con la escala de .periodo (26px de alto, 10.5px, .07em) y con la semantica
 * warn, que es la que el board ya usa para un mes abierto en styles.css:360.
 * Lleva SIEMPRE la fecha de corte: una cifra viva sin corte no se puede leer. */
.periodo.en-curso { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-bg); }
.periodo-corte { font-size: 11.5px; color: var(--muted); white-space: nowrap; }

/* ══ 4. Tarjeta KPI, con variacion contra el ano anterior ════════════════════
 * Componente 2 de 10.
 *
 * La tarjeta SI existe en el board: es .snfig, la celda de cifra de la vista
 * Snapshot. Lo que NO existe es un indicador de TENDENCIA (flecha, signo,
 * color de juicio), y su ausencia es deliberada: styles.css:2315-2317 y
 * snapshot.js:542-547 fijan la ley de que una comparacion se dice como
 * DISTANCIA y nunca con un adjetivo comparativo, porque un adjetivo sobre la
 * menor de dos lecturas se lee como veredicto y no tiene sujeto. */

/* origen: styles.css:2293-2298 (.snfigs).
 * TRES TARJETAS COMPARTIENDO CUATRO FILAS. subgrid, para que la etiqueta, la
 * cifra, su aritmetica y el pie caigan en las MISMAS cuatro lineas en las tres,
 * por largas que sean las palabras. Esta es la regla de "todas las tarjetas
 * nacen en la misma linea", y en el board es estructural, no un ajuste. */
.kpis {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
  grid-template-rows: auto auto auto auto;
  /* origen: styles.css:2276 (.snband). En el board el margen inferior lo pone
   * el envoltorio de la banda; aca va en la propia rejilla, que es la unica
   * pieza que se extrajo. Sin el, el bloque de abajo queda pegado. */
  margin: 0 0 22px;
}
/* origen: styles.css:2299-2301 (.snfig) */
.kpi {
  display: grid; grid-row: span 4; grid-template-rows: subgrid;
  border: 1px solid var(--line); border-radius: 12px; background: var(--card);
  padding: 16px 18px;
}
/* origen: styles.css:2302 (.snfigk) */
.kpi-etiqueta { font-size: 11.5px; color: var(--slate); align-self: end; }
/* origen: styles.css:2303-2305 (.snfigv .snder) */
.kpi-valor { align-self: end; padding-top: 6px; }
.kpi-valor > span {
  font-size: 27px; font-weight: 650; letter-spacing: -.015em;
  display: block; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
/* origen: styles.css:2306-2307 (.snfigo). La aritmetica, bajo la cifra. */
.kpi-como {
  font-size: 10.5px; color: var(--muted); line-height: 1.45;
  align-self: start; padding-top: 4px;
}
/* origen: styles.css:2308-2313 (.snfigm / .snfigml). El pie, separado por su
 * propia linea, con la etiqueta a la izquierda y el valor a la derecha. Aca
 * vive la variacion contra el ano anterior. */
.kpi-pie {
  font-size: 12.5px; color: var(--slate); align-self: end;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line);
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
}
.kpi-pie-etiqueta {
  font-size: 11px; color: var(--muted); letter-spacing: .04em;
  text-transform: uppercase;
}
/* origen: styles.css:2318-2319 (.snread-fig / .snder).
 * LEIDO: la tinta de la empresa. DERIVADO: nunca la misma tinta. */
.cifra-leida { color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 600; }
.cifra-derivada { color: var(--slate); font-variant-numeric: tabular-nums; }
/* origen: styles.css:2322-2323 (.snabs). AUSENTE es un punto, jamas un cero.
 * Un cero de verdad se escribe 0. */
.cifra-ausente { color: var(--muted); }
/* origen: styles.css:2440 (.snpend). Una regla que todavia no se acuerda lo
 * dice EN PALABRAS, porque una impresora en blanco y negro se come un relleno. */
.marca-pendiente {
  display: inline-block; font-size: 10px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--warn);
}

/* ══ 5. Tabla financiera ═════════════════════════════════════════════════════
 * Componente 3 de 10. origen: styles.css:229-391 y :622-643. */

/* origen: styles.css:237-238 (.tablecard). La tarjeta recorta y NUNCA
 * scrollea; el scroller de adentro es el unico contenedor con scroll de la
 * pagina, para que jamas haya una barra dentro de otra. */
.tabla-marco {
  position: relative; background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; overflow: hidden; max-width: 100%;
}
/* origen: styles.css:239-247 (.tablescroll). scroll-snap MANDATORY y no
 * proximity: proximity puede descansar entre dos puntos, que es exactamente la
 * media columna que este mecanismo existe para hacer imposible. */
.tabla-scroll {
  overflow-x: auto; max-width: 100%;
  scrollbar-width: thin; scrollbar-color: #CBD5E1 transparent;
  scroll-snap-type: x mandatory;
  scroll-padding-inline-start: var(--labelw, 0px);
}
/* origen: styles.css:250 */
.tabla-scroll:focus-visible { outline: 2px solid var(--info); outline-offset: -2px; }
/* origen: styles.css:255-259 */
.tabla-scroll::-webkit-scrollbar { height: 9px; }
.tabla-scroll::-webkit-scrollbar-track { background: var(--soft); }
.tabla-scroll::-webkit-scrollbar-thumb { background: #CBD5E1; border-radius: 999px; border: 2px solid var(--soft); }
.tabla-scroll::-webkit-scrollbar-thumb:hover { background: var(--slate); }

/* EL CONMUTADOR DE COLUMNA, para el telefono.
 *
 * DECISION: conmutador, no apilado. El board ya tiene exactamente este control
 * (.periodbar con .swopt, styles.css:174-181) para elegir QUE PERIODO esta en
 * pantalla, asi que no hay que inventar un lenguaje nuevo: es el mismo gesto
 * que un lector del board ya conoce. Y resuelve el problema de raiz, que era
 * que la segunda columna quedaba fuera de la pantalla: una columna esta entera
 * en pantalla o no esta, que es la ley que el board escribio en styles.css:285.
 * Apilar habria roto esa ley en vez de cumplirla.
 *
 * Fuera del telefono no existe: ahi caben las dos columnas. */
.conmutador { display: none; }

/* origen: styles.css:295-297 (table.statement). --colw manda el ancho de TODA
 * columna de valor: una columna esta entera en pantalla o no esta. */
table.financiera {
  border-collapse: separate; border-spacing: 0; font-size: 13px;
  table-layout: fixed; width: max-content; min-width: 100%;
  --colw: 138px; --badgeh: 36px; --labelmin: 220px;
}
/* origen: styles.css:298-301 */
table.financiera thead th {
  position: sticky; top: 0; background: var(--card); z-index: 3;
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--slate);
  font-weight: 600; padding: 10px 12px; border-bottom: 1px solid #CBD5E1;
  text-align: right; vertical-align: top; white-space: nowrap;
}
/* origen: styles.css:305. La columna de linea es sticky en el CUERPO y tiene
 * que serlo en la CABECERA tambien, o su titulo se va bajo los meses. */
table.financiera thead th.col-linea { text-align: left; left: 0; z-index: 5; }
/* origen: styles.css:309-311 */
table.financiera thead th.col-valor { width: var(--colw); min-width: var(--colw); }
/* origen: styles.css:319-321. LA RANURA DE MARGEN RESERVADA: toda fila lleva
 * el borde de 3px, transparente salvo en las marcadas, para que una fila
 * marcada mida EXACTAMENTE lo que mide una sin marcar. */
table.financiera tbody th {
  font-weight: 400; text-align: left; padding: 7px 12px 7px 9px;
  border-bottom: 1px solid var(--line); border-left: 3px solid transparent;
  background: var(--card); position: sticky; left: 0; z-index: 2;
}
/* origen: styles.css:324-326. Una sola regla manda el ancho de la columna de
 * etiqueta en cabecera y cuerpo, para que no puedan discrepar. */
table.financiera thead th.col-linea, table.financiera tbody th {
  width: var(--labelw, 220px); min-width: var(--labelw, 220px); max-width: var(--labelw, 220px);
}
/* origen: styles.css:327-333 */
table.financiera td { padding: 7px 12px; border-bottom: 1px solid var(--line); white-space: nowrap; }
td.num { text-align: right; font-variant-numeric: tabular-nums; }
td.num.negativo { color: var(--neg); }
td.num.acumulado { font-weight: 600; background: var(--soft); }
td.num.porcentaje { color: var(--slate); }
td.num.vacio { color: var(--muted); text-align: right; }
/* AUSENTE y NO APLICA son cosas distintas y se escriben distinto.
 * Ausente (.cifra-ausente, punto medio) dice "hay un dato y no lo tenemos".
 * No aplica (guion) dice "esta magnitud no existe para esta linea": un saldo
 * no tiene acumulado, porque acumular un stock no significa nada. El board ya
 * separa las dos ideas en styles.css:628-635, donde un total ausente lleva su
 * marca y una nota explica por que ausente no es "faltante". */
td.num.no-aplica { color: var(--muted); text-align: right; }
/* origen: styles.css:336. Un mes abierto es movimiento vivo, no un cierre:
 * tinta atenuada, distinta de la tinta plena de un mes cerrado y validado. */
td.num.abierto { color: var(--slate); }

/* origen: styles.css:376. Filas de grupo: nivel de tablero de un vistazo. */
table.financiera tr.n0 th, table.financiera tr.n0 td { font-weight: 700; background: var(--soft); }
/* origen: styles.css:377, :381-383. La fila desplegable dice en voz alta que
 * es un boton; el galon gira 90 grados al abrir. */
table.financiera tr.abrible th { cursor: pointer; }
table.financiera tr.abrible:focus-visible { outline: none; }
table.financiera tr.abrible:focus-visible th {
  box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--info); border-radius: 4px;
}
.galon { display: inline-block; width: 16px; color: var(--slate); transition: transform 120ms cubic-bezier(.2, 0, 0, 1); }
table.financiera tr.abrible[aria-expanded="true"] .galon { transform: rotate(90deg); }
/* origen: styles.css:384, :390-391 */
table.financiera tr.n1 th { padding-left: 32px; color: var(--slate); }
table.financiera tr.n1 td { color: var(--slate); }
table.financiera tr.n1 td.num.negativo { color: var(--neg); }

/* origen: styles.css:622-626. Un encabezado de seccion es una fila de
 * etiqueta que cruza la tarjeta, NUNCA una cifra: un encabezado no es un total. */
table.financiera tr.seccion th {
  text-align: left; font-size: 11px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--slate);
  background: var(--soft); padding: 8px 12px; border-bottom: 1px solid var(--line);
}
/* origen: styles.css:633. Subtotal de seccion. */
table.financiera tr.subtotal th, table.financiera tr.subtotal td { font-weight: 700; background: var(--soft); }
/* origen: styles.css:634-635. La nota dice POR QUE en palabras, para que
 * ausente no se lea nunca como "faltante" ni como "no hay".
 *
 * VIVE FUERA DEL SCROLLER, hermana de .tabla-scroll y no fila de la tabla.
 * Dentro, en una tabla mas ancha que la pantalla, la nota se cortaba a mitad de
 * frase y habia que arrastrarla para terminar de leerla. La prosa no se
 * arrastra, se lee. Medido el 31-08-2026 con sin-recorte-horizontal. */
.tabla-nota {
  padding: 8px 12px 12px; font-size: 11px; color: var(--muted);
  line-height: 1.5; border-top: 1px solid var(--line); margin: 0;
}
/* origen: styles.css:643 (tr.ifrsgrand). EL TOTAL GENERAL, mas pesado que un
 * subtotal: cierra el lado como un subtotal cierra una seccion.
 * EL FONDO DEL BOARD NO SE PUDO EXTRAER, porque el board usa ahi un literal
 * fuera de la paleta. Decision de Sam del 31-08-2026: se resuelve con los
 * tokens que ya existen, sin token nuevo. --line es el siguiente escalon de la
 * rampa despues de --soft, que es el fondo del subtotal, asi que el total pesa
 * mas que un subtotal sin inventar un color. */
table.financiera tr.total th, table.financiera tr.total td {
  font-weight: 700; background: var(--line);
}

/* ══ 6. Barra de avance ══════════════════════════════════════════════════════
 * Componente 4 de 10. origen: styles.css:2817-2872.
 *
 * LA BARRA NO SE LLENA, SE CUENTA: una celda por paso real, y ninguna avanza
 * por un temporizador. Una barra que se mueve sola es una cifra inventada con
 * otra forma. Ley del board, styles.css:2819-2822, y se hereda entera. */
.avance {
  /* El margen inferior es 22px, el que el board le da a un bloque apilado
   * (.snband, styles.css:2276). El board no lo necesita porque nunca pone una
   * tabla justo debajo de la barra; aca si, y sin el las dos tarjetas quedaban
   * a 0px. Cazado por bloques-con-aire el 31-08-2026. */
  margin: 16px 0 22px; padding: 14px 16px; background: var(--card);
  border: 1px solid var(--line); border-radius: 10px;
}
.avance:empty { display: none; }
/* origen: styles.css:2825-2828 */
.avance-top { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.avance-dice { flex: 1 1 260px; margin: 0; color: var(--ink); font-size: 12.5px; line-height: 1.55; }
.avance-reloj { margin: 0; color: var(--muted); font-size: 11.5px; white-space: nowrap; }
/* origen: styles.css:2830-2843 */
.avance-barra { display: flex; gap: 3px; margin: 10px 0 0; height: 8px; }
.avance-celda { flex: 1 1 0; min-width: 0; border-radius: 2px; background: var(--soft); border: 1px solid var(--line); }
.avance-celda.hecho { background: var(--slate); border-color: var(--slate); }
.avance-celda.cache { background: var(--muted); border-color: var(--muted); }
.avance-celda.fallo {
  background: repeating-linear-gradient(135deg, var(--muted) 0 2px, var(--card) 2px 5px);
  border-color: var(--line);
}
.avance-celda.omitido {
  background: repeating-linear-gradient(135deg, var(--line) 0 2px, var(--card) 2px 5px);
  border-color: var(--line);
}
.avance-celda.corriendo {
  border-color: var(--slate);
  background: repeating-linear-gradient(135deg, var(--line) 0 4px, var(--card) 4px 8px);
  animation: avancePan 1.1s linear infinite;
}
/* origen: styles.css:2846-2849 */
@keyframes avancePan { from { background-position: 0 0; } to { background-position: 11.3px 0; } }
/* origen: styles.css:2873-2875 */
@media (prefers-reduced-motion: reduce) { .avance-celda.corriendo { animation: none; } }
/* LA BARRA DE PROPORCION. DECISION CRISTAL v1.0.0, con las medidas de la barra
 * de pasos de arriba (8px de alto, radio 2px, relleno --slate sobre --soft).
 *
 * NO CONTRADICE la ley de "la barra no se llena, se cuenta". Lo que esa ley
 * prohibe es una barra que avanza sola por un temporizador. Esta muestra la
 * razon entre DOS CIFRAS MEDIDAS que estan las dos escritas en la misma vista,
 * y por eso el lector puede rehacer la division a mano. */
.avance-proporcion {
  height: 8px; margin: 10px 0 0; border-radius: 2px; overflow: hidden;
  background: var(--soft); border: 1px solid var(--line);
}
.avance-proporcion > span { display: block; height: 100%; background: var(--slate); }

/* origen: styles.css:2851-2871 */
.avance-pasos { list-style: none; margin: 12px 0 0; padding: 0; }
.avance-paso { position: relative; padding: 7px 0 7px 20px; font-size: 12px; line-height: 1.5; border-top: 1px solid var(--line); }
.avance-paso:first-child { border-top: 0; }
.avance-paso::before {
  content: ""; position: absolute; left: 3px; top: 13px;
  width: 7px; height: 7px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card); box-sizing: border-box;
}
.avance-paso.hecho::before { background: var(--slate); border-color: var(--slate); }
.avance-paso.cache::before { background: var(--muted); border-color: var(--muted); }
.avance-paso.corriendo::before { border: 2px solid var(--slate); background: var(--card); }
.avance-paso.omitido::before { border-color: var(--line); background: var(--card); }
.avance-que { display: block; color: var(--ink); }
.avance-estado { display: block; margin-top: 2px; color: var(--slate); font-size: 11.5px; }
.avance-paso.esperando .avance-que { color: var(--muted); }
.avance-paso.esperando .avance-estado { color: var(--muted); }

/* ══ 7. Botones y enlaces, con todos sus estados ═════════════════════════════
 * Componente 8 de 10. origen: styles.css:169-191, :688-694, :720-726. */

/* origen: styles.css:689-694 (.navlink). La pastilla del board: 999px de
 * radio, borde --line, texto --slate. En reposo, hover, activo y foco. */
.boton {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--slate);
  text-decoration: none; background: var(--card);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 14px;
  cursor: pointer; transition: all 150ms ease;
}
.boton:hover { border-color: #CBD5E1; color: var(--ink); }
.boton[aria-current="page"], .boton.activo {
  color: var(--card); background: var(--accent); border-color: var(--accent);
}
.boton:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }
/* origen: styles.css:724-725 (.rmbtn.primary). El boton principal usa la
 * ranura de identidad, que es senaletica y por eso esta permitido; jamas
 * toca un dato. */
.boton.principal { color: var(--card); background: var(--accent); border-color: var(--accent); }
.boton.principal:hover { background: var(--ink); border-color: var(--ink); }
/* DECISION CRISTAL v1.0.0: el board no declara un estado deshabilitado para
 * esta pastilla. Se construye con --muted, que es la tinta que el board ya usa
 * para todo lo que esta presente y no se puede accionar (styles.css:2870). */
.boton[disabled] { color: var(--muted); background: var(--card); border-color: var(--line); cursor: default; }
.boton[disabled]:hover { color: var(--muted); border-color: var(--line); }

/* origen: styles.css:169-173 (.swopt). La pastilla de vista, un punto mas
 * chica que un boton de accion. */
.pastilla {
  font-size: 12.5px; font-weight: 600; color: var(--slate); text-decoration: none;
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 16px;
  background: var(--card); cursor: pointer;
}
.pastilla.activa { color: var(--card); background: var(--accent); border-color: var(--accent); }
.pastilla:not(.activa):hover { border-color: #CBD5E1; color: var(--ink); }
.pastilla:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }

/* origen: styles.css:26-28 (.wordmark). El enlace de texto. */
.enlace { color: var(--ink); text-decoration: underline; }
.enlace:hover { color: var(--slate); }
.enlace:focus-visible { outline: 2px solid var(--info); outline-offset: 4px; border-radius: 3px; }

/* ══ 8. Estado vacio ═════════════════════════════════════════════════════════
 * Componente 6 de 10. origen: styles.css:141-146 (main > .empty).
 *
 * ES UNA TARJETA, y esta ACOTADA a la vista. En el board la regla esta scoped
 * a `main >` por una razon medida: `.empty` es tambien la clase de una cifra
 * ausente dentro de un estado financiero, y una caja de 28px de padding
 * alrededor de un punto convertia cada mes faltante en un widget. */
main > .vacio {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 28px; color: var(--slate); font-size: 13.5px;
}
/* origen: styles.css:151-156 (.fault). La superficie no pudo arrancar: una
 * tarjeta, no un aviso flotante. Se queda, se imprime, y lleva la linea que
 * un responsable necesita para actuar. Semantica warn, nunca identidad. */
.falla {
  background: var(--warn-bg); border: 1px solid var(--warn); border-radius: 12px;
  padding: 22px 24px; color: var(--ink); font-size: 13.5px; line-height: 1.6;
}
.falla strong { display: block; font-size: 15px; margin-bottom: 6px; }
.falla .detalle {
  margin-top: 12px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; color: var(--warn); word-break: break-word;
}

/* ══ 9. Menu vertical por secciones ══════════════════════════════════════════
 * Componente 5 de 10.
 *
 * DECISION CRISTAL v1.0.0. El board NO tiene menu vertical: navega con una
 * fila horizontal de pastillas (.topnav, styles.css:688). Los valores de aca
 * vienen del branch feature/nucleo-layout-vertical, donde ya estaban escritos,
 * y se apoyan en escalas que el board si declara:
 *   - el titulo de grupo sigue a .grouphead (styles.css:69-70): mayusculas,
 *     700, con espaciado de letra y tinta atenuada;
 *   - el item sigue a .navlink (styles.css:689) en tamano y peso;
 *   - el estado deshabilitado usa --muted, la tinta del board para lo presente
 *     y no accionable (styles.css:2870).
 * Los aprueba Sam en el ciclo visual, renderizados. */
.app { display: flex; min-height: 100vh; }
.lateral {
  width: 232px; flex: 0 0 232px; background: var(--card);
  border-right: 1px solid var(--line); display: flex; flex-direction: column;
}
/* EL ESPACIO DE IDENTIDAD DE LA EMPRESA. Es el UNICO lugar de toda la
 * superficie donde entra la identidad de la empresa, y entra de dos maneras y
 * de ninguna otra: una IMAGEN de logo y TEXTO. Ningun color ni tipografia
 * propios en el cromo, que es lo que hace que ocho empresas se vean como una
 * plataforma y no como ocho plantillas pintadas. El gate lo comprueba, y el
 * control negativo de la fase 8 ya demuestra que un color de marca en el CSS
 * de la empresa hace fallar gate/diseno con archivo, linea y valor. */
.marca {
  padding: 20px 20px 16px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px;
}
/* origen: styles.css:110-114 (.chip .mark). El board le da al logo de una
 * empresa un cuadro de 40 por 40 con radio 10 y la imagen contenida dentro.
 * Ese 40px es el techo del logo en escritorio.
 * NO ENCONTRADO: el relleno del cuadro. El board usa ahi un literal fuera de
 * la paleta, asi que el cuadro queda sin fondo propio, solo con su borde. */
.marca-logo {
  width: 40px; height: 40px; flex: none; border-radius: 10px;
  border: 1px solid var(--line); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.marca-logo img { max-width: 100%; max-height: 40px; object-fit: contain; padding: 4px; }
.marca-texto { min-width: 0; }
/* .08em y no .14em: origen styles.css:69-70 (.grouphead), que es el espaciado
 * de letra con el que el board escribe un titulo en mayusculas. A .14em un
 * nombre de doce letras no cabe en los 140px de texto que deja el lateral y se
 * parte en dos lineas. Medido el 31-08-2026, sobre el render. */
.marca-nombre {
  display: block;
  font-size: 15px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink);
}
/* EL ESLOGAN NO SE TRUNCA. Una linea, y si no cabe es que es demasiado largo
 * para este espacio: se cambia el eslogan, no se corta. Un eslogan cortado con
 * puntos suspensivos dice de la empresa exactamente lo contrario de lo que un
 * eslogan existe para decir. */
.marca-eslogan {
  display: block; margin-top: 3px;
  font-size: 11px; line-height: 1.35; color: var(--slate);
  white-space: normal; overflow: visible; text-overflow: clip;
}
.menu { flex: 1; padding: 14px 0; overflow-y: auto; }
/* sigue a styles.css:69-70 (.grouphead) */
.grupo-titulo {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); margin: 16px 20px 6px; font-weight: 700;
}
.menu button {
  display: block; width: 100%; text-align: left; cursor: pointer;
  font-family: inherit; font-size: 14px; color: var(--slate);
  background: none; border: 0; border-left: 3px solid transparent;
  padding: 8px 20px;
}
.menu button:hover { background: var(--soft); color: var(--ink); }
.menu button[aria-current="page"] {
  background: var(--soft); color: var(--ink); font-weight: 700;
  border-left-color: var(--slate);
}
.menu button:focus-visible { outline: 2px solid var(--info); outline-offset: -2px; }
/* Un modulo del catalogo que la empresa todavia no activo: presente, atenuado
 * y no accionable. Es como la empresa se entera de que puede pedirlo. */
.menu button[disabled] { color: var(--muted); cursor: default; }
.menu button[disabled]:hover { background: none; color: var(--muted); }
.disponible { font-size: 10px; color: var(--muted); margin-left: 6px; }
/* origen: styles.css:675-678 (footer.inst). EL SELLO VIVE EN EL PIE DE PAGINA,
 * no dentro del menu. En un telefono el lateral esta plegado, y un sello que
 * solo se ve abriendo el menu incumple el punto 9 de la lista de aceptacion.
 * El board ya lo tenia resuelto asi. Medido el 31-08-2026, con el gate en rojo. */
.pie-inst {
  border-top: 1px solid var(--line); margin-top: 56px; padding: 14px 28px;
  display: flex; justify-content: space-between; align-items: baseline;
  flex-wrap: wrap; gap: 6px 18px; font-size: 11px; color: var(--slate);
}
/* El sello de version. NO nombra a Cristal: identidad del holding fuera de la
 * superficie de la empresa (decision de Sam, 31-08-2026). */
.sello { color: var(--muted); font-size: 11px; margin: 0; }

/* La columna de contenido y su barra de titulo. */
.contenido { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* origen: styles.css:16-17 y :23. Pie pegado: el contenido crece, y en una
 * pagina corta el pie se apoya en el borde inferior en vez de flotar. */
.contenido main { flex: 1; }
.barra {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 18px 28px; background: var(--card);
  border-bottom: 1px solid var(--line);
}
.barra h1 { font-size: 20px; margin: 0; font-weight: 700; }
.barra-meta { margin: 0; font-size: 12px; color: var(--grey); }
/* origen: styles.css:21 (.wrap). 1080px es el ancho maximo de contenido del
 * board, y no cambia aca. */
main { padding: 24px 28px 40px; max-width: 1080px; }

/* ══ 10. Vista Snapshot: bloques del board ═══════════════════════════════════
 * Componente 9 de 10. origen: styles.css:2325-2343.
 * La tarjeta con cabecera propia y la tabla de lectura que el board usa para
 * mostrar las lineas como las publica la contabilidad de la empresa. */
.bloque {
  border: 1px solid var(--line); border-radius: 12px; background: var(--card);
  margin: 0 0 22px; overflow: hidden;
}
/* origen: styles.css:2327-2331 */
.bloque-cab {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; padding: 14px 20px; border-bottom: 1px solid var(--line);
  background: var(--soft);
}
.bloque-cab h2 {
  font-size: 12px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--slate); margin: 0; font-weight: 700;
}
.bloque-nota { font-size: 11.5px; color: var(--muted); }
/* origen: styles.css:2333-2343 (.sntab). La tabla de lectura: sin marco
 * propio, porque el bloque ya se lo da. */
.tabla-lectura { width: 100%; border-collapse: collapse; }
.tabla-lectura th {
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--slate); font-weight: 600; padding: 9px 20px; text-align: left;
}
.tabla-lectura td { font-size: 13px; color: var(--slate); padding: 9px 20px; border-top: 1px solid var(--line); }
.tabla-lectura tbody tr:first-child td { border-top: 0; }
.tabla-lectura .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla-lectura tr.fuerte td { color: var(--ink); font-weight: 650; background: var(--soft); }
.tabla-lectura tr.fuerte .cifra-leida, .tabla-lectura tr.fuerte td.num { color: var(--ink); }

/* ══ 11. Lista de Documentos ═════════════════════════════════════════════════
 * Componente 10 de 10. origen: styles.css:1566-1612. */
.doc-sum { font-size: 13px; color: var(--slate); margin: 0 0 16px; }
.doc-sum strong { color: var(--ink); font-weight: 700; }
/* origen: styles.css:1574-1583 */
.doc-grupo { border: 1px solid var(--line); border-radius: 12px; background: var(--card); margin-bottom: 10px; overflow: hidden; }
.doc-cab {
  display: flex; align-items: center; gap: 12px; padding: 13px 16px;
  cursor: pointer; background: none; border: 0; width: 100%; text-align: left; font: inherit;
}
.doc-cab:hover { background: var(--soft); }
.doc-cab:focus-visible { outline: 2px solid var(--info); outline-offset: -2px; }
.doc-titulo { font-weight: 700; font-size: 13.5px; color: var(--ink); }
.doc-cuenta { font-size: 11px; color: var(--grey); font-variant-numeric: tabular-nums; }
.doc-galon { margin-left: auto; color: var(--muted); transition: transform 150ms ease; font-size: 13px; }
.doc-grupo.abierto .doc-galon { transform: rotate(90deg); }
.doc-filas { display: none; }
.doc-grupo.abierto .doc-filas { display: block; }
/* origen: styles.css:1584-1589 */
.doc-fila {
  display: flex; align-items: center; gap: 13px; padding: 11px 16px;
  border: 0; border-top: 1px solid var(--line);
  background: none; width: 100%; text-align: left; font: inherit; cursor: pointer;
}
.doc-fila:hover { background: var(--soft); }
.doc-fila:focus-visible { outline: 2px solid var(--info); outline-offset: -2px; }
.doc-fila.ocupada { opacity: .6; cursor: progress; }
.doc-fila.fallida { background: var(--neg-bg); }
/* origen: styles.css:1590-1593 */
.doc-tipo {
  flex: 0 0 auto; font-size: 9px; font-weight: 700; letter-spacing: .05em;
  padding: 4px 6px; border-radius: 6px; background: var(--soft);
  border: 1px solid var(--line); color: var(--slate); min-width: 42px; text-align: center;
}
.doc-tipo.pdf { color: var(--neg); }
.doc-tipo.doc { color: var(--info); }
/* origen: styles.css:1594-1597 */
.doc-meta { min-width: 0; display: flex; flex-direction: column; }
.doc-nombre { font-size: 13.5px; color: var(--ink); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doc-sub { font-size: 11.5px; color: var(--grey); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doc-fecha { margin-left: auto; flex: 0 0 auto; font-size: 12px; color: var(--grey); font-variant-numeric: tabular-nums; padding-left: 10px; }
/* LA SUBIDA DE UN DOCUMENTO. Estructura y estilos, sin logica: el contrato de
 * almacenamiento vive en documentos-contrato.md de la skill y lo implementa
 * otra fase.
 * NO HAY ACCION DE ELIMINAR EN NINGUNA PARTE, y no es un olvido: un documento
 * publicado no se borra, se reemplaza por una version nueva y la anterior
 * queda. El gate lo comprueba. */
.doc-subir {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 11px 16px; border: 0; border-top: 1px dashed var(--line);
  background: none; text-align: left; font: inherit; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--slate);
}
.doc-subir:hover { background: var(--soft); color: var(--ink); }
.doc-subir:focus-visible { outline: 2px solid var(--info); outline-offset: -2px; }
.doc-subir[disabled] { color: var(--muted); cursor: default; }
.doc-subir[disabled]:hover { background: none; color: var(--muted); }
/* Los cuatro estados de una fila que paso por la subida. Cada uno se dice
 * ademas EN PALABRAS en el subtitulo de la fila, porque un relleno es un
 * estado que hay que decodificar y una impresora en blanco y negro se lo come. */
.doc-fila.subiendo { opacity: .6; cursor: progress; }
.doc-fila.publicado .doc-estado { color: var(--pos); }
.doc-fila.fallida .doc-estado { color: var(--neg); }
.doc-fila.reemplazado .doc-nombre { color: var(--slate); }
.doc-fila.reemplazado .doc-estado { color: var(--muted); }
.doc-estado {
  font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; margin-top: 2px;
}

/* origen: styles.css:1609-1611. Un cajon vacio lo dice, y su titulo se atenua. */
.doc-grupo.vacia .doc-titulo { color: var(--muted); font-weight: 600; }
.doc-grupo.vacia .doc-galon { visibility: hidden; }
.doc-ninguno { font-size: 12.5px; color: var(--muted); padding: 11px 16px; border-top: 1px solid var(--line); }

/* ══ 12. Telefono ════════════════════════════════════════════════════════════
 * Componente 7 de 10: el menu movil desplegable.
 *
 * DECISION CRISTAL v1.0.0 en cuanto al DESPLEGABLE: el board no tiene uno, su
 * fila horizontal envuelve o scrollea (styles.css:840, :1318). El mecanismo de
 * apertura viene del branch feature/nucleo-layout-vertical.
 * LO QUE SI ES DEL BOARD y se hereda entero:
 *   - la ley de los 44px de alto minimo para todo control tocable
 *     (styles.css:1429-1433), medida por el board a un costo concreto;
 *   - el reajuste de la tabla financiera en pantalla angosta
 *     (styles.css:841-845): la tabla sigue siendo una tabla, las etiquetas de
 *     fila quedan visibles y la PAGINA nunca scrollea a lo ancho;
 *   - los paddings reducidos de encabezado y tira (styles.css:846-847). */

/* LA BARRA SUPERIOR DEL TELEFONO. Reemplaza al boton flotante que habia antes.
 *
 * POR QUE SE CAMBIO: un boton flotante TAPA. Medido el 31-08-2026 con la regla
 * control-fijo-sobre-contenido: tapaba el valor de Total patrimonio en Balance,
 * la cabecera de la tabla en Finanzas y en Resumen, el sello en Mes en curso y
 * el cajon de Actas en Documentos. Una barra de alto fijo no tapa nada, porque
 * el contenido le reserva su alto.
 *
 * VA ANTES del media query, no despues: con la misma especificidad gana el
 * ultimo, y puesta abajo apagaba la barra tambien a 390px. */
.barra-superior { display: none; }
.menu-boton { display: none; }

/* origen: styles.css:659, :834 (el board quiebra en 640px).
 * 760px es DECISION CRISTAL: el menu lateral de 232px mas una tabla de --colw
 * 138px con etiqueta de 220px no caben juntos bajo ese ancho. */
@media (max-width: 760px) {
  .app { flex-direction: column; }
  .lateral {
    width: 100%; flex: none; border-right: 0; border-bottom: 1px solid var(--line);
    display: none;
  }
  .lateral.abierto { display: flex; }
  .barra { padding: 14px 16px; }
  .pie-inst { padding: 14px 16px; margin-top: 32px; }
  /* El logo baja a 32px: en un telefono la cabecera es el espacio mas caro que
   * hay, y el board ya paga ese precio en su propia cabecera (styles.css:29-32). */
  .marca-logo { width: 32px; height: 32px; border-radius: 8px; }
  .marca-logo img { max-height: 32px; }
  .barra h1 { font-size: 17px; }
  /* 76px de relleno inferior vivian aca porque un boton flotaba en esa esquina.
   * El boton se fue a la barra superior el 31-08-2026 y el hueco se quedo: un
   * relleno que ya no reserva nada es una cicatriz, no una decision. */
  main { padding: 16px 16px 32px; }

  .conmutador {
    display: flex; gap: 8px; padding: 10px 12px;
    border-bottom: 1px solid var(--line); background: var(--soft);
  }
  /* UNA COLUMNA ENTERA, O NINGUNA. Se cuenta por posicion y no por atributo en
   * cada celda: la columna 1 es la etiqueta de linea, la 2 el mes y la 3 el
   * acumulado. Las filas de seccion llevan colspan y no tienen tercera celda,
   * asi que no les pasa nada. */
  .conmutable[data-col="0"] tr > :nth-child(3),
  .conmutable[data-col="1"] tr > :nth-child(2) { display: none; }
  .conmutable table.financiera, .conmutable table.tabla-lectura { width: 100%; }

  /* En Documentos el nombre pasa a dos lineas y la fecha baja bajo el estado.
   * A una columna, un nombre de archivo no cabe en una linea, y cortarlo obliga
   * a adivinar cual es. Medido el 31-08-2026 con nombres-cortados. */
  .doc-fila { flex-wrap: wrap; align-items: flex-start; }
  .doc-nombre, .doc-sub { white-space: normal; overflow: visible; text-overflow: clip; }
  .doc-fecha { flex: 1 1 100%; margin-left: 55px; padding-left: 0; margin-top: 3px; }

  /* origen: styles.css:841-845. La tabla se aprieta, no se rompe. */
  table.financiera { --colw: 124px; --badgeh: 46px; --labelmin: 150px; }
  table.financiera tbody th { white-space: normal; }
  table.financiera thead th, table.financiera td { padding-left: 9px; padding-right: 9px; }
  /* origen: styles.css:846-847 */
  .enc { padding: 16px 16px; }
  .tira-estado { padding: 10px 16px; }

  /* origen: styles.css:2297 adaptado: tres columnas de tarjeta no caben en un
   * telefono. Una sola columna conserva el subgrid y por lo tanto la ley de
   * que las tarjetas nacen en la misma linea. */
  .kpis { grid-template-columns: 1fr; }
  .kpi-valor > span { font-size: 21px; }

  /* LA LEY DE LOS 44px. origen: styles.css:1429-1433. */
  .boton, .pastilla { min-height: 44px; display: inline-flex; align-items: center; }
  .menu button { min-height: 44px; }
  .doc-fila, .doc-cab, .doc-subir { min-height: 44px; }

  /* 44px, el mismo piso que la ley de toque del board (styles.css:1429). */
  .barra-superior {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    position: fixed; top: 0; left: 0; right: 0; height: 44px; z-index: 20;
    background: var(--card); border-bottom: 1px solid var(--line); padding: 0 4px 0 14px;
  }
  .barra-superior-nombre {
    font-size: 12px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--ink);
    white-space: nowrap; overflow: hidden; text-overflow: clip; min-width: 0;
  }
  /* El contenido RESERVA el alto de la barra. Es la diferencia entre una banda
   * y algo que flota encima. */
  body { padding-top: 44px; }
  .app { min-height: calc(100vh - 44px); }
  .menu-boton {
    display: block; position: static; height: 44px; min-height: 44px;
    font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
    background: none; color: var(--slate);
    border: 0; padding: 0 14px;
  }
  .menu-boton[aria-expanded="true"] { color: var(--ink); }
  .menu-boton:focus-visible { outline: 2px solid var(--info); outline-offset: -2px; }
}

/* origen: styles.css:862. Nada se mueve para quien pidio que no se mueva. */
@media (prefers-reduced-motion: reduce) { * { transition-duration: .01ms !important; } }
