/* ═══════════════════════════════════════════════════════════════
   MIEL · Componentes — botones, chips, mensajes, código, línea de
   herramientas, tarjetas de confirmación, agentes, tareas, avisos
   y paleta de comandos.
   ───────────────────────────────────────────────────────────────
   Tres reglas que se repiten en todo el archivo:

     1. Todo estado interactivo existe: reposo, hover, activo, foco
        de teclado, deshabilitado y —donde aplique— cargando.

     2. Ningún estado se comunica SOLO con color. Siempre hay una
        segunda señal: un icono, un borde, un peso, una posición.

     3. El vidrio vive en el marco. Todo lo que lleva una cifra va
        sobre superficie opaca, porque un dato sobre fondo
        translúcido cambia de contraste según lo que pase por
        detrás.
   ═══════════════════════════════════════════════════════════════ */

/* ── Botones ───────────────────────────────────────────── */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  height:38px; padding:0 var(--sp-4);
  border:1px solid var(--border-strong); border-radius:var(--r-md);
  background:var(--surface); color:var(--text);
  font-size:var(--fs-sm); font-weight:var(--peso-semi); letter-spacing:var(--track);
  box-shadow:var(--shadow-1);
  /* La sombra entra en la transición: al pasar el mouse el botón sube, y al
     pulsarlo se aplasta contra la superficie. Sin eso el hover es solo un
     cambio de color y el botón no se siente como un objeto. */
  transition:background var(--t-fast), border-color var(--t-fast),
             color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast);
  white-space:nowrap;
}
.btn:hover:not(:disabled) {
  border-color:var(--border-brand); color:var(--accent);
  transform:translateY(-1px); box-shadow:var(--shadow-2);
}
.btn:active:not(:disabled) { transform:translateY(1px); box-shadow:var(--shadow-1); }
.btn:disabled { opacity:.45; box-shadow:none; transform:none; }

.btn-primary {
  background:var(--grad-marca);
  border-color:transparent; color:var(--text-on-brand);
  font-weight:var(--peso-fuerte);
  box-shadow:0 6px 20px rgba(232,184,92,.28);
}
.btn-primary:hover:not(:disabled) {
  color:var(--text-on-brand);
  box-shadow:0 10px 26px rgba(232,184,92,.4);
}
.btn-primary:active:not(:disabled) { box-shadow:0 3px 10px rgba(232,184,92,.3); }

.btn-ghost { background:transparent; border-color:transparent; box-shadow:none; }
.btn-ghost:hover:not(:disabled) { background:var(--accent-soft); border-color:var(--border-brand); box-shadow:none; }

.btn-danger { color:var(--danger); border-color:color-mix(in oklab, var(--danger) 45%, transparent); background:var(--danger-soft); }
.btn-danger:hover:not(:disabled) { color:var(--danger); border-color:var(--danger); }

.btn-ok { color:var(--ok); border-color:color-mix(in oklab, var(--ok) 45%, transparent); background:var(--ok-soft); }
.btn-ok:hover:not(:disabled) { color:var(--ok); border-color:var(--ok); }

.btn-icon { width:36px; height:36px; padding:0; border-radius:11px; }
.btn-sm { height:28px; padding:0 var(--sp-2); font-size:var(--fs-xs); border-radius:9px; }
.btn-block { width:100%; margin-top:var(--sp-2); }

/* Los botones del marco —los de la barra— son de vidrio, no de superficie:
   están sobre la aurora y una tarjeta opaca ahí se ve como un parche. */
.topbar .btn-icon { background:var(--glass); border-color:var(--glass-line); box-shadow:none; }
.topbar .btn-icon:hover { background:var(--accent-soft); border-color:var(--border-brand); }

/* Encendido y apagado tienen que distinguirse SIN color: el botón activo
   lleva además el halo. Quien no distingue el oro del gris tiene que poder
   saber si lo están escuchando. */
.btn[aria-pressed="true"] {
  background:var(--grad-marca); color:var(--text-on-brand);
  border-color:transparent; box-shadow:var(--glow);
}

/* Cargando: el botón se queda del mismo tamaño y cambia de contenido. Si se
   encogiera, la fila entera se movería justo después de que alguien apretó,
   que es cuando peor cae. */
.btn[data-cargando] { pointer-events:none; color:transparent; position:relative; }
.btn[data-cargando]::after {
  content:''; position:absolute; width:15px; height:15px; border-radius:50%;
  border:2px solid currentColor; border-top-color:transparent;
  color:var(--text-2); animation:spin 700ms linear infinite;
}
.btn-primary[data-cargando]::after { color:var(--text-on-brand); }

/* Los iconos de voz se dibujan en CSS: dos formas simples valen menos que un
   archivo SVG más una petición, y heredan el color del botón en los dos
   temas y en los dos estados. */
