/*
 * El tablero. Una hoja, porque son cinco pantallas y comparten casi todo.
 *
 * Ni un valor literal: todo sale de `tokens.css`. Es la regla que hace que
 * cambiar de marca sea cambiar un archivo, y no se empieza uno nuevo tirándola.
 *
 * El aire de los lados sale de `--aire` y de ningún otro sitio. Cuando cada
 * pantalla lo ponía por su cuenta no coincidían, y una columna que no es recta
 * se nota aunque no se sepa qué se está mirando.
 */

* { box-sizing: border-box; }

/* `scrollbar-gutter: stable` reserva el hueco de la barra de scroll SIEMPRE, haya
   o no contenido que desborde: sin esto, el contenido salta a la izquierda cuando
   la barra aparece (al pasar de una pantalla corta a una larga). */
html { height: 100%; scrollbar-gutter: stable; }

body {
  --aire: var(--space-8);
  /* El ancho de la columna. Todo lo que se lee vive dentro de ella y la
     columna vive en el centro: pegado a los bordes de una pantalla ancha, el
     ojo tiene que viajar de una punta a la otra para leer una fila.

     El número NO es redondo: son exactamente las cuatro tarjetas de la portada
     con sus tres huecos (4 × 13rem + 3 × 1rem). Así la portada llena la columna
     en vez de quedarse centrada DENTRO de ella, que era de donde salía que el
     margen de la portada no fuera el mismo que el de las demás pantallas. */
  --columna: 55rem;
  margin: 0;
  min-height: 100%;
  /* El color va debajo y el cielo encima, separados y no en el atajo
     `background`: si el navegador no entendiera el cielo, el atajo se llevaría
     por delante también el color y dejaría todo sobre blanco. */
  background-color: var(--color-canvas);
  background-image: var(--color-sky);
  background-attachment: fixed;
  background-repeat: no-repeat;
  color: var(--color-ink);
  font: var(--weight-normal) var(--text-md)/1.5 var(--font-ui);
  -webkit-font-smoothing: antialiased;
}
@media (max-width: 48rem) { body { --aire: var(--space-5); } }

/*
 * El centrado, en un solo sitio.
 *
 * `max(aire, mitad de lo que sobra)`: mientras la ventana sea estrecha manda el
 * aire de siempre, y en cuanto pasa del ancho de la columna manda el centrado.
 * Va en el relleno y no en un `margin: auto` sobre un envoltorio para que la
 * cabecera —que sí ocupa todo el ancho, con su línea de abajo de punta a
 * punta— alinee su contenido con el del centro. Con dos anchos distintos, el
 * título de la sección y lo que hay debajo no arrancan en la misma vertical, y
 * eso se nota sin saber qué se está mirando.
 */
.t-head, .t-main {
  padding-inline: max(var(--aire), calc((100% - var(--columna)) / 2));
}

h1, h2, p, figure { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }

.t-svg { width: var(--space-6); height: var(--space-6); }

/* ── Cabecera ─────────────────────────────────────────────────────────────── */
.t-head {
  display: flex; align-items: center; gap: var(--space-3);
  padding-block: var(--space-4);
  border-bottom: 1px solid var(--color-line);
  background: var(--color-surface);
  /* Fija arriba: al desplazar cualquier pantalla, la cabecera sigue a la vista.
     Por encima del contenido pero por debajo de los modales (su velo va más alto). */
  position: sticky; top: 0; z-index: 20;
}
.t-head-mark {
  width: var(--space-5); height: var(--space-5);
  border-radius: var(--radius-sm);
  background: var(--color-accent);
}
.t-head-t { font-size: var(--text-lg); font-weight: var(--weight-bold); letter-spacing: -.01em; }
.t-head-gap { flex: 1; }
.t-head-op { font-size: var(--text-xs); color: var(--color-ink-faint); }
/* «Salir» (solo en modo alojado): discreto, a la derecha del nombre. Compacto
   para no crecer el alto de la cabecera. */
.t-head-salir { padding-block: var(--space-1); padding-inline: var(--space-3); font-size: var(--text-xs); }
/* Del mismo alto que el cuadrito de la portada, y los dos MÁS BAJOS que la
   línea del título: así el título es quien manda en el alto de la cabecera y
   esta mide lo mismo en las cinco pantallas. Con el botón a 32px la cabecera
   crecía cinco píxeles al salir de la portada, que es de esos saltos que se
   notan sin saber qué se ha movido. */
.t-back {
  display: inline-grid; place-items: center;
  width: var(--space-6); height: var(--space-6);
  border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--color-ink-soft); cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease),
              color var(--motion-fast) var(--motion-ease);
}
.t-back:hover { background: var(--color-surface-sunk); color: var(--color-ink); }
.t-back .t-svg { width: var(--space-5); height: var(--space-5); }

/* ── El centro ────────────────────────────────────────────────────────────── */
/* `position: relative` para poder subir la fila de acciones del módulo (la
   `.t-barra`) a la altura del título, en vez de dejarla en una línea propia
   debajo. Ver `.t-barra` más abajo. */
.t-main { padding-block: var(--space-7); position: relative; }

.t-cargando, .t-vacio {
  padding: var(--space-8) 0;
  text-align: center; color: var(--color-ink-faint);
}
.t-vacio b { display: block; color: var(--color-ink); font-size: var(--text-lg); }
.t-vacio p { max-width: 34rem; margin: var(--space-3) auto 0; line-height: 1.6; }
.t-vacio.is-bad b, .t-vacio.is-bad { color: var(--color-danger); }
.t-roto {
  max-width: 34rem; margin: var(--space-8) auto; padding: var(--space-6);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); text-align: center;
}
.t-roto p { margin-top: var(--space-3); color: var(--color-ink-faint); }

/* ── La portada ───────────────────────────────────────────────────────────── */
/* Centrada en los dos ejes, con columnas de ancho FIJO: con `1fr` las cuatro se
   repartirían la pantalla y cada una sería un rectángulo enorme con tres
   palabras dentro. */
.t-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, 13rem);
  justify-content: center; align-content: center;
  gap: var(--space-5);
  min-height: 60vh;
}
.t-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2);
  aspect-ratio: 1;
  padding: var(--space-5);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  text-align: left; cursor: pointer;
  transition:
    border-color var(--motion-fast) var(--motion-ease),
    box-shadow var(--motion-fast) var(--motion-ease),
    transform var(--motion-fast) var(--motion-ease);
}
.t-card:hover {
  border-color: var(--color-line-strong);
  box-shadow: var(--shadow-3);
  transform: translateY(-3px);
}
.t-card:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.t-card-ic {
  display: inline-flex;
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-accent-tint); color: var(--color-accent);
}
.t-card-t { font-size: var(--text-xl); font-weight: var(--weight-semibold); }
/* La nota va PEGADA al título y no anclada abajo, que es lo que abría un hueco
   en mitad de la tarjeta. Anclarla no alineaba nada que no estuviera ya
   alineado: encima solo hay el icono y una línea de título, iguales en las
   cuatro, así que las cuatro notas arrancan a la misma altura igual. */
.t-card-n {
  font-size: var(--text-xs); color: var(--color-ink-faint); line-height: 1.5;
}

/* ── Inicio: el buscador arriba y las puertas debajo ──────────────────────── */
/* El buscador (que filtra las cards a la vista) va centrado y redondeado encima
   de la rejilla. Con él, la rejilla ya no se centra sola en 60vh: manda el flujo. */
.t-inicio { display: flex; flex-direction: column; gap: var(--space-6); }
.t-buscar { width: 100%; max-width: 26rem; margin: 0 auto; }
.t-buscar-in {
  width: 100%; padding: var(--space-3) var(--space-5);
  border: 1px solid var(--color-line); border-radius: 999px;
  background: var(--color-surface); color: var(--color-ink);
}
.t-buscar-in:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
/* La rejilla ocupa el ancho (ella ya centra sus columnas); sin esto, dentro del
   flex se encogería a una sola columna. */
.t-inicio .t-grid { width: 100%; min-height: auto; }
/* El buscador filtra ocultando cards con el atributo `hidden`. Como `.t-card` es
   `display:flex`, gana al `display:none` que el navegador le da a `[hidden]` (misma
   especificidad, y el autor manda), así que ocultarlas no hacía NADA. Esto lo
   arregla: una card oculta, oculta de verdad. */
.t-card[hidden] { display: none !important; }

/* El título grande del módulo, arriba de cada pantalla (no en el inicio, que ya
   tiene sus cards). Dice dónde estás con todas las letras, además de la miga. */
.t-titulo {
  font-size: var(--text-2xl, var(--text-xl)); font-weight: var(--weight-bold);
  letter-spacing: -.02em; margin-bottom: var(--space-6);
  /* Alto de línea fijo: la fila de acciones (`.t-barra`) se sube a esta misma
     banda y se centra contra ella, así el botón «Actualizar» queda al ras del
     título. */
  line-height: 2rem; min-height: 2rem;
}

/* ── Miga de pan y acento del negocio en la cabecera ──────────────────────── */
/* Dentro de un negocio, la cabecera dice dónde estás (`Inicio › Negocio › Sección`)
   y lleva un filo del color del negocio, para que se note sin leerlo que estás
   «dentro» y no en la red. El color sale de `--negocio-hue` (lo pone el armazón). */
.t-head.is-negocio { box-shadow: inset 0 -3px 0 0 hsl(var(--negocio-hue, 220) 60% 50% / .85); }
/* Se le da aire: la miga se sentía pequeña y apretada. Más hueco entre escalones
   y separadores, y un cuerpo algo mayor, sin que la cabecera crezca de más. */
