/* ══════════════════════════════════════════════════════════════
   Aureal IAUI · DISPOSICIÓN
   Aquí no hay ni un color literal: todo sale de theme.css.
   Si necesitas un color nuevo, defínelo allí como token.

   CORTES DE PANTALLA — sólo hay dos que decidan la disposición:

     900 px  compacta   barra lateral plegada, paneles a pantalla
                        completa. Aquí entran las tablets.
     620 px  estrecha   el compositor se apila: el modelo en su
                        línea y debajo lo pequeño. Los teléfonos.

   Van también en app.js, en la constante PANTALLA: si cambias uno,
   cambia los dos. No se detecta el APARATO a propósito —el
   userAgent miente y las tablets Android se declaran teléfonos—;
   lo que decide la colocación es cuánto sitio hay. Para el tamaño
   de los objetivos está (pointer: coarse), que sí dice algo cierto.

   TARJETAS Y AVISOS — antes de crear uno, mira docs/tarjetas.md:
   ya hay tarjeta de resultado (.tarjeta-fichero), de incidencia,
   aviso flotante, aviso de conversación y chips. Se reutilizan.
   ══════════════════════════════════════════════════════════════ */

* { box-sizing: border-box; }

body {
  margin: 0; overflow: hidden;
  /* 100vh en móvil incluye la barra de direcciones y deja el cuadro de
     escribir fuera de pantalla. dvh mide el hueco real. */
  height: 100vh;
  height: 100dvh;
  background: var(--iaui-bg-app); color: var(--iaui-text);
  font-family: var(--iaui-font); font-size: var(--iaui-font-size);
}

/* ─────────────── Acceso ─────────────── */
.login-screen { display: grid; place-items: center; height: 100vh; height: 100dvh;
                background: var(--iaui-bg-side); padding: 20px; }
.login-card {
  display: flex; flex-direction: column; gap: 12px; width: 330px;
  padding: 30px; border-radius: var(--iaui-radius-lg);
  background: var(--iaui-bg-app); border: 1px solid var(--iaui-border);
}
.brand-mark {
  display: grid; place-items: center; width: 30px; height: 30px; flex: none;
  border-radius: 8px; background: var(--iaui-accent); color: var(--iaui-text-invert);
  font-weight: 700; font-size: 12px; letter-spacing: .5px;
}

/* ─────────────── Estructura ─────────────── */
/* Se le resta lo que ocupe el teclado del móvil. La variable la pone app.js
   sólo si el navegador NO hace caso a interactive-widget=resizes-content; si lo
   hace, vale 0 y esto es 100dvh de siempre. */
#app { display: flex; height: 100vh; height: calc(100dvh - var(--teclado, 0px)); }

/* El ancho del lateral es el TOTAL (riel + panel): así el que ya tenía cada
   navegador guardado en iaui.sidebarWidth sigue valiendo tal cual. */
.sidebar {
  width: var(--iaui-sidebar-width); flex: none;
  display: flex; flex-direction: row; min-width: 0; overflow: hidden;
  background: var(--iaui-bg-side); border-right: 1px solid var(--iaui-border);
}

/* ── Riel de secciones ──
   Nunca se pliega: plegar esconde el panel de al lado y el lateral se queda
   en el ancho del riel. */
.rail {
  width: var(--iaui-sidebar-rail); flex: none;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 0 12px; border-right: 1px solid var(--iaui-border);
}
.rail-btn {
  display: grid; place-items: center; width: 36px; height: 36px; flex: none;
  border: none; border-radius: var(--iaui-radius-md); padding: 0;
  background: none; color: var(--iaui-text-muted); cursor: pointer;
}
.rail-btn svg { width: 18px; height: 18px; }
.rail-btn:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }
/* La sección abierta. Con el panel plegado no se marca ninguna: lo que se ve
   a la derecha es el chat, no esa sección. */
.rail-btn.active { background: var(--iaui-bg-active); color: var(--iaui-text); }
body.sidebar-collapsed .rail-btn.active { background: none; color: var(--iaui-text-muted); }
.rail-sep { width: 22px; height: 1px; margin: 4px 0; background: var(--iaui-border); flex: none; }
.rail-fin { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 4px; }

.side-panel { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
.panel-seccion { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* Con display: flex la regla del navegador para [hidden] pierde: sin esto, al
   haber más de una sección se veían todas a la vez, una debajo de otra. */
.panel-seccion[hidden] { display: none; }
body.sidebar-collapsed .sidebar { width: var(--iaui-sidebar-rail); }
body.sidebar-collapsed .side-panel { display: none; }
body.sidebar-collapsed .rail { border-right: none; }
body.sidebar-collapsed .resizer { display: none; }

/* Divisor arrastrable entre el panel y el chat */
.resizer {
  width: 5px; flex: none; cursor: col-resize; z-index: 5;
  margin-left: -2px; background: transparent; transition: background .15s;
}
.resizer:hover, .resizer.dragging { background: var(--iaui-accent); }
body.resizing { cursor: col-resize; user-select: none; }

.sidebar-brand { display: flex; align-items: center; gap: 9px; padding: 13px 14px 10px; font-size: 14px; }
.btn-icon {
  border: none; background: none; color: var(--iaui-text-muted);
  border-radius: var(--iaui-radius-sm); padding: 5px; line-height: 0; cursor: pointer;
}
.btn-icon:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }

.side-search {
  margin: 2px 10px 4px;
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px; border-radius: var(--iaui-radius-md); color: var(--iaui-text-muted);
}
.side-search:hover, .side-search:focus-within { background: var(--iaui-bg-hover); }
.side-search input {
  border: none; background: none; outline: none; padding: 0;
  color: var(--iaui-text); font-size: 14px; width: 100%;
}

.sidebar-section { padding: 10px 20px 4px; font-size: 12px; color: var(--iaui-text-muted); font-weight: 500; }

.conv-list { flex: 1; overflow-y: auto; padding: 0 10px 10px; min-height: 0; }
.conv-group { padding: 12px 10px 4px; font-size: 11.5px; color: var(--iaui-text-muted); font-weight: 500; }
.conv-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 10px; border-radius: var(--iaui-radius-md); cursor: pointer;
  font-size: 14px; color: var(--iaui-text);
}
.conv-item:hover { background: var(--iaui-bg-hover); }
.conv-item.active { background: var(--iaui-bg-active); font-weight: 500; }
.conv-item .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.conv-item .when { font-size: 11.5px; color: var(--iaui-text-muted); flex: none; }
/* La rueda en lugar de la hora mientras esa conversación genera (28-9-2026):
   la misma .cargando-mini de los adjuntos, un poco más pequeña. */
.conv-item .generando { flex: none; width: 13px; height: 13px; margin-right: 2px; }
.conv-item .menu {
  opacity: 0; border: none; background: none; color: var(--iaui-text-muted);
  padding: 0 3px; line-height: 1; cursor: pointer; flex: none;
}
.conv-item:hover .menu, .conv-item.active .menu { opacity: 1; }
.conv-empty { padding: 16px 12px; font-size: 13px; color: var(--iaui-text-muted); }

.sidebar-user { margin-top: 6px; }
.sidebar-user .dropdown-header { max-width: 220px; color: var(--iaui-text); font-weight: 600; }
.user-btn {
  display: grid; place-items: center; width: 36px; height: 36px;
  padding: 0; border: none; border-radius: 50%;
  background: none; cursor: pointer;
}
.user-btn:hover { background: var(--iaui-bg-hover); }
.avatar {
  position: relative; width: 26px; height: 26px; border-radius: 50%;
  background: var(--iaui-accent-grad); flex: none;
}
.online-dot {
  position: absolute; right: -1px; bottom: -1px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--iaui-online); border: 2px solid var(--iaui-bg-side);
}

/* ─────────────── Chat ─────────────── */
.chat { flex: 1; display: flex; flex-direction: column; min-width: 0; background: var(--iaui-bg-app); }
.chat-head {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 20px; border-bottom: 1px solid var(--iaui-border); font-size: 14px;
}
/* Título arriba y contexto debajo: el contexto describe la conversación,
   así que va con su nombre y no robando sitio al cuadro de escribir. */
.head-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.head-main #chat-title { font-weight: 500; }
/* Contexto y gasto comparten renglón mientras quepan; en pantalla estrecha el
   gasto baja solo, que es lo que se puede sacrificar antes. */
.head-sub { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; row-gap: 1px; }
.gasto-linea { font-size: 12px; color: var(--iaui-text-muted); white-space: nowrap; }
.gasto-linea b { font-weight: 600; color: var(--iaui-text); }
.gasto-linea.warn { color: var(--iaui-warn); }
.gasto-linea.danger { color: var(--iaui-danger); }
.gasto-linea .franja-agotada { font-weight: 600; }

.messages { flex: 1; overflow-y: auto; padding: 26px 20px 10px; }
.msg { max-width: var(--iaui-content-max); margin: 0 auto 22px; }
.msg.user { display: flex; justify-content: flex-end; }
/* El tope del 80 % va en el envoltorio (imágenes + texto), no en la burbuja:
   el envoltorio se ajusta a su contenido, y una burbuja al 80 % de eso partía
   en dos líneas hasta un «¿cómo va la vida?». */
.msg.user .cuerpo-usuario {
  max-width: 80%; min-width: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
.msg.user .body {
  background: var(--iaui-bg-bubble); padding: 10px 15px;
  border-radius: 14px; max-width: 100%; min-width: 0;
  white-space: pre-wrap; word-wrap: break-word;
}
.msg.assistant .who {
  display: flex; align-items: center; gap: 8px;
  font-weight: 600; font-size: 14px; margin-bottom: 6px;
}
.msg.assistant .who .dot {
  width: 18px; height: 18px; border-radius: 5px; flex: none;
  background: var(--iaui-accent); color: var(--iaui-text-invert);
  font-size: 9px; font-weight: 700; display: grid; place-items: center;
}
/* Quién sirvió la respuesta: en tenue, para que no compita con el modelo. */
.msg.assistant .who .via { font-weight: 400; font-size: 12px; color: var(--iaui-text-muted); }

/* ── Markdown renderizado ── */
.msg .body > :first-child { margin-top: 0; }
.msg .body > :last-child { margin-bottom: 0; }
.msg .body p { margin: 0 0 .85em; }
.msg .body h1, .msg .body h2, .msg .body h3,
.msg .body h4, .msg .body h5, .msg .body h6 {
  margin: 1.3em 0 .5em; font-weight: 600; line-height: 1.3;
}
.msg .body h1 { font-size: 1.45em; }
.msg .body h2 { font-size: 1.28em; }
.msg .body h3 { font-size: 1.13em; }
.msg .body h4, .msg .body h5, .msg .body h6 { font-size: 1em; }

.msg .body ul, .msg .body ol { margin: 0 0 .85em; padding-left: 1.5em; }
.msg .body li { margin-bottom: .3em; }
.msg .body li > ul, .msg .body li > ol { margin-top: .3em; }

.msg .body blockquote {
  margin: 0 0 .85em; padding: .1em 0 .1em 1em;
  border-left: 3px solid var(--iaui-border); color: var(--iaui-text-muted);
}
.msg .body a { color: var(--iaui-accent); text-decoration: underline; text-underline-offset: 2px; }
.msg .body hr { border: none; border-top: 1px solid var(--iaui-border); margin: 1.3em 0; }

/* Las tablas anchas se desplazan dentro de su caja, no rompen la página. */
.msg .body table {
  display: block; width: max-content; max-width: 100%; overflow-x: auto;
  border-collapse: collapse; margin: 0 0 .85em; font-size: .93em;
}
.msg .body th, .msg .body td {
  border: 1px solid var(--iaui-border); padding: 6px 11px; text-align: left;
}
.msg .body th { background: var(--iaui-bg-code); font-weight: 600; }

.msg pre {
  background: var(--iaui-bg-code); border: 1px solid var(--iaui-border);
  border-radius: var(--iaui-radius-md); padding: 13px; overflow-x: auto; margin: 0 0 .85em;
}
.msg pre code { background: none; padding: 0; font-size: 13px; }
.msg code {
  font-family: var(--iaui-font-mono); font-size: .88em;
  background: var(--iaui-bg-code); border: 1px solid var(--iaui-border);
  border-radius: 5px; padding: .1em .35em;
}

/* El texto ya no es preformateado: lo estructura el propio Markdown. */
.msg.assistant .body { line-height: 1.65; word-wrap: break-word; }
.cursor::after { content: "▌"; animation: blink 1s steps(2) infinite; color: var(--iaui-accent); }
@keyframes blink { 50% { opacity: 0; } }

/* ─────────────── Cuadro de escritura ─────────────── */
.composer-wrap { padding: 6px 20px 14px; }
/* La lista de tareas del modelo, encima del cuadro de escribir (14-9-2026). */
.todo-panel {
  max-width: var(--iaui-content-max); margin: 0 auto 6px;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md);
  background: var(--iaui-bg-side); font-size: 13px; overflow: hidden;
}
.todo-header {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 11px; border: 0; background: none; color: var(--iaui-text-muted);
  font: inherit; text-align: left; cursor: pointer;
}
.todo-header:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }
.todo-header > span:first-child { font-weight: 600; color: var(--iaui-text); }
.todo-count { font-variant-numeric: tabular-nums; }
.todo-current { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.todo-arrow { transition: transform .15s; }
.todo-header[aria-expanded="false"] .todo-arrow { transform: rotate(-90deg); }
.todo-list {
  list-style: none; margin: 0; padding: 4px 11px 8px;
  max-height: 180px; overflow-y: auto; border-top: 1px solid var(--iaui-border);
}
.todo { display: flex; align-items: flex-start; gap: 8px; padding: 2px 0; line-height: 1.45; }
.todo-box {
  flex: none; width: 15px; height: 15px; margin-top: 2px; border-radius: 4px;
  border: 1.5px solid var(--iaui-border); display: grid; place-items: center;
  font-size: 11px; line-height: 1;
}
.todo.completed .todo-box { background: var(--iaui-accent); border-color: var(--iaui-accent); color: var(--iaui-text-invert); }
.todo.completed .todo-text { color: var(--iaui-text-muted); text-decoration: line-through; }
.todo.in_progress .todo-box { border-color: var(--iaui-accent); }
.todo.in_progress .todo-box::after {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--iaui-accent);
}
.todo.in_progress .todo-text { font-weight: 600; }
.todo.cancelled .todo-text { color: var(--iaui-text-muted); text-decoration: line-through; opacity: .7; }
.composer {
  max-width: var(--iaui-content-max); margin: 0 auto;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-lg);
  background: var(--iaui-bg-app); padding: 10px 12px 8px; transition: border-color .15s;
}
.composer:focus-within { border-color: var(--iaui-accent); }
/* Origen del menú de «/» (el de comandos y prompts): se abre encima de la caja
   y a su ancho. Nada más dentro del compositor se posiciona contra él —los
   desplegables del modelo, herramientas y razonar cuelgan de su propio envoltorio
   y el de adjuntar lo coloca Popper—, así que no mueve nada de lo que había. */