.icono-mic, .icono-bocina { width:15px; height:15px; display:block; position:relative; }
.icono-mic::before {
  content:''; position:absolute; left:4px; top:0; width:7px; height:9px;
  border-radius:4px; background:currentColor;
}
.icono-mic::after {
  content:''; position:absolute; left:2px; top:8px; width:11px; height:6px;
  border:1.6px solid currentColor; border-top:none;
  border-radius:0 0 7px 7px;
}
.icono-bocina::before {
  content:''; position:absolute; left:1px; top:4px; width:6px; height:7px;
  background:currentColor;
  clip-path:polygon(0 0, 60% 0, 100% -40%, 100% 140%, 60% 100%, 0 100%);
}
.icono-bocina::after {
  content:''; position:absolute; left:8px; top:3px; width:6px; height:9px;
  border:1.6px solid currentColor; border-left:none;
  border-radius:0 6px 6px 0;
}

/* ── Botones del riel ──────────────────────────────────── */
.rail-btn {
  display:flex; align-items:center; gap:var(--sp-3);
  width:100%; padding:9px var(--sp-3);
  border-radius:11px; border:1px solid transparent;
  color:var(--text-2); font-size:var(--fs-sm); font-weight:var(--peso-medio);
  text-align:left; position:relative;
  transition:background var(--t), color var(--t), box-shadow var(--t);
}
.rail-btn:hover { background:var(--accent-soft); color:var(--text); }
.rail-btn[aria-current="true"] {
  background:var(--grad-realce); color:var(--text);
  box-shadow:inset 0 0 0 1px var(--border-brand);
}
.rail-btn[aria-current="true"]::before {
  content:''; position:absolute; left:0; top:8px; bottom:8px;
  width:3px; border-radius:var(--r-full); background:var(--accent);
}
.rail-btn .ico { width:20px; text-align:center; font-size:14px; flex:0 0 auto; opacity:.9; }
.rail-btn .kbd { margin-left:auto; }

/* ── Chips y píldoras ──────────────────────────────────── */
.chip {
  display:inline-flex; align-items:center; gap:6px;
  height:26px; padding:0 10px;
  border:1px solid var(--border); border-radius:var(--r-full);
  background:var(--surface-2); color:var(--text-2);
  font-size:var(--fs-xs); font-weight:var(--peso-medio); white-space:nowrap;
}
.topbar .chip {
  background:var(--glass); border-color:var(--glass-line);
  -webkit-backdrop-filter:var(--blur-sm); backdrop-filter:var(--blur-sm);
  height:30px;
}
.chip[data-tone="ok"]     { color:var(--ok);     background:var(--ok-soft);     border-color:color-mix(in oklab, var(--ok) 30%, transparent); }
.chip[data-tone="warn"]   { color:var(--warn);   background:var(--warn-soft);   border-color:color-mix(in oklab, var(--warn) 30%, transparent); }
.chip[data-tone="danger"] { color:var(--danger); background:var(--danger-soft); border-color:color-mix(in oklab, var(--danger) 30%, transparent); }
.chip[data-tone="brand"]  { color:var(--accent); background:var(--accent-soft); border-color:var(--border-brand); }
.chip-modulo { height:24px; font-size:var(--fs-xs); }

.dot { width:7px; height:7px; border-radius:var(--r-full); background:currentColor; flex:0 0 auto; box-shadow:0 0 8px currentColor; }
.dot.live { animation:pulse 2.2s ease-in-out infinite; }
/* El pulso del sistema: lo escribe hud.js con el resultado del último sondeo,
   y es la señal más barata de "sigue viva" que hay en la pantalla. */
.dot[data-estado="ok"]  { color:var(--ok); }
.dot[data-estado="mal"] { color:var(--danger); animation:none; }

/* ── Navegación unificada vanguardista (Topbar) ──────────── */
.topbar-nav {
  display:flex; align-items:center; gap:4px;
  background:var(--glass); padding:3px 6px;
  border-radius:var(--r-full); border:1px solid var(--glass-line);
  -webkit-backdrop-filter:var(--blur-sm); backdrop-filter:var(--blur-sm);
  box-shadow:var(--shadow-1);
}
.topbar-nav a {
  display:inline-flex; align-items:center; gap:5px;
  padding:5px 13px; border-radius:var(--r-full);
  font-size:var(--fs-xs); font-weight:var(--peso-semi);
  color:var(--text-2); text-decoration:none;
  transition:color var(--t-fast), background var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast);
}
.topbar-nav a:hover {
  color:var(--text); background:var(--accent-soft);
  transform:translateY(-1px); text-decoration:none;
}
.topbar-nav a.active {
  background:var(--grad-realce); color:var(--accent);
  box-shadow:inset 0 0 0 1px var(--border-brand);
}

.kbd {
  font-family:var(--font-mono); font-size:10.5px; line-height:1;
  padding:3px 5px; border-radius:var(--r-sm);
  border:1px solid var(--border-strong); border-bottom-width:2px;
  background:var(--surface-2); color:var(--text-3);
}

