/* transRudo web — hoja de estilo única.
 *
 * NO contiene ni un solo color de la paleta. Los `--azul`, `--verde`, `--chip-*`… los emite
 * `web/app/ui.py` en un bloque `:root` generado desde `transrudo.palette`, que es el mismo módulo
 * del que la app de escritorio saca su QSS. Así un color no puede divergir entre las dos
 * interfaces: no hay dos sitios donde cambiarlo. Hay un test que prohíbe los literales aquí.
 *
 * Los valores que sí están escritos son los que NO son paleta: radios, sombras y los grises con
 * alfa de los focos.
 *
 * Un solo tema claro, a propósito: es una herramienta de trabajo de alto contraste, para gente que
 * no va a buscar un interruptor de tema.
 */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--fuente);
  font-size: 15px;
  line-height: 1.55;
  color: var(--texto);
  background: var(--fondo);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

/* Salta la navegación. Invisible hasta que se le da el foco con el tabulador. */
.saltar {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--azul);
  color: #FFF;
  padding: .6rem 1rem;
  z-index: 10;
  border-radius: 0 0 var(--r-boton) 0;
}
.saltar:focus { left: 0; }

/* --- cabecera / navegación ------------------------------------------------ */
.app-cabecera {
  background: var(--superficie);
  border-bottom: 1px solid var(--borde);
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: .7rem 1.25rem;
  flex-wrap: wrap;
}
.app-marca {
  font-weight: 800;
  font-size: 1.02rem;
  letter-spacing: -.01em;
  color: var(--azul);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.app-marca span {
  background: var(--azul);
  color: #FFF;
  width: 1.6rem; height: 1.6rem;
  border-radius: 5px;
  display: grid; place-items: center;
  font-size: .82rem;
  letter-spacing: 0;
}
.app-nav { display: flex; gap: .25rem; flex-wrap: wrap; flex: 1; }
.app-nav a {
  color: var(--texto-sec);
  text-decoration: none;
  padding: .35rem .7rem;
  border-radius: var(--r-boton);
  font-weight: 600;
  font-size: .9rem;
  white-space: nowrap;
}
.app-nav a:hover { background: var(--hover); color: var(--texto); }
.app-nav a[aria-current] { background: var(--azul-tinte); color: var(--azul); }
.app-cabecera-fin { display: flex; align-items: center; gap: .75rem; margin-left: auto; }
.app-cabecera form { margin: 0; }

/* El selector de cliente del superadmin. Era una insignia estática cuyo único enlace llevaba a
   /admin, donde el cambio de verdad era un botón al final de una tabla: para cambiar de cliente
   había que abandonar lo que estuvieras haciendo. Ahora la insignia ES el control. */
.app-cliente {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: var(--azul-tinte);
  border-radius: 20px;
  padding: .15rem .3rem .15rem .5rem;
  margin: 0;
  white-space: nowrap;
}
.app-cliente select {
  border: 0;
  background: transparent;
  color: var(--azul);
  font-size: .82rem;
  font-weight: 600;
  font-family: inherit;
  padding: .15rem 1.2rem .15rem .2rem;
  max-width: 11rem;
  cursor: pointer;
}
.app-cliente select:focus-visible { outline: 2px solid var(--azul); border-radius: var(--r-campo); }
.app-cliente .btn { padding: .15rem .55rem; font-size: .78rem; }

/* Para etiquetas que un lector de pantalla necesita y la vista no. */
.visualmente-oculto {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.app-cuenta {
  color: var(--texto-sec);
  font-size: .85rem;
  text-decoration: none;
  white-space: nowrap;
}
.app-cuenta:hover { color: var(--texto); text-decoration: underline; }

/* Una contraseña de un solo uso, para leerla en voz alta por teléfono sin equivocarse. Monoespacio
   y espaciada: el alfabeto de `auth.py` ya evita 0/O y 1/l, y esto acaba el trabajo. */
.clave-nueva {
  font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: .12em;
  background: var(--superficie);
  border: 1px solid var(--borde-med);
  border-radius: var(--r-campo);
  padding: .15rem .5rem;
  user-select: all;          /* un clic la selecciona entera */
}

/* --- contenedor / cajas --------------------------------------------------- */
.app-cuerpo { padding: 1.75rem 1.25rem 2.5rem; max-width: 68rem; margin: 0 auto; }
h1 { font-size: 1.45rem; font-weight: 700; letter-spacing: -.015em; margin: 0 0 .35rem; }
h2 { font-size: 1.05rem; font-weight: 700; margin: 0 0 .75rem; }
.sub { color: var(--texto-sec); margin: 0 0 1.5rem; font-size: .93rem; }
/* Una lista donde cada punto empieza por su chip de estado. Sin viñeta, porque el chip ya hace de
   marca y las dos juntas se estorban; con sangría colgante para que la segunda línea no se meta
   debajo del chip. */
.lista-motivos { list-style: none; padding: 0; margin: 0 0 1.5rem; display: grid; gap: .5rem; }
.lista-motivos li { padding-left: .1rem; }
p { margin: 0 0 .9rem; }
p:last-child { margin-bottom: 0; }
a { color: var(--azul); }

.caja {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--r-caja);
  padding: 1.25rem;
}
.caja > h2:first-child { margin-top: 0; }
.caja + .caja, .caja + .rejilla, .rejilla + .caja,
.caja + .desplegable, .desplegable + .caja { margin-top: 1.1rem; }
.rejilla { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }

.caja-accion {
  border-color: var(--azul);
  border-width: 2px;
  display: flex;
  flex-direction: column;
  gap: .8rem;
  align-items: flex-start;
}
.caja-peligro { border-color: var(--rojo); border-width: 2px; }
.caja-peligro > h2 { color: var(--rojo); }

/* El filtro del registro: una fila, no un formulario apilado. */
.filtro { display: flex; align-items: flex-end; gap: .75rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
.filtro .campo { margin: 0; min-width: 12rem; }

/* --- un lote de la bandeja de pendientes ---------------------------------- */
/* Una subida entera: qué es, qué se puede hacer con TODA ella, y los archivos detrás de un
   desplegable. La bandeja era una lista plana y dos meses sin facturar se veían como 140 filas. */
.lote + .lote { margin-top: .9rem; }
.lote-cabeza {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: .9rem;
}
.lote .desplegable { margin-top: 0; }
.lote .tabla-scroll { border: 0; border-radius: 0; }

/* La columna de marcar. Estrecha, y el área pinchable la da el propio checkbox aumentado: en un
   móvil una casilla del tamaño por defecto es imposible de acertar con el pulgar. */
th.marca, td.marca { width: 2.5rem; text-align: center; }
.marca input[type="checkbox"] { width: 1.15rem; height: 1.15rem; accent-color: var(--azul); }
th.marca .pista {
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  cursor: pointer;
  margin: 0;
}
/* La casilla maestra necesita JavaScript; sin él, marcar de una en una sigue funcionando. Igual
   que la zona de soltar archivos: la mejora se añade, no se exige. */
.marca-todos { display: none; }
.js .marca-todos { display: inline-block; }
/* Fuera de un `th`, la etiqueta entera se esconde con su casilla: si no, sin JavaScript quedaría el
   texto «Quitar todos» junto a un hueco vacío, prometiendo un mando que no está. */
.marca-todos-caja { display: none; }
.js .marca-todos-caja { display: flex; align-items: center; gap: .35rem; cursor: pointer; margin: 0; }

/* Una tabla de evidencia que no puede empujar la decisión fuera de la pantalla: se ve alrededor de
   una decena de filas y el resto se alcanza haciendo scroll DENTRO de la caja. La cabecera se queda
   pegada arriba, porque una tabla con scroll propio y sin cabecera visible son datos sin nombre. */
.tabla-limitada .tabla-scroll { max-height: 22rem; overflow-y: auto; overscroll-behavior: contain; }
.tabla-limitada thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--superficie);
}