.composer { position: relative; }
.composer textarea {
  width: 100%; border: none; outline: none; resize: none; background: none;
  color: var(--iaui-text); font: inherit; max-height: 220px; padding: 2px 2px 6px;
}
/* Cola de mensajes (28-9-2026): lo escrito con Enter mientras el modelo
   responde. Encima de la caja de escribir, una línea por mensaje, con los mismos
   botones de lápiz y papelera que las filas de prompts y memorias. */
.cola-mensajes {
  display: flex; flex-direction: column; gap: 2px; margin: 0 0 8px; padding: 6px 8px;
  border: 1px dashed var(--iaui-border); border-radius: var(--iaui-radius-md);
  background: var(--iaui-bg-hover);
}
.cola-cabecera {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 12px; color: var(--iaui-text-muted);
}
.cola-enviar {
  border: 1px solid var(--iaui-accent); background: var(--iaui-accent); color: var(--iaui-text-invert);
  border-radius: var(--iaui-radius-sm); padding: 1px 8px; font-size: 12px; cursor: pointer;
}
.cola-fila { display: flex; align-items: flex-start; gap: 6px; font-size: 13.5px; }
.cola-txt {
  flex: 1; min-width: 0; padding-top: 3px; white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 4.6em; overflow: hidden;
}
.cola-fila .prompt-acciones { opacity: 1; }
/* Más específico que «.composer textarea» (la caja de escribir va sin borde ni
   fondo): el campo de editar una línea sí los lleva, para verse como campo. */
.composer .cola-fila textarea.cola-campo {
  flex: 1; font-size: 13.5px; padding: 4px 6px; max-height: 140px;
  border: 1px solid var(--iaui-border); background: var(--iaui-bg-app); border-radius: var(--iaui-radius-sm);
}
.cola-fila button[data-cola-borrar]:hover { color: var(--iaui-danger); }

/* La copia invisible con la que se mide la altura de la caja (ajustarAltura en
   app.js). Fuera del flujo y sin altura: sólo cuenta su scrollHeight. */
.composer textarea.medidor-entrada {
  position: absolute; left: 0; top: 0; height: 0; min-height: 0; overflow: hidden;
  visibility: hidden; pointer-events: none; max-height: none;
}
.composer-bar { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
/* Un <select> no se estira como una caja normal dentro de un flex: hay que
   envolverlo en algo que sí crezca y decirle que ocupe el 100% de él. */
/* Se encoge si hace falta pero NO estira: un botón mide lo que dice, y era el
   ancho completo con la flecha pegada al borde lo que le daba aire de <select>
   del sistema. El min-width: 0 deja que el texto se recorte con puntos suspensivos
   en vez de empujar al botón de enviar fuera de la fila. */
.model-wrap { flex: 0 1 auto; min-width: 0; }
.model-picker {
  width: 100%; max-width: 100%;
  /* Con borde, el mismo gris del recuadro del mensaje: sin él los tres
     desplegables no se leían como controles, parecían texto suelto. */
  border: 1px solid var(--iaui-border); background: none; color: var(--iaui-text-muted);
  font-size: 13px; outline: none; cursor: pointer;
  padding: 3px 4px; border-radius: var(--iaui-radius-sm);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.model-picker:hover { background: var(--iaui-bg-hover); border-color: var(--iaui-text-muted); }
.model-picker:focus { border-color: var(--iaui-accent); }

/* ── El selector de modelo ───────────────────────────────────────────────
   Un panel propio en vez del desplegable del sistema. El motivo no es la
   estética: con veinte modelos, una lista de texto plano no dice cuál razona,
   cuál ve imágenes, cuál no admite herramientas ni cuál no cabe ya en esta
   conversación, y todo eso el servidor ya lo manda. */
/* Los tres desplegables cuelgan su panel de aquí, así que los tres necesitan
   ser el origen de la posición. */
.model-wrap, .tools-wrap { position: relative; }
.model-boton {
  display: inline-flex; align-items: center; gap: 5px; text-align: left;
  width: auto; max-width: 100%;
}
/* Sin flex:1: así la flecha se queda pegada al texto en vez de irse al borde. */
.model-boton-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.model-boton-flecha { width: 14px; height: 14px; flex: none; opacity: .7; }
.model-boton[aria-expanded="true"] { border-color: var(--iaui-accent); background: var(--iaui-bg-hover); }

.picker-panel {
  /* Atado a los DOS lados del control, así que mide lo que mida el control y se
     ajusta solo al ancho de la ventana. El min-width es para los dos pequeños
     —herramientas y razonar—, que si no saldrían de 90 px y no cabría el texto;
     cuando gana el mínimo, el panel crece hacia la derecha (el navegador suelta
     el «right» al estar sobrerrestringido). */
  position: absolute; bottom: calc(100% + 6px); left: 0; right: 0; z-index: 50;
  min-width: min(260px, calc(100vw - 24px));
  max-width: calc(100vw - 24px);
  background: var(--iaui-bg-app); border: 1px solid var(--iaui-border);
  border-radius: var(--iaui-radius-md);
  box-shadow: 0 12px 32px rgb(0 0 0 / .18), 0 2px 6px rgb(0 0 0 / .08);
  overflow: hidden;
}
.picker-buscar { padding: 8px 8px 4px; }
.picker-buscar input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 13px;
  padding: 7px 10px; border-radius: var(--iaui-radius-sm); outline: none;
  border: 1px solid var(--iaui-border);
  background: var(--iaui-bg-hover); color: var(--iaui-text);
}
.picker-buscar input:focus { border-color: var(--iaui-accent); }
/* Con pocos modelos el buscador estorba más de lo que ayuda. */
.picker-buscar[hidden] { display: none; }

.picker-lista { max-height: min(52vh, 420px); overflow-y: auto; padding: 4px; }
.picker-grupo {
  padding: 9px 10px 5px; font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--iaui-text-muted);
}
.picker-fila {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 9px; border: 0; background: none; text-align: left;
  border-radius: var(--iaui-radius-sm); cursor: pointer; color: var(--iaui-text);
  font: inherit;
}
.picker-fila:hover, .picker-fila.marcada { background: var(--iaui-bg-hover); }
.picker-fila[aria-selected="true"] { background: var(--iaui-bg-hover); }
.picker-fila[aria-selected="true"] .picker-nombre { font-weight: 600; }
/* El que no cabe en la conversación sigue VISIBLE y con su motivo: esconderlo
   haría creer que el modelo ha desaparecido del plan. */