/* ── Tabs ──────────────────────────────────────────────── */
.tab {
  flex:1; padding:var(--sp-2) var(--sp-2) 10px;
  border-bottom:2px solid transparent;
  color:var(--text-3); font-size:var(--fs-sm); font-weight:var(--peso-semi);
  transition:color var(--t), border-color var(--t);
}
.tab:hover { color:var(--text-2); }
.tab[aria-selected="true"] { color:var(--accent); border-bottom-color:var(--accent); }
.tab .count {
  display:inline-block; min-width:17px; padding:0 4px; margin-left:5px;
  border-radius:var(--r-full); background:var(--surface-3);
  font-family:var(--font-cifra); font-size:10px; font-weight:var(--peso-fuerte);
  line-height:16px; text-align:center;
}

/* ── Tarjetas ──────────────────────────────────────────── */
/* Superficie OPACA: acá viven las cifras. */
.card {
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--r-lg); padding:var(--sp-4);
  box-shadow:var(--shadow-1);
  transition:box-shadow var(--t), border-color var(--t);
}
.card:hover { box-shadow:var(--shadow-2); border-color:var(--border-strong); }
.card-head { display:flex; align-items:center; gap:var(--sp-2); margin-bottom:var(--sp-3); }
/* El rótulo termina en una línea que corre hasta el borde: es lo que le da al
   panel la densidad de un puesto de mando en vez de la de un formulario. */
.card-title {
  display:flex; align-items:center; gap:var(--sp-2); flex:1;
  font-family:var(--font-mono); font-size:var(--fs-xs); font-weight:var(--peso-normal);
  letter-spacing:var(--track-rotulo); text-transform:uppercase; color:var(--text-3);
}
.card-title::after { content:''; flex:1; height:1px; background:var(--border); }
.pie-tarjeta { margin-top:var(--sp-2); font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3); }

.stat { display:flex; flex-direction:column; gap:2px; }
/* Las cifras van en monoespaciada: ancho fijo, columnas que no bailan, y un
   dato que se ve distinto de una frase le dice al ojo "esto se copia". */
.stat-value {
  font-family:var(--font-cifra); font-size:var(--fs-xl); font-weight:var(--peso-fuerte);
  line-height:1.05; letter-spacing:var(--track-tight);
  font-variant-numeric:tabular-nums; color:var(--accent);
}
.stat-value.sm { font-size:var(--fs-md); }
.stat-label { font-size:var(--fs-xs); color:var(--text-3); }
.stat-grid { display:grid; grid-template-columns:1fr 1fr; gap:var(--sp-3); }
.stat-grid + .stat-grid, .stat + .stat-grid { margin-top:var(--sp-3); }

.spark { display:flex; align-items:flex-end; gap:2px; height:34px; margin-top:var(--sp-3); }
.spark i {
  flex:1; min-height:2px; border-radius:2px 2px 0 0;
  background:var(--accent-soft); transition:height var(--dur-4) var(--curva-expresiva);
}
.spark i.hi { background:var(--accent); opacity:.7; }

/* ── Listas de datos (bóveda, canal, agenda) ───────────── */
.lista { list-style:none; display:flex; flex-direction:column; gap:2px; margin-top:var(--sp-2); }
.lista li {
  padding:7px var(--sp-2); border-left:2px solid var(--border);
  font-size:var(--fs-sm); color:var(--text-2);
}
.lista li small {
  display:block; font-family:var(--font-mono); font-size:var(--fs-xs);
  color:var(--text-3); margin-top:2px;
}
.lista--grado li { display:flex; align-items:center; gap:var(--sp-2); }
.lista--grado li b { margin-left:auto; font-family:var(--font-cifra); color:var(--accent); }
/* La agenda muestra solo lo PENDIENTE: listar lo ya cumplido bajo un título
   que dice "agenda" no es información de más, es información falsa. */
.lista--tareas li[data-prioridad="ALTA"] { border-left-color:var(--warn); }
.buscador { margin-top:var(--sp-2); }

/* La consola de voz: lo que Miel oyó y lo que contestó. */
.consola {
  max-height:180px; overflow-y:auto; margin-top:var(--sp-2);
  padding:var(--sp-2); border-radius:var(--r-sm);
  background:var(--bg-sunken); border:1px solid var(--border);
  font-family:var(--font-mono); font-size:var(--fs-xs); line-height:1.5;
}
.consola p + p { margin-top:4px; }
.consola .yo   { color:var(--text); }
.consola .miel { color:var(--accent); }
.consola .sis  { color:var(--text-3); }
.consola .mal  { color:var(--danger); }

/* ── Mensajes ──────────────────────────────────────────── */
.msg { display:flex; gap:var(--sp-3); animation:fade-up var(--dur-3) var(--curva-expresiva) both; }
.msg.user { flex-direction:row-reverse; }

.avatar {
  width:32px; height:32px; flex:0 0 auto; border-radius:10px;
  display:grid; place-items:center; overflow:hidden;
  font-size:11px; font-weight:var(--peso-fuerte); letter-spacing:.04em;
  border:1px solid var(--border);
}
.msg.miel .avatar {
  background:conic-gradient(from 210deg, var(--gold-400), var(--cyan-400), var(--gold-400));
  border-color:transparent; box-shadow:0 0 16px rgba(232,184,92,.3);
  color:transparent;
}
.msg.user .avatar { background:var(--info-soft); color:var(--info); border-color:transparent; }