/* --- botones -------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  font: inherit;
  font-weight: 600;
  border-radius: var(--r-boton);
  padding: .5rem 1rem;
  border: 1px solid var(--borde);
  background: var(--hover);
  color: var(--texto);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  touch-action: manipulation;
}
.btn:hover { background: var(--borde); }
.btn-pri { background: var(--azul); border-color: var(--azul-osc); color: #FFF; }
.btn-pri:hover { background: var(--azul-osc); }
.btn-ok { background: var(--verde); border-color: var(--verde-osc); color: #FFF; }
.btn-ok:hover { background: var(--verde-osc); }
.btn-fantasma { background: var(--superficie); color: var(--texto-sec); }
.btn-fantasma:hover { background: var(--hover); color: var(--texto); border-color: var(--borde-med); }
.btn-peligro { background: transparent; color: var(--rojo); border-color: var(--rojo); padding: .45rem .8rem; }
.btn-peligro:hover { background: var(--rojo-bg); }
.btn-grande { padding: .7rem 1.4rem; font-size: 1rem; }
/* Cuadrado, porque dentro sólo hay un dibujo: el nombre viaja en un .visualmente-oculto que el
   ancho de móvil saca a la vista (ver el @media del final). */
.btn-icono { padding: .45rem; }
.btn-icono svg { display: block; }
.btn:disabled { background: var(--borde); color: var(--texto-mudo); border-color: var(--borde); cursor: not-allowed; }
.btn:focus-visible, a:focus-visible, summary:focus-visible { outline: 2px solid var(--azul); outline-offset: 2px; }