.picker-fila[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

/* Monograma en vez de logotipo: no hay logos en la base, y una letra con un
   color derivado del nombre distingue a simple vista sin descargar nada. */
.picker-logo {
  flex: none; width: 26px; height: 26px; border-radius: 7px;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: #fff;
  text-transform: uppercase; letter-spacing: -.02em;
}
/* En columna: los dos <span> son en línea por defecto y el proveedor se pegaba
   al nombre en el mismo renglón. */
/* En los desplegables sencillos —herramientas, razonamiento— el hueco del logo
   lleva un icono de trazo del color del texto, no un cuadrado de marca. */
.picker-logo-icono { background: none; color: var(--iaui-text-muted); }
/* Ocupa sitio y no se ve: mantiene alineado el texto de las filas sin icono. */
.picker-logo-hueco { background: none; }
.picker-logo-icono svg { width: 17px; height: 17px; }
.picker-fila[aria-selected="true"] .picker-logo-icono { color: var(--iaui-accent); }

/* Con icono propio no se pinta el cuadrado de color: el dibujo trae el suyo. */
.picker-logo-img { background: none; padding: 1px; object-fit: contain; }
.picker-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.picker-nombre {
  display: block; font-size: 13.5px; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.picker-sub {
  display: block; font-size: 11px; color: var(--iaui-text-muted); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.picker-derecha { flex: none; display: flex; align-items: center; gap: 7px; }
.picker-ctx {
  font-size: 11px; font-weight: 600; color: var(--iaui-text-muted);
  font-variant-numeric: tabular-nums;
}
.picker-marcas { display: flex; gap: 4px; color: var(--iaui-text-muted); }
.picker-marcas svg { width: 14px; height: 14px; }
.picker-vacio { padding: 14px 12px; font-size: 12.5px; color: var(--iaui-text-muted); }

/* En el móvil el panel ocupa el ancho del compositor: 280px fijos se salían. */
@media (max-width: 640px) {
  .picker-panel { left: 0; right: 0; min-width: 0; max-width: none; }
}
/* El de enviar, siempre a la derecha. Antes lo empujaba el combo del modelo,
   que ocupaba todo el ancho sobrante; ahora que mide lo que su texto, hay que
   decirlo. */
.send-btn, .composer-bar #stop { margin-left: auto; }
.send-btn { border-radius: var(--iaui-radius-md); line-height: 0; padding: 7px 10px; flex: none; }
.composer-hint {
  max-width: var(--iaui-content-max); margin: 6px auto 0;
  text-align: center; font-size: 11.5px; color: var(--iaui-text-muted);
}

/* Aviso emergente con el aire del original: oscuro y compacto. */
.tooltip-inner {
  background: var(--iaui-tooltip-bg); color: var(--iaui-tooltip-text);
  border-radius: 8px; padding: 6px 11px; font-size: 13px; font-weight: 500;
}
.tooltip .tooltip-arrow::before { border-right-color: var(--iaui-tooltip-bg); }
/* Un aviso emergente no se pulsa nunca: que no se trague el clic de lo que
   tapa. Con la cuarta pestaña de Tareas (Skills, 28-9-2026) las pestañas se
   corrieron y el de «Nueva conversación» del riel, que sale a su derecha, quedó
   justo encima de «Agentes» mientras se desvanecía: el clic caía en el aviso y
   la pestaña no cambiaba (tareas.cjs). */
.tooltip { pointer-events: none; }

/* ══════════════════════════════════════════════════════════
   Móvil y tableta
   ══════════════════════════════════════════════════════════ */

/* Fondo oscurecido bajo el panel: en móvil el lateral flota encima
   del chat, y hace falta algo que se pueda tocar para cerrarlo. */
.scrim {
  position: fixed; inset: 0; z-index: 25;
  background: rgba(0, 0, 0, .45);
  opacity: 0; pointer-events: none; transition: opacity .18s;
}
body.sidebar-open .scrim { opacity: 1; pointer-events: auto; }

@media (max-width: 900px) {
  /* En móvil el lateral deja de compartir ancho con el chat: se convierte en
     un cajón que se desliza por encima, con el riel y el panel juntos. Plegar
     no existe aquí: si el escritorio lo dejó plegado, en el cajón se anula,
     porque si no se abriría un cajón con sólo el riel. */
  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 30;
    width: min(84vw, 320px) !important;
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: 0 0 24px rgba(0, 0, 0, .3);
  }
  body.sidebar-open .sidebar { transform: none; }

  body.sidebar-collapsed .side-panel { display: flex; }
  body.sidebar-collapsed .rail { border-right: 1px solid var(--iaui-border); }
  body.sidebar-collapsed .rail-btn.active { background: var(--iaui-bg-active); color: var(--iaui-text); }

  .resizer { display: none !important; }
  #collapse { display: none; }

  /* El chat ocupa todo: nada le roba ancho. */
  .chat { width: 100%; }

  .chat-head { padding: 10px 12px; gap: 8px; align-items: flex-start; }
  /* Una barra por renglón, cada una con su texto. En una sola fila la segunda
     se quedaba sin etiqueta —dos barras y un número suelto, sin saber de qué
     era la segunda— y eso es peor que ocupar un renglón más (29-8-2026, visto
     en un Android). */
  .head-sub { flex-direction: column; align-items: flex-start; gap: 1px; }
  /* Barra corta y letra algo menor: en un móvil de 412 px el hueco que queda
     junto al «Generando…» y la carpeta son ~180 px, y con la barra de 52 y el
     texto a 11,5 el renglón se partía en dos. */
  .context-meter { font-size: 11px; gap: 5px; }
  .context-meter .bar { width: 36px; }
  .head-sub .context-meter .text { white-space: nowrap; }
  .messages { padding: 16px 12px 6px; }
  .msg { margin-bottom: 18px; }
  .msg.user .body { max-width: 88%; }

  .composer-wrap { padding: 4px 10px calc(10px + env(safe-area-inset-bottom)); }
  .composer { padding: 8px 10px 6px; border-radius: 14px; }
  .composer-hint { display: none; }          /* nadie usa Mayús+Enter en un móvil */
  .last-stats { display: none; }             /* no cabe, y el dato está en la barra */

  .composer-bar { gap: 6px; }

  /* El espaciador empujaba el botón de enviar a la línea de abajo. */
  .composer-bar > .flex-grow-1 { display: none; }

  /* Base cero para que el desplegable crezca y encoja de verdad; con base
     automática el texto largo lo hacía saltar de línea antes de encogerse. */
  .tools-btn { order: 0; flex: none; }
  .tools-wrap { order: 0; flex: none; }
  .model-wrap { order: 1; }
  /* El razonamiento, DETRÁS del modelo: depende de él —los niveles se rehacen
     en cada cambio de modelo— y leerlo antes no tiene sentido. Lleva la clase
     'tools-wrap', así que sin esta línea heredaba order:0 y en pantalla
     estrecha salía delante del modelo, al revés que en el escritorio. */
  #razon-wrap { order: 2; }
  .send-btn, #stop { order: 3; flex: none; }

  /* El panel de ajustes ocupa la pantalla en vez de robar ancho al chat. */

  /* El visor, igual: a pantalla completa. */
  .visor-panel {
    position: fixed; inset: 0; z-index: 40; width: 100%;
    transform: translateX(100%); transition: transform .2s ease;
    border-left: none;
  }
  body.visor-open .visor-panel { width: 100%; transform: none; }

  /* La ventana de perfil, a pantalla completa. */
  .modal-dialog { margin: 0; max-width: none; min-height: 100dvh; }
  .profile-modal { border-radius: 0; min-height: 100dvh; }
}

/* En el MÓVIL los cinco no caben en una línea y la barra se partía sola por
   donde le venía bien, dejando el enviar huérfano en una TERCERA línea justo
   cuando el teclado ya ocupa media pantalla. Aquí se decide dónde parte:

       📎 [ modelo .................................... ]
       [herramientas] [razonar]                       [↑]

   En la tablet (~800 px) NO se aplica: ahí caben los tres en una línea y así
   está bien, que es justo lo que se comprobó el 30-8-2026 en las dos.
   El corte es el mismo 620 px que ya usan las rejillas de facturación. */
@media (max-width: 620px) {
  /* Primera línea: el clip y el modelo. El clip delante porque despliega su
     menú hacia arriba y quiere el borde izquierdo. Ojo, el elemento de la fila
     es #attach-wrap: la clase .tools-btn está en el botón de DENTRO y ordenarla
     no coloca nada. */
  #attach-wrap { order: 0; }
  /* Va solo en su línea, pero tampoco estira: si lo hiciera volvería a parecer
     un desplegable del sistema, que es justo lo que se quitó. Se recorta con
     puntos suspensivos cuando el nombre no cabe. */
  .model-wrap { order: 1; flex: 0 1 auto; }

  /* El salto de línea, sin tocar el HTML: un pseudoelemento que ocupa el ancho
     entero y no se ve. Va entre el modelo y las herramientas, así que todo lo
     que tenga un orden mayor cae a la segunda fila. Sin esto había que elegir
     entre que el modelo se llevara la línea él solo —y entonces el clip se
     quedaba huérfano arriba— o que se mezclaran los cinco y el enviar acabara
     en una tercera. */
  .composer-bar::after { content: ''; flex-basis: 100%; height: 0; order: 2; }

  /* Segunda línea: lo pequeño, y el enviar a la derecha. El espaciador que
     hacía ese hueco está oculto en pantalla estrecha, de ahí el margen auto. */
  .tools-wrap { order: 3; }
  #razon-wrap { order: 4; }
  /* La velocidad, con los pequeños. Sin orden propio se quedaba en la primera
     línea —delante del modelo, porque va sin `order`—. */
  #last-stats { order: 4; }
  .send-btn, #stop { order: 5; margin-left: auto; }
}

/* Tocar con el dedo pide objetivos más grandes que apuntar con el ratón.
   Y menos de 16px en un campo hace que iOS acerque la página al enfocarlo. */
@media (pointer: coarse) {
  .conv-item { padding: 11px 10px; }
  .conv-item .menu { opacity: 1; padding: 4px 8px; }
  .rail-btn, .user-btn { width: 42px; height: 42px; }
  .side-search { padding: 11px 10px; }
  .btn-icon { padding: 9px; }
  .dropdown-item { padding-top: 10px; padding-bottom: 10px; }
  .step > summary { padding: 10px 12px; }
  input, textarea, select, .side-search input { font-size: 16px; }
}

/* Pantallas muy estrechas: aún cabe, pero justo. */
@media (max-width: 380px) {
  .messages { padding: 12px 9px 4px; }
  .context-meter .bar { width: 60px; }
}

/* ─────────────── Pantalla de usuario ─────────────── */
.profile-modal {
  background: var(--iaui-bg-app); color: var(--iaui-text);
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-lg);
}
.profile-modal .modal-header,
.profile-modal .modal-footer { border-color: var(--iaui-border); }
.profile-modal .nav-tabs { border-color: var(--iaui-border); }
.profile-modal .nav-link {
  color: var(--iaui-text-muted); border: none; border-bottom: 2px solid transparent;
  background: none; padding: 8px 14px;
}
.profile-modal .nav-link:hover { color: var(--iaui-text); }
.profile-modal .nav-link.active {
  color: var(--iaui-accent); border-bottom-color: var(--iaui-accent); background: none;
}
.profile-modal .form-control {
  background: var(--iaui-bg-app); color: var(--iaui-text);
  border-color: var(--iaui-border);
}
.profile-modal .form-control:focus { background: var(--iaui-bg-app); color: var(--iaui-text); }
.profile-modal .btn-close { filter: var(--iaui-close-filter); }

.field-label {
  display: block; font-size: 13px; font-weight: 600;
  margin: 14px 0 5px; color: var(--iaui-text);
}
.field-hint { font-size: 12.5px; color: var(--iaui-text-muted); margin: 5px 0 0; }

.profile-head { display: flex; align-items: center; gap: 16px; margin-bottom: 6px; }
.avatar-slot {
  position: relative; width: 68px; height: 68px; border-radius: 50%;
  background: var(--iaui-accent-grad); flex: none; overflow: hidden;
  display: grid; place-items: center;
}
.avatar-slot img { width: 100%; height: 100%; object-fit: cover; }
.avatar-slot span {
  color: var(--iaui-text-invert); font-weight: 700; font-size: 22px; letter-spacing: .5px;
}

.profile-facts {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 16px;
  margin: 20px 0 0; padding-top: 14px; border-top: 1px solid var(--iaui-border);
  font-size: 13px;
}
.profile-facts dt { color: var(--iaui-text-muted); font-weight: 400; }
.profile-facts dd { margin: 0; }

/* ─────────────── Contexto y consumo ─────────────── */
.context-meter {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--iaui-text-muted);
}
.context-meter .bar {
  display: block; width: 90px; height: 4px; border-radius: 2px;
  background: var(--iaui-bg-hover); overflow: hidden; flex: none;
}
.context-meter .bar i {
  display: block; height: 100%; width: 0; border-radius: 3px;
  background: var(--iaui-accent); transition: width .4s ease;
}
.context-meter.warn .bar i { background: var(--iaui-warn); }
.context-meter.danger .bar i { background: var(--iaui-danger); }
.context-meter.danger .text { color: var(--iaui-danger); }

.last-stats { font-size: 12px; color: var(--iaui-text-muted); white-space: nowrap; }
#live-stats:not(:empty)::after { content: " · "; }
#live-stats { color: var(--iaui-accent); font-variant-numeric: tabular-nums; }

/* ─────────────── Ajustes de generación ─────────────── */

.params-head {
  display: flex; align-items: center; gap: 10px;
  padding-top: 13px; padding-bottom: 13px; font-size: 14px;
  border-bottom: 1px solid var(--iaui-border); margin-bottom: 6px;
}

.params-actions { display: flex; gap: 8px; padding-top: 16px; padding-bottom: 4px; }

/* ─────────────── Pasos: razonamiento y herramientas ─────────────── */
.msg .steps:not(:empty) { margin-bottom: 10px; display: flex; flex-direction: column; gap: 5px; }
/* Las cajas entre dos trozos de texto: aire por arriba y por abajo. */
.flujo > .steps:not(:empty) { margin: 10px 0; }
.flujo > .steps:first-child { margin-top: 0; }
.step {
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-sm);
  background: var(--iaui-bg-side); font-size: 13px; overflow: hidden;
}
.step > summary {
  cursor: pointer; padding: 6px 11px; color: var(--iaui-text-muted);
  display: flex; align-items: center; gap: 8px; list-style: none; user-select: none;
}
.step > summary::-webkit-details-marker { display: none; }
.step > summary:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }
.step > summary .ic { font-size: 12px; }
.step[open] > summary { border-bottom: 1px solid var(--iaui-border); }
.step .think {
  padding: 11px 13px; color: var(--iaui-text-muted); font-size: 13px;
  line-height: 1.6; white-space: pre-wrap; max-height: 300px; overflow-y: auto;
}
.step .tool-io { padding: 10px 13px; }
.step .tool-io b { display: block; font-size: 11px; color: var(--iaui-text-muted); margin: 6px 0 3px; }
.step .tool-io b:first-child { margin-top: 0; }
.step .tool-io pre {
  margin: 0; padding: 8px 10px; background: var(--iaui-bg-code);
  border: 1px solid var(--iaui-border); border-radius: 6px;
  font-size: 12px; max-height: 220px; overflow: auto; white-space: pre-wrap;
}