/* 76ch es el ancho comodo para leer prosa; pasarse cansa la vista. Pero una
   TABLA o un bloque de codigo no se leen renglon por renglon: se escanean, y
   ahi el limite los aprieta hasta romperlos. Por eso la burbuja se ensancha
   sola cuando trae uno. */
.msg-body { min-width:0; max-width:min(100%, 76ch); transition:max-width var(--t); }
.msg.user .msg-body { max-width:min(100%, 62ch); }
.msg-body:has(table), .msg-body:has(pre) { max-width:100%; }

.bubble {
  padding:var(--sp-4) var(--sp-5);
  border-radius:var(--r-lg);
  font-size:var(--fs-md); line-height:var(--lh);
  overflow-wrap:anywhere;
  transition:box-shadow var(--t);
}
.msg.miel .bubble {
  background:var(--surface); border:1px solid var(--border);
  border-top-left-radius:var(--r-sm);
  box-shadow:var(--shadow-2);
}
/* La propia lleva el realce de marca en vez de un azul plano: es la misma
   familia de color que la aurora y el degradado, así la conversación se lee
   como una sola pieza. El texto sigue siendo el del tema —blanco sobre un
   tinte claro en tema claro era ilegible—. */
.msg.user .bubble {
  background:var(--grad-realce); color:var(--text);
  border:1px solid var(--border-brand);
  border-top-right-radius:var(--r-sm);
  box-shadow:var(--shadow-1);
}
.bubble b, .bubble strong { color:var(--accent); font-weight:var(--peso-semi); }

/* Mientras Miel escribe, el último párrafo lleva un cursor. Es la señal de
   que el texto sigue llegando y no de que se cortó. */
.bubble[data-escribiendo] > :last-child::after {
  content:''; display:inline-block; vertical-align:-2px;
  width:2px; height:1em; margin-left:3px;
  background:var(--accent); animation:pulse 1s steps(2) infinite;
}

.msg-foot {
  display:flex; align-items:center; gap:var(--sp-2);
  margin-top:5px; font-size:var(--fs-xs); color:var(--text-3);
  opacity:0; transition:opacity var(--t-fast);
}
.msg:hover .msg-foot, .msg-foot:focus-within { opacity:1; }
.msg.user .msg-foot { justify-content:flex-end; }
.msg-foot .btn-sm { height:24px; }
/* En pantalla táctil no hay hover: las acciones del mensaje quedarían
   invisibles para siempre. */
@media (pointer:coarse) { .msg-foot { opacity:1; } }

/* ── Contenido enriquecido dentro de la burbuja ────────── */
.bubble p + p { margin-top:.65em; }
.bubble h3, .bubble h4 {
  font-family:var(--font-display); font-size:var(--fs-md);
  font-weight:var(--peso-fuerte); letter-spacing:var(--track-tight);
  margin:.9em 0 .35em;
}
.bubble h3:first-child, .bubble h4:first-child { margin-top:0; }
.bubble ul, .bubble ol { margin:.5em 0 .5em 1.35em; }
.bubble li + li { margin-top:.25em; }
.bubble blockquote {
  margin:.6em 0; padding:.35em 0 .35em var(--sp-3);
  border-left:3px solid var(--border-brand); color:var(--text-2);
}
.bubble hr { margin:.9em 0; border:0; border-top:1px solid var(--border); }
.bubble code {
  font-family:var(--font-mono); font-size:.88em;
  background:var(--surface-3); padding:.12em .38em; border-radius:var(--r-sm);
}

/* La tabla dentro de una respuesta es un dato, y se comporta como tal:
   monoespaciada en las cifras, versalitas en la cabecera y scroll propio. Sin
   el scroll, una tabla de cinco columnas en un teléfono de 390px desborda la
   página entera. */
.bubble table {
  width:100%; border-collapse:collapse; margin:.7em 0;
  font-size:var(--fs-sm); display:block; overflow-x:auto;
  -webkit-overflow-scrolling:touch; overscroll-behavior-x:contain;
}
.bubble th, .bubble td { border-bottom:1px solid var(--border); padding:8px 10px; text-align:left; }
.bubble th {
  font-family:var(--font-mono); font-size:var(--fs-xs);
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--text-3); font-weight:var(--peso-semi);
}
.bubble td:not(:first-child) { font-family:var(--font-cifra); font-variant-numeric:tabular-nums; }

.codeblock {
  margin:.7em 0; border:1px solid var(--border); border-radius:var(--r-md);
  background:var(--bg-sunken); overflow:hidden;
}
.codeblock-head {
  display:flex; align-items:center; gap:var(--sp-2);
  padding:5px var(--sp-2) 5px var(--sp-3);
  background:var(--surface-2); border-bottom:1px solid var(--border);
  font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3);
}
.codeblock pre { margin:0; padding:var(--sp-3); overflow-x:auto; -webkit-overflow-scrolling:touch; }
/* Sin `tabular-nums` en código: el ancho fijo ya lo da la familia y las
   cifras heredadas del cuerpo desalinean los operadores. */
.codeblock code { background:none; padding:0; font-size:var(--fs-sm); line-height:1.55; font-variant-numeric:normal; }