.t-migas { display: flex; align-items: center; gap: var(--space-4); min-width: 0; overflow: hidden; }
.t-miga {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: 0; border: 0; background: none; cursor: pointer;
  font-size: var(--text-xl); font-weight: var(--weight-bold); letter-spacing: -.01em;
  color: var(--color-ink-soft); white-space: nowrap;
}
.t-miga-sep { margin-inline: var(--space-1); }
.t-miga:hover { color: var(--color-ink); }
.t-miga.is-actual { color: var(--color-ink); cursor: default; }
.t-miga-sep { color: var(--color-ink-faint); }
.t-miga-punto {
  width: .6rem; height: .6rem; border-radius: 50%; flex: 0 0 auto;
  background: hsl(var(--negocio-hue, 220) 55% 50%);
}

/* ── Negocios: las puertas a cada negocio ─────────────────────────────────── */
.t-negocios {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: var(--space-4);
}
.t-negocio {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2);
  padding: var(--space-5); text-align: left; cursor: pointer;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md); background: var(--color-surface);
  transition: border-color var(--motion-fast) var(--motion-ease),
              box-shadow var(--motion-fast) var(--motion-ease),
              transform var(--motion-fast) var(--motion-ease);
}
.t-negocio:hover { box-shadow: var(--shadow-3); transform: translateY(-2px); }
.t-negocio:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.t-negocio-top { display: flex; align-items: center; gap: var(--space-3); width: 100%; }
.t-negocio-punto {
  width: .6rem; height: .6rem; border-radius: 50%; flex: 0 0 auto;
  background: hsl(var(--negocio-hue, 220) 55% 50%);
}
.t-negocio-t { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.t-negocio-nota { font-size: var(--text-xs); color: var(--color-ink-soft); line-height: 1.5; }
.t-negocio-nota.is-none { color: var(--color-ink-faint); font-style: italic; }
.t-negocio-datos { font-size: var(--text-2xs); color: var(--color-ink-faint); }

/* ── Configuración del negocio: el panel de «Compartir» ───────────────────── */
/* La pestaña Compartir enseña el enlace de recomendación y su QR en un panel. La
   pestaña General usa el formulario normal (`.t-form`) con su «Guardar» fijo. */
.t-panel {
  padding: var(--space-5);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); max-width: 38rem;
}
.t-recomendar-fila { display: flex; gap: var(--space-2); }
.t-recomendar-qr { width: 200px; max-width: 70vw; margin: var(--space-4) auto var(--space-2); }
.t-guardado { align-self: center; color: var(--color-ok); font-size: var(--text-sm); font-weight: var(--weight-semibold); }

/* ── Listas de fichas (pagos, cocinas) ────────────────────────────────────── */
.t-lista {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
  gap: var(--space-4);
}
.t-item {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.t-item-top { display: flex; align-items: center; gap: var(--space-3); }
.t-item-t { font-size: var(--text-lg); font-weight: var(--weight-semibold); }
.t-item-datos {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  font-size: var(--text-2xs); color: var(--color-ink-faint);
}
.t-item-nota {
  flex: 1;
  font-size: var(--text-xs); color: var(--color-ink-soft); line-height: 1.6;
}
.t-item-nota b { color: var(--color-ink); font-weight: var(--weight-semibold); }
.t-item-nota.is-none { color: var(--color-ink-faint); font-style: italic; }
.t-item-acts { display: flex; gap: var(--space-3); }
/* El importe destaca porque es la cifra que decide. */
.t-monto {
  margin-left: auto;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-accent-tint); color: var(--color-accent);
  font-weight: var(--weight-bold); font-variant-numeric: tabular-nums;
}
.t-pill {
  margin-left: auto;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
}
.t-pill.is-ok { background: var(--color-ok-tint); color: var(--color-ok); }
.t-pill.is-bad { background: var(--color-danger-tint); color: var(--color-danger); }
.t-pill.is-off { background: var(--color-surface-sunk); color: var(--color-ink-faint); }

/* La etiqueta «Global» de una forma heredada de la red vista DENTRO de un negocio:
   dice que se ve pero se gestiona en el inicio global. Es la ÚNICA marca de que es
   heredada: nada de filo de color a la izquierda (borde pintado prohibido). */
.t-tag-global {
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-accent-tint); color: var(--color-accent);
  font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: .04em;
}

/* Una casilla con su texto al lado, alineados por arriba para etiquetas largas. */
.t-check { display: flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; }
.t-check span { font-size: var(--text-sm); line-height: 1.5; }
.t-check input { margin-top: 0.2em; flex: none; }

/* Una columna de casillas, cada una con su explicación debajo del nombre. */
.t-checks { display: flex; flex-direction: column; gap: var(--space-4); }
.t-check-nota { display: block; margin-top: var(--space-1); font-size: var(--text-xs); color: var(--color-ink-faint); }
.t-tag {
  margin-left: var(--space-2); padding: 0 var(--space-2);
  border: 1px solid var(--color-line); border-radius: var(--radius-sm);
  font-size: var(--text-2xs); color: var(--color-ink-faint);
}

/* ── Botones ──────────────────────────────────────────────────────────────── */
.t-btn {
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  background: transparent; color: var(--color-ink);
  font-size: var(--text-sm); font-weight: var(--weight-semibold); cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease);
}
.t-btn:hover:not(.is-locked) { background: var(--color-surface-sunk); }
.t-btn:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.t-btn:disabled { opacity: .5; cursor: default; }
.t-btn.is-primary {
  background: var(--color-accent); border-color: transparent; color: var(--color-accent-ink);
}
.t-btn.is-primary:hover:not(:disabled):not(.is-locked) { background: var(--color-accent-strong); }
.t-btn.is-danger { border-color: transparent; background: var(--color-danger-tint); color: var(--color-danger); }
/* Botón «plano»: sin contenedor ni relleno, solo texto. Es el nivel más bajo de
   la jerarquía —un apoyo de otro módulo (p. ej. «Categorías» desde Productos)—:
   no compite con el primario (relleno) ni el secundario (contorno). */
.t-btn.is-plano {
  padding-inline: var(--space-2); border-color: transparent; background: transparent;
  color: var(--color-ink-soft);
}
.t-btn.is-plano:hover:not(:disabled) { background: transparent; color: var(--color-accent); text-decoration: underline; }

/* ── Conversaciones y Ejecuciones: margen lateral pequeño ──────────────────── */
/* Estas dos aprovechan el ancho (lista + detalle), así que van más cerca de los
   bordes que el resto —la columna centrada del panel las apretaría—. Anula el
   centrado por columna (cabecera y contenido a la vez, para que alineen). */
.t-head.is-ancho, .t-main.is-ancho { padding-inline: var(--aire); }

/* ── Conversaciones ───────────────────────────────────────────────────────── */
/* Dos columnas: la lista a la izquierda y el chat de la elegida a la derecha.
   Elegir otra es un clic; al entrar no hay ninguna y la derecha invita a elegir. */
.t-dos {
  display: grid; grid-template-columns: 22rem 1fr; gap: var(--space-5);
  align-items: stretch;
}
/* Apilado en pantalla estrecha: ahí cada uno toma su alto. */
@media (max-width: 60rem) {
  .t-dos { grid-template-columns: 1fr; }
  .t-col-lista { height: auto; max-height: 46vh; }
  .t-col-hilo { height: 70vh; }
}
.t-col-lista {
  display: flex; flex-direction: column; gap: 1px;
  height: 76vh; overflow-y: auto;
  padding: var(--space-2);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface);
}
.t-conv {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-3);
  border: 0; border-radius: var(--radius-sm);
  background: transparent; text-align: left; cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease);
}
.t-conv:hover { background: var(--color-surface-sunk); }
.t-conv.is-on { background: var(--color-accent-tint); color: var(--color-accent); }
.t-conv-top { display: flex; align-items: baseline; gap: var(--space-3); }
.t-conv-cuando { margin-left: auto; font-size: var(--text-2xs); color: var(--color-ink-faint); }
.t-conv.is-on .t-conv-cuando { color: var(--color-accent); }
.t-conv-nota { font-size: var(--text-2xs); color: var(--color-ink-faint); }

/* Una fila de la lista de Ejecuciones: quién, cuándo, un vistazo de la respuesta,
   y su modelo/costo/pasos. Mismo aspecto pulsable que una conversación. */
.t-ejec {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-3);
  border: 0; border-radius: var(--radius-sm);
  background: transparent; text-align: left; cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease);
}
.t-ejec:hover { background: var(--color-surface-sunk); }
.t-ejec.is-on { background: var(--color-accent-tint); }
.t-ejec-top { display: flex; align-items: baseline; gap: var(--space-2); }
.t-ejec-top b { font-size: var(--text-sm); }
.t-ejec-cuando { margin-left: auto; font-size: var(--text-2xs); color: var(--color-ink-faint); }
.t-ejec-txt {
  font-size: var(--text-xs); color: var(--color-ink-soft); line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.t-ejec-nota { font-size: var(--text-2xs); color: var(--color-ink-faint); font-family: var(--font-mono); }
.t-ejec.is-on .t-ejec-txt, .t-ejec.is-on .t-ejec-nota { color: var(--color-accent); }
/* El estado, por un punto antes del nombre y por el color de su palabra: verde
   completada, ámbar en curso (late), rojo falló. */
.t-ejec-punto {
  flex: none; align-self: center; width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--color-line-strong);
}
.t-ejec-est { text-transform: uppercase; letter-spacing: .04em; }
.t-ejec.is-ok .t-ejec-punto { background: var(--color-ok); }
.t-ejec.is-ok .t-ejec-est { color: var(--color-ok); }
.t-ejec.is-fallo .t-ejec-punto { background: var(--color-danger); }
.t-ejec.is-fallo .t-ejec-est { color: var(--color-danger); }
.t-ejec.is-curso .t-ejec-punto {
  background: var(--color-warn); animation: t-late 1.4s var(--motion-ease) infinite;
}
.t-ejec.is-curso .t-ejec-est { color: var(--color-warn); }
/* Llegada y cambio suaves (plan de panel): una ejecución nueva entra deslizándose
   desde arriba; un cambio de estado (verde↔ámbar↔rojo) transiciona el color en vez
   de saltar. El punto y la palabra del estado llevan su propia transición. */