/* El botón de menú sólo existe cuando el lateral es un cajón. */
.only-mobile { display: none; }
@media (max-width: 900px) { .only-mobile { display: inline-flex; } }

/* ─────────────── Selector de herramientas ─────────────── */
.tools-btn {
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid transparent; background: none; color: var(--iaui-text-muted);
  border-radius: var(--iaui-radius-sm); padding: 4px 7px; cursor: pointer;
  font-size: 12px; line-height: 1;
}
.tools-btn:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }
.tools-btn.on { color: var(--iaui-accent); border-color: var(--iaui-accent); }
/* Dos parpadeos de medio segundo cuando cambia el número de ficheros de la
   conversación: el modelo acaba de crear, borrar o cambiar algo y el cliente no
   está mirando ahí. Fuerte, normal, fuerte, y se queda quieto — sin bucle: un
   icono que parpadea sin parar se convierte en ruido y se deja de ver.
   Con 'prefers-reduced-motion' no se anima nada, sólo se marca el color. */
.tools-btn.avisa { animation: carpeta-avisa 1.5s ease-in-out 1; }
@keyframes carpeta-avisa {
    0% { color: var(--iaui-accent); transform: scale(1.18); }
   33% { color: var(--iaui-text-muted); transform: scale(1); }
   66% { color: var(--iaui-accent); transform: scale(1.18); }
  100% { color: var(--iaui-text-muted); transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .tools-btn.avisa { animation: none; color: var(--iaui-accent); }
}

.tools-menu { min-width: 260px; max-height: 320px; overflow-y: auto; }
.tools-menu .head {
  padding: 7px 14px 5px; font-size: 11.5px; color: var(--iaui-text-muted);
}
.tools-menu label {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 14px; font-size: 14px; cursor: pointer;
}
.tools-menu label:hover { background: var(--iaui-bg-hover); }
.tools-menu .foot {
  padding: 6px 14px 8px; font-size: 11.5px; color: var(--iaui-text-muted);
  border-top: 1px solid var(--iaui-border); margin-top: 4px; line-height: 1.45;
}

/* La herramienta activa es un combo, con el aire del selector de modelo. */
.tools-wrap { flex: none; min-width: 0; }
.tools-picker { width: auto; max-width: 170px; padding: 4px 7px; border-radius: var(--iaui-radius-sm); }
.tools-picker.on { color: var(--iaui-accent); border-color: var(--iaui-accent); }

/* Detalles de la caja de herramienta */
.step .srv { color: var(--iaui-text-muted); font-weight: 400; font-size: 11.5px; }
.step .bad { color: var(--iaui-danger); }
.step .run { color: var(--iaui-accent); font-size: 11.5px; }
.step summary { gap: 7px; }

/* Puntos suspensivos animados mientras el modelo razona, para que se note que
   la caja está viva aunque esté cerrada. */
.step.thinking .dots::after {
  content: "…"; display: inline-block; width: 1em;
  animation: pensando 1.2s steps(4) infinite;
}
@keyframes pensando { 0% { clip-path: inset(0 100% 0 0); } 100% { clip-path: inset(0 0 0 0); } }

/* ─────────────── Lista: archivadas ─────────────── */
.sidebar-section { display: flex; align-items: center; gap: 8px; }
.link-btn {
  margin-left: auto; border: none; background: none; padding: 0;
  color: var(--iaui-text-muted); font-size: 11.5px; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.link-btn:hover { color: var(--iaui-accent); }
.link-btn.on { color: var(--iaui-accent); font-weight: 600; }
.conv-item .snippet {
  display: block; width: 100%; font-size: 11.5px; color: var(--iaui-text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px;
}
.conv-item.with-snippet { flex-wrap: wrap; align-items: flex-start; }

/* ─────────────── Ir al final ─────────────── */
.messages-wrap { flex: 1; position: relative; min-height: 0; display: flex; }
.messages-wrap .messages { flex: 1; }

/* El modelo de la conversación abierta ya no está disponible: fijo bajo la
   cabecera, fuera del scroll, porque la conversación se abre por el final y
   ahí dentro no lo vería nadie. */
.aviso-modelo {
  padding: 7px 20px;
  font-size: 13px;
  color: var(--iaui-warn);
  background: var(--iaui-bg-side);
  border-bottom: 1px solid var(--iaui-border);
}
.to-bottom {
  position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
  border: 1px solid var(--iaui-border); background: var(--iaui-bg-app);
  color: var(--iaui-text); border-radius: 50%; width: 34px; height: 34px;
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--iaui-shadow);
}
.to-bottom:hover { border-color: var(--iaui-accent); color: var(--iaui-accent); }

/* ─────────────── Copiar ─────────────── */
.msg-actions { display: flex; gap: 4px; margin-top: 7px; opacity: 0; transition: opacity .15s; }
.msg:hover .msg-actions { opacity: 1; }
/* Bajo la burbuja del usuario, pegado a ella y a su derecha. */
.msg.user .msg-actions { margin-top: -2px; }
.msg-actions button {
  border: none; background: none; color: var(--iaui-text-muted);
  border-radius: var(--iaui-radius-sm); padding: 4px 8px;
  font-size: 11.5px; cursor: pointer; display: flex; align-items: center; gap: 5px;
}
.msg-actions button:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }

.msg pre { position: relative; }
.msg pre .copy-code {
  position: absolute; top: 6px; right: 6px;
  border: 1px solid var(--iaui-border); background: var(--iaui-bg-app);
  color: var(--iaui-text-muted); border-radius: 6px;
  padding: 3px 8px; font-size: 11px; cursor: pointer; opacity: 0; transition: opacity .15s;
}
.msg pre:hover .copy-code { opacity: 1; }
.msg pre .copy-code:hover { color: var(--iaui-accent); border-color: var(--iaui-accent); }

@media (pointer: coarse) {
  .msg-actions { opacity: 1; }
  .msg pre .copy-code { opacity: 1; }
}

/* ─────────────── Mi consumo ─────────────── */
.consumo-titulo { font-size: 13px; font-weight: 600; margin: 20px 0 8px; }
.cuota {
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md);
  padding: 15px 17px; background: var(--iaui-bg-side);
}
.cuota-cifras { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.cuota-cifras .grande {
  font-size: 26px; font-weight: 700; color: var(--iaui-accent);
  font-variant-numeric: tabular-nums;
}
.cuota.warn .grande { color: var(--iaui-warn); }
.cuota.danger .grande { color: var(--iaui-danger); }
.cuota-cifras .de { font-size: 13px; color: var(--iaui-text-muted); }
.cuota-bar {
  height: 6px; border-radius: 3px; background: var(--iaui-bg-hover);
  margin: 11px 0 9px; overflow: hidden;
}
.cuota-bar i { display: block; height: 100%; background: var(--iaui-accent); border-radius: 3px; transition: width .4s; }
.cuota.warn .cuota-bar i { background: var(--iaui-warn); }
.cuota.danger .cuota-bar i { background: var(--iaui-danger); }
.cuota-pie { font-size: 12px; color: var(--iaui-text-muted); line-height: 1.5; }

/* Saldo: la misma caja que la cuota, con los importes de recarga. */
#mi-saldo { margin-top: 14px; }
.cuota.saldo .grande { color: var(--iaui-text); }
.saldo-botones { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin: 12px 0 8px; }
.saldo-otro { display: flex; align-items: center; gap: 6px; }
.saldo-otro input {
  width: 90px; padding: 4px 8px; font-size: 13px;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-sm);
  background: var(--iaui-bg-app); color: var(--iaui-text);
}
.saldo-historial { margin-top: 12px; }
.saldo-historial summary { font-size: 12px; color: var(--iaui-text-muted); cursor: pointer; }

table.consumo { width: 100%; border-collapse: collapse; font-size: 13px; }
table.consumo td { padding: 7px 6px; border-bottom: 1px solid var(--iaui-border); vertical-align: middle; }
table.consumo tr:last-child td { border-bottom: none; }
table.consumo .et { max-width: 210px; }
table.consumo .et span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
table.consumo .et small { color: var(--iaui-text-muted); font-size: 11px; }
table.consumo .ba { width: 32%; }
table.consumo .ba i { display: block; height: 6px; border-radius: 3px; background: var(--iaui-accent); min-width: 2px; }
table.consumo .co { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }

/* Rejillas de los datos de facturación */
.dos-columnas { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.tres-columnas { display: grid; grid-template-columns: 1fr 1.4fr 1.4fr; gap: 0 14px; }
@media (max-width: 620px) {
  .dos-columnas, .tres-columnas { grid-template-columns: 1fr; }
}

/* ─────────────── Imágenes adjuntas ─────────────── */
.composer.soltando { border-color: var(--iaui-accent); background: var(--iaui-accent-soft); }
.adjuntos { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 9px; }
.adjunto {
  position: relative; width: 62px; height: 62px; border-radius: var(--iaui-radius-sm);
  overflow: hidden; border: 1px solid var(--iaui-border); background: var(--iaui-bg-side);
  display: grid; place-items: center;
}
.adjunto img { width: 100%; height: 100%; object-fit: cover; }
.adjunto .quitar {
  position: absolute; top: 2px; right: 2px; width: 18px; height: 18px;
  border: none; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff;
  font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
}
.adjunto.subiendo { opacity: .6; }
.cargando-mini {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--iaui-border); border-top-color: var(--iaui-accent);
  animation: girar .8s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }
/* Media vuelta al pulsar «Actualizar»: confirma que se ha hecho algo aunque el
   fichero no haya cambiado y la vista salga idéntica. */
#visor-recargar.girando svg { animation: girar 0.6s ease-in-out 1; }

.cuerpo-usuario { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; max-width: 80%; }
.msg-imgs { display: flex; gap: 7px; flex-wrap: wrap; justify-content: flex-end; }
.msg-imgs img {
  max-width: 190px; max-height: 190px; border-radius: 10px;
  border: 1px solid var(--iaui-border); display: block;
}
/* Las que devuelve una herramienta: a la izquierda, bajo su caja, y más grandes. */
.steps .msg-imgs.herramienta { justify-content: flex-start; margin: 2px 0 4px; }
.steps .msg-imgs.herramienta img { max-width: 360px; max-height: 360px; }
.msg.user .cuerpo-usuario .body { background: var(--iaui-bg-bubble); padding: 10px 15px;
  border-radius: 14px; white-space: pre-wrap; word-wrap: break-word; }

/* ─────────────── Menú de adjuntos ─────────────── */
.attach-menu { min-width: 250px; }
.attach-menu .head {
  padding: 8px 14px 5px; font-size: 11.5px; color: var(--iaui-text-muted);
}
.attach-menu .dropdown-item {
  display: flex; align-items: flex-start; gap: 11px; padding: 9px 14px;
}
.attach-menu .ic { font-size: 17px; line-height: 1.2; }
.attach-menu b { display: block; font-size: 14px; font-weight: 600; }
.attach-menu small { display: block; font-size: 11.5px; color: var(--iaui-text-muted); }