/* --- distintivos de estado ------------------------------------------------ */
.chip {
  display: inline-block;
  border-radius: 4px;
  padding: .15rem .5rem;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
}
.chip-ok       { background: var(--chip-ok-bg);       color: var(--chip-ok-fg); }
.chip-atencion { background: var(--chip-atencion-bg); color: var(--chip-atencion-fg); }
.chip-error    { background: var(--chip-error-bg);    color: var(--chip-error-fg); }
.chip-cargado  { background: var(--chip-cargado-bg);  color: var(--chip-cargado-fg); }
.chip-neutro   { background: var(--chip-neutro-bg);   color: var(--chip-neutro-fg); }

/* --- avisos --------------------------------------------------------------- */
.aviso {
  border-radius: var(--r-caja);
  padding: .85rem 1.1rem;
  border: 1px solid;
  border-left-width: 4px;
  font-size: .93rem;
  margin: 0 0 1.1rem;
}
.aviso p { margin: 0; }
.aviso p + p { margin-top: .4rem; }
.aviso-error    { background: var(--rojo-bg);    border-color: var(--rojo);  color: var(--rojo-texto); }
.aviso-atencion { background: var(--ambar-bg);   border-color: var(--ambar); color: var(--ambar-texto); }
.aviso-ok       { background: var(--verde-bg);   border-color: var(--verde); color: var(--verde-texto); }
.aviso-info     { background: var(--azul-tinte); border-color: var(--azul);  color: var(--azul-texto); }

/* --- campos --------------------------------------------------------------- */
label { display: block; font-weight: 600; font-size: .89rem; margin-bottom: .3rem; }
input[type=text], input[type=date], input[type=email], input[type=password], select {
  font: inherit;
  padding: .45rem .6rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-campo);
  background: var(--superficie);
  color: var(--texto);
  max-width: 100%;
}
input:focus, select:focus { outline: none; border-color: var(--azul); box-shadow: 0 0 0 3px var(--azul-tinte); }
.campo { margin-bottom: 1rem; }
.campo .pista { color: var(--texto-sec); font-size: .82rem; font-weight: 400; margin: .25rem 0 0; }
.campo-ancho input[type=text] { width: 100%; }

.opcion {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  padding: .7rem .85rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-boton);
  margin-bottom: .6rem;
  background: var(--superficie);
}
.opcion:has(input:checked) { border-color: var(--azul); background: var(--azul-tinte); }
.opcion input[type=radio], .opcion input[type=checkbox] { margin-top: .35rem; flex: none; }
.opcion label { margin: 0; cursor: pointer; }
.opcion .pista { font-weight: 400; color: var(--texto-sec); font-size: .84rem; margin: .15rem 0 0; }
.opcion-cuerpo { flex: 1; min-width: 0; }

