/*
  Estilos del copiloto. Escritos a mano, sin framework y sin build.

  El criterio es el de una herramienta de trabajo, no el de una app de chat: texto
  cómodo de leer durante horas, jerarquía clara entre la respuesta y sus avisos, y
  nada que se mueva sin motivo. Un contador va a tener esto abierto todo el día al
  lado de una planilla.
*/

/*
  La paleta, y por qué es violeta.

  El acento es **el violeta del logo de Amethy**, `#7956cc`, tomado del archivo y no
  elegido a ojo. Va como acento contenido sobre papel casi blanco —enlaces, foco, un
  par de botones—, **nunca como fondo de pantalla y nunca en degradado**: el violeta
  eléctrico en degradado hacia el azul es la marca de agua de lo generado por defecto,
  y es justo lo que hace que una herramienta parezca una demo.

  **Hay dos violetas y no uno.** El de la marca rellena; para texto sobre fondos claros
  se usa `--acento-texto`, que es el mismo tono oscurecido. No es capricho: el violeta
  del logo sobre el tinte claro da 4,6:1, que pasa raspando, y varias etiquetas de la
  interfaz son de 11 px. El oscurecido da 6,8:1 sobre el tinte y 7,9:1 sobre blanco.

  Los neutros llevan un dejo de violeta en lugar de ser grises puros. La diferencia no
  se nota mirando un color solo; se nota en el conjunto, que es lo que separa una
  paleta elegida de un acento pegado encima de una gris.

  Los tres colores con significado —alerta, error y el verde del "salió bien"— **no**
  se tiñeron: un aviso tiene que leerse como aviso aunque cambie la marca, y son las
  únicas señales que la persona interpreta por color antes que por texto.

  Contraste verificado sobre papel: el acento da 7:1 y la tinta suave 6:1, los dos por
  encima del mínimo de AA para texto normal.
*/

:root {
  --tinta: #1f1b26;
  --tinta-suave: #625c6e;
  --papel: #f8f7fa;
  --superficie: #ffffff;
  --borde: #e3e0e9;
  --acento: #7956cc;
  --acento-texto: #5c3da6;
  --acento-suave: #f2edfb;
  --alerta: #8a5a00;
  --alerta-fondo: #fdf6e7;
  --error: #9b2c2c;
  /* El verde del semáforo del estado del sistema. Es apagado a propósito: la
     paleta de Amethy es violeta y un verde saturado al lado del acento se roba
     la pantalla. Además es lo bastante oscuro para leerse sobre su propio fondo
     claro, que es lo que decide si el cartel sirve. */
  --ok: #2f6b4f;
  --ok-fondo: #eef6f1;
  --radio: 8px;
  --ancho-texto: 68ch;
  /* El redactor de mails es más ancho que la prosa a propósito. `--ancho-texto` es
     la medida cómoda para **leer** un párrafo; acá se escribe y se pega un mail
     entero, y a 68ch un mail de tres párrafos obliga a escribir por una ranura. */
  --ancho-redaccion: 92ch;
  --ancho-pregunta: 46ch;
  /* Dos sombras y ninguna llamativa. La primera levanta apenas una tarjeta del
     papel; la segunda es para lo que flota de verdad —el login— y sigue siendo
     suave. Una sombra fuerte sobre fondo casi blanco se lee como suciedad. */
  --sombra: 0 1px 2px rgba(31, 27, 38, 0.04), 0 1px 3px rgba(31, 27, 38, 0.03);
  --sombra-alta: 0 1px 2px rgba(31, 27, 38, 0.04), 0 8px 24px rgba(31, 27, 38, 0.07);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--papel);
  color: var(--tinta);
  font: 16px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* El enlace para saltar el menú: invisible hasta que se lo enfoca con el teclado.
   Sin esto, llegar al campo de consulta con Tab obliga a pasar por toda la lista de
   conversaciones. */
.saltar {
  position: absolute;
  left: -9999px;
}
.saltar:focus {
  left: 1rem;
  top: 1rem;
  z-index: 10;
  background: var(--superficie);
  padding: 0.5rem 1rem;
  border-radius: var(--radio);
}

.visualmente-oculto {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.disposicion {
  display: grid;
  grid-template-columns: 280px 1fr;
  min-height: 100vh;
}

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

/* `sticky` y alto de ventana: con la página scrolleando, un lateral que se estira a
   todo el largo del documento se llevaría la lista de conversaciones y el botón de
   salir hacia abajo, y habría que scrollear tres pantallas para cambiar de hilo. */
.lateral {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--borde);
  background: var(--superficie);
}

.lateral__cabecera { padding: 1rem; }

/* Las secciones, en columna y con el mismo ancho. Sueltos, el navegador los ponía
   dos en un renglón y uno en el siguiente, cada uno del ancho de su texto. */
.lateral__nav { display: grid; gap: 0.15rem; margin-top: 0.75rem; }
.lateral__nav .boton {
  text-align: left;
  padding: 0.5rem 0.7rem;
  border-color: transparent;
  transition: background-color 0.12s ease;
}
.lateral__nav .boton:hover { background: var(--papel); }
.lateral__nav .boton--aca { background: var(--acento-suave); }

/* El único botón lleno del lateral es el que hace algo, no el que dice dónde estás. */
.lateral__cabecera .boton--principal { display: block; text-align: center; }
.lateral__hilos { flex: 1; overflow-y: auto; padding: 0 0.5rem; }
.lateral__pie {
  border-top: 1px solid var(--borde);
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  font-size: 0.9rem;
}

.hilo {
  display: block;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radio);
  color: var(--tinta);
  text-decoration: none;
  font-size: 0.92rem;
  /* Un título largo se corta con puntos suspensivos en vez de romper el ancho del
     panel: los títulos salen de la primera pregunta y pueden ser largos. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hilo { transition: background-color 0.12s ease; }
.hilo:hover { background: var(--papel); }
/* La conversación abierta se marca con el tinte **y** con el acento al costado, el
   mismo recurso que usa la navegación para decir en qué pantalla estás. Con el tinte
   solo, en una lista de treinta hilos el activo se pierde apenas se hace scroll. */
.hilo--activo,
.hilo-fila--activa {
  background: var(--acento-suave);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--acento);
}

/* El hilo y su botón de archivar van en una fila. El botón no puede ir *dentro* del
   enlace —un `<button>` adentro de un `<a>` no es HTML válido y cada navegador lo
   desarma distinto—, así que comparten fila y el enlace se queda con todo el ancho
   sobrante. */
.hilo-fila {
  display: flex;
  align-items: center;
  border-radius: var(--radio);
}
.hilo-fila .hilo { flex: 1; min-width: 0; }
.hilo-fila:hover { background: var(--papel); }
.hilo-fila--activa .hilo { background: none; box-shadow: none; }

/* Aparece al pasar por encima, y también al llegar con el teclado: si solo
   respondiera a `:hover`, quien navega con Tab no tendría cómo archivar nada. */
.hilo__archivar {
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  margin-right: 0.35rem;
  border: 0;
  border-radius: var(--radio);
  background: none;
  color: var(--tinta-suave);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease, background-color 0.12s ease, color 0.12s ease;
}
.hilo-fila:hover .hilo__archivar,
.hilo__archivar:focus-visible { opacity: 1; }
.hilo__archivar:hover { background: var(--acento-suave); color: var(--tinta); }

/* En pantalla táctil no hay `hover`, así que el botón sería invisible para siempre. */
@media (hover: none) {
  .hilo__archivar { opacity: 1; }
}

.lateral__vacio {
  color: var(--tinta-suave);
  font-size: 0.9rem;
  padding: 0.6rem 0.75rem;
  margin: 0;
}
/* La primera consulta de alguien agrega su hilo al lateral con un `hx-swap-oob`, que
   inserta y no reemplaza: sin esto, el "todavía no preguntaste nada" queda debajo de
   la conversación que acaba de aparecer. */
.lateral__hilos:has(.hilo-fila) .lateral__vacio { display: none; }

.quien { color: var(--tinta-suave); }

/* --- Chat ---------------------------------------------------------------- */

.principal { display: flex; flex-direction: column; min-width: 0; }