/* Ficha de documento: un PDF no tiene vista previa */
.adjunto.doc {
  width: auto; min-width: 130px; max-width: 200px; height: 62px;
  flex-direction: column; gap: 3px; padding: 8px 10px;
  justify-content: center; align-items: flex-start;
}
.adjunto .doc-ic { font-size: 18px; }
.adjunto .doc-nombre {
  font-size: 11px; color: var(--iaui-text-muted); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.msg-doc {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 13px; border-radius: 10px; font-size: 13px;
  background: var(--iaui-bg-side); border: 1px solid var(--iaui-border);
  color: var(--iaui-text); text-decoration: none;
}
.msg-doc:hover { border-color: var(--iaui-accent); color: var(--iaui-accent); }
.adjunto .doc-info { font-size: 10px; color: var(--iaui-accent); }

/* Selector de nivel de razonamiento */

/* Aviso breve: aparece abajo, se va solo, no bloquea nada. */
.aviso-flotante {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  max-width: min(90vw, 30rem);
  padding: .6rem 1rem;
  border: 1px solid var(--iaui-border);
  border-radius: var(--iaui-radius-md);
  background: var(--iaui-bg-side);
  color: var(--iaui-text);
  box-shadow: var(--iaui-shadow);
  font-size: .9rem;
  animation: aviso-entra .18s ease-out;
}

@keyframes aviso-entra {
  from { opacity: 0; transform: translate(-50%, .5rem); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* Ficheros de la conversación: cada fila es descarga + borrar. Más ancho que
   el menú de herramientas, que los nombres de los documentos son largos; en
   pantallas estrechas, lo que quepa. */
.espacio-menu {
  min-width: min(400px, calc(100vw - 24px));
  max-width: min(600px, calc(100vw - 24px));
}
.espacio-menu .fichero {
  display: flex;
  align-items: center;
}

.espacio-menu .fichero .dropdown-item {
  flex: 1;
  min-width: 0;
  /* El clip al lado del nombre, no encima: la fila es un flex, no un bloque. */
  display: flex;
  align-items: flex-start;
  gap: 9px;
  white-space: normal;
}
.espacio-menu .fichero .dropdown-item > span:last-child { min-width: 0; flex: 1; }

/* Un nombre que no cabe en una línea sigue en la siguiente (dos como mucho)
   en vez de cortarse con puntos suspensivos. */
.espacio-menu .fichero .dropdown-item b {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.3;
}

.espacio-menu .fichero .quitar {
  flex: 0 0 auto;
  margin-right: .4rem;
  padding: 4px 6px;
  border: 0;
  border-radius: var(--iaui-radius-sm);
  background: transparent;
  color: var(--iaui-text-muted);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

.espacio-menu .fichero .quitar:hover {
  background: var(--iaui-bg-hover);
  color: var(--iaui-danger);
}

/* «Ver»: abre el fichero en el panel visor sin bajarlo. */
.espacio-menu .fichero .ver {
  flex: 0 0 auto;
  margin-right: .2rem;
  padding: 0 .4rem;
  border: 0;
  border-radius: var(--iaui-radius-sm);
  background: transparent;
  color: var(--iaui-text-muted);
  font-size: 14px;
  line-height: 1.6;
}

.espacio-menu .fichero .ver:hover {
  background: var(--iaui-bg-hover);
  color: var(--iaui-text);
}

/* ─────────────── Visor de ficheros ─────────────── */
/* Mismo mecanismo que el panel de ajustes, más ancho: enseña un documento. */
.visor-panel {
  width: 0; flex: none; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--iaui-bg-side); border-left: 1px solid var(--iaui-border);
  transition: width .18s ease;
}
body.visor-open .visor-panel { width: var(--iaui-visor-width, min(720px, 55vw)); }

/* Mientras se arrastra, sin transición: el panel sigue al ratón, no lo persigue. */
body.resizing .visor-panel { transition: none; }

/* Su divisor: sólo cuando el visor está abierto, pegado a su borde izquierdo. */
.resizer-visor { display: none; margin-left: 0; margin-right: -2px; }
body.visor-open .resizer-visor { display: block; }
.visor-head { padding-left: 18px; padding-right: 18px; margin-bottom: 0; flex: none; }
/* Exacto (PDF de LibreOffice) / Texto (markdown de pandoc). Si no hay botones, el de bajar se va a la derecha. */
.visor-modo { display: flex; border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-sm); overflow: hidden; margin-right: 6px; flex: none; }
.visor-modo button { border: 0; background: transparent; color: var(--iaui-text-muted); font-size: 12px; padding: 3px 9px; cursor: pointer; }
.visor-modo button:hover { color: var(--iaui-text); }
.visor-modo button.on { background: var(--iaui-bg-hover); color: var(--iaui-text); }
#visor-modo[hidden] + #visor-bajar { margin-left: auto; }
.visor-head #visor-titulo { min-width: 0; }
/* El árbol comparte panel con el visor: arriba, con su propio desplazamiento y
   un tope de altura para que la vista no se quede sin sitio. */
.visor-arbol {
  flex: none; max-height: 38%; overflow: auto;
  padding: 8px 10px; font-size: 13px;
  border-bottom: 1px solid var(--iaui-border);
}
.visor-arbol .arbol-vacio { font-size: 12px; color: var(--iaui-text-muted); margin: 4px 2px; }
.visor-arbol details { margin: 0; }
.visor-arbol summary {
  cursor: pointer; padding: 3px 4px; border-radius: var(--iaui-radius-sm);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.visor-arbol summary:hover { background: var(--iaui-bg-hover); }
.visor-arbol summary .ic { margin-right: 5px; }
/* Cada nivel se mete un poco: sin la sangría el árbol es una lista plana. */
.visor-arbol details > details,
.visor-arbol details > .arbol-fichero { margin-left: 13px; }
.arbol-fichero {
  display: flex; align-items: center; gap: 6px;
  padding: 3px 4px; border-radius: var(--iaui-radius-sm); cursor: pointer;
}
.arbol-fichero:hover { background: var(--iaui-bg-hover); }
.arbol-fichero.activo { background: var(--iaui-bg-active); font-weight: 600; }
.arbol-fichero .nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.arbol-fichero .tam { font-size: 11px; color: var(--iaui-text-muted); white-space: nowrap; }
/* Bajar y borrar sólo al pasar por encima: en reposo el árbol se lee mejor. */
.arbol-fichero .baja, .arbol-fichero .quita {
  visibility: hidden; border: 0; background: none; padding: 0 2px;
  color: var(--iaui-text-muted); font-size: 13px; line-height: 1; text-decoration: none; cursor: pointer;
}
.arbol-fichero:hover .baja, .arbol-fichero:hover .quita,
.arbol-fichero:focus-within .baja, .arbol-fichero:focus-within .quita { visibility: visible; }
.arbol-fichero .quita:hover { color: var(--iaui-danger); }
/* El de descargar es un <a> y sin esto sale azul —y morado tras visitarlo—
   mientras el de borrar, que es un <button>, sale gris. */
.arbol-fichero a.baja, .arbol-fichero a.baja:visited { color: var(--iaui-text-muted); }
.arbol-fichero a.baja:hover { color: var(--iaui-text); }
.arbol-fichero .baja svg { display: block; }
#visor-arbol-btn.on { background: var(--iaui-bg-active); }
/* La cabecera del desplegable lleva el atajo al árbol a la derecha. */
.espacio-menu .head .ver-arbol {
  float: right; border: 0; background: none; padding: 0;
  color: var(--iaui-accent); font-size: 11px; cursor: pointer;
}

.visor-cuerpo { flex: 1; min-height: 0; overflow: auto; padding: 14px 18px 24px; font-size: 14px; }
.visor-cuerpo img { max-width: 100%; height: auto; }
.visor-cuerpo pre { white-space: pre-wrap; word-break: break-word; }
.visor-cuerpo .smallcaps { font-variant: small-caps; }
.visor-cuerpo table { border-collapse: collapse; margin-bottom: 12px; font-size: 13px; }
.visor-cuerpo th, .visor-cuerpo td { border: 1px solid var(--iaui-border); padding: 3px 8px; vertical-align: top; }
.visor-cuerpo .visor-hoja td, .visor-cuerpo .visor-hoja th { white-space: nowrap; }
.visor-cuerpo canvas { display: block; max-width: 100%; height: auto; margin: 0 auto 12px; box-shadow: 0 1px 4px rgba(0, 0, 0, .3); }
.visor-hojas, .visor-modos { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.visor-modos .on { background: var(--iaui-bg-hover); }
/* HTML: el conmutador arriba y el marco ocupando el resto del panel. */
.visor-html { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.visor-html iframe { flex: 1; min-height: 0; width: 100%; border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-sm); background: #fff; }
.visor-html pre { flex: 1; min-height: 0; overflow: auto; margin: 0; }
.visor-hojas .on { background: var(--iaui-bg-hover); }
.visor-aviso { font-size: 12px; color: var(--iaui-text-muted); margin-bottom: 8px; }

/* Documentos de texto (Word, Writer, RTF…): el markdown de pandoc dentro de un
   folio blanco sobre fondo gris, como las páginas del PDF. Blanco y texto
   oscuro también en tema oscuro: es papel. El folio llena el ancho del panel;
   los márgenes van en % del ancho y la altura mínima es la de una hoja, así
   que las proporciones son las del papel se abra como se abra. */
.visor-cuerpo.folio { background: var(--iaui-bg-side); padding: 18px 18px 28px; }
.visor-folio-fondo { container-type: inline-size; }
.visor-folio {
  position: relative;   /* los bloques se miden respecto a la hoja al repartirlos */
  box-sizing: border-box; width: 100%;
  min-height: calc(100cqw * var(--folio-alto, 1.414));
  background: #fff; color: #1a1a1a;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
  /* Si el documento declara su letra, el estilo en línea la pone (tamaño en
     proporción al papel, familia y tamaños de título); esto es lo de por defecto. */
  font-size: clamp(12px, 1.9cqw, 17px); line-height: 1.35;
  overflow-wrap: anywhere;
}
.visor-folio > :first-child { margin-top: 0; }
.visor-folio h1 { font-size: var(--folio-h1, 1.7em); }
.visor-folio h2 { font-size: var(--folio-h2, 1.4em); }
.visor-folio h3 { font-size: var(--folio-h3, 1.2em); }
.visor-folio h1, .visor-folio h2, .visor-folio h3, .visor-folio h4 { margin: 1em 0 .45em; line-height: 1.2; }
/* La forma del párrafo la declara el documento (Vistas.Letra); estas variables
   son lo de por defecto para cuando no la trae o no se entiende. La sangría de
   primera línea no se aplica al párrafo que sigue a un título: en un documento
   de verdad ése empieza a bocajarro. */
.visor-folio p, .visor-folio ul, .visor-folio ol {
  margin: var(--folio-antes, 0) 0 var(--folio-despues, .65em);
}
.visor-folio p { text-indent: var(--folio-sangria, 0); }
.visor-folio h1 + p, .visor-folio h2 + p, .visor-folio h3 + p,
.visor-folio h4 + p, .visor-folio > p:first-child { text-indent: 0; }
.visor-folio a { color: #1a4fd6; }
.visor-folio pre, .visor-folio code { background: #f3f3f4; color: #1a1a1a; }
.visor-folio pre { padding: .6em .8em; border-radius: 4px; }
.visor-folio blockquote { border-left: 3px solid #cfcfcf; margin: 0 0 .8em; padding-left: .8em; color: #444; }
.visor-folio table { font-size: .92em; }
.visor-folio th, .visor-folio td { border-color: #bdbdbd; }
.visor-folio th { background: #f3f3f4; }
.visor-folio hr { border: none; border-top: 1px solid #bdbdbd; margin: 1.2em 0; }
/* Entre hoja y hoja, su número. */
.visor-folio-num { text-align: center; font-size: 11px; color: var(--iaui-text-muted); margin: 6px 0 14px; }

/* Elegir idioma en la pantalla de entrada. */
.login-lang { display: flex; justify-content: center; align-items: center; gap: 4px; margin-top: 12px; color: var(--iaui-text-muted); font-size: 13px; }
.login-lang .btn-link { padding: 0 4px; font-size: 13px; text-decoration: none; }

/* ─────────────── Bienvenida (conversación vacía) ─────────────── */
.bienvenida {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center; gap: 8px;
  padding: 24px; pointer-events: none;
}
.bienvenida .brand-mark { width: 52px; height: 52px; font-size: 19px; border-radius: 14px; margin-bottom: 10px; }
.bienvenida-hola { margin: 0; color: var(--iaui-text-muted); font-size: 16px; }
/* La frase, a lo grande y con el color de acento en degradado: es el «hero». */
.bienvenida h2 {
  margin: 0; font-size: 42px; font-weight: 700; letter-spacing: -.5px; max-width: 22ch; line-height: 1.15;
  background: linear-gradient(100deg, var(--iaui-accent), color-mix(in srgb, var(--iaui-accent) 55%, var(--iaui-text)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.bienvenida-pista { margin: 10px 0 0; color: var(--iaui-text-muted); font-size: 14px; }
@media (max-width: 640px) { .bienvenida h2 { font-size: 28px; } .bienvenida .brand-mark { width: 44px; height: 44px; } }
/* El atributo hidden NO la ocultaba: la regla de arriba pone display:flex y una
   regla de autor gana siempre a la del navegador, así que la bienvenida seguía
   dibujándose encima de la conversación aunque el código la diera por oculta. */
.bienvenida[hidden] { display: none; }
/* Con poco alto —el teclado del móvil abierto— la bienvenida no cabe y se
   derramaba sobre la caja de escribir. En vez de quitarla, encoge: el saludo
   sigue estando, sólo que más pequeño (29-8-2026, visto en un Android).
   El overflow es el cinturón: pase lo que pase, no se sale de su hueco. */
.bienvenida { overflow: hidden; }
@media (max-height: 620px) {
  .bienvenida { padding: 10px; gap: 3px; }
  .bienvenida .brand-mark { width: 34px; height: 34px; font-size: 14px; border-radius: 10px; margin-bottom: 4px; }
  .bienvenida-hola { font-size: 13px; }
  .bienvenida h2 { font-size: 24px; max-width: 24ch; line-height: 1.2; }
  .bienvenida-pista { font-size: 12px; margin-top: 4px; }
}
/* Y si queda de verdad poco —el teclado de un móvil alto deja menos de 430 px—
   sólo se va la línea de la pista, que es lo prescindible. El logotipo y el
   saludo se quedan, más pequeños: en un Android real con el teclado abierto
   sobraba sitio y la pantalla quedaba desangelada sin ellos. */
@media (max-height: 430px) {
  .bienvenida-pista { display: none; }
  .bienvenida .brand-mark { width: 28px; height: 28px; font-size: 12px; border-radius: 8px; margin-bottom: 2px; }
  .bienvenida-hola { font-size: 12px; }
  .bienvenida h2 { font-size: 19px; max-width: 30ch; }
}
/* La opción Imagen apagada con un modelo sin visión: se ve, pero no se puede pulsar. */
.attach-menu .dropdown-item.disabled { opacity: .45; cursor: not-allowed; }

/* ── Mi suscripción ── */
#mi-suscripcion { margin-bottom: 14px; }
.cuota.suscripcion .grande { color: var(--iaui-text); font-size: 22px; }
.cuota.suscripcion.danger { border-color: var(--iaui-danger); }
.planes { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; margin-top: 8px; }
.plan {
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md);
  padding: 12px 13px; background: var(--iaui-bg-app); display: flex; flex-direction: column; gap: 5px;
}
.plan-nombre { font-weight: 600; }
.plan-precio { font-size: 20px; font-weight: 700; color: var(--iaui-accent); font-variant-numeric: tabular-nums; }
.plan-precio small { font-size: 12px; font-weight: 400; color: var(--iaui-text-muted); }
.plan-detalle { font-size: 12px; color: var(--iaui-text-muted); line-height: 1.45; flex: 1; }
.plan.actual { border-color: var(--iaui-accent); }
.plan-nota { color: var(--iaui-text); }
#sus-panel-cambio { margin-top: 10px; }
/* La casilla de condiciones: legible, y roja si intentó seguir sin marcarla. */
.consentimiento { display: flex; gap: 8px; align-items: flex-start; font-size: 12px; line-height: 1.45; margin: 6px 0 10px; color: var(--iaui-text); }
.consentimiento input { margin-top: 2px; }
.consentimiento.falta { color: var(--iaui-danger); }
#mi-periodos .cuota.periodo { margin-top: 14px; }
#mi-periodos .cuota.periodo .grande { color: var(--iaui-text); }

/* El plan que se eligió en la landing, al llegar a la app. */
.plan.elegido { outline: 3px solid var(--iaui-accent); outline-offset: 2px; }

/* Tarjeta de incidencia: cuando algo se rompe, el usuario ve esto y no un JSON. */
/* Colores sacados de --iaui-danger mezclado con el fondo (27-9-2026; antes eran
   literales, con su copia a mano para el oscuro): el token ya cambia con el
   tema, así que claro y oscuro salen de la misma regla. */
.step.incidencia {
  border: 1px solid color-mix(in srgb, var(--iaui-danger) 45%, var(--iaui-bg-app));
  background: color-mix(in srgb, var(--iaui-danger) 7%, var(--iaui-bg-app));
  border-radius: 10px;
  padding: 10px 12px;
  margin: 6px 0;
}
.step.incidencia .inc-cab { display: flex; gap: 8px; align-items: center;
                            color: color-mix(in srgb, var(--iaui-danger) 85%, var(--iaui-text)); }
.step.incidencia .inc-txt { margin-top: 4px; font-size: .95em; }
.step.incidencia .inc-ref { margin-top: 6px; font-size: .8em; opacity: .65; font-family: ui-monospace, monospace; }
/* El oscuro sale del ATRIBUTO del tema (los tokens cambian con él), nunca de
   @media (prefers-color-scheme): así la tarjeta se quedaba en claro —fondo rosa
   y texto gris clarito, ilegible— con la web en oscuro y el sistema en claro,
   que es justo lo que pasa al elegir el tema a mano (19-9-2026). */
/* Aviso RECUPERABLE (el modelo se pausó, se puede continuar): con el color de
   acento de la web, no el rojo de error. Tranquiliza en vez de alarmar. */
/* El fondo va REBAJADO con el de la app: el «soft» a pelo tiraba demasiado a
   azul para un aviso que sólo informa. El borde también, más tenue que el
   acento puro; el color fuerte se queda para el título y el icono. */
.step.incidencia.aviso {
  background: color-mix(in srgb, var(--iaui-accent-soft) 45%, var(--iaui-bg-app));
  border-color: color-mix(in srgb, var(--iaui-accent) 35%, var(--iaui-bg-app));
}
/* El título, en un azul MÁS CLARO que el acento puro: es un aviso que
   tranquiliza, no una alarma. En oscuro el acento ya es de por sí un azul
   suave, así que allí se deja tal cual. */
.step.incidencia.aviso .inc-cab { color: color-mix(in srgb, var(--iaui-accent) 72%, var(--iaui-bg-app)); }
[data-bs-theme="dark"] .step.incidencia.aviso .inc-cab { color: var(--iaui-accent); }

/* Sólo aparece cuando se paga con saldo: que se note que ahí sí hay dinero. */
/* Ámbar del tema oscurecido hacia el texto: el --iaui-warn a pelo se lee mal
   en letra pequeña sobre blanco. En oscuro el mismo cálculo lo aclara. */
.last-stats.prepago { color: color-mix(in srgb, var(--iaui-warn) 75%, var(--iaui-text)); font-weight: 600; }


/* ── Tarjeta de fichero dentro de una respuesta ─────────────────────────────
   El modelo escribe [[fichero: informe.docx]] y sale esto. Azul y no rojo: el
   rojo es de las incidencias y aquí no ha fallado nada, al contrario. Va
   pegada a la siguiente si hay varias, para que un encargo con tres ficheros
   se lea como un bloque y no como tres avisos sueltos. */
.tarjeta-fichero {
  display: flex; align-items: center; gap: 10px;
  margin: 8px 0; padding: 9px 12px;
  /* Marco gris como el resto de la interfaz y sólo una pista de color a la
     izquierda: con el acento a tope el recuadro gritaba más que la respuesta,
     y esto no es un aviso, es un resultado. El color-mix va sobre transparente
     —no sobre blanco— para que valga igual en el tema oscuro. */
  border: 1px solid var(--iaui-border); border-left: 3px solid
    color-mix(in srgb, var(--iaui-accent) 45%, var(--iaui-border));
  border-radius: var(--iaui-radius-sm);
  background: color-mix(in srgb, var(--iaui-accent) 4%, transparent);
}
.tarjeta-fichero + .tarjeta-fichero { margin-top: -4px; }
.tarjeta-fichero .tf-ic { font-size: 20px; line-height: 1; }
.tarjeta-fichero .tf-txt { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.tarjeta-fichero .tf-txt b { font-size: 13px; overflow-wrap: anywhere; }
.tarjeta-fichero .tf-txt span { font-size: 11.5px; color: var(--iaui-text-muted); }
.tarjeta-fichero .tf-btn {
  border: none; background: none; cursor: pointer; padding: 4px 6px;
  border-radius: var(--iaui-radius-sm); font-size: 15px; line-height: 1;
  color: var(--iaui-text-muted); text-decoration: none;
}
.tarjeta-fichero .tf-btn:hover { background: var(--iaui-bg-hover); color: var(--iaui-text); }
/* El de descargar es un <a>: sin esto hereda el azul de los enlaces y desentona
   con el ojo y la papelera, que son botones. */
.tarjeta-fichero a.tf-btn,
.tarjeta-fichero a.tf-btn:visited { color: var(--iaui-text-muted); }
.tarjeta-fichero a.tf-btn:hover { color: var(--iaui-text); }
.tarjeta-fichero .tf-btn svg { display: block; }
.tarjeta-fichero .tf-borra:hover { color: var(--iaui-danger); }


/* El saldo de prepago cuando la franja se ha agotado. Sin barra a propósito:
   no es un porcentaje de nada, es lo que queda para seguir. En verde apagado,
   no en rojo: no es un aviso de que algo va mal, es la salida. */
.prepago-chip {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 8px; padding: 2px 8px;
  /* Verde APAGADO: el --iaui-online del tema llevado hacia el texto. Antes era
     var(--iaui-ok, #2e7d32), pero --iaui-ok nunca existió y salía siempre el
     literal, también en oscuro (verde oscuro sobre fondo oscuro). */
  --chip: color-mix(in srgb, var(--iaui-online) 60%, var(--iaui-text));
  border: 1px solid var(--chip); border-radius: 999px;
  font-size: 11.5px; line-height: 1.6; white-space: nowrap;
  color: var(--chip);
  background: color-mix(in srgb, var(--chip) 8%, transparent);
}


/* El límite semanal agotado. Mismo formato que el de prepago —son hermanos y
   salen juntos— pero en rojo apagado: es un tope alcanzado, no una avería. Con
   el rojo de los errores parecería que algo se ha roto. */
.semana-chip {
  display: inline-flex; align-items: center;
  margin-left: 8px; padding: 2px 8px;
  /* Rojo APAGADO: el de los errores llevado hacia el gris del texto. */
  --chip: color-mix(in srgb, var(--iaui-danger) 75%, var(--iaui-text-muted));
  border: 1px solid color-mix(in srgb, var(--chip) 55%, var(--iaui-border));
  border-radius: 999px;
  font-size: 11.5px; line-height: 1.6; white-space: nowrap;
  color: var(--chip);
  background: color-mix(in srgb, var(--chip) 7%, transparent);
}


/* Mientras se relanza una respuesta que llegó vacía (13-9-2026). Late despacio
   para que se vea que sigue vivo, y desaparece en cuanto llega la respuesta. */
.aviso-trabajando {
  display: inline-block; margin: .35rem 0;
  font-size: .8rem; color: var(--iaui-text-muted);
  border: 1px dashed var(--iaui-border); border-radius: 999px;
  padding: .2rem .75rem;
  animation: aviso-latido 1.6s ease-in-out infinite;
}
@keyframes aviso-latido { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .aviso-trabajando { animation: none; } }


/* Botón de escuchar, al lado del de copiar. Mientras suena se pone del color de
   acento para que se vea de un vistazo cuál de las respuestas está sonando. */
.msg-actions [data-voz].sonando { color: var(--iaui-accent); font-weight: 600; }
.msg-actions [data-voz][disabled] { opacity: .6; cursor: default; }

/* Aviso de versión nueva (19-9-2026): abajo a la derecha, discreto, con el
   color de acento. Sale cuando el servidor dice que hay web nueva; si la
   persona no está generando ni escribiendo, la página se recarga sola a los
   pocos segundos y vuelve a su conversación (app.js, comprobarVersion). */
.version-nueva {
  position: fixed; right: 16px; bottom: 16px; z-index: 1080;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-radius: var(--iaui-radius-md);
  background: color-mix(in srgb, var(--iaui-accent-soft) 60%, var(--iaui-bg-app));
  border: 1px solid color-mix(in srgb, var(--iaui-accent) 35%, var(--iaui-bg-app));
  color: var(--iaui-text); font-size: 13px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
}
.version-nueva button {
  border: 1px solid var(--iaui-accent); background: var(--iaui-accent);
  color: var(--iaui-text-invert); border-radius: var(--iaui-radius-sm);
  padding: 3px 10px; font-size: 13px;
}
@media (max-width: 600px) { .version-nueva { left: 16px; right: 16px; justify-content: space-between; } }

/* ─────────────── Prompts (27-9-2026) ─────────────── */
.prompt-nuevo {
  margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-sm);
  background: none; color: var(--iaui-text); font-size: 12px; padding: 2px 8px 2px 6px; cursor: pointer;
}
.prompt-nuevo:hover { border-color: var(--iaui-accent); color: var(--iaui-accent); }
.prompt-nuevo svg { width: 13px; height: 13px; }

/* Título arriba y el principio del texto debajo, en pequeño: con veinte
   prompts de títulos parecidos, la primera línea es lo que los distingue. */
.prompt-item { align-items: flex-start; }
.prompt-item .prompt-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.prompt-item .name { font-size: 13.5px; }
.prompt-item .snippet {
  font-size: 11.5px; color: var(--iaui-text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.prompt-acciones { display: flex; gap: 2px; flex: none; opacity: 0; }
/* Las filas de memorias usan los mismos botones: sin nombrarlas aquí, se
   quedaban con opacidad 0 en el escritorio y no se veían nunca (27-9-2026). */
.prompt-item:hover .prompt-acciones, .prompt-item:focus-within .prompt-acciones,
.memoria-item:hover .prompt-acciones, .memoria-item:focus-within .prompt-acciones { opacity: 1; }
.prompt-acciones button {
  border: none; background: none; color: var(--iaui-text-muted); line-height: 0;
  padding: 4px; border-radius: var(--iaui-radius-sm); cursor: pointer;
}
.prompt-acciones button:hover { background: var(--iaui-bg-active); color: var(--iaui-text); }
.prompt-acciones button[data-prompt-borrar]:hover { color: var(--iaui-danger); }
.prompt-acciones svg { width: 14px; height: 14px; }
/* Con el dedo no hay «pasar por encima»: los botones, siempre a la vista. */
@media (pointer: coarse) {
  .prompt-acciones { opacity: 1; }
  .prompt-acciones button { padding: 7px; }
}
.prompt-texto { font-family: var(--iaui-font-mono); font-size: 13px; min-height: 12em; }

/* El icono del «Guardar como prompt», a la medida del texto del botón. */
.msg-actions button svg { width: 13px; height: 13px; }

/* El menú de «/»: las clases del selector de modelos, con la lista algo más
   corta porque en el móvil el teclado ya se come media pantalla. */
.comandos-panel .picker-lista { max-height: min(40vh, 320px); }
.comandos-panel .picker-cabeza {
  padding: 8px 12px 4px; font-size: 11px; color: var(--iaui-text-muted);
}
.comandos-panel .picker-teclas { float: right; }
/* En una pantalla táctil no hay flechas ni Escape que valgan. */
@media (pointer: coarse) { .comandos-panel .picker-teclas { display: none; } }
.comandos-panel .picker-cabeza kbd {
  font-family: var(--iaui-font-mono); font-size: 10.5px; padding: 0 4px;
  border: 1px solid var(--iaui-border); border-radius: 4px;
  background: var(--iaui-bg-hover); color: var(--iaui-text); margin-left: 2px;
}

/* ─────────────── Memorias (27-9-2026) ─────────────── */
/* El interruptor en la cabecera de la sección, entre el título y «Nueva». */
.memoria-interruptor { margin: 0 0 0 auto; padding-left: 2.5em; min-height: 0; display: flex; align-items: center; }
.memoria-interruptor .form-check-input { cursor: pointer; margin-top: 0; }
.memoria-interruptor + .prompt-nuevo { margin-left: 0; }
.memoria-estado { margin: 0; padding: 2px 20px 8px; font-size: 11.5px; color: var(--iaui-text-muted); line-height: 1.35; }
.memoria-estado.apagadas { color: var(--iaui-warn); }

.memoria-grupo { padding-left: 10px; }
.memoria-item { align-items: flex-start; cursor: default; }
.memoria-item .memoria-txt {
  flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.4;
  overflow-wrap: anywhere; white-space: normal;
}
/* Las propuestas, destacadas: son las que esperan una decisión. */
.memoria-item.pendiente {
  display: flex; flex-direction: column; gap: 6px;
  margin: 4px 0 8px; padding: 8px 10px;
  border: 1px solid var(--iaui-accent); border-radius: var(--iaui-radius-md);
  background: var(--iaui-accent-soft); color: var(--iaui-text);
}
.memoria-botones { display: flex; gap: 6px; flex-wrap: wrap; }
.memoria-botones .btn { font-size: 12px; padding: 2px 10px; }

.memoria-contador {
  flex: none; padding: 6px 20px 10px; font-size: 11.5px; color: var(--iaui-text-muted);
  border-top: 1px solid var(--iaui-border);
}
.memoria-contador.lleno { color: var(--iaui-warn); }

.memoria-modal-pie { display: flex; gap: 12px; align-items: flex-start; justify-content: space-between; margin-top: 6px; }
.memoria-cuenta { flex: none; font-size: 12px; color: var(--iaui-text-muted); font-variant-numeric: tabular-nums; }
.memoria-cuenta.lleno { color: var(--iaui-danger); font-weight: 600; }

/* La tarjeta que sale debajo de una respuesta cuando el modelo propone algo. */
.memoria-tarjetas:empty { display: none; }
/* Es una .tarjeta-fichero (la de los ficheros entregados): aquí sólo lo propio. */
.memoria-tarjeta .tf-ic svg { display: block; width: 20px; height: 20px; color: var(--iaui-accent); }
.memoria-tarjeta .tf-btn svg { width: 16px; height: 16px; }
.memoria-tarjeta .tf-acepta:hover { color: var(--iaui-online); }
.memoria-tarjeta .memoria-resultado:empty { display: none; }
.memoria-tarjeta .memoria-error { color: var(--iaui-danger); }
/* Ya decidida: se queda como constancia, sin la pista de color. */
.memoria-tarjeta[data-estado="aceptada"], .memoria-tarjeta[data-estado="descartada"] {
  border-left-color: var(--iaui-border); background: none;
}
.memoria-tarjeta[data-estado="aceptada"] .memoria-resultado { color: var(--iaui-online); }
.memoria-tarjeta[data-estado="descartada"] .memoria-cita { color: var(--iaui-text-muted); text-decoration: line-through; }
/* Con «Recordar esto», el mensaje del usuario lleva tres botones y en el móvil
   el envoltorio (80 % del ancho) no los cabe en una fila: se partían por dentro
   («Guardar como / prompt», el icono encima del texto). Cada botón entero, y si
   no caben, a la fila de abajo, pegados a la derecha como la burbuja. */
.msg-actions button { white-space: nowrap; flex: none; }
.msg.user .msg-actions { flex-wrap: wrap; justify-content: flex-end; }

/* Diálogos de la casa (dialogo.js): confirmar, informar y pedir un texto, en vez
   de confirm()/alert()/prompt() del navegador. Por encima de cualquier otro
   modal —revocar una clave se pregunta DENTRO de «Mi perfil»—, y su fondo
   oscuro tapa también al de debajo. */
.modal.dialogo { z-index: 1070; }
.modal-backdrop.dialogo-fondo { z-index: 1065; }
.modal.dialogo .dialogo-texto { overflow-wrap: anywhere; white-space: pre-line; }
/* En el móvil los modales de formulario van a pantalla completa (ver arriba);
   una pregunta de sí o no, no: se queda como tarjeta centrada con su margen. */
@media (max-width: 900px) {
  .modal.dialogo .modal-dialog { margin: 16px; min-height: calc(100dvh - 32px); }
  .modal.dialogo .profile-modal { min-height: 0; border-radius: var(--iaui-radius-lg); }
}

/* ─────────────── Tareas y agentes (27-9-2026) ─────────────── */
/* Pestañas compactas, las de «Mi perfil» en pequeño: subrayado de acento en la
   elegida. Van de cabecera de la sección (Tareas | Agentes) y, dentro del
   editor de agentes, para cambiar entre la ficha y el texto. */
.pestanas {
  display: flex; gap: 2px; flex: none;
  padding: 8px 12px 0; border-bottom: 1px solid var(--iaui-border);
}
.pestana {
  border: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
  background: none; color: var(--iaui-text-muted);
  font-size: 13px; padding: 6px 10px; cursor: pointer;
}
.pestana:hover { color: var(--iaui-text); }
.pestana.active { color: var(--iaui-accent); border-bottom-color: var(--iaui-accent); font-weight: 500; }
.pestana:focus-visible { outline: 2px solid var(--iaui-accent); outline-offset: -2px; border-radius: var(--iaui-radius-sm); }
.pestanas-modal { padding: 0; margin-bottom: 6px; }
.pestana-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pestana-panel[hidden] { display: none; }
.tareas-acciones { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 20px 4px; flex: none; }
.tareas-acciones .prompt-nuevo { margin-left: 0; }

/* Cada agente: nombre, descripción y «modelo · vN» en tres renglones cortos. El
   ▶ empieza una tarea con él; lo demás, en el menú «···» como en los chats. */
.agente-item { align-items: flex-start; }
.agente-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.agente-txt .name, .agente-desc, .agente-meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agente-txt .name { font-size: 13.5px; }
.agente-desc, .agente-meta { font-size: 11.5px; color: var(--iaui-text-muted); }
.agente-desc:empty { display: none; }
.agente-empezar {
  border: none; background: none; color: var(--iaui-text-muted); line-height: 0;
  padding: 4px; border-radius: var(--iaui-radius-sm); cursor: pointer; flex: none; opacity: 0;
}
.agente-item:hover .agente-empezar, .agente-item:focus-within .agente-empezar { opacity: 1; }
.agente-empezar:hover { background: var(--iaui-bg-active); color: var(--iaui-accent); }
.agente-empezar svg { width: 14px; height: 14px; }
@media (pointer: coarse) { .agente-empezar { opacity: 1; padding: 7px; } }

/* El modal de «Nueva tarea»: cada agente, un botón grande de tres renglones. */
.tarea-agentes .conv-group { padding-left: 0; }
.tarea-opcion {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  width: 100%; text-align: left; margin-bottom: 6px; padding: 8px 12px;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md);
  background: none; color: var(--iaui-text); cursor: pointer;
}
.tarea-opcion:hover, .tarea-opcion:focus-visible { border-color: var(--iaui-accent); background: var(--iaui-accent-soft); }
.tarea-opcion b { font-weight: 600; font-size: 14px; overflow-wrap: anywhere; }
.tarea-opcion-desc { font-size: 13px; overflow-wrap: anywhere; }
.tarea-opcion-desc:empty { display: none; }
.tarea-opcion-meta { font-size: 11.5px; color: var(--iaui-text-muted); }

/* En la cabecera de una tarea: «Agente: Revisor · v3». Al pulsarlo, su texto. */
.tarea-agente {
  display: inline-flex; align-items: center; gap: 5px; min-width: 0; max-width: 100%;
  border: 1px solid var(--iaui-border); border-radius: 999px; background: none;
  color: var(--iaui-text); font-size: 12px; padding: 1px 9px 1px 7px; cursor: pointer;
}
.tarea-agente:hover { border-color: var(--iaui-accent); color: var(--iaui-accent); }
.tarea-agente svg { width: 13px; height: 13px; flex: none; color: var(--iaui-accent); }
.tarea-agente span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* En una tarea el modelo, las herramientas y el razonamiento los pone el agente
   (y el servidor): no se enseñan los selectores. */
/* La clase va en la CAJA de escribir y no en <body> (27-9-2026): en el body
   obligaba a recalcular la página entera en cada cambio de tarea a chat, y
   Chromium (Brave, Chrome) en Linux con Wayland y NVIDIA dejaba trozos viejos
   de la pantalla a la vista. Firefox no lo hacía. Sólo afecta a la caja. */
#composer.en-tarea .model-wrap, #composer.en-tarea #tools-wrap, #composer.en-tarea #razon-wrap { display: none !important; }

/* El aviso de conversación puede llevar varias líneas y un botón (la versión nueva). */
.aviso-modelo .aviso-linea + .aviso-linea { margin-top: 4px; }
.aviso-boton {
  margin-left: 6px; font-size: 12px; padding: 1px 10px; border-radius: var(--iaui-radius-sm);
  border: 1px solid var(--iaui-warn); background: none; color: var(--iaui-warn); cursor: pointer; white-space: nowrap;
}
.aviso-boton:hover { background: color-mix(in srgb, var(--iaui-warn) 14%, transparent); }

/* El editor de agentes. */
.agente-rejilla { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 12px; }
@media (max-width: 620px) { .agente-rejilla { grid-template-columns: minmax(0, 1fr); } }
.profile-modal .form-select { background-color: var(--iaui-bg-app); color: var(--iaui-text); border-color: var(--iaui-border); }
.agente-texto { min-height: 24em; white-space: pre; overflow-wrap: normal; overflow-x: auto; }
.agente-avisos {
  padding: 8px 12px; font-size: 13px; color: var(--iaui-text);
  border: 1px solid color-mix(in srgb, var(--iaui-warn) 45%, transparent); border-radius: var(--iaui-radius-md);
  background: color-mix(in srgb, var(--iaui-warn) 10%, var(--iaui-bg-app));
}
.agente-avisos b { color: var(--iaui-warn); font-weight: 600; }
.agente-avisos ul { margin: 2px 0 0; padding-left: 18px; }
.agente-avisos li { overflow-wrap: anywhere; }
.agente-version { font-size: 12px; color: var(--iaui-text-muted); }
.agente-ver-texto {
  margin: 0; padding: 12px; font-family: var(--iaui-font-mono); font-size: 12.5px;
  white-space: pre-wrap; overflow-wrap: anywhere; color: var(--iaui-text);
  background: var(--iaui-bg-side); border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md);
}

/* Etiquetas (27-9-2026): píldoras pequeñas y discretas, en gris y sin color —
   no son un estado ni un aviso, sólo palabras para buscar—. Tres como mucho y
   «+n»; la lista entera va en el title. Ver docs/tarjetas.md. */
/* Si no caben en una línea, bajan a la siguiente: recortadas a «c…», «re…» en
   el lateral estrecho no se leían (probado el 27-9-2026). */
.etiquetas { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 3px; min-width: 0; }
.etiquetas:empty { display: none; }
.etiqueta {
  font-size: 10.5px; line-height: 1.5; padding: 0 6px; max-width: 100%;
  border: 1px solid var(--iaui-border); border-radius: 999px; color: var(--iaui-text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.etiqueta-mas { border-style: dashed; }
/* Una tarea en su lista: título, hora y «···» arriba; el agente y su versión debajo. */
.tarea-item.with-snippet .dropdown { order: 0; }
.tarea-item.with-snippet .snippet { order: 1; margin-top: 0; }

/* ─────────────── Skills (28-9-2026) ─────────────── */
/* Cuatro pestañas en el lateral (Tareas | Agentes | Flujos | Skills): más
   juntas, y si aun así no caben (un idioma con palabras largas, el panel en su
   ancho mínimo) se desplazan en vez de partirse o salirse. */
.pestanas-cuatro { gap: 0; overflow-x: auto; scrollbar-width: none; }
.pestanas-cuatro::-webkit-scrollbar { display: none; }
.pestanas-cuatro .pestana { padding: 6px 5px; font-size: 12.5px; white-space: nowrap; flex: none; }
/* Las skills elegidas en la ficha de un agente: las píldoras de las etiquetas
   con un ✕ para quitarla (docs/tarjetas.md, «Etiquetas»); con el borde ámbar
   la que no se encuentra. Sin color de relleno: no son un estado. */
.agente-skills { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.agente-skills .etiquetas { margin-top: 0; }
.agente-skills .form-select { width: auto; max-width: 100%; flex: 1 1 200px; }
.etiqueta-quitar { display: inline-flex; align-items: center; gap: 3px; font-size: 12px; padding: 1px 4px 1px 8px; color: var(--iaui-text); }
.etiqueta-quitar button {
  border: none; background: none; color: var(--iaui-text-muted); cursor: pointer;
  padding: 0 3px; line-height: 1; font-size: 11px; border-radius: 999px;
}
.etiqueta-quitar button:hover { color: var(--iaui-danger); background: var(--iaui-bg-hover); }
.etiqueta-mala { border-color: var(--iaui-warn); }
/* La zona de ficheros del editor de skills: una tarjeta de resultado por
   fichero, y el recuadro se marca en acento al arrastrar encima. */
.skill-ficheros {
  margin-top: 14px; padding: 10px 12px; border: 1px dashed var(--iaui-border);
  border-radius: var(--iaui-radius-md);
}
.skill-ficheros.arrastrando { border-color: var(--iaui-accent); background: color-mix(in srgb, var(--iaui-accent) 8%, transparent); }
.skill-ficheros-cab { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.skill-ficheros-cuenta { font-size: 12px; color: var(--iaui-text-muted); }
.skill-ficheros .tarjeta-fichero { margin: 6px 0; }
.skill-ficheros .tarjeta-fichero + .tarjeta-fichero { margin-top: -2px; }
.skill-ficheros-vacio { padding: 4px 0; }
.skill-fichero-vista { margin-top: 8px; }
.skill-fichero-vista-cab { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; font-size: 13px; overflow-wrap: anywhere; }
.skill-fichero-vista pre { max-height: 22em; overflow: auto; }

/* ─────────────── Flujos (28-9-2026) ─────────────── */
/* La caja de un paso de flujo en el chat: una caja de paso más (.step, la de las
   herramientas y el razonamiento), arriba de la respuesta del agente. Plegada:
   «Paso 3 · Revisor · vuelta 2 de 3 · coste»; abierta, lo decidido antes de él.
   Ver docs/tarjetas.md. */
.msg .flow-box:not(:empty) { margin-bottom: 8px; }
.step.flow > summary { color: var(--iaui-text); }
.step.flow .flow-tit { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.step.flow .flow-ev { margin: 0; padding: 8px 13px 8px 30px; font-size: 12.5px; color: var(--iaui-text-muted); }
.step.flow .flow-ev li + li { margin-top: 2px; }
.step.flow .flow-ev li { overflow-wrap: anywhere; }
.step.flow .flow-ev li.aviso { color: var(--iaui-warn); }
/* La caja del final: el color dice cómo acabó (verde, bien; ámbar, parado o en
   el tope; rojo, algo falló), con la franja de la izquierda como la tarjeta de
   resultado, sin fondo de alarma. */
.msg.flow-fin { margin-top: -8px; }
.step.flow.fin { border-left: 3px solid var(--iaui-online); }
.step.flow.fin.parado { border-left-color: var(--iaui-warn); }
.step.flow.fin.mal { border-left-color: var(--iaui-danger); }
.step.flow.fin.bien > summary .ic { color: var(--iaui-online); }
.step.flow.fin.mal > summary .ic { color: var(--iaui-danger); }

/* El editor: a la izquierda el diagrama, que se coloca solo (de arriba abajo,
   las ramas en columnas y los bucles envolviendo sus pasos); a la derecha, al
   pulsar una caja, su configuración. Nada se arrastra. */
.flujo-lienzo { position: relative; display: flex; gap: 12px; align-items: flex-start; margin-top: 4px; }
.fd {
  flex: 1; min-width: 0; overflow: auto; max-height: 58vh; padding: 12px 8px 16px;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md); background: var(--iaui-bg-side);
}
.fd-lista { display: flex; flex-direction: column; align-items: center; min-width: min-content; }
.fd-caja {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  min-width: 170px; max-width: 260px; padding: 6px 12px; text-align: center;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md);
  background: var(--iaui-bg-app); color: var(--iaui-text); font-size: 13px;
}
button.fd-caja { cursor: pointer; }
button.fd-caja:hover, button.fd-caja:focus-visible { border-color: var(--iaui-accent); outline: none; }
.fd-caja.fd-activa { border-color: var(--iaui-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--iaui-accent) 30%, transparent); }
.fd-caja.fd-mal { border-color: var(--iaui-danger); }
.fd-caja.fd-mal .fd-sub { color: var(--iaui-danger); }
.fd-tit { display: flex; align-items: center; gap: 6px; max-width: 100%; }
.fd-nombre { overflow-wrap: anywhere; font-weight: 500; }
.fd-ic { font-size: 11px; flex: none; }
.fd-ic svg { display: block; width: 14px; height: 14px; color: var(--iaui-accent); }
.fd-sub { font-size: 11.5px; color: var(--iaui-text-muted); overflow-wrap: anywhere; }
.fd-cab { background: var(--iaui-bg-side); }
/* El ⊕ entre paso y paso, con el trazo que los une por arriba y por abajo. */
.fd-mas {
  position: relative; width: 22px; height: 22px; margin: 12px 0; padding: 0; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px dashed var(--iaui-text-muted); border-radius: 50%;
  background: var(--iaui-bg-app); color: var(--iaui-text-muted); cursor: pointer;
}
.fd-mas svg { width: 13px; height: 13px; }
.fd-mas:hover, .fd-mas:focus-visible { border-style: solid; border-color: var(--iaui-accent); color: var(--iaui-accent); outline: none; }
.fd-mas::before, .fd-mas::after, .fd-linea {
  content: ""; position: absolute; left: 50%; width: 1px; height: 12px; background: var(--iaui-border);
}
.fd-mas::before { bottom: 100%; }
.fd-mas::after { top: 100%; }
.fd-lista > .fd-mas:first-child::before, .fd-lista > .fd-mas:last-child::after { display: none; }
.fd-linea { position: static; display: block; height: 16px; }
.fd-vacio { font-size: 12px; color: var(--iaui-text-muted); padding: 6px; }
/* Un bucle envuelve sus pasos; un «según» abre sus ramas en columnas. */
.fd-bucle {
  display: flex; flex-direction: column; align-items: center; padding: 8px 14px 4px;
  border: 1px dashed color-mix(in srgb, var(--iaui-accent) 60%, var(--iaui-border)); border-radius: var(--iaui-radius-lg);
  background: color-mix(in srgb, var(--iaui-accent) 5%, transparent);
}
.fd-segun { display: flex; flex-direction: column; align-items: center; }
.fd-ramas {
  display: flex; gap: 14px; align-items: flex-start; justify-content: center;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--iaui-border);
}
.fd-rama { display: flex; flex-direction: column; align-items: center; min-width: 140px; }
.fd-etq {
  font-size: 11.5px; line-height: 1.6; padding: 0 9px; max-width: 100%; overflow-wrap: anywhere;
  border: 1px solid var(--iaui-border); border-radius: 999px; color: var(--iaui-text-muted); background: var(--iaui-bg-app);
}
/* El menú del ⊕: el de Bootstrap, colgado del botón. */
.fd-menu { position: absolute; z-index: 5; min-width: 240px; }
.fd-menu .dropdown-item { display: flex; flex-direction: column; white-space: normal; }
.fd-menu-tit { font-size: 13.5px; }
.fd-menu-pista { font-size: 11.5px; color: var(--iaui-text-muted); }
/* La configuración de la caja elegida. */
.fd-config {
  width: 300px; flex: none; padding: 10px 12px; position: sticky; top: 0;
  border: 1px solid var(--iaui-border); border-radius: var(--iaui-radius-md); background: var(--iaui-bg-app);
}
.fd-config-tit { display: block; margin-bottom: 2px; }
.fd-config .field-label { margin-top: 8px; }
.fd-config .field-hint { margin: 4px 0 0; }
.fd-config-parte[hidden] { display: none; }
.fd-config-error { color: var(--iaui-danger); font-size: 12.5px; min-height: 0; margin-top: 6px; }
.fd-config-error:empty { display: none; }
.fd-config-pie { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
/* Sólo mirar: sin ⊕ ni cajas que pulsar, y el aviso de por qué. */
.flujo-solo-mirar { color: var(--iaui-warn); }
/* En pantalla estrecha, todo en columna: las ramas una debajo de otra y el panel debajo. */
@media (max-width: 900px) {
  .flujo-lienzo { flex-direction: column; }
  .fd-config { width: 100%; position: static; }
  .fd-ramas { flex-direction: column; align-items: stretch; }
  .fd-rama { min-width: 0; }
  .fd-caja { min-width: 0; width: 100%; max-width: none; }
  .fd-lista, .fd-bucle, .fd-segun, .fd-rama { min-width: 0; align-items: stretch; }
  .fd-etq { align-self: center; }
  .fd-linea, .fd-mas { align-self: center; }
}