.t-ejec-punto { transition: background-color var(--motion-base) var(--motion-ease); }
.t-ejec-est { transition: color var(--motion-base) var(--motion-ease); }
.t-ejec.is-entra { animation: t-ejec-entra var(--motion-base) var(--motion-ease); }
@keyframes t-ejec-entra {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .t-ejec.is-entra { animation: none; }
}

/* La columna del hilo: su cabecera (nombre + memoria) fija arriba, y solo rueda
   el hilo. Así el nombre y los botones no se van cuando el chat pasa de una
   pantalla. `min-width:0` deja que la celda encoja por debajo de su contenido. */
.t-col-hilo {
  display: flex; flex-direction: column;
  height: 76vh; min-width: 0;
  padding: var(--space-5);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface);
}
.t-hilo-cab {
  display: flex; align-items: center; gap: var(--space-3); flex: 0 0 auto;
  margin-bottom: var(--space-4); padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-line);
}
.t-hilo-nombre {
  font-weight: var(--weight-semibold); font-size: var(--text-md);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.t-hilo-acts { margin-left: auto; display: flex; gap: var(--space-2); flex: none; }
@media (max-width: 40rem) { .t-hilo-acts { flex-wrap: wrap; justify-content: flex-end; } }
.t-col-rueda { flex: 1; min-height: 0; overflow-y: auto; }
.t-hilo {
  display: flex; flex-direction: column; gap: var(--space-4);
  max-width: 48rem; margin: 0 auto; width: 100%;
}

/* El estado vacío de la derecha: un icono y una frase que invita a elegir de la
   izquierda. Vale para Conversaciones y para Ejecuciones. */
.t-elige {
  height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-2); text-align: center; color: var(--color-ink-faint);
}
.t-elige-ic {
  display: inline-flex; color: var(--color-ink-faint); opacity: .5;
}
.t-elige-ic .t-svg { width: var(--space-8); height: var(--space-8); }
.t-elige-t { font-weight: var(--weight-semibold); font-size: var(--text-md); color: var(--color-ink-soft); }
.t-elige-d { font-size: var(--text-sm); }

.t-msg {
  max-width: 42rem;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunk);
}
/* Quién habla se distingue por el LADO y por el fondo, no solo por la etiqueta:
   un hilo largo se sigue con la vista, no leyendo quién es cada uno. */
.t-msg.is-agent { align-self: flex-end; background: var(--color-accent-tint); }
.t-msg.is-system {
  align-self: center; background: transparent;
  border: 1px dashed var(--color-line-strong);
  color: var(--color-ink-faint); font-size: var(--text-xs);
}
/* El del agente es un BOTÓN (toda la burbuja): se pulsa —siempre— para ver su
   detalle en el cajón. Se resetea el aspecto de botón; el «Detalle ›» del pie lo
   anuncia. */
.t-msg-cab {
  border: 0; font: inherit; text-align: left; cursor: pointer;
  transition: filter var(--motion-fast) var(--motion-ease);
}
.t-msg-cab:hover { filter: brightness(1.06); }
.t-msg-ver {
  display: block; margin-top: var(--space-2);
  font-size: var(--text-2xs); font-weight: var(--weight-semibold); color: var(--color-accent);
}
.t-msg-quien {
  display: block;
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  color: var(--color-ink-faint);
}
.t-msg.is-agent .t-msg-quien { color: var(--color-accent); }
.t-msg-txt { display: block; margin: var(--space-2) 0 0; white-space: pre-wrap; line-height: 1.6; }
.t-msg-cuando {
  display: block; margin-top: var(--space-2);
  font-size: var(--text-2xs); color: var(--color-ink-faint);
}
/* La respuesta con su costo (plan 14, Fase 2): modelo, tokens y $ estimado, en
   mono para que los números se alineen y se lean como el dato técnico que son. */
.t-msg-costo {
  display: block; margin-top: var(--space-2);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  color: var(--color-ink-faint);
}
/* De la raya «empieza de cero» hacia arriba: lo que el agente ya no recuerda. Se
   conserva la FORMA que distingue quién habla —el lado y la burbuja— pero sin
   color: `grayscale` apaga el tinte del agente y el matiz del resto, así se lee de
   un vistazo qué sigue vivo (a color, abajo) y qué quedó atrás (en gris). */
.t-msg.is-olvidado {
  filter: grayscale(1); opacity: .5;
  background: color-mix(in srgb, var(--color-surface-sunk) 45%, transparent);
}
.t-msg.is-agent.is-olvidado { background: color-mix(in srgb, var(--color-surface-sunk) 45%, transparent); }
.t-msg.is-olvidado .t-msg-quien,
.t-msg.is-olvidado .t-msg-ver,
.t-msg.is-olvidado .t-msg-txt { color: var(--color-ink-faint); }

/* ── Qué hizo el agente por dentro: las llamadas de un mensaje ─────────────── */
/* El detalle de un mensaje del agente enseña qué herramientas llamó, cómo salieron
   y con qué argumentos/resultado. Es diagnóstico del operador: antes solo se veía
   consultando la base a mano. */
.t-calls {
  display: flex; flex-direction: column; gap: var(--space-2);
}
/* Sin borde izquierdo pintado (prohibido): el desenlace va en un punto de color
   antes de la etiqueta y en el color de la etiqueta misma. */
.t-call {
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
}
.t-call-top {
  display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap;
  font-size: var(--text-2xs);
}
.t-call-top b { font-family: var(--font-mono); font-size: var(--text-xs); }
.t-call-tag {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--color-ink-soft); text-transform: uppercase; letter-spacing: .04em;
}
/* El punto de estado antes de la etiqueta, del mismo código de color que los nodos. */
.t-call-tag::before {
  content: ""; flex: none; width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--color-line-strong);
}
.t-call.is-ok .t-call-tag::before { background: var(--color-ok); }
.t-call.is-rejected .t-call-tag::before { background: var(--color-sky); }
.t-call.is-failed .t-call-tag::before { background: var(--color-danger); }
.t-call.is-rejected .t-call-tag { color: var(--color-sky); }
.t-call.is-failed .t-call-tag { color: var(--color-danger); }
.t-call-ms { margin-left: auto; color: var(--color-ink-faint); }
.t-call-io {
  margin-top: var(--space-2); padding: var(--space-2);
  background: var(--color-surface-sunk); border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--text-2xs); line-height: 1.5;
  white-space: pre-wrap; word-break: break-word; overflow-x: auto;
}
.t-call-out { color: var(--color-ink-soft); }
.t-call-cargando { font-size: var(--text-2xs); color: var(--color-ink-faint); }
/* Cada payload rotulado: qué mandó el agente y qué devolvió la herramienta, para
   no tener que adivinar cuál `pre` es cuál. El rótulo va tenue, sobre su bloque. */
.t-call-campo { margin-top: var(--space-2); }
.t-call-campo .t-call-io { margin-top: var(--space-1); }
.t-call-rot {
  display: block; font-size: var(--text-2xs); color: var(--color-ink-faint);
  text-transform: uppercase; letter-spacing: .04em;
}

/* Lo que el agente recuerda de una persona vive ahora en la barra de arriba del
   hilo (`.t-chat-acts`): «Ver apuntes», «Borrar apuntes» y «Empezar de cero». */
/* La raya que marca dónde alguien empezó de cero. El texto va encima de la
   línea y con el fondo del panel detrás, para que la línea no lo cruce. */
.t-corte {
  display: flex; align-items: center; justify-content: center;
  margin: var(--space-3) 0;
  border-top: 1px dashed var(--color-line-strong);
}
.t-corte span {
  margin-top: calc(var(--space-2) * -1 - 1px);
  padding: 0 var(--space-3);
  background: var(--color-surface);
  font-size: var(--text-2xs); color: var(--color-ink-faint);
  text-transform: uppercase; letter-spacing: .06em;
}
/* Un botón que borra no puede tener el tamaño del que guarda. */
.t-btn.is-chico { padding: var(--space-2) var(--space-3); font-size: var(--text-2xs); }

/* ── El lienzo de nodos: la conversación como flujo, al estilo n8n ─────────── */
/* Un área de trabajo con fondo de puntos; los nodos, del mismo tamaño y
   minimalistas, se arrastran a gusto y se pulsan para ver su detalle en un modal.
   El dibujo lo pone `montarFlujo`; esto es solo su aspecto. */

/* El área rueda en las dos direcciones: el grafo puede ser más grande que el
   hueco, y así se recorre sin que la página entera se ensanche. */
.t-flujo-host { flex: 1; min-height: 0; }
.t-lienzo {
  height: 100%; overflow: hidden; position: relative;
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  /* El fondo de puntos del área de trabajo, tipo n8n: una rejilla de puntitos
     tenues que da sensación de lienzo. Vive aquí (no en el área) para cubrir todo
     el visor; `montarFlujo` mueve y escala su posición/tamaño con la vista, así
     el fondo acompaña al paneo y al zoom. */
  background-color: var(--color-canvas);
  background-image: radial-gradient(var(--color-line-strong) 1.2px, transparent 1.2px);
  background-size: 22px 22px; background-position: 0 0;
  /* Sin scroll: el lienzo se recorre arrastrando (izquierdo desde el vacío, o
     central) y se hace zoom con la rueda, como en n8n. Libre en las 4 direcciones. */
  cursor: grab; touch-action: none;
}
/* Al panear el cursor lo dice; el `!important` gana sobre el `grab`/`pointer` de
   los nodos mientras se recorre. */