/* **La página scrollea entera, y eso es deliberado.** Acá había `height: 100vh`, que
   clavaba el chat al alto exacto de la ventana y dejaba scrollear solo la columna de
   mensajes por dentro. Se veía bien y se usaba mal: la rueda del mouse no movía nada
   si el puntero caía fuera de esa columna, no se podía alejar la vista para leer una
   respuesta larga de corrido, y con el zoom del navegador alto el cuadro de escribir
   quedaba apretado contra el borde de abajo.

   `min-height` y no `height`: en una conversación corta el chat sigue ocupando la
   pantalla —el cuadro de escribir no queda flotando en el medio— y en una larga crece
   lo que haga falta. `dvh` y no `vh` porque en el celular la barra del navegador
   aparece y desaparece, y `vh` mide siempre la ventana sin barra: con `vh` el cuadro
   de escribir queda debajo del borde visible justo cuando la barra está.

   Lo que hace que esto no empeore nada es que el cuadro de escribir es `sticky`: la
   página se mueve libre y el lugar donde se pregunta sigue estando siempre a la vista. */
.chat {
  display: grid;
  grid-template-rows: 1fr auto auto;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 1.5rem;
  min-height: 100dvh;
  padding: 1.5rem;
}

/* La conversación va **centrada** en su columna, no pegada al borde izquierdo.
   En una pantalla ancha —que es donde esto se usa, al lado de una planilla— el texto
   arrancaba en el extremo izquierdo con medio metro de papel vacío a la derecha, y
   eso es lo que hace que una herramienta se vea sin terminar.

   El truco es una sola pista de grilla del ancho del texto: los mensajes se apoyan
   en ella y el `margin-left: auto` de la pregunta sigue funcionando adentro. */
.chat__mensajes {
  grid-column: 1;
  display: grid;
  align-content: start;
  justify-content: center;
  grid-template-columns: minmax(0, var(--ancho-texto));
  padding: 0 0.5rem;
}

/* La barra fina que había acá se fue con el scroll interno: ahora la que se ve es la
   de la página, que es la que el navegador ya dibuja como corresponde. Se conserva en
   la lista de conversaciones, que sí sigue scrolleando por dentro. */
.lateral__hilos { scrollbar-width: thin; scrollbar-color: var(--borde) transparent; }
.lateral__hilos::-webkit-scrollbar { width: 8px; }
.lateral__hilos::-webkit-scrollbar-thumb {
  background: var(--borde);
  border-radius: 999px;
}

.mensaje {
  max-width: var(--ancho-texto);
  margin: 0 0 1.25rem;
  padding: 1.1rem 1.35rem;
  border-radius: var(--radio);
  background: var(--superficie);
  border: 1px solid var(--borde);
  box-shadow: var(--sombra);
  /* El ancla del enlace permanente cae acá: sin este margen, al saltar desde Teams
     el mensaje queda pegado al borde superior y parece cortado. */
  scroll-margin-top: 1.5rem;
}

/* La pregunta se lee como una pregunta: más angosta que la respuesta, sin borde ni
   sombra, y corrida a la derecha. Con el mismo ancho y la misma tarjeta que la
   respuesta, las dos cosas pesaban igual en la pantalla — y no pesan igual: una es
   lo que alguien tipeó en diez segundos y la otra es lo que hay que leer con
   atención. */
.mensaje--usuario {
  max-width: var(--ancho-pregunta);
  background: var(--acento-suave);
  border-color: transparent;
  box-shadow: none;
  margin-left: auto;
  padding: 0.85rem 1.1rem;
}

.mensaje__cabecera {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.8rem;
  color: var(--tinta-suave);
  margin-bottom: 0.5rem;
}
.mensaje__quien {
  font-weight: 600;
  text-transform: capitalize;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
/* Quién contestó, con el acento: de un vistazo se distingue la respuesta de
   Alfred de la pregunta propia sin leer una palabra. */
.mensaje--asistente .mensaje__quien { color: var(--acento-texto); }
/* Los agentes que trabajaron van después del nombre y más livianos: son el
   detalle, no el interlocutor. */
.mensaje__agentes { font-weight: 400; color: var(--tinta-suave); }

/* El bigote de Alfred (`_alfred.html`). Círculo en el violeta suave, bigote en el
   violeta de texto: los dos tonos de la marca, sin degradado. `currentColor` hace
   que tome el color del texto donde esté; el círculo se pinta acá y no en el SVG
   para que el fondo cambie con el tema y no con el archivo. */
.alfred {
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--acento-suave);
  color: var(--acento-texto);
}

.mensaje__cuerpo > *:first-child { margin-top: 0; }
.mensaje__cuerpo > *:last-child { margin-bottom: 0; }

/* El markdown de una respuesta necesita su propio ritmo. Con los tamaños por defecto
   del navegador, un `##` adentro de un mensaje sale más grande que el título de la
   pantalla, y una respuesta con tres subtítulos se lee como tres respuestas. */
.mensaje__cuerpo h1,
.mensaje__cuerpo h2,
.mensaje__cuerpo h3 {
  font-size: 1rem;
  line-height: 1.4;
  margin: 1.25rem 0 0.5rem;
}
.mensaje__cuerpo ul,
.mensaje__cuerpo ol { padding-left: 1.3rem; margin: 0.6rem 0; }
.mensaje__cuerpo li { margin-bottom: 0.3rem; }
.mensaje__cuerpo p { margin: 0.7rem 0; }

.mensaje__cuerpo code {
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.88em;
  padding: 0.1rem 0.3rem;
  border-radius: 4px;
  background: var(--papel);
  border: 1px solid var(--borde);
}
.mensaje__cuerpo pre {
  overflow-x: auto;
  padding: 0.8rem 1rem;
  border-radius: var(--radio);
  background: var(--papel);
  border: 1px solid var(--borde);
}
.mensaje__cuerpo pre code { border: none; padding: 0; background: none; }

/* Una cita adentro de una respuesta es normativa transcripta: se marca con el
   acento al costado, que es como se marca lo citado en todo el resto del sistema. */
.mensaje__cuerpo blockquote {
  margin: 0.8rem 0;
  padding: 0.1rem 0 0.1rem 0.9rem;
  border-left: 3px solid var(--acento-suave);
  color: var(--tinta-suave);
}

.mensaje__cuerpo a { color: var(--acento-texto); }
.mensaje__cuerpo table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.92rem;
}
.mensaje__cuerpo th,
.mensaje__cuerpo td {
  border: 1px solid var(--borde);
  padding: 0.4rem 0.6rem;
  text-align: left;
}
/* Dos acciones y no una: ver las fuentes y anotar el criterio correcto. `wrap`
   porque el segundo abre un formulario que ocupa el ancho entero. */
.mensaje__pie {
  margin-top: 0.75rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: flex-start;
}

/* Anotar el criterio del estudio desde una respuesta (D9).

   Va cerrado. La acción normal frente a una respuesta es leerla; corregir el
   criterio del estudio es lo excepcional, y un formulario de cuatro campos abierto
   debajo de cada mensaje convertiría la conversación en un cuestionario. */
/* El pulgar arriba/abajo. Va antes que anotar el criterio porque es lo que se hace
   seguido: un clic contra un formulario de cuatro campos. */
.valorar { display: contents; }
.valorar__hecho { font-size: 0.85rem; color: var(--tinta-suave); }
.valorar__mal summary { cursor: pointer; display: inline-block; }
.valorar__mal summary::-webkit-details-marker { display: none; }
.valorar__forma {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.6rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--papel);
  min-width: 22rem;
  max-width: 100%;
}
.valorar__forma input { font: inherit; }

/* `display: contents` y no una caja: los controles de adentro pasan a ser hijos
   directos del pie del mensaje, así que "ver las fuentes", el pulgar y "anotar el
   criterio" comparten **una sola fila** que envuelve cuando no entra. Con una caja
   propia, cada grupo se llevaba su renglón y el pie quedaba en tres escalones. */
.mensaje__acciones { display: contents; }

/* El borrador que escribió el copiloto se marca. Un texto que el modelo redactó y uno
   que escribió una persona no se pueden ver igual: quien lo manda a la firma tiene que
   saber cuál de los dos está leyendo. */
.anotar__nota--borrador {
  border-left: 3px solid var(--acento);
  padding-left: 0.6rem;
  color: var(--tinta);
}

/* El borrador que vino de internet se marca en el ámbar del aviso, el mismo del
   cartel de arriba del mensaje y nunca el violeta de la marca (D43): quien lo manda
   a la firma tiene que ver que está adoptando algo que nadie del estudio verificó. */