/* ── Línea de actividad de herramientas ────────────────── */
/* Se muestra SIEMPRE, no solo cuando algo falla: es lo que separa una
   respuesta calculada de una inventada. */
.tool {
  border:1px solid var(--glass-line); border-radius:var(--r-md);
  background:var(--glass); overflow:hidden;
  animation:fade-up var(--dur-2) var(--curva-entrada);
}
.tool > summary {
  display:flex; align-items:center; gap:var(--sp-2);
  padding:7px var(--sp-3); cursor:pointer; list-style:none;
  font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3);
}
.tool > summary::-webkit-details-marker { display:none; }
.tool > summary::after { content:'▾'; margin-left:auto; color:var(--text-3); transition:transform var(--t-fast); }
.tool[open] > summary::after { transform:rotate(180deg); }
.tool[data-state="err"] > summary { color:var(--danger); }
.tool[data-state="ok"] .tool-badge { color:var(--ok); }
.tool-name { font-family:var(--font-mono); color:var(--cyan-600); }
:root[data-theme="dark"] .tool-name { color:var(--cyan-400); }
.tool-risk {
  font-size:9.5px; font-weight:var(--peso-fuerte); letter-spacing:.06em;
  padding:2px 5px; border-radius:var(--r-sm); background:var(--surface-3); color:var(--text-3);
}
.tool-body { padding:0 var(--sp-3) var(--sp-3); border-top:1px solid var(--glass-line); }
.tool-body pre {
  margin-top:var(--sp-2); padding:var(--sp-2); max-height:280px; overflow:auto;
  background:var(--bg-sunken); border-radius:var(--r-sm);
  font-family:var(--font-mono); font-size:var(--fs-xs); line-height:1.5;
}

/* ── Hallazgos de los agentes ──────────────────────────── */
/* El nivel se dice con el filete y con el fondo, y el texto del hallazgo
   nunca depende del color para entenderse. */
.findings { display:flex; flex-direction:column; gap:6px; margin-top:var(--sp-2); }
.finding {
  display:flex; gap:var(--sp-2); padding:9px var(--sp-3);
  border-left:3px solid var(--text-3); border-radius:0 var(--r-sm) var(--r-sm) 0;
  background:var(--surface-3); font-size:var(--fs-sm); line-height:1.45;
}
.finding[data-level="error"] { border-left-color:var(--danger); background:var(--danger-soft); }
.finding[data-level="warn"]  { border-left-color:var(--warn);   background:var(--warn-soft); }
.finding[data-level="info"]  { border-left-color:var(--info);    background:var(--info-soft); }
.finding .fx { display:block; margin-top:3px; font-size:var(--fs-xs); color:var(--text-2); }
.finding .fw { display:block; margin-top:2px; font-size:var(--fs-xs); color:var(--text-3); font-family:var(--font-mono); }

.score { display:inline-flex; align-items:center; gap:6px; font-family:var(--font-cifra); font-size:var(--fs-xs); font-weight:var(--peso-fuerte); }
.score-bar { width:56px; height:6px; border-radius:var(--r-full); background:var(--surface-3); overflow:hidden; }
.score-bar > i { display:block; height:100%; background:var(--ok); border-radius:inherit; transition:width var(--dur-4) var(--curva-expresiva); }
.score[data-tone="warn"] .score-bar > i { background:var(--warn); }
.score[data-tone="danger"] .score-bar > i { background:var(--danger); }

/* ── Tarjeta de confirmación ───────────────────────────── */
/* Miel pide permiso antes de escribir en disco, mandar un correo o tocar algo
   que no se deshace. Esta pieza existe para que ese permiso sea una decisión y
   no un trámite: nombre exacto de la herramienta, argumentos a la vista, y el
   botón que confirma separado del que cancela. */
.confirm {
  border:1px solid var(--border-brand); border-left:4px solid var(--accent);
  border-radius:var(--r-lg); background:var(--surface);
  padding:var(--sp-4); box-shadow:var(--shadow-2);
  animation:fade-up var(--dur-3) var(--curva-expresiva);
}
.confirm[data-level="CRITICAL"] { border-color:color-mix(in oklab, var(--danger) 45%, transparent); border-left-color:var(--danger); }
.confirm-title { font-size:var(--fs-xs); font-weight:var(--peso-fuerte); letter-spacing:.06em; text-transform:uppercase; color:var(--accent); }
.confirm[data-level="CRITICAL"] .confirm-title { color:var(--danger); }
.confirm-tool { font-family:var(--font-mono); font-size:var(--fs-md); font-weight:var(--peso-semi); margin-top:4px; }
.confirm-desc { font-size:var(--fs-sm); color:var(--text-2); margin-top:4px; }
.confirm pre {
  margin-top:var(--sp-2); padding:var(--sp-2); max-height:200px; overflow:auto;
  background:var(--bg-sunken); border-radius:var(--r-sm);
  font-family:var(--font-mono); font-size:var(--fs-xs);
}
.confirm-actions { display:flex; gap:var(--sp-2); margin-top:var(--sp-3); }
.confirm-actions .btn { flex:1; }
/* Ya resuelta no desaparece: qué se autorizó y qué no es parte de la
   conversación. */