.t-lienzo.is-paneando, .t-lienzo.is-paneando * { cursor: grabbing !important; }
/* El área se mueve y escala con un `transform` (lo aplica `montarFlujo`); el
   origen arriba-izquierda hace que el zoom hacia el cursor cuadre. */
.t-lienzo-area { position: absolute; top: 0; left: 0; transform-origin: 0 0; will-change: transform; }
/* Las flechas van DEBAJO de los nodos para no tapar sus clics. `overflow:visible`
   para que una flecha a un nodo arrastrado fuera del tamaño inicial no se recorte
   (el tamaño también crece al arrastrar, en `montarFlujo`). */
.t-lienzo-svg { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.t-arista { fill: none; stroke: var(--color-line-strong); stroke-width: 1.5; }

/* Un nodo: una caja absoluta, TODOS del mismo tamaño. Minimalista: una etiqueta
   de qué es y su título, nunca el mensaje. Sin borde izquierdo de color —el estado
   de una herramienta va en un punto, no en el borde—. */
.t-flnodo {
  position: absolute;
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  padding: var(--space-2) var(--space-3); text-align: left;
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-ink);
  font: inherit; cursor: grab; touch-action: none;
  box-shadow: var(--shadow-1);
  transition: border-color var(--motion-fast) var(--motion-ease),
              box-shadow var(--motion-fast) var(--motion-ease);
}
.t-flnodo:hover { border-color: var(--color-line-strong); }
.t-flnodo.is-arrastrando { cursor: grabbing; box-shadow: var(--shadow-2); z-index: 3; }
/* Lo que ENTRÓ (el mensaje del cliente): resaltado con el acento, «aquí empieza».
   Ya no hay un nodo «Disparador» aparte: este primer nodo ES la entrada. */
.t-flnodo.is-cliente { background: var(--color-accent-wash); border-color: var(--color-accent); }
.t-flnodo.is-cliente .t-flnodo-tag { color: var(--color-accent); }
/* Entrada del sistema: más discreta, con borde punteado. */
.t-flnodo.is-system { background: transparent; border-style: dashed; border-color: var(--color-line-strong); }
.t-flnodo-tag {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  text-transform: uppercase; letter-spacing: .04em; color: var(--color-ink-faint);
}
.t-flnodo-titulo {
  font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Los DOS importantes van más grandes y levantados: se ven de un vistazo. */
.t-flnodo.is-grande {
  padding: var(--space-3) var(--space-4); gap: var(--space-1);
  border-width: 2px; box-shadow: var(--shadow-2); z-index: 2;
}
.t-flnodo.is-grande .t-flnodo-titulo { font-size: var(--text-md); }

/* La salida: la RESPUESTA del agente, coloreada por su ESTADO —verde si respondió,
   ámbar si sigue en curso, rojo si murió antes—. Es el cierre del turno; sustituye
   al viejo nodo «Agente» suelto. */
.t-flnodo.is-respuesta .t-flnodo-titulo { display: flex; align-items: center; gap: var(--space-2); }
.t-flnodo.is-respuesta .t-flnodo-titulo::before {
  content: ""; flex: none; width: .6rem; height: .6rem; border-radius: 50%;
  background: var(--color-line-strong);
}
.t-flnodo.is-respuesta.is-ok { border-color: var(--color-ok); background: var(--color-ok-tint); }
.t-flnodo.is-respuesta.is-ok .t-flnodo-titulo::before { background: var(--color-ok); }
.t-flnodo.is-respuesta.is-ok .t-flnodo-tag { color: var(--color-ok); }
.t-flnodo.is-respuesta.is-fallo { border-color: var(--color-danger); background: var(--color-danger-tint); }
.t-flnodo.is-respuesta.is-fallo .t-flnodo-titulo::before { background: var(--color-danger); }
.t-flnodo.is-respuesta.is-fallo .t-flnodo-tag { color: var(--color-danger); }
.t-flnodo.is-respuesta.is-curso { border-color: var(--color-warn); background: var(--color-warn-tint); }
.t-flnodo.is-respuesta.is-curso .t-flnodo-tag { color: var(--color-warn); }
/* El punto en curso late, para que se sienta «vivo» (se refresca solo cada pocos s). */
.t-flnodo.is-respuesta.is-curso .t-flnodo-titulo::before {
  background: var(--color-warn); animation: t-late 1.4s var(--motion-ease) infinite;
}

/* El hito de los extremos: una pastilla «INICIO» / «FIN» que resalta dónde
   empieza y dónde acaba la tubería. Toma el color del propio nodo (acento en la
   entrada; el del estado en la salida). */
.t-flnodo-hito {
  align-self: flex-start; margin-bottom: 2px;
  padding: 0 var(--space-2); border-radius: 999px; border: 1px solid currentColor;
  font-size: 10px; font-weight: var(--weight-bold);
  text-transform: uppercase; letter-spacing: .08em; line-height: 1.5;
}
.t-flnodo.is-cliente .t-flnodo-hito, .t-flnodo.is-system .t-flnodo-hito { color: var(--color-accent); }
.t-flnodo.is-respuesta.is-ok .t-flnodo-hito { color: var(--color-ok); }
.t-flnodo.is-respuesta.is-curso .t-flnodo-hito { color: var(--color-warn); }
.t-flnodo.is-respuesta.is-fallo .t-flnodo-hito { color: var(--color-danger); }

/* La herramienta lleva su título en mono y un punto de estado antes: verde si
   salió, azul si se rechazó a propósito, rojo si falló. El punto reemplaza al
   viejo borde de color. */
.t-flnodo.is-tool .t-flnodo-titulo {
  font-family: var(--font-mono); font-size: var(--text-xs);
  display: flex; align-items: center; gap: var(--space-2);
}
.t-flnodo.is-tool .t-flnodo-titulo::before {
  content: ""; flex: none; width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--color-line-strong);
}
.t-flnodo.is-tool.is-ok .t-flnodo-titulo::before { background: var(--color-ok); }
.t-flnodo.is-tool.is-rejected .t-flnodo-titulo::before { background: var(--color-sky); }
.t-flnodo.is-tool.is-failed .t-flnodo-titulo::before { background: var(--color-danger); }

/* Piezas del detalle de un nodo, reusadas en su modal. */
.t-nodo-full { white-space: pre-wrap; line-height: 1.6; font-size: var(--text-sm); }
.t-nodo-motivo { font-size: var(--text-xs); color: var(--color-danger); }
.t-nodo-estado {
  font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: .04em;
  color: var(--color-ink-soft);
}
.t-nodo-estado.is-ok { color: var(--color-ok); }
.t-nodo-estado.is-curso { color: var(--color-warn); }
.t-nodo-estado.is-fallo { color: var(--color-danger); }
.t-nodo-cuando {
  display: block; margin-top: var(--space-2); font-size: var(--text-2xs); color: var(--color-ink-faint);
}

/* Contenedores del detalle de un nodo. Lo DICHO (un mensaje, una respuesta) va en
   su propio bloque, como una cita; los DATOS del turno (canal, modelo, costo, hora)
   van en una rejilla de filas rotuladas. Así se distingue de un vistazo qué es el
   texto del mensaje y qué es información del modal. */