.anotar__nota--internet {
  border-left: 3px solid var(--alerta);
  padding-left: 0.6rem;
  color: var(--tinta);
}

/* "Guardar en el corpus" va solo, debajo de las fuentes web, y no en el pie: el pie
   no existe para una respuesta de internet, y no hay que darle una fila que sugiera
   que faltan los otros botones. */
.mensaje__guardar { margin-top: 0.75rem; }

/* Cerrado, el `<details>` es un botón más de la fila. Abierto, se lleva el renglón
   entero: un formulario de cuatro campos con el ancho de su resumen es ilegible. */
.anotar[open],
.valorar__mal[open] { width: 100%; }
.anotar summary { cursor: pointer; display: inline-block; }
.anotar summary::-webkit-details-marker { display: none; }

.anotar__form {
  margin-top: 0.6rem;
  padding: 0.85rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--papel);
}
.anotar__nota {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.85rem;
  color: var(--tinta-suave);
}

/* --- Avisos -------------------------------------------------------------- */

.aviso {
  margin: 0.75rem 0 0;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radio);
  border-left: 3px solid var(--alerta);
  background: var(--alerta-fondo);
  font-size: 0.9rem;
}
.aviso ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }

/* El aviso del 80% del tope. Va arriba de la conversación y no al pie: es una
   advertencia sobre lo que conviene hacer **antes** de escribir la consulta
   siguiente, y al pie se lee después de haberla pagado. */
.aviso--presupuesto {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
}
.aviso--presupuesto:empty { display: none; }

/* El aviso de "se guardó en el corpus". Va arriba, junto al del presupuesto, y no
   pegado a la respuesta: habla del archivo, no de lo que se contestó.

   En violeta y no en ámbar a propósito. El ámbar de `.aviso` es para lo que hay que
   corregir; esto, casi siempre, es algo que salió bien y que además avisa que falta
   un paso de otra persona. Pintarlo de advertencia haría que un guardado exitoso se
   leyera como un problema cada vez. */
.aviso--corpus {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border-left-color: var(--acento);
  background: var(--acento-suave);
  color: var(--acento-texto);
}
.aviso--corpus:empty { display: none; }

/* El "no tengo respaldo" se muestra con el mismo peso que una respuesta: decirlo es
   el producto (D25), no una falla que haya que disimular. */
.aviso--sin-respaldo {
  border-left-color: var(--error);
  background: #fdf0f0;
  color: var(--error);
  font-weight: 600;
}

/* --- La respuesta que vino de internet ------------------------------------
   El violeta de la marca es el color de lo que el estudio respalda. Una respuesta
   sin respaldo NO puede usarlo, y tampoco puede usar el rojo del error: no falló
   nada. Va en el ámbar del aviso, que en esta hoja ya significa "leelo antes de
   seguir", y con el fondo tramado para que se distinga incluso en blanco y negro
   o en una captura de pantalla comprimida. */
.mensaje--internet {
  border-left: 3px solid var(--alerta);
  background: var(--alerta-fondo);
  background-image: repeating-linear-gradient(
    135deg,
    transparent 0 10px,
    rgba(138, 90, 0, 0.035) 10px 20px
  );
}

.aviso--internet {
  border-left-color: var(--alerta);
  background: #fbeeda;
  color: var(--alerta);
}
.aviso--internet strong { font-weight: 600; }
/* En el panel de revisión el aviso lleva las fuentes adentro: mismo ámbar, y el
   listado hereda el estilo de las fuentes web del chat. */
.propuesta__internet { margin-bottom: 0.75rem; }
.propuesta__internet p { margin: 0; }
.propuesta__internet .fuentes-web { margin: 0.5rem 0 0; }

/* Una respuesta que salió del archivo y no del modelo (D48). Verde y no ámbar: no
   es una advertencia, es una buena noticia —salió casi gratis— que igual hay que decir. */
.aviso--reutilizada {
  border-left-color: var(--ok);
  background: var(--ok-fondo);
  color: var(--ok);
}
.aviso--reutilizada p { margin: 0; }
.aviso--reutilizada strong { font-weight: 600; }
.aviso__accion { margin-top: 0.5rem; }

.fuentes-web {
  margin: 0.75rem 0 0;
  padding-left: 1.2rem;
  font-size: 0.9rem;
  color: var(--tinta-suave);
}
.fuentes-web__item { margin-bottom: 0.25rem; }
.fuentes-web__item a { color: var(--alerta); }
.fuentes-web__dominio {
  color: var(--tinta-suave);
  font-size: 0.85em;
}
.fuentes-web__dominio::before { content: " · "; }

/* Al imprimir no aparece, porque el pie con "Guardar como PDF" tampoco se le
   ofrece. Si alguien igual manda a imprimir la página entera, el aviso tiene que
   viajar con el texto: es el único caso en que esto llega al papel. */
@media print {
  .mensaje--internet { background: none; border-left: 3px solid #000; }
  .aviso--internet { border: 1px solid #000; color: #000; background: none; }
  /* El cartel de reutilización es de la pantalla: en el papel va la respuesta con
     sus fuentes, que son las mismas que tenía la original. */
  .aviso--reutilizada { display: none; }
}

/* --- Formulario ---------------------------------------------------------- */

/* Lo que va en la columna del texto se centra con ella. Sin esto, la conversación
   quedaba centrada y el cuadro de escribir seguía pegado a la izquierda. */
.consultar,
.progreso,
#error-consulta,
.aviso--presupuesto,
.aviso--corpus,
.chat > .aviso {
  grid-column: 1;
  width: 100%;
  max-width: var(--ancho-texto);
  margin-inline: auto;
}

/* El cartel de un pedido rechazado. Va **en la columna del texto y pegado al
   compositor**, que es donde está mirando quien acaba de apretar Consultar: la regla
   de arriba lo trae a la columna 1 —sin ella la grilla lo mandaba a la columna del
   panel de fuentes, contra el borde derecho, lejos de lo que lo produjo—.

   Vacío no ocupa nada. Sin esto, el hueco de un error que no ocurrió empujaría el
   cuadro de escribir hacia arriba en cada carga de la pantalla. */
#error-consulta:empty { display: none; }
#error-consulta .aviso { margin: 0 0 0.5rem; }

/* El compositor es **una** caja con el botón adentro, y no un textarea al lado de un
   botón. La diferencia se nota al escribir: con dos controles sueltos, el foco
   ilumina medio renglón y el resto queda flotando. */
/* En columna desde que hay una fila de acciones abajo. Antes era una fila sola
   —textarea y botón, uno al lado del otro—; con el adjuntador en el medio, esa
   disposición empujaba el texto a un canal cada vez más angosto. */
/* Pegado al borde de abajo mientras la página se mueve. Es la contracara de haberle
   sacado el alto fijo al chat: sin esto, preguntar de nuevo en una conversación de
   treinta mensajes obligaría a bajar hasta el final cada vez.

   `bottom: 0` se mide contra la ventana y no contra el `padding` del chat, así que
   mientras está pegado no queda ninguna franja por donde se vea pasar el texto: el
   cuadro es opaco y los mensajes le pasan por detrás. Al llegar al final del todo se
   despega solo y vuelve a su lugar, con el aire del `padding` debajo. */
.consultar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem;
  border: 1px solid var(--borde);
  border-radius: 12px;
  background: var(--superficie);
  box-shadow: var(--sombra);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.consultar:focus-within {
  border-color: var(--acento);
  box-shadow: 0 0 0 3px var(--acento-suave);
}
.consultar textarea {
  border: none;
  background: none;
  padding: 0.5rem 0.6rem;
  box-shadow: none;
  width: 100%;
  resize: vertical;
}

/* La fila de abajo: adjuntar a la izquierda, consultar a la derecha, y los nombres
   de los archivos ocupando lo que sobra.

   **Envuelve.** Con tres controles y el nombre del archivo, en una pantalla
   angosta no entra todo en un renglón: sin `wrap`, el botón de consultar se monta
   encima de la casilla y las dos cosas quedan a medio leer. Se descubrió capturando
   el chat a 430 px, que es el ancho donde nadie mira. */
.consultar__pie {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  row-gap: 0.5rem;
  align-items: center;
  padding-inline: 0.1rem;
}
.consultar__pie .boton--principal { margin-inline-start: auto; }

/* La casilla de guardar en el corpus. `flex: 0 0 auto` para que no la achique el
   nombre de un archivo largo: es un control con el que se decide algo, y medio
   texto cortado sobre una casilla tildable se lee como un error de la pantalla. */
.consultar__corpus {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--tinta-suave);
  cursor: pointer;
}

.consultar__corpus label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
}
.consultar__corpus input {
  accent-color: var(--acento);
  margin: 0;
}
/* El "qué es" (D50), del mismo tamaño y color que la casilla: es parte de la misma
   decisión, no un control aparte. */