/* --- zona de arrastre ----------------------------------------------------- */
.soltar {
  border: 2px dashed var(--borde-med);
  border-radius: var(--r-caja);
  background: var(--superficie);
  padding: 2.25rem 1.25rem;
  text-align: center;
}
.soltar.activa { border-color: var(--azul); background: var(--azul-tinte); }
.soltar-icono { color: var(--borde-med); margin-bottom: .6rem; line-height: 0; }
.soltar strong { display: block; font-size: 1.05rem; margin-bottom: .25rem; }
.soltar .pista { color: var(--texto-sec); font-size: .88rem; margin: .1rem 0 0; }
.soltar-elegir {
  background: none; border: none; color: var(--azul);
  font: inherit; font-weight: 600; text-decoration: underline; cursor: pointer; padding: 0;
}
/* Sin JavaScript la zona de arrastre no puede funcionar, así que el <input> de siempre queda
   visible y el adorno se esconde. La subida sin JS sigue teniendo su test. */
.soltar-nativo { margin-top: .9rem; }
.js .soltar-nativo { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.js .soltar-adorno { display: block; }
.soltar-adorno { display: none; }

.recuento {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  background: var(--verde-bg);
  border: 1px solid var(--verde);
  border-radius: var(--r-boton);
  padding: .6rem .9rem;
  margin-top: .9rem;
  font-size: .92rem;
}
.recuento.excede { background: var(--ambar-bg); border-color: var(--ambar); }
.recuento b { font-variant-numeric: tabular-nums; }
.recuento .quitar { margin-left: auto; }

/* --- tablas --------------------------------------------------------------- */
.tabla-scroll {
  overflow-x: auto;
  border: 1px solid var(--borde);
  border-radius: var(--r-caja);
  background: var(--superficie);
}
table { border-collapse: collapse; width: 100%; font-size: .88rem; }
/* `vertical-align` por defecto de un `<td>` es `middle`. Mientras todas las celdas de una fila
   tienen una sola línea da igual — pero en cuanto una (el estado con su fecha debajo, o la
   plantilla con su fila de iconos debajo) ocupa dos líneas, la fila entera se estira a esa altura y
   TODAS las demás celdas —de una sola línea— quedan centradas dentro de ese hueco extra: los
   iconos de acción flotan a media altura con un espacio vacío encima y debajo, que es justo la caja
   roja que José marcó en las dos capturas. `top` alinea cada celda arriba, así el sobrante de
   altura se queda abajo, de forma predecible, en vez de repartirse alrededor del contenido corto. */
th, td { padding: .55rem .75rem; text-align: left; border-bottom: 1px solid var(--borde); vertical-align: top; overflow-wrap: anywhere; }
thead th {
  background: var(--hover);
  color: var(--texto-sec);
  font-weight: 700;
  font-size: .74rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
}
tbody tr:last-child td { border-bottom: none; }
td.n { text-align: right; font-variant-numeric: tabular-nums; }
tr.warn  td { background: var(--fila-atencion); }
tr.error td { background: var(--fila-error); }
/* Nunca poner esta clase directamente en un `<td>`: un `display:flex` en la celda misma hace que su
   caja deje de estirarse para llenar la altura de la fila —a diferencia de una celda normal, que
   siempre ocupa la fila entera aunque su contenido sea corto— así que su borde inferior queda por
   encima del de sus vecinas y la línea divisoria entre filas se ve cortada en ese tramo (visto en
   `main.py`, tres tablas, medido con varias filas: la caja de la celda quedaba ~10px corta en TODAS
   las filas). Ponerla siempre en un `<span>`/`<div>` DENTRO de un `<td>` normal — el patrón que ya
   usa la columna Plantilla. */
.acciones { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.acciones form { margin: 0; display: flex; gap: .4rem; align-items: center; }
/* Dentro de una tabla, `.acciones` no puede envolver: un contenedor flex con `flex-wrap: wrap`
   calcula su ancho mínimo como el del hijo más ancho (no la suma), así que la regla de abajo
   (`width: 1%`, «encógete a tu mínimo») lo tomaba al pie de la letra y apilaba cada botón en su
   propia línea — la fila se disparaba de alto y desalineaba toda la rejilla. Fuera de una tabla
   (diálogos de confirmación) `.acciones` sigue pudiendo envolver en móvil. */
table .acciones { flex-wrap: nowrap; }
/* La última columna (sin cabecera, con los botones de acción) no tiene ancho propio: sin esto se
   estira para absorber todo el espacio sobrante de la tabla y deja un hueco grande antes de los
   botones en vez de una rejilla apretada. `width: 1%` + `nowrap` es el truco estándar para «esta
   columna vale lo mínimo que necesita su contenido» — el sobrante pasa a las columnas de datos. Va
   antes del bloque de móvil para que `.tabla-tarjetas td { width: 100% }` (ahí abajo) siga ganando
   en pantallas estrechas por orden de aparición, sin necesitar su propio `@media` aquí.

   🔴 Acotado a `.tabla-acciones`, que `ui.tabla` pone cuando la última cabecera va vacía. Sin
   acotar agarraba la última columna de TODAS las tablas, incluidas las que terminan en texto
   libre: el «Detalle» del Historial y el «Motivo» de la bandeja de pendientes salían en una sola
   línea interminable que desbordaba la tabla y estrujaba las demás columnas. La regla mira lo que
   la columna ES, no dónde está. Lo vigila D12 en `tests/test_diseno.py`. */
table.tabla-acciones td:last-child,
table.tabla-acciones th:last-child { width: 1%; white-space: nowrap; }

/* --- pasos y progreso ----------------------------------------------------- */
.pasos { list-style: none; padding: 0; margin: 0 0 1.25rem; display: flex; gap: .4rem; flex-wrap: wrap; }
.pasos li {
  display: flex;
  align-items: center;
  gap: .4rem;
  color: var(--texto-mudo);
  font-size: .87rem;
  font-weight: 600;
  padding: .3rem .7rem .3rem .35rem;
  border-radius: 20px;
  background: var(--chip-neutro-bg);
}
.pasos li b {
  display: grid; place-items: center;
  width: 1.35rem; height: 1.35rem;
  border-radius: 50%;
  background: var(--borde);
  color: var(--superficie);
  font-size: .72rem;
}
.pasos li.hecho { color: var(--verde); background: var(--verde-bg); }
.pasos li.hecho b { background: var(--verde); }
.pasos li.activo { color: var(--azul); background: var(--azul-tinte); }
.pasos li.activo b { background: var(--azul); }

progress { width: 100%; height: 1.1rem; }
.reloj { color: var(--texto-sec); font-size: .88rem; font-variant-numeric: tabular-nums; }

.desplegable { border: 1px solid var(--borde); border-radius: var(--r-caja); background: var(--superficie); }
.desplegable > summary {
  padding: .75rem 1.1rem;
  cursor: pointer;
  font-weight: 600;
  font-size: .93rem;
  color: var(--azul);
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.desplegable > summary::-webkit-details-marker { display: none; }
.desplegable > summary::before { content: "\25B8"; font-size: .8rem; }
.desplegable[open] > summary::before { content: "\25BE"; }
.desplegable[open] > summary { border-bottom: 1px solid var(--borde); }
.desplegable .tabla-scroll { border: none; border-radius: 0; }
/* Un panel por factura de destino: la pregunta que trae al operador aquí es «¿de dónde salen?», y
   agrupadas se contesta sola. El separador es lo que impide que cuarenta filas de dos facturas
   distintas se lean como una sola lista. */
.grupo-duplicados + .grupo-duplicados { border-top: 1px solid var(--borde); }
.grupo-duplicados h4 { margin: 0; padding: .7rem .9rem .2rem; font-size: .92rem; }
.grupo-duplicados .pista { margin: 0; padding: 0 .9rem .5rem; }
.marcables > .marca-todos-caja { padding: .6rem .9rem 0; }

.vacio { text-align: center; padding: 2.5rem 1.25rem; color: var(--texto-sec); }
.vacio strong { display: block; color: var(--texto); font-size: 1.02rem; margin-bottom: .3rem; }

/* --- «elige un cliente»: la misma pantalla en TODAS las secciones ---------- */
/* El superadmin no pertenece a ningún cliente, así que toda pantalla que sea DE un cliente tiene
   que preguntar cuál. Cada sección lo hacía a su manera: dos con textos y botones distintos, dos
   con su propio desplegable dentro del formulario, y tres —/facturas entre ellas— devolviendo el
   JSON crudo de la negativa, que en un navegador es un callejón sin salida. El desplegable vive
   aquí, en la propia página que no se ha podido mostrar, y al elegir vuelves a ella. */
.elegir { max-width: 27rem; margin: 0 auto; }
.elegir .vacio { padding: 1.5rem .5rem 1.25rem; }
.elegir select { width: 100%; }
.elegir .btn { width: 100%; }

.resumen-linea { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; margin-bottom: 1.1rem; font-size: .95rem; }
.pie { margin-top: 1.5rem; color: var(--texto-sec); font-size: .88rem; }
.dato { font-variant-numeric: tabular-nums; font-weight: 700; }
.cifra { font-size: 1.35rem; }
.err { color: var(--rojo); }

/* --- gastos sueltos de la Pequeña ------------------------------------------ */
.gastos { border: 1px solid var(--borde); border-radius: var(--r-boton); padding: .85rem; margin: 1.1rem 0 0; }
.gastos legend { font-weight: 600; font-size: .89rem; padding: 0 .35rem; }
.gastos .pista { color: var(--texto-sec); font-size: .84rem; margin: 0 0 .75rem; }
.gasto { display: flex; gap: .75rem; flex-wrap: wrap; }
.gasto .campo { margin-bottom: .5rem; }
.gasto .campo:first-child { flex: 1 1 16rem; }
.gasto .campo:first-child input { width: 100%; }
.gasto .campo:last-child { flex: 0 0 7rem; }
.gasto .campo:last-child input { width: 100%; }

/* --- ficha de una factura -------------------------------------------------- */
/* Un <dl> y no una tabla: no son filas comparables entre sí, son los campos de una sola cosa. */
.datos { display: grid; grid-template-columns: auto 1fr; gap: .35rem 1.1rem; margin: .9rem 0 1.1rem; }
.datos dt { color: var(--texto-sec); font-size: .85rem; }
.datos dd { margin: 0; }
/* El encabezado de cada tanda: la marca de tiempo va dentro del titular, en gris, porque es lo que
   distingue una tanda de otra y fuera del titular se lee como si fuera otra cosa. */
.tanda { margin: 1.6rem 0 .5rem; font-size: 1rem; }
.tanda span { font-weight: 400; color: var(--texto-sec); font-size: .85rem; }

/* --- entrar --------------------------------------------------------------- */
.entrar { max-width: 22rem; margin: 5rem auto; padding: 0 1.25rem; }
.entrar .app-marca { justify-content: center; margin-bottom: 1.5rem; font-size: 1.2rem; }
.entrar .caja > * { width: 100%; }
.entrar input { width: 100%; margin-bottom: .8rem; }
.entrar .btn { width: 100%; }

/* --- móvil: la lista deja de ser tabla y pasa a fichas -------------------- */
@media (max-width: 40rem) {
  .app-cuerpo { padding: 1.25rem .9rem 2rem; }
  .app-nav { order: 3; width: 100%; }
  .tabla-tarjetas thead { display: none; }
  .tabla-tarjetas, .tabla-tarjetas tbody, .tabla-tarjetas tr, .tabla-tarjetas td { display: block; width: 100%; }
  .tabla-tarjetas tr { border-bottom: 1px solid var(--borde); padding: .5rem 0; }
  .tabla-tarjetas tr:last-child { border-bottom: none; }
  .tabla-tarjetas td { border: none; padding: .2rem .75rem; display: flex; gap: .75rem; }
  .tabla-tarjetas td::before {
    content: attr(data-col);
    color: var(--texto-sec);
    font-size: .74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    min-width: 6.5rem;
    padding-top: .15rem;
  }
  .tabla-tarjetas td:empty { display: none; }
  /* En ficha, tres iconos pelados en fila no se distinguen —y aquí sobra el ancho—, así que el
     nombre que el lector de pantalla ya leía se saca también a la vista. Es la MISMA etiqueta: no
     hay una segunda cadena que se pueda quedar desfasada. */
  .btn-icono { padding: .45rem .8rem; }
  .btn-icono .visualmente-oculto {
    position: static;
    width: auto; height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
  }
}

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

/* --- tarjetas de la ficha ------------------------------------------------ */
/* Una tarjeta = una cosa (D1). La cabecera lleva el nombre, el número y el estado; el estado vive
   con su sujeto y no en una tabla aparte (D2). */
.tarjeta-cabeza {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .5rem 1rem; flex-wrap: wrap; margin-bottom: .2rem;
}
.tarjeta-cabeza h3 { margin: 0; font-size: 1.02rem; display: flex; align-items: baseline; gap: .5rem; }
.tarjeta-num { color: var(--texto-sec); font-weight: 700; font-size: .95rem; }
.tarjeta-chips { display: flex; gap: .35rem; flex-wrap: wrap; }
.tarjeta > .acciones { margin-top: .9rem; }

/* La franja de Hacienda DENTRO de la tarjeta del documento al que se refiere. */
.hacienda {
  border-top: 1px solid var(--borde); margin-top: .9rem; padding-top: .75rem;
  font-size: .89rem; color: var(--texto-sec);
}
.hacienda b { color: var(--texto); font-weight: 600; }
.hacienda .dato { font-size: .85rem; }

/* «¿Qué toca ahora?»: una sola caja y una sola acción siguiente (D7). */
.toca { border-left: 4px solid var(--azul); }
.toca h2 { margin-bottom: .35rem; }
.toca p { color: var(--texto-sec); font-size: .93rem; }
.toca .acciones { margin-top: .9rem; }

/* --- diálogos ------------------------------------------------------------ */
/* `dialog:target` es la versión SIN JavaScript: el botón es un enlace de verdad a este id, así que
   sin script el navegador salta aquí y esta regla lo hace visible dentro de la página. Con script,
   `showModal()` lo saca por encima y `::backdrop` apaga el resto. */
.dlg {
  border: 1px solid var(--borde); border-radius: var(--r-caja); background: var(--superficie);
  color: var(--texto); padding: 1.25rem; max-width: 30rem; width: calc(100% - 2rem);
  overscroll-behavior: contain;
}
.dlg::backdrop { background: var(--velo); }
.dlg-titulo { margin: 0 0 .75rem; font-size: 1.05rem; }
.dlg .campo:last-of-type { margin-bottom: 1rem; }
.dlg input[type=text], .dlg input[type=file] { width: 100%; }
.dlg .acciones { justify-content: flex-end; }
dialog:target { display: block; }

@media (max-width: 40rem) {
  .tarjeta-cabeza { flex-direction: column; align-items: flex-start; gap: .4rem; }
}

/* --- el color dice la verdad (D11) --------------------------------------- */
/* El chip de salud de la ficha: ES el estado de la pantalla, así que pesa más que «Emitida». */
.chip-grande { font-size: .95rem; padding: .35rem .85rem; letter-spacing: .02em; }

/* La tira de pasos no tenía forma de decir que algo salió MAL: sólo «hecho» (verde) y «activo»
   (azul). Por eso «En Hacienda» salía en verde sobre una factura rechazada. */
.pasos li.fallo { color: var(--rojo); background: var(--rojo-bg); }
.pasos li.fallo b { background: var(--rojo); }

/* La caja «¿qué toca ahora?» se colorea por gravedad. Era azul siempre, también para contar que
   Hacienda había rechazado la factura. */
.toca-problema { border-left-color: var(--rojo); }
.toca-problema h2 { color: var(--rojo); }
.toca-falta { border-left-color: var(--ambar); }
.toca-ok { border-left-color: var(--verde); }