.t-nodo-msg {
  margin-block: var(--space-3); padding: var(--space-3);
  border-radius: var(--radius-sm); background: var(--color-surface-sunk);
}
.t-nodo-msg-rot {
  display: block; margin-bottom: var(--space-1);
  font-size: var(--text-2xs); color: var(--color-ink-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
.t-nodo-info { display: grid; gap: var(--space-2); margin-top: var(--space-3); }
.t-nodo-fila {
  display: grid; grid-template-columns: 9rem 1fr; gap: var(--space-3); align-items: baseline;
}
.t-nodo-rot {
  font-size: var(--text-2xs); color: var(--color-ink-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
.t-nodo-val { font-size: var(--text-sm); color: var(--color-ink); }
.t-nodo-val.is-danger { color: var(--color-danger); }
@media (max-width: 30rem) {
  .t-nodo-fila { grid-template-columns: 1fr; gap: var(--space-1); }
}

/* ── Formulario del agente ────────────────────────────────────────────────── */
.t-sitio {
  display: flex; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.t-sitio-fijo {
  margin-bottom: var(--space-6);
  font-size: var(--text-sm); color: var(--color-ink-faint);
}
.t-sitio-fijo b { color: var(--color-ink); font-weight: var(--weight-semibold); }

.t-form { display: flex; flex-direction: column; gap: var(--space-6); max-width: 38rem; }
.t-campo { display: flex; flex-direction: column; gap: var(--space-2); }
.t-campo-top { display: flex; align-items: center; gap: var(--space-3); }
.t-label { font-size: var(--text-sm); font-weight: var(--weight-semibold); }
/*
 * La pista.
 *
 * Cuelga hacia ABAJO a propósito: hacia arriba, la del primer campo queda
 * debajo de la cabecera, que es lo único de la pantalla que va por encima.
 *
 * `visibility` además de `opacity` para que cerrada no se pueda pulsar ni la
 * encuentre el lector de pantalla; solo con `opacity` sigue estando ahí,
 * invisible y en medio.
 */
.t-pista { position: relative; display: inline-flex; }
.t-pista-b {
  display: grid; place-items: center;
  width: var(--space-5); height: var(--space-5); padding: 0;
  border: 1px solid var(--color-line-strong); border-radius: 50%;
  background: transparent; color: var(--color-ink-faint);
  font-size: var(--text-2xs); font-weight: var(--weight-bold);
  line-height: 1; cursor: help;
  transition: color var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease);
}
.t-pista-b:hover { color: var(--color-accent); border-color: var(--color-accent); }
.t-pista-b:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.t-pista-caja {
  position: absolute; top: calc(100% + var(--space-2)); left: 0; z-index: 40;
  width: max-content; max-width: min(24rem, 70vw);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-line-strong); border-radius: var(--radius-md);
  background: var(--color-surface-deep);
  box-shadow: var(--shadow-3);
  color: var(--color-ink-soft);
  font-size: var(--text-xs); font-weight: var(--weight-normal); line-height: 1.6;
  text-align: left; white-space: normal;
  opacity: 0; visibility: hidden;
  transition: opacity var(--motion-fast) var(--motion-ease),
              visibility var(--motion-fast) var(--motion-ease);
}
.t-pista-caja b { color: var(--color-ink); font-weight: var(--weight-semibold); }
.t-pista:hover .t-pista-caja,
.t-pista:focus-within .t-pista-caja { opacity: 1; visibility: visible; }

/* Cifras y nada más: con la palabra «caracteres» detrás deja de ser un dato al
   margen y se convierte en una frase que hay que leer. */
.t-cuenta {
  margin-left: auto;
  font-size: var(--text-2xs); color: var(--color-ink-faint);
  font-variant-numeric: tabular-nums;
}
.t-cuenta.is-cerca { color: var(--color-danger); font-weight: var(--weight-semibold); }

/*
 * Los campos, de LÍNEA.
 *
 * Nada de caja completa: solo el filo de abajo que sostiene el texto, sobre el
 * fondo de la pantalla. Al enfocar, ese filo se pone del color de acento (con una
 * segunda línea por `box-shadow`, que no mueve nada de sitio). El desplegable de
 * verdad —el que se busca escribiendo— es `.t-combo`, más abajo; el `<select>`
 * nativo que aún queda en algún formulario hereda el mismo filo para que no
 * desentone hasta que se migre.
 */
.t-input, .t-select, .t-area {
  width: 100%;
  padding: var(--space-2) 0;
  border: 0; border-bottom: 1px solid var(--color-line-strong); border-radius: 0;
  background: transparent; color: var(--color-ink);
  transition: border-color var(--motion-fast) var(--motion-ease);
}
.t-area { resize: vertical; line-height: 1.6; }
/* El área que CRECE: arranca de una línea (como los demás campos) y se estira con
   lo que se escribe hasta un tope; de ahí, scroll. La altura la ajusta el JS; aquí
   van el mínimo, el máximo y que no se pueda arrastrar el asa (crece sola). */
.t-area.is-auto {
  min-height: calc(1.6em + var(--space-2) * 2);
  max-height: 12rem; overflow-y: auto; resize: none;
}
.t-select { width: auto; min-width: 12rem; cursor: pointer; padding-right: var(--space-5); }

/* ── Campos de número: sus flechas de subir/bajar, propias ─────────────────── */
/* Las flechas nativas son feas y no se dejan estilar; se ocultan y se ponen unas
   propias que aparecen —con fundido— al pasar por encima o al enfocar el campo. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.t-num { position: relative; }
.t-num .t-input { padding-right: var(--space-6); }
.t-num-flechas {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column;
  opacity: 0; transition: opacity var(--motion-fast) var(--motion-ease);
}
.t-num:hover .t-num-flechas, .t-num:focus-within .t-num-flechas { opacity: 1; }
.t-num-b {
  display: grid; place-items: center;
  width: 1.2rem; height: .82rem; padding: 0;
  border: 0; background: transparent; color: var(--color-ink-faint);
  cursor: pointer; line-height: 1;
  transition: color var(--motion-fast) var(--motion-ease);
}
.t-num-b:hover { color: var(--color-accent); }
.t-num-b:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 1px; }
/* La flecha, dibujada con dos filos (como el caret del combo). */
.t-num-b::before {
  content: ""; width: .4rem; height: .4rem;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
}
.t-num-b.is-sube::before { transform: translateY(2px) rotate(225deg); }
.t-num-b.is-baja::before { transform: translateY(-2px) rotate(45deg); }
.t-input:focus, .t-select:focus, .t-area:focus {
  outline: none;
  border-bottom-color: var(--color-accent);
  box-shadow: 0 1px 0 0 var(--color-accent);
}
.t-form-acts { display: flex; align-items: center; gap: var(--space-4); }
.t-form-nota { font-size: var(--text-xs); color: var(--color-ink-faint); }

/* Lo que está mal se dice DEBAJO del campo que lo tiene, y el campo se pone
   rojo. Una lista de frases en una ventana obliga a leerlas, entenderlas y
   adivinar a cuál de los tres campos se refiere cada una. */
.t-fallo {
  font-size: var(--text-xs); color: var(--color-danger); line-height: 1.5;
}
/* Y el aviso de lo que NO está mal pero conviene saber, en el mismo sitio y en
   otro color: si fuera rojo parecería un error que hay que arreglar. */
.t-aviso {
  font-size: var(--text-xs); color: var(--color-ink-faint); line-height: 1.5;
}
.t-aviso b { color: var(--color-ink-soft); font-weight: var(--weight-semibold); }
.t-input.is-mal, .t-select.is-mal, .t-area.is-mal { border-bottom-color: var(--color-danger); }
.t-input.is-mal:focus, .t-select.is-mal:focus, .t-area.is-mal:focus {
  border-bottom-color: var(--color-danger); box-shadow: 0 1px 0 0 var(--color-danger);
}

/* ── El combo: desplegable que se escribe (el campo de lista de todo el panel) ── */
/* Por fuera es una línea como cualquier campo; la flecha a la derecha dice si está
   abierto. El cursor de escritura (palito) al pasar por encima avisa de que se
   puede teclear —y al teclear, filtra—. Ver `lib/combo.js`. */
.t-combo { position: relative; display: block; }
.t-combo-in {
  width: 100%;
  padding: var(--space-2) var(--space-6) var(--space-2) 0;
  border: 0; border-bottom: 1px solid var(--color-line-strong); border-radius: 0;
  background: transparent; color: var(--color-ink);
  cursor: text;
  transition: border-color var(--motion-fast) var(--motion-ease);
}
.t-combo-in:focus {
  outline: none;
  border-bottom-color: var(--color-accent);
  box-shadow: 0 1px 0 0 var(--color-accent);
}
.t-combo.is-mal .t-combo-in { border-bottom-color: var(--color-danger); }
.t-combo.is-mal .t-combo-in:focus { box-shadow: 0 1px 0 0 var(--color-danger); }
/* La flecha: un chevron de dos filos, girado; al abrir apunta hacia arriba. */
.t-combo-caret {
  position: absolute; right: var(--space-2); top: 50%;
  width: .45rem; height: .45rem; margin-top: -.35rem;
  border-right: 2px solid var(--color-ink-faint);
  border-bottom: 2px solid var(--color-ink-faint);
  transform: rotate(45deg);
  transition: transform var(--motion-fast) var(--motion-ease);
  pointer-events: none;
}
.t-combo.is-open .t-combo-caret { transform: rotate(225deg); margin-top: -.15rem; }
.t-combo-list {
  position: absolute; z-index: 50; left: 0; right: 0; top: calc(100% + var(--space-1));
  margin: 0; padding: var(--space-1); list-style: none;
  max-height: 15rem; overflow-y: auto;
  border: 1px solid var(--color-line-strong); border-radius: var(--radius-md);
  background: var(--color-surface); box-shadow: var(--shadow-3);
}
.t-combo-opt {
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
  cursor: pointer; line-height: 1.4;
}
.t-combo-opt.is-activa,
.t-combo-opt:hover { background: var(--color-accent-tint); color: var(--color-accent); }
.t-combo-opt.is-sel { font-weight: var(--weight-semibold); }
/* Cuando abajo no cabe, la lista se abre hacia ARRIBA (lo decide el JS midiendo el
   sitio que queda). El alto máximo lo pone el JS al abrir, según lo que cabe. */
.t-combo.is-arriba .t-combo-list {
  top: auto; bottom: calc(100% + var(--space-1));
}

/* ── Pestañas ─────────────────────────────────────────────────────────────── */
.t-tabs {
  display: flex; gap: var(--space-4);
  border-bottom: 1px solid var(--color-line);
  margin-bottom: var(--space-6);
}
.t-tab {
  padding: var(--space-3) var(--space-1);
  border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
  background: transparent; color: var(--color-ink-faint);
  font-weight: var(--weight-semibold); cursor: pointer;
  transition: color var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease);
}
.t-tab:hover { color: var(--color-ink); }
.t-tab.is-activa { color: var(--color-accent); border-bottom-color: var(--color-accent); }
.t-tab:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* ── Métricas: el KPI y las tres tablas clave-valor ───────────────────────── */
.t-metricas { display: flex; flex-direction: column; gap: var(--space-6); }
/* El KPI grande del gasto total, arriba: lo primero que se quiere ver. */
.t-kpi {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-5);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface);
}
.t-kpi-rot {
  font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: .04em;
  color: var(--color-ink-faint);
}
.t-kpi-monto { font-size: var(--text-3xl, var(--text-2xl)); font-weight: var(--weight-bold); letter-spacing: -.02em; }
.t-kpi-sub { font-size: var(--text-xs); color: var(--color-ink-soft); }
/* Las tres tablas, en una misma fila; se apilan cuando no caben. */
.t-tablas {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5);
  align-items: start;
}
@media (max-width: 60rem) { .t-tablas { grid-template-columns: 1fr; } }
.t-tabla { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.t-kv {
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); overflow: hidden;
}
/* La cabecera de dos columnas: el nombre de la columna y «Gasto». */
.t-kv-cab {
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-line);
  font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: .04em;
  color: var(--color-ink-faint);
}
/* Una fila pulsable: etiqueta, gasto y una flecha a la derecha que indica que se
   puede abrir su detalle. Toda la fila es el botón. */