.consultar__corpus select {
  font: inherit;
  font-size: 0.85rem;
  color: var(--tinta);
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  max-width: 18rem;
}

/* Los archivos elegidos. En una línea y con puntos suspensivos: cinco nombres
   largos empujarían el botón de consultar fuera de la caja. El `title` del navegador
   no alcanza acá, así que la lista completa se ve al pasar el mouse por el texto. */
.consultar__adjuntos {
  min-width: 0;
  /* `1 1 6rem` y no `1`: la base flexible deja que el nombre se achique hasta seis
     caracteres y recién ahí empuje a la casilla y al botón al renglón de abajo. Con
     `flex: 1` la base es cero, el nombre nunca fuerza el wrap y los controles se
     apretaban unos contra otros hasta solaparse. */
  flex: 1 1 6rem;
  font-size: 0.85rem;
  color: var(--tinta-suave);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* El `label` que hace de botón de adjuntar. Sin esto se comporta como texto: no
   muestra la manito y el `padding` del `.boton` no le aplica del todo. */
.consultar__pie label.boton {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  white-space: nowrap;
}

/* El foco del `input` oculto tiene que verse en el `label`, que es lo único que se
   ve. Sin esto, recorrer el formulario con Tab pasa por el adjuntador sin que nada
   lo indique. */
.consultar input[type="file"]:focus-visible + label.boton {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
}
.consultar textarea:focus-visible {
  outline: none;
  border: none;
  box-shadow: none;
}

/* --- Campos ---------------------------------------------------------------

   **Esto faltaba entero.** No había una sola regla para `input` ni para `select`:
   cada formulario del sistema dibujaba una tarjeta prolija y adentro ponía los
   controles crudos del navegador, que en Windows vienen con su borde gris de 1995.
   La pantalla se veía a medio terminar, y no por falta de trabajo sino porque nunca
   se escribió esta sección.

   El selector va por tipo y no `input` a secas: un `[type=hidden]` con padding
   ocupa lugar, y una casilla de verificación estirada al 100% es un rectángulo
   enorme. Los tipos se enumeran; los que falten se agregan el día que aparezcan.
   --------------------------------------------------------------------------- */

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="date"],
input:not([type]),
select,
textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  font: inherit;
  color: var(--tinta);
  background: var(--superficie);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

input::placeholder,
textarea::placeholder { color: var(--tinta-suave); opacity: 0.75; }

/* El ancho completo es el default correcto porque casi todos los formularios del
   sistema apilan sus campos. Las dos excepciones son filas horizontales —el pie del
   redactor y el cambio de rol de una cuenta—, donde un `select` estirado empuja el
   botón fuera de la fila. Se listan acá y no se resuelve al revés: si el default
   fuera `auto`, cada formulario nuevo nacería con los campos encogidos y habría que
   acordarse de estirarlos. */
.redactar__pie select,
.cuentas__enlinea select,
.cuentas__enlinea input { width: auto; }

textarea {
  flex: 1;
  padding: 0.75rem;
  resize: vertical;
}

/* Un `label` suelto arriba de su campo: chico, firme y con aire. Es lo que hace que
   un formulario se lea como una lista de preguntas y no como un bloque de cajas. */
label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--tinta-suave);
  margin-bottom: 0.3rem;
}

.campo { display: block; }

/* El foco se marca con el acento **y** con un anillo suave alrededor. El outline
   solo es correcto para accesibilidad pero se ve prestado; el anillo lo integra al
   resto sin perder los 2 px que hacen que se vea desde lejos. */
input[type="text"]:focus-visible,
input[type="email"]:focus-visible,
input[type="password"]:focus-visible,
input[type="search"]:focus-visible,
input[type="number"]:focus-visible,
input[type="date"]:focus-visible,
input:not([type]):focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: none;
  border-color: var(--acento);
  box-shadow: 0 0 0 3px var(--acento-suave);
}

.boton:focus-visible,
summary:focus-visible,
a:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
}

.boton {
  padding: 0.6rem 1.1rem;
  border-radius: var(--radio);
  border: 1px solid var(--borde);
  background: var(--superficie);
  color: var(--tinta);
  font: inherit;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  line-height: 1.4;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}
/* Un botón y un campo de texto tenían el mismo borde, el mismo radio y el mismo
   fondo: desde que los campos dejaron de ser los crudos del navegador, en un
   formulario no se distinguía cuál de los dos rectángulos se podía apretar. El
   `hover` es lo que los separa — un campo no reacciona al pasar por encima. */
.boton:hover { background: var(--papel); border-color: var(--tinta-suave); }
.boton--principal {
  background: var(--acento);
  border-color: var(--acento);
  color: #fff;
  font-weight: 600;
}
.boton--principal:hover { background: var(--acento-texto); border-color: var(--acento-texto); }
.boton--discreto:hover { background: var(--acento-suave); border-color: var(--acento); }
.boton--discreto {
  padding: 0.35rem 0.6rem;
  font-size: 0.85rem;
  color: var(--acento-texto);
}
/* Sacar de uso un criterio. Usa el ámbar de `--alerta` y no un rojo nuevo: en esta
   pantalla el ámbar ya significa "mirá esto antes de seguir" —lo usa el cartel de los
   criterios sin indexar— y retirar es exactamente eso, no una emergencia. Un rojo
   propio sumaría un tercer color de aviso a un producto que tiene dos. */
.boton--retirar { color: var(--alerta); }
.boton--retirar:hover { background: var(--alerta-fondo); border-color: var(--alerta); }

.boton[disabled] { opacity: 0.55; cursor: progress; }

/* --- Progreso ------------------------------------------------------------ */

.progreso {
  grid-column: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-height: 1.9rem;
  margin: 0.5rem 0;
  font-size: 0.85rem;
  color: var(--tinta-suave);
}
.etapa {
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--superficie);
  border: 1px solid var(--borde);
}
.etapa--actual { border-color: var(--acento); color: var(--acento-texto); font-weight: 600; }

/* --- Fuentes ------------------------------------------------------------- */

.fuentes {
  grid-column: 2;
  grid-row: 1 / -1;
  width: 0;
  overflow: hidden;
  transition: width 120ms ease-out;
}
/* El panel solo ocupa lugar cuando tiene algo adentro: con la pantalla vacía, el
   chat usa todo el ancho. */
.fuentes:has(.fuentes__contenido) {
  width: 380px;
  overflow-y: auto;
  border-left: 1px solid var(--borde);
  padding-left: 1.25rem;
}

.fuentes__titulo { font-size: 1rem; }
.fuentes__lista { padding-left: 1.2rem; }
.fuente { margin-bottom: 1.25rem; font-size: 0.88rem; }
.fuente__afirmacion { font-weight: 600; margin: 0 0 0.35rem; }
.fuente__origen { margin: 0 0 0.35rem; color: var(--tinta-suave); }
.fuente__texto {
  margin: 0.5rem 0 0;
  padding: 0.6rem 0.8rem;
  background: var(--superficie);
  border-left: 3px solid var(--borde);
  white-space: pre-wrap;
}
.fuente--inaccesible { opacity: 0.75; }
.fuente__origen--oculto { font-style: italic; }

.etiqueta {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  border-radius: 4px;
  background: var(--acento-suave);
  color: var(--acento-texto);
  font-size: 0.78rem;
  font-weight: 600;
}
/* Lo que no es norma se marca en ámbar, el color de los avisos: una opinión del
   Consejo citada como si rigiera es el error que este panel existe para evitar. */
.etiqueta--doctrina { background: var(--alerta-fondo); color: var(--alerta); }

/* --- Pantallas sueltas --------------------------------------------------- */