.confirm-resolved { margin-top:var(--sp-2); font-size:var(--fs-sm); font-weight:var(--peso-semi); text-align:center; }

/* ── Campos ────────────────────────────────────────────── */
.field { display:flex; flex-direction:column; gap:4px; }
.field > label { font-size:var(--fs-xs); font-weight:var(--peso-semi); color:var(--text-2); }
.field > label .req { color:var(--danger); }
.input, .textarea, .select {
  width:100%; padding:9px var(--sp-3);
  border:1px solid var(--border-strong); border-radius:var(--r-sm);
  background:var(--surface); color:var(--text); font-size:var(--fs-sm);
  transition:border-color var(--t-fast), box-shadow var(--t-fast);
}
.input:focus, .textarea:focus, .select:focus {
  outline:none; border-color:var(--accent); box-shadow:0 0 0 4px var(--accent-soft);
}
.input::placeholder, .textarea::placeholder { color:var(--text-3); }
.hint { font-size:var(--fs-xs); color:var(--text-3); padding:0 2px 4px; }
.task-form { display:flex; flex-direction:column; gap:var(--sp-2); }

/* ── Compositor ────────────────────────────────────────── */
/* Vidrio: es marco, no dato. */
.composer-box {
  display:flex; align-items:flex-end; gap:var(--sp-2);
  padding:var(--sp-2);
  border:1px solid var(--glass-line); border-radius:18px;
  background:var(--glass-2);
  -webkit-backdrop-filter:var(--blur-lg); backdrop-filter:var(--blur-lg);
  box-shadow:var(--shadow-2);
  transition:border-color var(--t-fast), box-shadow var(--t-fast);
}
.composer-box:focus-within { border-color:var(--border-brand); box-shadow:var(--shadow-2), 0 0 0 4px var(--accent-soft); }
#input {
  flex:1; min-height:24px; max-height:200px; resize:none;
  border:none; background:none; padding:6px var(--sp-2);
  font-size:var(--fs-md); line-height:1.5;
}

/* Safari de iOS AMPLIA la pagina entera al enfocar un campo cuya fuente mide
   menos de 16px. Con --fs-md en 14.5px eso pasaba al tocar el compositor: la
   pagina quedaba ampliada, mas ancha que la pantalla, y a partir de ahi no se
   podia desplazar el chat ni escribir comodo. No es un capricho tipografico,
   son 16px exactos o el navegador hace zoom.
   Se limita a punteros gruesos para no engordar el texto en escritorio. */
@media (pointer:coarse) {
  #input, .input, .textarea, .select { font-size:16px; }
  /* Y el area sensible es el TEXTAREA, no el recuadro: tocar el relleno del
     recuadro no enfoca nada. Medido en iPhone, el campo quedaba en 25px. */
  #input { min-height:var(--tap); padding-block:10px; }
  /* También los chicos: `.btn-sm` son acciones reales —«Ejecutar revisión
     general», «Diagnóstico»—, no adornos, y a 36px el dedo las falla. */
  .btn, .btn-sm, .rail-btn, .tab, .palette-item, .suggestion, .cap { min-height:var(--tap); }
  .btn-icon { width:var(--tap); height:var(--tap); }
}
#input:focus { outline:none; box-shadow:none; }
.composer-meta {
  display:flex; align-items:center; gap:var(--sp-2);
  margin-top:6px; font-size:var(--fs-xs); color:var(--text-3);
}
.suggestions { display:flex; gap:var(--sp-2); flex-wrap:wrap; margin-bottom:var(--sp-2); }
/* En pantalla angosta las sugerencias dejan de apilarse y se deslizan: tres
   frases largas envueltas ocupaban tres renglones, que en un teléfono es más
   alto que la propia conversación. */
@media (max-width:560px) {
  .suggestions { flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; padding-bottom:2px; }
  .suggestions::-webkit-scrollbar { display:none; }
  .suggestion { white-space:nowrap; }
}
.suggestion {
  display:inline-flex; align-items:center;
  padding:7px 13px; border:1px solid var(--glass-line); border-radius:var(--r-full);
  background:var(--glass); font-size:var(--fs-xs); font-weight:var(--peso-medio); color:var(--text-2);
  transition:color var(--t), border-color var(--t), transform var(--t);
}
.suggestion:hover { border-color:var(--border-brand); color:var(--accent); transform:translateY(-1px); }

/* ── Escribiendo… ──────────────────────────────────────── */
/* El desfase entre los puntos es lo que lo hace leer como respiración y no
   como parpadeo. */
.typing { display:flex; align-items:center; gap:var(--sp-3); animation:fade-in var(--t); }
.typing-dots {
  display:flex; gap:5px; padding:13px var(--sp-4);
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--r-lg); border-top-left-radius:var(--r-sm);
}
.typing-dots i { width:7px; height:7px; border-radius:var(--r-full); background:var(--accent); opacity:.35; animation:bounce 1.1s var(--curva-estandar) infinite; }
.typing-dots i:nth-child(2) { animation-delay:.15s; }
.typing-dots i:nth-child(3) { animation-delay:.3s; }
@keyframes bounce { 0%,60%,100% { transform:none; opacity:.35; } 30% { transform:translateY(-5px); opacity:1; } }