.t-kv-fila {
  display: grid; grid-template-columns: 1fr auto auto; gap: var(--space-3);
  align-items: baseline; width: 100%;
  padding: var(--space-3); border: 0; border-top: 1px solid var(--color-line);
  background: transparent; text-align: left; cursor: pointer; color: var(--color-ink);
  transition: background var(--motion-fast) var(--motion-ease);
}
.t-kv-fila:first-of-type { border-top: 0; }
.t-kv-fila:hover { background: var(--color-surface-sunk); }
.t-kv-fila:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
.t-kv-k {
  font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.t-kv-v { font-size: var(--text-sm); font-weight: var(--weight-semibold); font-variant-numeric: tabular-nums; }
.t-kv-flecha { align-self: center; color: var(--color-ink-faint); font-size: var(--text-lg); line-height: 1; }
.t-kv-fila:hover .t-kv-flecha { color: var(--color-ink); }
.t-kv-vacio { padding: var(--space-3); font-size: var(--text-xs); color: var(--color-ink-faint); }
.t-kv-v.is-none { color: var(--color-ink-faint); font-weight: var(--weight-normal); font-style: italic; }
/* Un código/aclaración pequeña junto a la clave (la moneda, la fuente…). */
.t-kv-cod { color: var(--color-ink-faint); font-size: var(--text-2xs); font-weight: var(--weight-normal); }
/* Una fila de solo lectura (el historial): sin cursor ni realce. */
.t-kv-fila.is-plana { cursor: default; }
.t-kv-fila.is-plana:hover { background: transparent; }

/* ── Tasas: dos tablas clave-valor centradas (actual arriba, historial abajo) ── */
.t-tasas {
  max-width: 34rem; margin-inline: auto;
  display: flex; flex-direction: column; gap: var(--space-6);
}

/* ── Memoria: el modal con la info general y el apartado de cards ───────────── */
.t-mem-cards { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-4); }
.t-mem-card {
  display: grid; grid-template-columns: 1fr auto auto; gap: var(--space-3); align-items: center;
  width: 100%; padding: var(--space-4); text-align: left; cursor: pointer;
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-ink);
  transition: background var(--motion-fast) var(--motion-ease);
}
.t-mem-card:hover:not(:disabled) { background: var(--color-surface-sunk); }
.t-mem-card:disabled { opacity: .55; cursor: default; }
.t-mem-card-t { font-weight: var(--weight-semibold); }
.t-mem-card-n { font-size: var(--text-xs); color: var(--color-ink-faint); }
/* Las dos opciones de «Empezar de cero»: cada una explica su consecuencia. */
.t-mem-opts { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-4) 0; }
.t-mem-opt {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-4); text-align: left; cursor: pointer;
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-ink);
  transition: border-color var(--motion-fast) var(--motion-ease),
              background var(--motion-fast) var(--motion-ease);
}
.t-mem-opt:hover:not(:disabled) { border-color: var(--color-ink-soft); background: var(--color-surface-sunk); }
.t-mem-opt:disabled { opacity: .5; cursor: default; }
.t-mem-opt b { font-size: var(--text-sm); }
.t-mem-opt span { font-size: var(--text-xs); color: var(--color-ink-soft); line-height: 1.5; }
.t-mem-opt.is-danger b { color: var(--color-danger); }
.t-mem-opt.is-danger:hover:not(:disabled) { border-color: var(--color-danger); }

/* El hueco de un módulo embebido como pestaña de Agente (Formas de pago / Tasas). */
.t-sub { display: block; margin-top: var(--space-5); }

/* ── Herramientas agrupadas por paquete (colapsables) ─────────────────────── */
.t-paqs { display: flex; flex-direction: column; gap: var(--space-3); }
.t-paq {
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface); overflow: hidden;
}
.t-paq-cab {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4);
}
/* El interruptor enciende el paquete ENTERO (es la unidad de coherencia). Vive
   fuera del botón que colapsa para que tocarlo no despliegue, ni al revés. */
.t-paq-check { display: inline-flex; margin-top: 2px; }
.t-paq-toggle {
  display: flex; align-items: flex-start; gap: var(--space-3); flex: 1; min-width: 0;
  padding: 0; border: 0; background: transparent; text-align: left; cursor: pointer;
}
.t-paq-info { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.t-paq-t {
  display: flex; align-items: center; gap: var(--space-2);
  font-weight: var(--weight-semibold);
}
.t-paq-id {
  padding: 0 var(--space-2); border-radius: var(--radius-sm);
  background: var(--color-accent-tint); color: var(--color-accent);
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  font-family: var(--font-mono, monospace);
}
/* El resumen nunca se ve entero: una línea con puntos suspensivos, y el texto
   completo en el tooltip (atributo `title`). Así la cabecera no crece con la
   descripción y todas las filas de paquete miden lo mismo. */
.t-paq-resumen {
  font-size: var(--text-xs); color: var(--color-ink-faint); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.t-paq-caret {
  flex: none; margin-top: .35rem;
  width: .45rem; height: .45rem;
  border-right: 2px solid var(--color-ink-faint);
  border-bottom: 2px solid var(--color-ink-faint);
  transform: rotate(45deg);
  transition: transform var(--motion-fast) var(--motion-ease);
}
.t-paq.is-open .t-paq-caret { transform: rotate(225deg); margin-top: .5rem; }

/* Las herramientas del paquete, en LISTA (no en pills): cada una su nombre y, en
   una línea debajo, para qué sirve.

   Desplegar/plegar SE ANIMA: el contenedor es un grid cuya única fila pasa de
   `0fr` (cerrado) a `1fr` (abierto), y lo de dentro lleva `overflow:hidden` y
   `min-height:0` para que la altura real se pueda recortar mientras crece. Se usa
   esto y no `max-height` con un número mágico: la lista mide lo que mida sin que
   haya que adivinar un tope. Nada de `hidden`: cortaba en seco. */
.t-paq-tools {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--motion-base) var(--motion-ease);
}
.t-paq.is-open .t-paq-tools { grid-template-rows: 1fr; }
.t-paq-tools-in {
  overflow: hidden; min-height: 0;
  display: flex; flex-direction: column;
  border-top: 1px solid var(--color-line);
}
.t-tool {
  display: flex; align-items: flex-start; gap: var(--space-3);
  /* Sangría a la izquierda: las herramientas quedan metidas respecto a la
     cabecera del paquete, para que se lea «esto es de aquí dentro». */
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-8);
}
/* Un fondo apenas más hundido bajo las herramientas remata la sangría: se lee de
   un vistazo que son «lo de dentro» del paquete, sin pintar un borde. */
.t-paq-tools-in { background: var(--color-canvas); }
.t-tool + .t-tool { border-top: 1px solid var(--color-line); }
.t-tool-sw { margin-top: 1px; }
.t-tool-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.t-tool-n { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-ink); }
/* La descripción tampoco se ve entera: una línea con elipsis y el texto completo
   en el `title`. Igual que el resumen del paquete, para que las filas no crezcan. */