/* La pantalla de una consulta nueva. Es lo primero que ve alguien cada mañana, y
   estaba resuelta con dos reglas: un párrafo gris pegado arriba a la izquierda.
   Ahora se apoya sobre el compositor, que es a donde tiene que ir la vista. */
.vacio {
  color: var(--tinta-suave);
  max-width: var(--ancho-texto);
  margin: auto 0 2rem;
  padding: 1rem 0;
}
/* En la bienvenida el bigote va solo, arriba del saludo, del tamaño de un avatar. */
.vacio .alfred { display: block; margin-bottom: 0.9rem; }
.vacio h1 {
  color: var(--tinta);
  font-size: 1.6rem;
  line-height: 1.25;
  margin: 0 0 0.6rem;
  letter-spacing: -0.01em;
}
.vacio p { margin: 0; max-width: 52ch; }

/* La pantalla vacía se empuja hacia abajo; una conversación con mensajes arranca
   arriba. `align-content` de la grilla lo resuelve sin JavaScript. */
.chat__mensajes:has(.vacio) { align-content: end; }

/* **Y desaparece en cuanto llega el primer mensaje.** htmx agrega el turno con
   `beforeend`, o sea que inserta y no reemplaza: sin esta regla, el "¿Qué necesitás
   consultar?" se queda arriba de la conversación hasta que alguien recargue la
   página. Se vio en la primera prueba con un navegador de verdad, el 2026-09-06.
   Mismo caso que el "todavía no preguntaste nada" del lateral. */
.chat__mensajes:has(.mensaje) .vacio { display: none; }
.chat__mensajes:has(.mensaje) { align-content: start; }

/* --- Entrar ---------------------------------------------------------------

   La única pantalla que ve alguien que todavía no entró, así que es la única donde
   la marca hace algo. Y hasta ahora era una caja de 46 rem —el ancho de una página
   de texto— con dos campos adentro: el formulario nadaba, y los campos eran los
   crudos del navegador.

   Ahora es una tarjeta angosta, centrada en la pantalla y no a cuatro centímetros
   del borde de arriba. `min-height: 100dvh` y no `100vh` por el navegador del
   teléfono, donde la barra de direcciones se come el 100vh y deja la tarjeta
   cortada.
   --------------------------------------------------------------------------- */

.entrar {
  width: 100%;
  max-width: 26rem;
  margin: 0 auto;
  padding: 2.25rem 2rem;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: 12px;
  box-shadow: var(--sombra-alta);
}

/* La pantalla de entrar no tiene barra lateral: ocupa todo y centra su tarjeta. */
.disposicion:has(.entrar) { grid-template-columns: 1fr; }
.principal:has(.entrar) {
  justify-content: center;
  align-items: center;
  min-height: 100dvh;
  padding: 2rem 1rem;
}

/* El bigote en la puerta: centrado, en el violeta de texto, pegado al saludo. */
.entrar .alfred { display: block; margin: 0 auto 0.5rem; }

.entrar h1 {
  font-size: 1.35rem;
  text-align: center;
  margin: 0 0 0.4rem;
  color: var(--tinta);
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* La frase debajo del saludo. Va en tinta suave y chica: es la presentación, no el
   título, y no tiene que competir con el formulario que viene abajo. */
.entrar__frase {
  font-size: 0.9rem;
  line-height: 1.45;
  text-align: center;
  margin: 0 auto 1.75rem;
  max-width: 30ch;
  color: var(--tinta-suave);
}

.entrar__form { display: grid; gap: 0.25rem; }
.entrar__form label { margin-top: 0.75rem; }
.entrar__form button { margin-top: 1.5rem; width: 100%; }

/* El error del login lleva el rojo de error y no el ámbar de aviso: no es algo que
   convenga mirar, es algo que impidió entrar. El texto es el mismo para un mail que
   no existe y para una contraseña equivocada — eso lo decide el servidor, no esta
   regla, pero conviene recordarlo acá. */
.entrar__error {
  margin: 0 0 0.5rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radio);
  border-left: 3px solid var(--error);
  background: #fdf0f0;
  color: var(--error);
  font-size: 0.9rem;
}

.entrar__ayuda {
  margin: 1.75rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--borde);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--tinta-suave);
}

.error {
  max-width: 46rem;
  margin: 4rem auto;
  padding: 2rem;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
}
.persona__email, .persona__roles { color: var(--tinta-suave); font-size: 0.85rem; }

/* --- Redacción de mails (/redactar) -------------------------------------- */

/*
  Un borrador se lee distinto que una respuesta del copiloto: es texto plano que se
  va a copiar tal cual, así que se muestra en monoespaciada y respetando los saltos
  de línea. Si acá se aplicara el interlineado del chat, el mail se vería de una
  manera en pantalla y de otra en el cliente de correo.
*/
/* La columna de la grilla también, o el `max-width` de abajo no hace nada: los mails
   viven dentro de `.chat__mensajes`, que fija una pista del ancho de la prosa. Un
   `max-width` mayor que su pista de grilla se ignora en silencio, que es la forma
   más común de "cambié el CSS y no pasó nada". */
#mails { grid-template-columns: minmax(0, var(--ancho-redaccion)); }

/* Los mails acompañan el ancho del compositor. Con el borrador angosto y la caja de
   escribir ancha, el mismo texto se ve con dos anchos distintos y da la sensación de
   que el que se copia no es el que se escribió. */
.mail {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 0.9rem 1.1rem;
  margin-bottom: 1rem;
  max-width: var(--ancho-redaccion);
}
.mail--pedido { background: var(--acento-suave); border-color: transparent; }
.mail__cabecera {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  color: var(--tinta-suave);
}
.mail__quien { font-weight: 600; color: var(--tinta); }
.mail__tono {
  border: 1px solid var(--borde);
  border-radius: 999px;
  padding: 0 0.5rem;
}
.mail__hora { margin-left: auto; }
.mail__cuerpo {
  white-space: pre-wrap;
  font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
  font-size: 0.95rem;
  line-height: 1.55;
}
.mail__pie { margin-top: 0.75rem; }

.aviso--datos {
  background: var(--alerta-fondo);
  color: var(--alerta);
  border-left: 3px solid var(--alerta);
  padding: 0.75rem 1rem;
  border-radius: var(--radio);
  margin: 0 0 1rem;
}

/* El compositor de mails, más grande que el del chat. Una consulta son dos
   renglones; un mail son varios párrafos y encima suele haber otro mail pegado
   arriba. Con la caja del chat, escribirlo se siente como hacerlo por una ranura. */
.redactar {
  max-width: var(--ancho-redaccion);
  padding: 0.9rem;
  gap: 0.75rem;
}
.redactar textarea {
  min-height: 5.5rem;
  line-height: 1.55;
}
/* El punteo es el campo principal: es donde se escribe siempre, mientras que el mail
   recibido se pega una vez y se pliega. */
.redactar #puntos { min-height: 9rem; }
.redactar label[for="puntos"] { font-weight: 600; font-size: 0.9rem; }

.redactar__recibido summary { cursor: pointer; color: var(--tinta-suave); }
.redactar__recibido textarea { margin-top: 0.5rem; }
.redactar .opcional { font-weight: 400; }
.redactar__pie { display: flex; gap: 0.75rem; align-items: center; }
.redactar__pie select {
  font: inherit;
  padding: 0.5rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
}
.redactar__pie .boton { margin-left: auto; }
/* La ayuda de los tonos, para no tener que abrir el `<select>` para adivinar cuál
   es cuál. Chica y al pie: se lee la primera semana y después estorba. */
.redactar__ayuda {
  list-style: none;
  padding: 0;
  margin: 0.75rem 0 0;
  font-size: 0.8rem;
  color: var(--tinta-suave);
  display: grid;
  gap: 0.15rem;
}