/* ── Agentes ───────────────────────────────────────────── */
.agent { border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface); overflow:hidden; }
.agent + .agent { margin-top:var(--sp-2); }
.agent > summary {
  display:flex; align-items:center; gap:var(--sp-2);
  padding:10px var(--sp-3); cursor:pointer; list-style:none;
}
.agent > summary::-webkit-details-marker { display:none; }
.agent-ico { font-size:15px; width:22px; text-align:center; }
.agent-name { font-size:var(--fs-sm); font-weight:var(--peso-semi); }
.agent-mod { font-family:var(--font-mono); font-size:10px; letter-spacing:.05em; text-transform:uppercase; color:var(--text-3); }
.agent-caps { padding:0 var(--sp-2) var(--sp-2); display:flex; flex-direction:column; gap:2px; }
.cap {
  display:flex; align-items:center; gap:var(--sp-2); width:100%;
  padding:7px var(--sp-2); border-radius:var(--r-sm);
  font-size:var(--fs-xs); color:var(--text-2); text-align:left;
  transition:background var(--t-fast), color var(--t-fast);
}
.cap:hover { background:var(--accent-soft); color:var(--text); }
.cap-name { font-family:var(--font-mono); font-weight:var(--peso-semi); }
.cap-desc { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-3); }

.agent-form { padding:var(--sp-3); border-top:1px solid var(--border); background:var(--surface-2); display:flex; flex-direction:column; gap:var(--sp-2); }
.agent-result { padding:var(--sp-3); border-top:1px solid var(--border); }
.agent-result pre {
  margin-top:var(--sp-2); padding:var(--sp-2); max-height:260px; overflow:auto;
  background:var(--bg-sunken); border-radius:var(--r-sm);
  font-family:var(--font-mono); font-size:var(--fs-xs); line-height:1.5;
}

/* ── Tareas ────────────────────────────────────────────── */
.task { display:flex; align-items:flex-start; gap:var(--sp-2); padding:var(--sp-2) var(--sp-3); border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface); }
.task + .task { margin-top:var(--sp-2); }
.task.done { opacity:.55; }
.task.done .task-title { text-decoration:line-through; }
.task-title { font-size:var(--fs-sm); font-weight:var(--peso-medio); line-height:1.35; }
.task-meta { font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3); margin-top:2px; }
.task-check {
  width:18px; height:18px; flex:0 0 auto; margin-top:2px;
  border:1.5px solid var(--border-strong); border-radius:var(--r-sm);
  display:grid; place-items:center; font-size:11px; color:transparent;
  transition:background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.task-check:hover { border-color:var(--ok); color:var(--ok); }
.task.done .task-check { background:var(--ok); border-color:var(--ok); color:#fff; }
.prio { font-family:var(--font-mono); font-size:9.5px; font-weight:var(--peso-fuerte); padding:1px 5px; border-radius:var(--r-sm); }
.prio[data-p="ALTA"]   { background:var(--danger-soft); color:var(--danger); }
.prio[data-p="NORMAL"] { background:var(--info-soft);   color:var(--info); }
.prio[data-p="BAJA"]   { background:var(--surface-3);   color:var(--text-3); }

/* ── Avisos flotantes ──────────────────────────────────── */
/* Nunca tapan el compositor: un aviso que se come el botón de enviar
   convierte un mensaje en un estorbo. */
.toast {
  display:flex; align-items:flex-start; gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-4); border-radius:var(--r-md);
  background:var(--surface); border:1px solid var(--border);
  border-left:3px solid var(--info); box-shadow:var(--shadow-3);
  font-size:var(--fs-sm); pointer-events:auto;
  animation:fade-up var(--dur-3) var(--curva-expresiva);
}
.toast[data-tone="ok"]     { border-left-color:var(--ok); }
.toast[data-tone="warn"]   { border-left-color:var(--warn); }
.toast[data-tone="danger"] { border-left-color:var(--danger); }
.toast.out { animation:fade-in var(--t) reverse forwards; }

/* ── Paleta de comandos ────────────────────────────────── */
.palette {
  width:min(620px, 100%); max-height:min(60vh, 520px);
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--glass-2); -webkit-backdrop-filter:var(--blur-lg); backdrop-filter:var(--blur-lg);
  border:1px solid var(--glass-line);
  border-radius:var(--r-xl); box-shadow:var(--shadow-3);
  animation:fade-up var(--dur-2) var(--curva-expresiva);
}
.palette-input {
  padding:var(--sp-4); border:none; border-bottom:1px solid var(--glass-line);
  background:none; font-size:var(--fs-lg); outline:none;
}
.palette-list { overflow-y:auto; padding:var(--sp-2); }
.palette-item {
  display:flex; align-items:center; gap:var(--sp-3); width:100%;
  padding:9px var(--sp-3); border-radius:var(--r-sm);
  font-size:var(--fs-sm); text-align:left; color:var(--text-2);
}
.palette-item[aria-selected="true"] { background:var(--accent-soft); color:var(--text); }
.palette-item .ico { width:20px; text-align:center; }
.palette-item .sub { margin-left:auto; font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3); }
.palette-empty { padding:var(--sp-5); text-align:center; color:var(--text-3); font-size:var(--fs-sm); }