.t-tool-d {
  font-size: var(--text-xs); color: var(--color-ink-faint); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Una herramienta apagada: el nombre se atenúa; la nota de dependencia, en acento. */
.t-tool.is-off .t-tool-n { color: var(--color-ink-faint); }
.t-tool-dep {
  font-size: var(--text-2xs); color: var(--color-accent); font-weight: var(--weight-semibold);
}
/* Vacía no ocupa (ni deja el hueco del gap): solo aparece cuando hay dependencia. */
.t-tool-dep:empty { display: none; }

/* ── Interruptor (toggle) ─────────────────────────────────────────────────── */
/* La casilla nativa se cambia por un interruptor con el estilo del sistema. El
   input real sigue ahí (oculto): mantiene el foco, el teclado y el `change`. */
.t-switch { position: relative; display: inline-flex; flex: none; }
.t-switch input {
  position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer;
}
.t-switch input:disabled { cursor: default; }
.t-switch-riel {
  width: 2.2rem; height: 1.25rem; border-radius: 999px;
  background: var(--color-line-strong);
  transition: background var(--motion-fast) var(--motion-ease);
}
.t-switch-riel::after {
  content: ""; display: block;
  width: .95rem; height: .95rem; margin: .15rem; border-radius: 50%;
  background: var(--color-surface);
  transition: transform var(--motion-fast) var(--motion-ease);
}
.t-switch input:checked + .t-switch-riel { background: var(--color-accent); }
.t-switch input:checked + .t-switch-riel::after { transform: translateX(.95rem); }
.t-switch input:disabled + .t-switch-riel { opacity: .6; }
.t-switch input:focus-visible + .t-switch-riel { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* ── El botón de Guardar, anclado abajo ───────────────────────────────────── */
/* Se queda pegado al fondo del visor mientras se hace scroll, para que Guardar se
   vea siempre. Sin caja ni fondo: solo el botón (y su nota) sobre la pantalla —el
   cuadro recto de antes no casaba con el degradado del fondo—. Sin cambios, el
   botón se bloquea (gris, cursor de no-permitido y una pista de por qué). */
.t-guardar-barra {
  position: sticky; bottom: 0; z-index: 30;
  display: flex; align-items: center; gap: var(--space-4);
  margin-top: var(--space-6);
  padding: var(--space-4) 0;
}
.t-btn.is-locked {
  background: var(--color-line-strong); color: var(--color-ink-faint);
  cursor: not-allowed; box-shadow: none;
}

/* ── Diálogo ──────────────────────────────────────────────────────────────── */
.t-velo {
  position: fixed; inset: 0; z-index: 80;
  display: flex; justify-content: center; align-items: safe center;
  padding: var(--space-5);
  background: var(--color-veil);
  /* El scroll de un modal alto vive AQUÍ, no en el cuerpo del diálogo: así una
     pista (el tooltip del `?`) puede salirse del cuerpo sin que un `overflow` la
     recorte. `safe center` centra cuando cabe y alinea arriba cuando no, para que
     la parte de arriba de un modal muy alto siga siendo alcanzable. Sin scroll
     horizontal: una pista ancha se recorta contra el borde, no empuja una barra. */
  overflow-y: auto; overflow-x: hidden;
}
.t-dialogo {
  width: 100%; max-width: 28rem;
  padding: var(--space-6);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-3);
}
.t-dialogo-t { font-size: var(--text-xl); font-weight: var(--weight-bold); }
.t-dialogo-c { margin-top: var(--space-4); line-height: 1.6; }
.t-dialogo-d {
  margin-top: var(--space-3);
  font-size: var(--text-xs); color: var(--color-ink-faint); line-height: 1.6;
}
.t-dialogo-acts {
  display: flex; justify-content: flex-end; gap: var(--space-3);
  margin-top: var(--space-6);
}

/* El modal de formulario: más ancho que el de preguntar. Cuando es más alto que
   la pantalla, el que se desplaza es el velo (ver arriba), no el cuerpo: un
   cuerpo con `overflow` recortaba las pistas y sacaba una barra horizontal. */
.t-dialogo.is-form { max-width: 34rem; }
.t-dialogo-cuerpo { margin-top: var(--space-5); }
.t-dialogo-cuerpo .t-form { max-width: none; }
/* El texto de consecuencia y los botones no se pegan: la decisión de dinero
   necesita aire entre lo que explica y lo que se pulsa. */
.t-dialogo-cuerpo > .t-dialogo-d { margin-top: var(--space-5); }
.t-dialogo-cuerpo > .t-form-acts { margin-top: var(--space-6); }

/* ── El cajón (drawer): detalle que entra desde la derecha ─────────────────── */
/* Para ver el detalle de un mensaje sin salir del chat: entra por un lado, deja
   ver detrás, y se va con la ✕, Escape o pulsando fuera. El velo lo alinea a la
   derecha (no centra como el modal). */
.t-velo-cajon { justify-content: flex-end; align-items: stretch; padding: 0; }
.t-cajon {
  width: 100%; max-width: 30rem; height: 100%;
  display: flex; flex-direction: column;
  border-left: 1px solid var(--color-line-strong);
  background: var(--color-surface); box-shadow: var(--shadow-3);
  /* Entra deslizándose: parte fuera a la derecha y `is-dentro` la trae. */
  transform: translateX(100%);
  transition: transform var(--motion-base) var(--motion-ease);
}
.t-cajon.is-dentro { transform: translateX(0); }
.t-cajon-cab {
  display: flex; align-items: center; gap: var(--space-3); flex: 0 0 auto;
  padding: var(--space-5); border-bottom: 1px solid var(--color-line);
}
.t-cajon-t { font-size: var(--text-lg); font-weight: var(--weight-bold); }
.t-cajon-x {
  margin-left: auto; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--space-6); height: var(--space-6);
  border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--color-ink-faint); cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}
.t-cajon-x:hover { background: var(--color-surface-sunk); color: var(--color-ink); }
.t-cajon-cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-5); }
.t-cajon-detalle { display: flex; flex-direction: column; gap: var(--space-3); }
.t-cajon-detalle [data-verflujo] { align-self: flex-start; }

/* Datos en campos separados —etiqueta a la izquierda, valor a la derecha—, para
   leer una referencia o un monto sin buscarlos dentro de una frase. */
.t-detalle { display: flex; flex-direction: column; }
.t-detalle-fila {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-5);
  padding: var(--space-3) 0; border-bottom: 1px solid var(--color-line);
}
.t-detalle-fila:last-child { border-bottom: 0; }
.t-detalle-fila > span { color: var(--color-ink-faint); font-size: var(--text-sm); flex: none; }
.t-detalle-fila > b { text-align: right; word-break: break-word; }
.t-detalle-fila > b.is-none { color: var(--color-ink-faint); font-weight: var(--weight-regular); font-style: italic; }
/* Lo que falta por pagar se distingue: es la cifra que decide si el pedido
   está saldado o a medias. */
.t-detalle-fila.is-falta > b, .t-saldo-item.is-falta b { color: var(--color-danger); }

/* ── Saldo de un pedido: cifras en fila dentro de la card de pagos ─────────── */
.t-saldo {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5);
  padding: var(--space-3) 0; border-top: 1px solid var(--color-line);
}
.t-saldo-item { display: flex; flex-direction: column; gap: 2px; }
.t-saldo-item span { font-size: var(--text-2xs); color: var(--color-ink-faint); }
.t-saldo-item b { font-variant-numeric: tabular-nums; }

/* ── Trozos por revisar dentro del modal de un pedido ─────────────────────── */
.t-sub-t {
  margin-top: var(--space-5); font-size: var(--text-sm); font-weight: var(--weight-semibold);
  color: var(--color-ink-soft);
}
.t-trozos { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-3); }
.t-trozo {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface-sunk);
}
.t-trozo-top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.t-trozo-top b { font-size: var(--text-lg); font-variant-numeric: tabular-nums; }
.t-trozo-top span { font-size: var(--text-2xs); color: var(--color-ink-faint); }
/* Un trozo ya decidido se ve, pero apagado: no se actúa sobre él. */
.t-trozo.is-captured, .t-trozo.is-failed { opacity: .72; }
.t-estado {
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
}
.t-estado.is-captured { background: var(--color-ok-tint); color: var(--color-ok); }
.t-estado.is-failed { background: var(--color-danger-tint); color: var(--color-danger); }
/* El efectivo contra entrega: un compromiso a la vista, no algo que se resuelva
   aquí. Ni éxito ni fallo —color de acento, informativo—, y algo apagado. */
.t-trozo.is-al_recibir { opacity: .85; }
.t-estado.is-al_recibir { background: var(--color-accent-tint); color: var(--color-accent); }

/* La barra de acciones de una pantalla (p. ej. el botón de refrescar en Pagos). */
.t-barra { display: flex; justify-content: flex-end; gap: var(--space-3); margin-bottom: var(--space-4); }

/* La fila de acciones sube al nivel del título del módulo. Cada pantalla pone su
   `.t-barra` de PRIMERA dentro de `#centro`; al sacarla del flujo y anclarla
   arriba a la derecha, queda al mismo nivel que el `<h1>` en vez de ocupar una
   línea propia debajo (así el «Actualizar» y demás controles pegan con el
   título). El `right` copia el margen lateral del centro para alinearse con el
   borde derecho del contenido, no con el del viewport. */
.t-main > #centro > .t-barra:first-child {
  position: absolute; z-index: 3;
  top: var(--space-7); right: max(var(--aire), calc((100% - var(--columna)) / 2));
  margin: 0; height: 2rem; align-items: center;
}
.t-main.is-ancho > #centro > .t-barra:first-child { right: var(--aire); }
/* En pantalla estrecha vuelve a su línea propia: al lado del título no cabría. */
@media (max-width: 40rem) {
  .t-main > #centro > .t-barra:first-child {
    position: static; height: auto; margin-bottom: var(--space-4);
  }
}

/* El botón «En vivo» del «casi en vivo» (plan 14, Fase 4): un punto que late
   mientras está encendido, apagado y quieto cuando se pausa. */
.t-vivo { display: inline-flex; align-items: center; gap: var(--space-2); }
.t-vivo-dot {
  width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--color-ink-faint);
}
.t-vivo.is-on { color: var(--color-accent); }
.t-vivo.is-on .t-vivo-dot { background: var(--color-ok); animation: t-latido 1.6s ease-in-out infinite; }
@keyframes t-latido { 0%, 100% { opacity: 1; } 50% { opacity: .2; } }
@media (prefers-reduced-motion: reduce) { .t-vivo.is-on .t-vivo-dot { animation: none; } }

/* El paginado: la cuenta a un lado, las flechas y «Página X de N» al otro. Uno
   solo para toda la app; va debajo de cada lista. Se envuelve en pantallas
   estrechas para que la cuenta y las flechas no se pisen. */
.t-paginas {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-3);
  margin-top: var(--space-5);
}
.t-paginas-cuenta { font-size: var(--text-sm); color: var(--color-ink-faint); }
.t-paginas-nav { display: inline-flex; align-items: center; gap: var(--space-3); }
.t-paginas-donde {
  font-size: var(--text-sm); color: var(--color-ink-soft);
  font-variant-numeric: tabular-nums; min-width: 8.5rem; text-align: center;
}
/* Las flechas son botones chicos cuadrados: el glifo ‹ › manda, no el ancho. */
.t-paginas-nav .t-btn { min-width: 2.25rem; }

/* Los apuntes de un contacto, en su modal: una lista para leer, no para tocar. */
.t-apuntes { display: flex; flex-direction: column; gap: var(--space-3); margin: 0; padding: 0; list-style: none; }
.t-apuntes li {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-line); border-radius: var(--radius-md);
  background: var(--color-surface-sunk); line-height: 1.5;
}

/* ── La barra de scroll, en TODA la app ─────────────────────────────────────

   Una sola forma en todos lados: sin carril (transparente), solo la barra, que
   aparece —con un fundido— al pasar el ratón por encima del área y se separa del
   canto con un borde transparente. No es un riel gris permanente que reserva sitio
   y empuja el contenido. */