/* ---------------------------------------------------------------------------
   El borrador se tiene que poder leer (2026-09-10).

   **La queja, textual: "queda en un espacio muy limitado para leer".** Se apretaba
   "Escribir el mail", el borrador llegaba entero... y se leía por una ranura de dos
   o tres renglones entre el aviso de Gemini y el formulario, sin que scrollear lo
   arreglara.

   La causa es `position: sticky; bottom: 0` de `.consultar`. En el chat es lo
   correcto: el compositor son dos renglones y lo que crece es la conversación, así
   que dejarlo pegado al pie hace que el lugar donde se pregunta esté siempre a mano.
   Acá el compositor es lo alto: el mail recibido son 12 renglones, el punteo 7, más
   el tono y la ayuda. En una notebook eso es casi la ventana entera. Y un elemento
   sticky que mide casi la ventana no deja "espacio abajo": tapa todo salvo una
   franja, y esa franja no se agranda por más que se scrollee, porque el que se
   mueve es el texto de atrás.

   Así que en redacción el compositor vuelve al flujo normal: la pantalla se lee
   como un documento —el mail arriba, el formulario abajo— y el borrador dispone de
   la ventana completa. Lo que se pierde es tener el botón "Ajustar" siempre a la
   vista; lo compensa `redactar.js`, que al llegar un borrador lo trae a pantalla y
   pliega el mail recibido.
   --------------------------------------------------------------------------- */
.chat--redactar .redactar {
  position: static;
}

/* Con un borrador en pantalla el formulario deja de ser el protagonista: lo que se
   viene es un ajuste de cinco palabras ("más corto", "sacale el plazo"), no volver a
   escribir el punteo entero. Y la chuleta de tonos ya cumplió: el tono se eligió en
   el turno anterior y está escrito en la cabecera del borrador.

   Se hace con `:has()` y no con un `{% if hilo %}` en la plantilla porque el primer
   borrador llega por HTMX, sin recargar la página: un condicional de Jinja recién se
   aplicaría en la carga siguiente, o sea nunca, porque nadie recarga. */
.chat--redactar:has(.mail--borrador) .redactar #puntos { min-height: 4.5rem; }
.chat--redactar:has(.mail--borrador) .redactar__ayuda { display: none; }

/* Para que el borrador no arranque pegado al borde de arriba cuando `redactar.js` lo
   trae a la vista. */
.mail--borrador { scroll-margin-top: 1rem; }

/* --- Pantallas angostas -------------------------------------------------- */

@media (max-width: 900px) {
  /* `minmax(0, 1fr)` y no `1fr`: el mínimo automático de una pista de grilla es el
     ancho de su contenido, así que con `1fr` a secas una respuesta larga empuja la
     columna y **desborda la pantalla entera** — aparece scroll horizontal y el texto
     se corta a la derecha. Es el fallo clásico de CSS grid y solo se ve en pantallas
     angostas, que es donde nadie mira. */
  .disposicion { grid-template-columns: minmax(0, 1fr); }
  .lateral { border-right: none; border-bottom: 1px solid var(--borde); }
  .lateral__hilos { display: flex; gap: 0.5rem; overflow-x: auto; min-width: 0; }
  .chat { grid-template-columns: minmax(0, 1fr); height: auto; padding: 1rem; }
  .chat__mensajes { grid-template-columns: minmax(0, 1fr); }
  .mensaje--usuario { max-width: 90%; }
  .fuentes:has(.fuentes__contenido) {
    grid-column: 1;
    width: auto;
    border-left: none;
    border-top: 1px solid var(--borde);
    padding: 1rem 0 0;
  }
}

/* Respetar a quien pidió que nada se mueva. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* --- Panel de costos ------------------------------------------------------ */

/* Más ancho que `--ancho-texto`: esto son tablas de números, no prosa. La medida
   cómoda de lectura aplica a un párrafo; a una tabla de cinco columnas la ahoga. */
.costos {
  max-width: 900px;
  padding: 1.5rem;
}
.costos__cabecera h1 { margin: 0 0 0.25rem; font-size: 1.5rem; }
.costos__periodo { margin: 0 0 1.5rem; color: var(--tinta-suave); font-size: 0.9rem; }

.tarjeta {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 1.25rem;
  margin-bottom: 1.5rem;
}
.tarjeta h2 { margin: 0 0 0.75rem; font-size: 1.05rem; }

/* El número grande, en tabulares: sin `tabular-nums` las cifras de una columna no
   alinean y comparar dos importes obliga a leerlos dígito por dígito. */