/* ── Estados vacíos y carga ────────────────────────────── */
/* El vacío es un estado, no un error: si no hay nada que mostrar hay que
   decirlo, no dejar un hueco que parece una falla de carga. */
.empty { padding:var(--sp-5) var(--sp-3); text-align:center; color:var(--text-3); font-size:var(--fs-sm); }
.empty .big { font-size:24px; display:block; margin-bottom:var(--sp-2); opacity:.6; }

/* El esqueleto imita la FORMA de lo que viene: lo que calma es reconocer de
   antemano dónde va a caer el título y dónde la cifra. */
.skeleton {
  height:14px; border-radius:var(--r-sm);
  background:linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size:200% 100%; animation:shimmer 1.4s var(--curva-estandar) infinite;
}
.spinner {
  width:14px; height:14px; border-radius:var(--r-full);
  border:2px solid var(--border-strong); border-top-color:var(--accent);
  animation:spin .7s linear infinite;
}

/* ── Bienvenida ────────────────────────────────────────── */
.welcome { text-align:center; padding:var(--sp-6) var(--sp-3) var(--sp-4); animation:fade-up var(--dur-4) var(--curva-expresiva); }
.welcome img { width:56px; height:56px; margin:0 auto var(--sp-3); }
.welcome h2 {
  font-family:var(--font-display); font-size:var(--fs-2xl);
  font-weight:var(--peso-fuerte); letter-spacing:var(--track-tight);
  background:var(--grad-texto);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.welcome p { color:var(--text-2); margin-top:var(--sp-2); max-width:52ch; margin-inline:auto; }
.welcome-grid {
  display:grid; grid-template-columns:repeat(auto-fit, minmax(190px,1fr));
  gap:var(--sp-2); margin-top:var(--sp-5); text-align:left;
}
.welcome-card {
  padding:var(--sp-4); border:1px solid var(--border); border-radius:var(--r-lg);
  background:var(--surface);
  transition:border-color var(--t), transform var(--t), box-shadow var(--t);
}
.welcome-card:hover { border-color:var(--border-brand); transform:translateY(-2px); box-shadow:var(--shadow-2); }
.welcome-card .t { font-size:var(--fs-sm); font-weight:var(--peso-semi); display:flex; align-items:center; gap:7px; }
.welcome-card .d { font-size:var(--fs-xs); color:var(--text-3); margin-top:4px; line-height:1.45; }

/* ── Servicios en vivo (panel lateral) ───────────────────── */
.svc-list { display:flex; flex-direction:column; gap:2px; }
.svc-row {
  display:flex; align-items:center; gap:9px;
  font-family:var(--font-mono); font-size:var(--fs-sm);
  padding:7px var(--sp-2); border-left:2px solid var(--border);
  background:var(--surface-2); color:var(--text-2);
}
.svc-row b { margin-left:auto; color:var(--text-3); font-weight:var(--peso-normal); font-size:var(--fs-xs); font-variant-numeric:tabular-nums; }
.svc-row .led { width:8px; height:8px; border-radius:50%; flex:none; }
.svc-row[data-vivo="si"] .led { background:var(--ok); box-shadow:0 0 8px var(--ok); }
.svc-row[data-vivo="si"] { border-left-color:var(--ok); }
/* Un servicio caído tiene que verse sin leer: es el dato que se busca justo
   cuando algo dejó de responder. */
.svc-row[data-vivo="no"] .led { background:var(--danger); box-shadow:0 0 8px var(--danger); }
.svc-row[data-vivo="no"] { border-left-color:var(--danger); background:var(--danger-soft); color:var(--danger); }

/* Cuadro de permiso de administrador. Es el único que pide escribir algo, y se
   distingue del resto a propósito: lo que autoriza no es el clic sino el
   código, y tiene que verse que este cuadro no es uno más. */
.confirm.admin { border-color:color-mix(in oklab, var(--warn, #d98e00) 55%, transparent); border-left-color:var(--warn, #d98e00); }
.confirm.admin .confirm-title { color:var(--warn, #d98e00); }
.confirm.admin .confirm-actions { flex-wrap:wrap; align-items:center; }
.confirm.admin .admin-codigo {
  flex:1 1 220px; min-width:180px;
  padding:var(--sp-2) var(--sp-3);
  font-family:var(--font-mono); font-size:var(--fs-sm);
  color:var(--text-1); background:var(--bg-2);
  border:1px solid var(--borde); border-radius:var(--radio-sm);
}
.confirm.admin .admin-codigo:focus { outline:2px solid var(--accent); outline-offset:1px; }
.confirm.admin .admin-error { margin-top:var(--sp-2); font-size:var(--fs-sm); }