* {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
*:hover {
  scrollbar-color: var(--color-line-strong) transparent;
}
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  /* Borde transparente + recorte al padding = una barra fina, separada del canto,
     que no pinta nada hasta que el ratón entra en el área. */
  background: transparent;
  border: 3px solid transparent;
  border-radius: var(--radius-full);
  background-clip: padding-box;
  transition: background var(--motion-base) var(--motion-ease);
}
:hover::-webkit-scrollbar-thumb {
  background: var(--color-line-strong);
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--color-ink-faint);
  background-clip: padding-box;
}
::-webkit-scrollbar-corner { background: transparent; }

/* Una tarjeta que se pulsa entera para abrir su detalle. El puntero y el realce
   al pasar por encima dicen que es pulsable; los botones de dentro siguen
   haciendo lo suyo (el JS los atiende antes de abrir nada). */
.t-item.is-click { cursor: pointer; transition: border-color var(--motion-fast) var(--motion-ease), background var(--motion-fast) var(--motion-ease); }
.t-item.is-click:hover { border-color: var(--color-line-strong); background: var(--color-surface-sunk); }

/* ══════════════════════════════════════════════════════════════════════════
   MOVIMIENTO

   Tres reglas, y las tres son la misma: el movimiento está para explicar de
   dónde salió algo, no para adornar.

     1. **Corto.** Nada pasa de `--motion-base`. Una animación que se nota
        como animación se convierte en una espera, y esta pantalla se usa
        muchas veces al día.
     2. **Entra, no sale.** Lo que aparece se anima; lo que se va, se va. La
        salida obligaría a sostener en pantalla algo que ya no está, y el
        siguiente clic llegaría antes que la despedida.
     3. **Se apaga entera si el sistema lo pide.** `prefers-reduced-motion` no
        es una preferencia estética: para quien tiene vértigo o migraña, el
        movimiento en pantalla es un síntoma. Se apaga con la consulta de al
        final, y por eso todo esto vive en un solo sitio.
   ══════════════════════════════════════════════════════════════════════════ */

@keyframes t-entra {
  from { opacity: 0; transform: translateY(var(--space-3)); }
  to   { opacity: 1; transform: none; }
}
@keyframes t-asoma {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes t-late {
  50% { opacity: .45; }
}

/* El cambio de pantalla: lo de dentro sube un poco al entrar. La cabecera no se
   anima —se queda quieta y es lo que da la sensación de que solo cambió el
   contenido, que es exactamente lo que pasó. */
.t-main { animation: t-entra var(--motion-base) var(--motion-ease) both; }

/* Las tarjetas de la portada entran una detrás de otra. El escalón es pequeño a
   propósito: lo justo para que se lea como un movimiento y no como cuatro
   cosas cargando a destiempo. */
.t-card { animation: t-entra var(--motion-base) var(--motion-ease) both; }
.t-card:nth-child(2) { animation-delay: 40ms; }
.t-card:nth-child(3) { animation-delay: 80ms; }
.t-card:nth-child(4) { animation-delay: 120ms; }

/* Lo que llega después de una consulta: las fichas de pagos y de cocinas, los
   mensajes de un hilo y la caja de la memoria. Sin escalonar —pueden ser
   cincuenta— porque un retraso por ficha convierte una lista larga en una
   cortinilla. */
.t-item, .t-msg, .t-form {
  animation: t-asoma var(--motion-fast) var(--motion-ease) both;
}

/* «Cargando…» respira. Es la diferencia entre una pantalla que está trabajando
   y una que se quedó colgada, y esa diferencia es lo único que quien mira
   quiere saber mientras espera. */
.t-cargando { animation: t-late 1.4s var(--motion-ease) infinite; }

/* El diálogo: el velo se enciende y la caja sube desde un poco más abajo. Lo
   que pregunta antes de confirmar un pago tiene que aparecer con cuerpo — un
   cambio instantáneo se lee como un parpadeo de la pantalla, y se pulsa sin
   verlo. */
.t-velo { animation: t-asoma var(--motion-fast) var(--motion-ease) both; }
.t-dialogo { animation: t-entra var(--motion-base) var(--motion-ease) both; }

/* La pista, que ya se movía con su propia transición, y la fila de la lista de
   conversaciones al elegirla: aquí no hace falta nada más. */

@media (prefers-reduced-motion: reduce) {
  /* Ni animaciones ni transiciones, en todo el tablero y sin excepciones.
     `.01ms` en vez de `0` porque hay navegadores que no disparan el evento de
     fin de animación con cero, y algo puede estar esperándolo. */
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Catálogo: la carta de una cocina, agrupada por categoría ──────────────── */

/* La fila de acciones de una pantalla que trabaja por cocina (Productos,
   Categorías). Envuelve en pantallas estrechas en vez de desbordar. */
.t-acciones {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.t-grupo { margin-bottom: var(--space-5); }
.t-grupo-t {
  margin: 0 0 var(--space-3);
  font-size: var(--text-2xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-ink-soft);
}

/* ── Secciones plegables con contador (Pagos, Deliveries, Productos…) ───────── */
/* Un `<details>`: el título dice cuántos hay —«Completados (5)»— y se pliega para
   apartar lo que ahora no se mira. El caret gira al abrir. Ver `seccion()` en
   lib/html.js. */
.t-seg { margin-bottom: var(--space-5); }
.t-seg-cab {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) 0; cursor: pointer; list-style: none; user-select: none;
}
.t-seg-cab::-webkit-details-marker { display: none; }
.t-seg-cab:focus-visible {
  outline: 2px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm);
}
.t-seg-t {
  font-size: var(--text-2xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--color-ink-soft); font-weight: var(--weight-semibold);
}
.t-seg-n { font-size: var(--text-2xs); color: var(--color-ink-faint); font-variant-numeric: tabular-nums; }
/* El caret: dos filos girados; a la derecha plegado, hacia abajo abierto. */
.t-seg-caret {
  width: .4rem; height: .4rem; flex: none; margin-right: var(--space-1);
  border-right: 2px solid var(--color-ink-faint); border-bottom: 2px solid var(--color-ink-faint);
  transform: rotate(-45deg);
  transition: transform var(--motion-fast) var(--motion-ease);
}
.t-seg[open] .t-seg-caret { transform: rotate(45deg); }
.t-seg-cuerpo { margin-top: var(--space-3); }

/* Productos como tabla clave-valor (dentro de `.t-kv`): cada fila es el producto
   —nombre y precio— pulsable para ver su detalle, más una tercera columna con las
   acciones en iconos (disponibilidad y borrar). No es un `<button>` con botones
   dentro (HTML inválido): la parte pulsable y las acciones son hermanas. */
.t-prod-fila {
  display: flex; align-items: center;
  border-top: 1px solid var(--color-line);
}
.t-prod-fila:first-child { border-top: 0; }
.t-prod-main {
  flex: 1; min-width: 0;
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-3); align-items: baseline;
  padding: var(--space-3); border: 0; background: transparent;
  text-align: left; cursor: pointer; color: var(--color-ink);
  transition: background var(--motion-fast) var(--motion-ease);
}
.t-prod-main:hover { background: var(--color-surface-sunk); }
.t-prod-main:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
.t-prod-acts { display: flex; gap: var(--space-1); padding: 0 var(--space-2) 0 var(--space-1); }
/* Un botón de acción de solo icono: cuadrado, sin contenedor hasta el hover. */
.t-ico {
  display: inline-grid; place-items: center; width: 2rem; height: 2rem;
  border: 0; border-radius: var(--radius-sm); background: transparent;
  color: var(--color-ink-soft); cursor: pointer;
  transition: background var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}
.t-ico:hover { background: var(--color-surface-sunk); color: var(--color-ink); }
.t-ico.is-danger:hover { color: var(--color-danger); }
.t-ico:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 1px; }
.t-ico .t-svg { width: var(--space-5); height: var(--space-5); }

/*
 * La zona de subir el CSV: se pulsa para elegir o se arrastra el archivo encima.
 *
 * Borde punteado a propósito —dice «suelta aquí» sin una palabra— y toda la caja
 * es el objetivo, no un `<input type=file>` diminuto. `is-drag` mientras se
 * arrastra por encima; `is-lleno` cuando ya hay un archivo elegido.
 */
.t-drop {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-3);
  padding: var(--space-6);
  border: 2px dashed var(--color-line-strong); border-radius: var(--radius-md);
  background: var(--color-surface-sunk);
  color: var(--color-ink-faint);
  text-align: center; cursor: pointer;
  transition: border-color var(--motion-fast) var(--motion-ease),
              background var(--motion-fast) var(--motion-ease),
              color var(--motion-fast) var(--motion-ease);
}
.t-drop:hover, .t-drop:focus-visible { border-color: var(--color-accent); color: var(--color-ink-soft); }
.t-drop:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.t-drop.is-drag { border-color: var(--color-accent); background: var(--color-surface); color: var(--color-ink); }
.t-drop.is-lleno { border-style: solid; border-color: var(--color-accent); color: var(--color-ink); }
.t-drop-ic { width: var(--space-7); height: var(--space-7); color: currentColor; }
.t-drop-t { font-size: var(--text-sm); line-height: 1.5; word-break: break-word; }

/* Un enlace de acción secundaria (p. ej. bajar la plantilla dentro del modal). */
.t-enlace {
  align-self: flex-start;
  font-size: var(--text-xs); color: var(--color-accent);
  text-decoration: underline; text-underline-offset: 2px;
}
.t-enlace:hover { color: var(--color-ink); }
.t-enlace:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm); }