.cifra {
  margin: 0 0 0.5rem;
  font-size: 2rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.cifra--alerta { color: var(--alerta); }
.cifra__de { font-size: 1rem; font-weight: 400; color: var(--tinta-suave); }

.barra {
  height: 8px;
  background: var(--borde);
  border-radius: 4px;
  overflow: hidden;
}
.barra__llena { height: 100%; background: var(--acento); }
.barra__llena--alerta { background: var(--alerta); }

.costos__nota {
  margin: 0.75rem 0 0;
  color: var(--tinta-suave);
  font-size: 0.85rem;
}

.tabla { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.tabla th, .tabla td { padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--borde); }
.tabla thead th {
  text-align: left;
  color: var(--tinta-suave);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.tabla tbody th { text-align: left; font-weight: 600; }
.tabla .numero { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla tbody tr:last-child th, .tabla tbody tr:last-child td { border-bottom: none; }

.tenue { color: var(--tinta-suave); font-weight: 400; font-size: 0.85em; }

/* El color no es lo único que distingue una fila en alerta: lleva además su etiqueta
   escrita. Un panel que solo pinta el fondo no le dice nada a quien no distingue ese
   ocre del blanco. */
.fila--alerta { background: var(--alerta-fondo); }
.fila--agotada { background: #fdf0f0; }

.etiqueta {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}
.etiqueta--alerta { background: var(--alerta); color: #fff; }
.etiqueta--agotada { background: var(--error); color: #fff; }

/* ---------------------------------------------------------------------------
   El panel de cuentas (/usuarios).

   Es la pantalla con más consecuencias del sistema, y el estilo tiene un solo
   trabajo propio: que el estado de cada cuenta se lea de un vistazo. Por eso la
   fila dada de baja se atenúa y la trabada se marca, en vez de que las tres
   diferencias vivan solo en el texto de una columna.
   --------------------------------------------------------------------------- */

.cuentas { max-width: 72rem; }

.cuentas__cabecera { margin-bottom: 1rem; }
.cuentas__nota {
  color: var(--tinta-suave);
  font-size: 0.88rem;
  margin: 0.35rem 0 0;
}

/* El resultado de la última operación. El verde no está en la paleta base porque
   hasta ahora ninguna pantalla confirmaba nada: las demás muestran datos, esta
   hace cosas, y "salió bien" tiene que distinguirse de "prestá atención". */
.aviso--ok {
  border-left-color: #2f6f4f;
  background: #eef6f1;
}
.aviso--alerta {
  border-left-color: var(--error);
  background: #fdf0f0;
}

.cuentas__lista { list-style: none; margin: 0.75rem 0 0; padding: 0; }
.cuentas__trabada {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 0.5rem 0;
  border-top: 1px solid var(--borde);
}

.cuentas__email {
  display: block;
  font-weight: 400;
  font-size: 0.82rem;
  color: var(--tinta-suave);
}

/* "vos" al lado del propio nombre. Sin esto, la fila propia se confunde con
   cualquier otra, y es justo la que no conviene tocar por error. */
.cuentas__vos {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: var(--acento-suave);
  color: var(--acento-texto);
  font-size: 0.72rem;
  font-weight: 600;
}

.cuentas__baja { opacity: 0.62; }
.etiqueta--baja { background: var(--tinta-suave); color: #fff; }

.cuentas__sesiones {
  display: block;
  font-size: 0.78rem;
  color: var(--tinta-suave);
  margin-top: 0.2rem;
}

.cuentas__nunca { color: var(--tinta-suave); font-style: italic; }

.cuentas__acciones {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: flex-start;
}

/* El cambio de contraseña va dentro de un `details` cerrado: es la acción más
   destructiva de la fila —cierra todas las sesiones— y no tiene por qué estar
   a un clic de distancia mientras se mira la tabla. */
.cuentas__acciones details { width: 100%; }
.cuentas__acciones summary { cursor: pointer; display: inline-block; }
.cuentas__acciones summary::-webkit-details-marker { display: none; }

.cuentas__forma {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.6rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--papel);
}

.cuentas__enlinea { display: flex; gap: 0.35rem; align-items: center; }

.cuentas__alta {
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  align-items: start;
}
.cuentas__alta button { grid-column: 1 / -1; justify-self: start; }

/* ---------------------------------------------------------------------------
   El logo del estudio.

   `width` y `height` van en el HTML además de acá: sin ellos el navegador no sabe
   cuánto espacio reservar y el resto de la pantalla salta cuando la imagen carga.
   Se nota sobre todo en el login, donde el salto mueve el campo de mail justo
   cuando alguien ya está tipeando.
   --------------------------------------------------------------------------- */

.entrar__logo {
  display: block;
  width: 200px;
  max-width: 100%;
  height: auto;
  margin: 0 auto 1rem;
}

.lateral__logo {
  display: block;
  width: 132px;
  max-width: 100%;
  height: auto;
  margin-bottom: 0.9rem;
  /* Discreto a propósito: adentro la marca acompaña, no encabeza. Recupera el color
     completo al pasar por encima, que alcanza para que no parezca un error. */
  opacity: 0.75;
  transition: opacity 0.15s ease;
}
.lateral__logo:hover { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .lateral__logo { transition: none; }
}

/* Alfred debajo del logo: el bigote y el nombre, chicos y en gris. El logo lleva
   su propio margen inferior, así que esto solo agrega el suyo hacia el botón. */
.lateral__alfred {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: -0.35rem 0 1rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--tinta-suave);
}

/* ---------------------------------------------------------------------------
   El conocimiento del estudio (/conocimiento).

   La pantalla tiene un trabajo visual propio: que **no se confunda una propuesta
   con un criterio publicado**. Una espera firma y la otra ya la tiene, y el ciclo
   entero existe para sostener esa diferencia. Por eso la propuesta se dibuja como
   una ficha con borde y el texto en un recuadro tipo borrador, y lo publicado va
   en una tabla sobria, que es como se lee lo que ya está decidido.
   --------------------------------------------------------------------------- */

.saber { max-width: 60rem; }

.saber__cabecera { margin-bottom: 1rem; }
.saber__nota {
  color: var(--tinta-suave);
  font-size: 0.88rem;
  margin: 0.35rem 0 0;
}
.saber__cuando {
  display: block;
  font-size: 0.78rem;
  color: var(--tinta-suave);
}

.propuesta {
  border: 1px solid var(--borde);
  border-left: 3px solid var(--acento);
  border-radius: var(--radio);
  padding: 1rem;
  margin-top: 0.9rem;
}

.propuesta__cabecera {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
}
.propuesta__cabecera h3 { margin: 0; font-size: 1.02rem; }

.propuesta__quien {
  color: var(--tinta-suave);
  font-size: 0.82rem;
  margin: 0.25rem 0 0.6rem;
}
.propuesta__origen { font-style: italic; }

/* El texto propuesto, con aspecto de borrador y no de criterio. Se muestra tal
   cual se escribió —sin interpretar markdown—: darle formato de publicado a algo
   que nadie firmó es exactamente lo que este ciclo evita. */
.propuesta__texto {
  white-space: pre-wrap;
  background: var(--papel);
  border: 1px dashed var(--borde);
  border-radius: var(--radio);
  padding: 0.7rem 0.85rem;
  font-size: 0.95rem;
}

.propuesta__porque {
  margin: 0.6rem 0 0;
  font-size: 0.9rem;
  color: var(--tinta-suave);
}

.propuesta__acciones {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  flex-wrap: wrap;
  margin-top: 0.85rem;
}
.propuesta__acciones summary { cursor: pointer; display: inline-block; }
.propuesta__acciones summary::-webkit-details-marker { display: none; }

.propuesta__rechazo {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.6rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--papel);
  min-width: 18rem;
}

/* `.anotar__form` es el formulario de proponer un criterio dibujado dentro de una
   respuesta del chat. Es el mismo formulario, así que comparte el estilo en vez de
   tener una copia que se desincronice: el día que a este le falte un campo, se va a
   notar en las dos pantallas a la vez. */
/* --- Corregir un criterio publicado: la v2 (D9) ---------------------------

   La fila de la accion no lleva borde propio: es la continuacion de la fila de
   arriba, no una fila de datos mas. Con borde, la tabla pareceria tener el doble de
   criterios de los que tiene. */
.saber__fila-accion > td {
  border-top: none;
  padding-top: 0;
}
.corregir summary { cursor: pointer; display: inline-block; }
.corregir summary::-webkit-details-marker { display: none; }
.corregir__form {
  margin-top: 0.6rem;
  padding: 0.85rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--papel);
}

/* El cambio propuesto, con lo que dice hoy al lado. En una sola columna cuando no
   entran las dos: leer dos textos en tiras de seis caracteres es peor que leerlos
   uno debajo del otro. */
.propuesta__cambio {
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  margin-top: 0.6rem;
}
.propuesta__cambio h4 {
  margin: 0 0 0.35rem;
  font-size: 0.85rem;
  color: var(--tinta-suave);
  font-weight: 600;
}
/* Lo que se va, atenuado; lo que viene, con el acento al costado. La diferencia se
   lee antes de haber leido una palabra, que es lo que hace falta cuando lo que se
   esta por firmar retira algo de circulacion. */
.propuesta__antes .propuesta__texto { opacity: 0.7; }
.propuesta__despues .propuesta__texto { border-left: 3px solid var(--acento); }

.etiqueta--version {
  border-color: var(--acento);
  color: var(--acento-texto);
}

.saber__alta,
/* La bandeja de documentos (D50). Cada documento es una `.propuesta` con un
   formulario de metadatos en grilla: ocho campos cortos que se leen de una vez, en
   vez de una columna larga que obliga a scrollear para llegar al botón. El borde
   izquierdo va en ámbar y no en violeta: lo que hay acá **todavía no es del
   corpus**, y el color lo dice antes que el título. */
.documento { border-left-color: var(--alerta); }
.documento__campos {
  display: grid;
  gap: 0.6rem 0.9rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin-top: 0.6rem;
}
.documento__campos label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.82rem;
  color: var(--tinta-suave);
}
.documento__campos input,
.documento__campos select {
  font: inherit;
  font-size: 0.92rem;
  color: var(--tinta);
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  min-width: 0;
}
.documento__form .saber__nota { margin-top: 0.6rem; }
.documento__descartar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--borde);
}
.documento__descartar .saber__nota { margin: 0; }

.anotar__form,
.corregir__form {
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  align-items: start;
}
.saber__alta .campo--ancho,
.anotar__form .campo--ancho,
.corregir__form .campo--ancho { grid-column: 1 / -1; }
.saber__alta textarea,
.anotar__form textarea,
.corregir__form textarea {
  width: 100%;
  font: inherit;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  resize: vertical;
}
.saber__alta button,
.anotar__form button,
.corregir__form button { grid-column: 1 / -1; justify-self: start; }

/* El enlace de la pantalla en la que se está parado. Se marca con el acento a la
   izquierda y no con un color de fondo: la barra lateral ya tiene botones llenos
   —el de "nueva consulta"— y pintar otro los pondría a competir. */
.boton--aca {
  border-left: 3px solid var(--acento);
  font-weight: 600;
  color: var(--acento-texto);
}


/* ---------------------------------------------------------------------------
   El panel de estado del sistema (Etapa 9).

   El recuadro cambia de color según cómo salió la corrida, pero **el color nunca
   es la única señal**: cada estado dice también en palabras qué pasó. Un semáforo
   que solo se lee por el color deja afuera a quien no distingue verde de rojo.
   --------------------------------------------------------------------------- */
.tests {
  padding: 1.5rem;
  max-width: var(--ancho-texto);
  display: grid;
  gap: 1.25rem;
  align-content: start;
}

.tests__explicacion,
.tests__nota { color: var(--tinta-suave); font-size: 0.9rem; }

.tests__acciones { display: grid; gap: 0.5rem; justify-items: start; }

.corrida {
  border: 1px solid var(--borde);
  border-left: 4px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  padding: 1rem 1.15rem;
  display: grid;
  gap: 0.4rem;
}

.corrida__titulo { font-size: 1.15rem; font-weight: 600; margin: 0; }
.corrida__detalle { margin: 0; color: var(--tinta-suave); }
.corrida__cuando { margin: 0; color: var(--tinta-suave); font-size: 0.85rem; }

.corrida--verde { border-left-color: var(--ok); background: var(--ok-fondo); }
.corrida--verde .corrida__titulo { color: var(--ok); }

.corrida--roja { border-left-color: var(--error); background: #fdf1f1; }
.corrida--roja .corrida__titulo { color: var(--error); }

/* "Rota" no es "roja": la corrida no terminó, así que no sabemos si el sistema
   está bien. Va en ámbar y no en rojo porque no es una mala noticia sobre el
   código, es la ausencia de noticia. */
.corrida--rota { border-left-color: var(--alerta); background: var(--alerta-fondo); }
.corrida--rota .corrida__titulo { color: var(--alerta); }

.corrida--en_curso { border-left-color: var(--acento); background: var(--acento-suave); }
.corrida--en_curso .corrida__titulo { color: var(--acento-texto); }

.corrida__motivo,
.falla__detalle {
  margin: 0.35rem 0 0;
  padding: 0.5rem 0.6rem;
  background: var(--papel);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  font-size: 0.8rem;
  /* Un traceback trae líneas larguísimas. Sin el scroll propio, estiran la caja y
     el resto de la pantalla se va al costado. */
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

.corrida__fallas {
  margin: 0.5rem 0 0;
  padding-left: 1.2rem;
  display: grid;
  gap: 0.75rem;
}

.falla__nombre { margin: 0; font-weight: 600; font-family: ui-monospace, monospace; }
.falla__archivo { margin: 0; color: var(--tinta-suave); font-size: 0.8rem; }


/* ---------------------------------------------------------------------------
   La pantalla de redacción reparte el alto distinto que el chat (2026-08-26).

   **El bug que arregla, porque cuesta creerlo:** se apretaba "Escribir el mail",
   el mail se generaba, se guardaba, el hilo aparecía en la barra lateral... y en
   la pantalla no pasaba nada. El borrador estaba en el DOM, entero, invisible.

   La causa es `grid-template-rows: 1fr auto auto` de `.chat`, que reparte por
   **posición**. En el chat el primer hijo es la lista de mensajes, así que se
   queda con la fila elástica y todo funciona. En redacción el primer hijo es el
   aviso de datos de Gemini: el aviso se queda con la fila que se estira y la
   lista de mails cae en una fila `auto` que, contra un `height: 100vh` y un
   formulario alto, se comprime hasta desaparecer. Como además tiene
   `overflow-y: auto`, no desborda: recorta en silencio.

   La segunda mitad del problema es que ese reparto por posición es **frágil**: el
   aviso de presupuesto aparece y desaparece según el consumo del mes, y al
   aparecer corre todos los hijos un lugar. O sea que la pantalla se rompía
   distinto según cuánta plata se hubiera gastado.

   Por eso acá no se cuenta posiciones: se pasa a columna flexible y la lista pide
   el sobrante por su cuenta. Da igual cuántos avisos haya arriba. `min-height: 0`
   es imprescindible: sin eso un hijo flexible no baja de su alto de contenido y
   vuelve a empujar el formulario fuera de la pantalla.

   Se hace con un modificador y no tocando `.chat` porque el chat sí necesita la
   grilla: tiene una segunda columna para el panel de fuentes, que acá no existe.
   --------------------------------------------------------------------------- */
.chat--redactar {
  display: flex;
  flex-direction: column;
  /* **La otra mitad del arreglo, y la que costó ver.** Pasar a columna flexible no
     alcanzaba: con `height: 100vh` heredado de `.chat`, el aviso más un formulario
     de dos cajas grandes ya llenan la ventana, así que la lista de mails —la única
     que puede encogerse— quedaba en cero píxeles igual. Medido en vivo: contenedor
     543px, contenido de la lista 506px, alto de la lista 0.

     El chat puede permitirse la altura fija porque su formulario es una sola caja
     baja y lo que crece es la conversación. Acá crece el formulario, así que la
     pantalla se comporta como un documento: ocupa la ventana como mínimo y, si el
     contenido no entra, la página scrollea. `.disposicion` ya usa `min-height`, o
     sea que el marco lo permitía desde siempre. */
  height: auto;
  min-height: 100vh;
}

.chat--redactar > .chat__mensajes {
  /* Que pida su alto real y no lo que sobre: acá no sobra nada. Y sin scroll propio,
     porque un panel que scrollea adentro de una página que también scrollea es la
     forma más rápida de perder de vista el mail recién escrito. */
  flex: none;
  min-height: 0;
  overflow-y: visible;
}


/* --- El informe en papel -------------------------------------------------- */

/* El membrete y las fuentes por mensaje existen solo para la hoja impresa. En
   pantalla el membrete seria un encabezado que repite lo que ya dice la pantalla, y
   las fuentes ya estan en el panel lateral, que es donde se consultan. */
.membrete,
.mensaje__impresion { display: none; }

/* Nico pidio "un informe en PDF". No hay una ruta que genere el archivo: lo genera el
   navegador, con su "Guardar como PDF", y esta hoja decide que sale y que no.

   La alternativa era una biblioteca de PDF del lado del servidor. Se descarto por
   ahora: es una dependencia pesada en Windows y obliga a maquetar el informe entero
   —portada, numeracion, saltos de pagina— para resolver algo que el navegador ya
   hace. Lo que se pierde es poder mandar el archivo por mail sin que una persona lo
   guarde primero; el dia que eso haga falta, esta hoja sigue sirviendo de maqueta. */
@media print {
  /* Margenes de una carta del estudio, no los del navegador. */
  @page { margin: 18mm 16mm 20mm; }

  /* Fondo blanco y tinta negra: el violeta de marca en una impresora laser sale gris
     sucio, y el fondo tenue de los mensajes se come el toner sin aportar nada. */
  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  /* Todo lo que es pantalla y no documento. */
  .lateral,
  .consultar,
  .progreso,
  #error-consulta,
  .fuentes,
  .saltar,
  .aviso--presupuesto,
  .mensaje__pie,
  .mensaje__acciones,
  .mensaje__guardar,
  .valorar,
  details.aviso--faltantes,
  button { display: none !important; }

  .disposicion { display: block; }
  .chat {
    display: block;
    min-height: 0;
    padding: 0;
  }
  .chat__mensajes { display: block; padding: 0; }

  .membrete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    border-bottom: 1.5pt solid #000;
    padding-bottom: 8pt;
    margin-bottom: 14pt;
  }
  .membrete__logo { height: 34px; width: auto; }
  .membrete__datos { text-align: right; }
  .membrete__titulo {
    margin: 0 0 2pt;
    font-size: 11pt;
    font-weight: 600;
  }
  .membrete__linea {
    margin: 0;
    font-size: 9pt;
    color: #333;
  }

  /* **Solo la respuesta que se pidio imprimir.** Sin esto sale la conversacion
     entera, que en un hilo de treinta mensajes son quince carillas que nadie queria.
     La clase la pone y la saca `imprimirRespuesta` en `progreso.js`. */
  body.imprimiendo .mensaje { display: none; }
  body.imprimiendo .mensaje.para-imprimir { display: block; }

  .mensaje {
    max-width: none;
    border: none;
    box-shadow: none;
    background: none;
    padding: 0;
    margin: 0 0 10pt;
    /* Que una respuesta no se parta al medio si entra entera en la carilla. */
    break-inside: avoid;
  }
  .mensaje--usuario {
    max-width: none;
    margin-left: 0;
    border-left: 2pt solid #000;
    padding-left: 8pt;
    font-weight: 600;
  }
  .mensaje__cabecera {
    font-size: 8.5pt;
    color: #444;
    margin-bottom: 3pt;
  }

  /* Las fuentes arrancan en su propio bloque, con una linea que las separa del
     cuerpo: en un papel de trabajo el respaldo se lee como respaldo, no como una
     continuacion de la respuesta. */
  .mensaje__impresion {
    display: block;
    break-inside: avoid;
    border-top: 0.5pt solid #999;
    margin-top: 10pt;
    padding-top: 6pt;
  }
  .mensaje__impresion .fuentes__titulo { font-size: 10pt; margin: 0 0 4pt; }
  .mensaje__impresion .fuentes__lista { margin: 0; padding-left: 14pt; font-size: 9.5pt; }
  .mensaje__impresion .fuente { margin-bottom: 5pt; break-inside: avoid; }

  /* Una tabla o un bloque de codigo largo se corta con la hoja en vez de salirse. */
  table, pre { break-inside: auto; }
  .mensaje__cuerpo table { width: 100%; font-size: 9.5pt; }

  /* Un enlace impreso sin su direccion es una referencia que no se puede seguir. */
  .mensaje__cuerpo a::after {
    content: " (" attr(href) ")";
    font-size: 8.5pt;
    color: #444;
  }
}
