/* BetterAI — El osciloscopio sobre suelo neutro, en tres calibraciones
   Tema por <html data-theme="…">: dark · light (claro) · amoled (negro verdadero).
   Los tres comparten estructura, hairlines y el rojo granate como única señal viva;
   cambia el suelo y la tiza. Los bloques de código son un tintero: fondo #161616
   y tiza clara en las tres calibraciones (el resaltado vive solo ahí).
   Voz tipográfica: Public Sans para todo (pesos 400/500/600); JetBrains Mono
   solo para datos verdaderos (código, telemetría, timestamps — pesos 400/500).
   dark:   suelo #1a1a1a · sidebar #1d1d1d · paneles #232323 · tiza #E8E8E8
   light:  papel #F3F0E9 · hundido #EBE7DD · paneles #FFFFFF · tinta #23201B
   amoled: negro #000000 · hundido #0a0a0a · paneles #101010 · tiza #F0F0F0
   Rojo granate #A9443C — relleno vivo; como texto #DE7767 en oscuro y amoled, #AC3239 sobre papel.
   Ámbar solo avisos. (El código sigue llamándose fosforo: nombre de guerra del backend.) */

/* Voz única — Public Sans (variable 100–900): la página entera habla sans.
   Datos verdaderos — JetBrains Mono (variable 100–800): código, telemetría,
   timestamps, contadores. Disciplina de pesos: sans {400,500,600}, mono {400,500}. */
@font-face {
  font-family: "Public Sans";
  src: url("../fonts/public-sans-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- Calibraciones de color ---------- */

/* OSCURO — la calibración original: el osciloscopio de noche */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  /* Suelo neutro — superficies grises planas, de fuera hacia dentro */
  --ground: #1a1a1a;        /* oklch(0.218 0 90) — fondo del chat, plano y sin textura */
  --ground-deep: #1d1d1d;   /* oklch(0.231 0 90) — sidebar, hundido */
  --panel: #232323;         /* oklch(0.256 0 90) — composer-interno, chips, menús, modales, burbujas */
  --panel-2: #282828;       /* oklch(0.277 0 90) — hovers y estados presionados */
  --hairline: #363636;      /* oklch(0.333 0 90) — bordes primarios y divisor de zonas */
  --hairline-soft: #2e2e2e; /* bordes internos secundarios */
  --ink: #E8E8E8;           /* oklch(0.931 0 90) — tiza neutra, texto primario */
  --ink-2: #A0A0A0;         /* oklch(0.706 0 90) — texto secundario y etiquetas */
  --ink-3: #8A8A8A;         /* oklch(0.633 0 90) — metadatos (AA sobre suelo) */
  /* Superficies con nombre propio del contrato */
  --surface-elev: #2b2b2b;        /* composer elevado */
  --surface-elev-border: #3a3a3a; /* borde del composer y bordes fuertes de control */
  --hover: #252525;               /* hover de items de chat */
  --active: #2a2a2a;              /* item activo */
  --user-bubble: #2a2a2a;         /* burbuja del mensaje de usuario */
  /* Rojo granate — la única señal viva. La familia entera gira del naranja
     terracota (oklch h≈40) al carmesí (h≈26): mismo papel de instrumento,
     más sangre y menos barro. Texto AA ≥4.5 sobre suelo/panel/elev. */
  --terracotta: #A9443C;        /* oklch(0.529 0.126 26) — relleno vivo: orbe, LED, traza */
  --terracotta-deep: #8A2F2B;   /* oklch(0.456 0.117 26) — pressed / borde fuerte */
  --terracotta-bright: #C34E44; /* oklch(0.585 0.142 27) — hover del relleno */
  --terracotta-text: #DE7767;   /* oklch(0.673 0.126 28) — granate como TEXTO (AA ≥4.5 en todo el suelo) */
  --terracotta-dim: rgba(222, 119, 103, 0.5);
  --terracotta-faint: rgba(169, 68, 60, 0.14);
  --terracotta-glow: rgba(195, 78, 68, 0.5);
  /* Ámbar — exclusivo de avisos */
  --amber: #E8A33D;
  --amber-dim: rgba(232, 163, 61, 0.45);
  /* Atmósfera y elevación */
  --backdrop: rgba(0, 0, 0, 0.6);
  --shadow: rgba(0, 0, 0, 0.5);
  --shadow-strong: rgba(0, 0, 0, 0.55);
  /* El tintero: en oscuro coincide con la calibración */
  --code-bg: #161616;
  --code-head: #232323;
  --code-panel: #232323;
  --code-panel-2: #282828;
  --code-hairline: #363636;
  --code-hairline-soft: #2e2e2e;
  --code-ink: #E8E8E8;
  --code-ink-2: #A0A0A0;
  --code-ink-3: #8A8A8A;
  --code-terracotta-text: #DE7767;
  --code-terracotta-dim: rgba(222, 119, 103, 0.5);
  --code-terracotta-faint: rgba(169, 68, 60, 0.14);
  --code-amber: #E8A33D;
  --code-result: rgba(0, 0, 0, 0.35);
  --code-copy-done: #DE7767;
  --code-hljs-ink: #E8E8E8;

  /* Tipografías — voz única sans (Public Sans) + mono solo para datos
     verdaderos (JetBrains Mono). Sin serif: la marca también habla sans. */
  --sans: "Public Sans", -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  /* Medidas */
  --sidebar-w: 280px;
  --rail-w: 64px;
  --col-max: 760px;
}

/* PAPEL — la misma máquina de día: suelo cálido, paneles que flotan en blanco */
[data-theme="light"] {
  color-scheme: light;

  --ground: #F3F0E9;        /* papel cálido — fondo del chat, plano y sin textura */
  --ground-deep: #EBE7DD;   /* sidebar, hundido */
  --panel: #FFFFFF;         /* menús, modales, chips, burbujas — flotan sobre el papel */
  --panel-2: #F0EDE4;       /* hovers y estados presionados */
  --hairline: #D8D2C4;      /* bordes primarios y divisor de zonas */
  --hairline-soft: #E2DDD1; /* bordes internos secundarios */
  --ink: #23201B;           /* tinta, texto primario */
  --ink-2: #5C574D;         /* texto secundario y etiquetas */
  --ink-3: #757065;         /* metadatos (AA sobre papel) */
  --surface-elev: #FFFFFF;
  --surface-elev-border: #D8D2C4;
  --hover: #E8E4D9;
  --active: #E0DBCE;
  --user-bubble: #E8E4D9;
  /* Rojo granate: el relleno no cambia; el texto se hunde para leerse sobre claro.
     El texto-grade es más oscuro y más saturado que el de oscuro (más carmesí
     y menos rosa) para ganar contraste sobre papel sin virar a marrón. */
  --terracotta: #A9443C;
  --terracotta-deep: #8A2F2B;
  --terracotta-bright: #B5453A;
  --terracotta-text: #AC3239;   /* oklch(0.494 0.149 21) — AA ≥4.5 sobre papel y paneles */
  --terracotta-dim: rgba(172, 50, 57, 0.45);
  --terracotta-faint: rgba(169, 68, 60, 0.10);
  --terracotta-glow: rgba(169, 68, 60, 0.35);
  /* Ámbar — exclusivo de avisos. Con el acento ahora en carmesí (h≈26) el
     ámbar original (h≈75) quedaba a un paso de leerse como "rojo suave";
     se desplaza a oro más amarillo (h≈85) para que aviso y señal no se
     confundan: oro = cuidado, granate = vivo. */
  --amber: #B07C10;             /* ámbar texto-grade para avisos legibles sobre claro */
  --amber-dim: rgba(176, 124, 16, 0.45);
  --backdrop: rgba(28, 24, 18, 0.4);
  --shadow: rgba(28, 24, 18, 0.16);
  --shadow-strong: rgba(28, 24, 18, 0.22);
  /* El tintero sigue oscuro — el código no cambia de calibración */
  --code-bg: #161616;
  --code-head: #2E2E2E;
  --code-panel: #2E2E2E;
  --code-panel-2: #383838;
  --code-hairline: #3A3A3A;
  --code-hairline-soft: #333333;
  --code-ink: #E8E8E8;
  --code-ink-2: #A0A0A0;
  --code-ink-3: #8A8A8A;
  --code-terracotta-text: #DE7767;
  --code-terracotta-dim: rgba(222, 119, 103, 0.5);
  --code-terracotta-faint: rgba(169, 68, 60, 0.14);
  --code-amber: #E8A33D;
  --code-result: rgba(0, 0, 0, 0.35);
  --code-copy-done: #DE7767;
  --code-hljs-ink: #E8E8E8;
}

/* AMOLED — negro verdadero: la calibración del panel OLED. El suelo no emite luz;
   la estructura se lee con hairlines apenas por encima del negro. */
[data-theme="amoled"] {
  color-scheme: dark;

  --ground: #000000;        /* negro verdadero — fondo del chat, cero emisión en reposo */
  --ground-deep: #0a0a0a;   /* sidebar, hundido — un paso sobre el negro para que el divisor lea */
  --panel: #101010;         /* menús, modales, chips, burbujas */
  --panel-2: #161616;       /* hovers y estados presionados */
  --hairline: #222222;      /* bordes primarios y divisor de zonas — visible sobre OLED */
  --hairline-soft: #1a1a1a; /* bordes internos secundarios */
  --ink: #F0F0F0;           /* tiza, un punto más clara que en dark: AA sobrado sobre #000 */
  --ink-2: #A8A8A8;         /* texto secundario y etiquetas */
  --ink-3: #949494;         /* metadatos (AA sobre negro) */
  --surface-elev: #141414;
  --surface-elev-border: #242424;
  --hover: #141414;
  --active: #1c1c1c;
  --user-bubble: #1c1c1c;
  /* Rojo granate — la familia no cambia; #DE7767 sigue AA (~6.9:1) sobre #000 */
  --terracotta: #A9443C;
  --terracotta-deep: #8A2F2B;
  --terracotta-bright: #C34E44;
  --terracotta-text: #DE7767;
  --terracotta-dim: rgba(222, 119, 103, 0.5);
  --terracotta-faint: rgba(169, 68, 60, 0.14);
  --terracotta-glow: rgba(195, 78, 68, 0.5);
  /* Ámbar — exclusivo de avisos (oro en claro; aquí el ámbar puro sigue
     leyéndose distinto del granate: h≈75 vs h≈26) */
  --amber: #E8A33D;
  --amber-dim: rgba(232, 163, 61, 0.45);
  /* Atmósfera casi negra: la profundidad la dan los paneles, no la sombra */
  --backdrop: rgba(0, 0, 0, 0.75);
  --shadow: rgba(0, 0, 0, 0.6);
  --shadow-strong: rgba(0, 0, 0, 0.7);
  /* El tintero sigue oscuro — idéntico al de dark */
  --code-bg: #161616;
  --code-head: #232323;
  --code-panel: #232323;
  --code-panel-2: #282828;
  --code-hairline: #363636;
  --code-hairline-soft: #2e2e2e;
  --code-ink: #E8E8E8;
  --code-ink-2: #A0A0A0;
  --code-ink-3: #8A8A8A;
  --code-terracotta-text: #DE7767;
  --code-terracotta-dim: rgba(222, 119, 103, 0.5);
  --code-terracotta-faint: rgba(169, 68, 60, 0.14);
  --code-amber: #E8A33D;
  --code-result: rgba(0, 0, 0, 0.35);
  --code-copy-done: #DE7767;
  --code-hljs-ink: #E8E8E8;
}

* { box-sizing: border-box; }

/* El atributo hidden siempre gana: sin esto, display:flex/grid de .toast/.modal/.chips lo anula */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  transition: background-color 0.2s ease, color 0.2s ease;
}

::selection { background: rgba(169, 68, 60, 0.35); color: var(--ink); }

textarea, input { caret-color: var(--terracotta-text); }

:focus-visible {
  outline: 2px solid var(--terracotta-dim);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Browser surfaces carry the design */
* { scrollbar-width: thin; scrollbar-color: var(--hairline) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--hairline); border-radius: 5px; border: 2px solid var(--ground); }
*::-webkit-scrollbar-track { background: transparent; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); overflow: hidden; white-space: nowrap;
}

.micro {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* ---------- Shell ---------- */

.app { display: flex; height: 100dvh; }

.main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* ---------- Sidebar ---------- */

/* Mismo tono que el chat: las zonas se separan con el divisor, no con color */
.sidebar {
  width: var(--sidebar-w);
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--ground-deep);
  border-right: 1px solid var(--hairline);
  overflow: hidden;
}

.sidebar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 14px 10px 18px;
}

.brand { display: flex; align-items: center; gap: 9px; min-width: 0; }

.brand__led {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 7px var(--terracotta-glow);
  flex: none;
}

/* La marca sin tracking: el wordmark respira normal, como un nombre propio.
   Voz única sans — la marca se distingue por peso y escala, no por familia. */
.brand__name {
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink);
}

.btn-new {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 14px 12px;
  padding: 9px 12px;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.btn-new svg { width: 15px; height: 15px; flex: none; color: var(--terracotta-text); }
.btn-new:hover { background: var(--panel-2); border-color: var(--surface-elev-border); }

.sidebar__search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 14px 14px;
  padding: 7px 10px;
  background: var(--panel);
  border: 1px solid var(--hairline-soft);
  border-radius: 8px;
  color: var(--ink-3);
}

.sidebar__search svg { width: 14px; height: 14px; flex: none; }

.sidebar__search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
}
.sidebar__search input::placeholder { color: var(--ink-3); }
.sidebar__search input:focus { outline: none; }
.sidebar__search:focus-within { border-color: var(--terracotta-dim); }

.sidebar__nav {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0 8px 8px;
  overflow: hidden;
}

.sidebar__section { padding: 4px 10px 8px; }

.chatlist {
  list-style: none;
  margin: 0;
  padding: 0 2px;
  overflow-y: auto;
  flex: 1;
}

.chatlist__empty {
  padding: 14px 10px;
  font-size: 12.5px;
  color: var(--ink-3);
}

.chat-item { position: relative; }

.chat-item__btn {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 8px 30px 8px 12px;
  font: inherit;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.chat-item__btn:hover { background: var(--hover); color: var(--ink); }

.chat-item.active .chat-item__btn { background: var(--active); color: var(--ink); }

.chat-item__title {
  display: block;
  font-size: 13.5px;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-item.active .chat-item__title::before {
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 5px var(--terracotta-glow);
  margin-right: 7px;
  vertical-align: 2px;
}

.chat-item__meta {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
}

.chat-item__actions {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  gap: 2px;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.chat-item:hover .chat-item__actions,
.chat-item:focus-within .chat-item__actions { opacity: 1; }

.chat-item__actions .iconbtn { width: 24px; height: 24px; }
.chat-item__actions .iconbtn svg { width: 13px; height: 13px; }

/* Pie de sidebar: chip de usuario + calibración + salida */
.sidebar__foot {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 10px 12px;
  border-top: 1px solid var(--hairline-soft);
}

/* Chip de usuario: avatar granate + nombre + rol; abre el panel de admin */
.userchip {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 5px 8px 5px 6px;
  margin-left: -6px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s ease;
}
.userchip:hover { background: var(--hover); }

.userchip__avatar {
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--terracotta);
  color: #F2F2F2;
  font-size: 12px;
  font-weight: 600;
  flex: none;
}

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

.userchip__name {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.userchip__role {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
}

/* Selector de calibración — gemelo del reasoningpick, anclado sobre el pie */
.themepick { position: relative; flex: none; }

.themepick__menu {
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  min-width: 168px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 11px;
  box-shadow: 0 14px 40px var(--shadow);
  z-index: 45;
}

.themepick__title { display: block; padding: 6px 10px 5px; font-size: 9.5px; color: var(--ink-3); }

.themepick__opt {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  background: none;
  border: none;
  border-radius: 7px;
  padding: 8px 10px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  cursor: pointer;
  text-align: left;
}
.themepick__opt:hover, .themepick__opt.hl { background: var(--panel-2); color: var(--ink); }
.themepick__opt[aria-selected="true"] { color: var(--ink); }
.themepick__opt[aria-selected="true"]::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 5px var(--terracotta-glow);
  flex: none;
}

/* Pastilla de muestra de cada calibración */
.themepick__swatch {
  width: 14px; height: 14px;
  border-radius: 5px;
  border: 1px solid var(--hairline);
  flex: none;
}
.themepick__opt[data-theme-opt="dark"] .themepick__swatch { background: #1a1a1a; }
.themepick__opt[data-theme-opt="light"] .themepick__swatch { background: #F3F0E9; }
/* Negro sobre panel casi negro: la pastilla necesita borde hairline propio para leerse */
.themepick__opt[data-theme-opt="amoled"] .themepick__swatch { background: #000000; border-color: #3a3a3a; }

/* Collapsed rail (desktop) */
@media (min-width: 768px) {
  .app.rail .sidebar { width: var(--rail-w); }
  .app.rail .brand__name,
  .app.rail .btn-new__label,
  .app.rail .sidebar__search,
  .app.rail .sidebar__section,
  .app.rail .chatlist,
  .app.rail .userchip__meta { display: none; }
  .app.rail .sidebar__head { justify-content: center; padding: 14px 8px 10px; }
  .app.rail .btn-new { justify-content: center; margin: 6px 10px 12px; padding: 9px 0; }
  .app.rail .sidebar__foot { justify-content: center; gap: 6px; padding: 10px 6px; }
  .app.rail .userchip { flex: none; margin-left: 0; padding: 5px; }
  .app.rail .themepick,
  .app.rail #logoutBtn { display: none; }
}

/* ---------- Topbar (mobile) ---------- */

.topbar {
  display: none;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline-soft);
  background: var(--ground-deep);
}

/* El título de marca también aquí, sin tracking ancho */
.topbar__title {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
}
.topbar__led {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 6px var(--terracotta-glow);
}

.backdrop {
  position: fixed; inset: 0;
  background: var(--backdrop);
  z-index: 30;
}

/* ---------- Chat column: el suelo ---------- */
/* Suelo plano y sin textura en las tres calibraciones: papel, gris o negro verdadero.
   Las zonas se definen con divisores hairline, no con cambios de color.
   La única voz sobre el suelo es la señal viva en granate. */

.chat {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--ground);
}

.chat__inner {
  max-width: var(--col-max);
  margin: 0 auto;
  padding: 40px 28px 32px;
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

/* Empty state */
.empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 48px 12px;
}

.empty__title {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(28px, 4.2vw, 40px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.18;
}

/* ---------- Messages ---------- */

.messages { display: flex; flex-direction: column; gap: 30px; }

.msg { position: relative; }

/* Aparición suave de cada fila nueva (mensaje y traza) */
.msg { animation: msg-in 0.26s cubic-bezier(0.22, 1, 0.36, 1); }

@keyframes msg-in {
  from { opacity: 0; transform: translateY(7px); }
  to { opacity: 1; transform: none; }
}

.msg__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 7px;
}

.msg__role {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-2);
}

.msg__time {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* El cuerpo del mensaje habla sans — la voz única de la página.
   15.5px / 1.6 — la medida de lectura cómoda de Public Sans. */
.msg__body {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 15.5px;
  line-height: 1.6;
  overflow-wrap: break-word;
}

.msg--user { padding-left: 26px; }
.msg--user .msg__body {
  background: var(--user-bubble);
  border: 1px solid var(--hairline-soft);
  border-radius: 12px;
  padding: 12px 16px;
}

.msg--assistant { padding-left: 14px; }
.msg--assistant::before {
  content: "";
  position: absolute;
  left: 0; top: 3px; bottom: 3px;
  width: 2px;
  border-radius: 1px;
  background: transparent;
}

/* Signature: the live trace */
.msg--streaming::before {
  background: var(--terracotta);
  box-shadow: 0 0 8px var(--terracotta-glow);
}

.msg--locked::before {
  background: var(--terracotta);
  animation: lockfade 0.6s ease forwards;
}

@keyframes lockfade { from { opacity: 1; } to { opacity: 0; } }

.stream-cursor {
  display: inline-block;
  width: 0.55em;
  height: 1.02em;
  margin-left: 3px;
  vertical-align: text-bottom;
  background: var(--terracotta);
  border-radius: 1px;
  animation: blink 1.05s steps(1) infinite;
}

@keyframes blink { 50% { opacity: 0; } }

.stopped-note {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--terracotta-text);
  letter-spacing: 0.06em;
  margin-top: 8px;
}

/* ---------- Trazas de razonamiento ---------- */

/* Indicador "pensando": lamparita viva + versalitas; lo enciende el JS al abrir traza */
.thinking {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 2px 0 10px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.thinking__lamp {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 6px var(--terracotta-glow);
  flex: none;
  animation: thinkpulse 1.3s ease-in-out infinite;
}

@keyframes thinkpulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.thinking__time {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* Etiqueta escalable: el texto largo de la escalación (SERVIDOR LENTO /
   SIN RESPUESTA) debe poder fluir sin romper la fila en pantallas estrechas. */
.thinking__label {
  min-width: 0;
}

/* Plegable del razonamiento: hairline que se vuelve granate mientras está vivo */
.reasoning {
  margin: 2px 0 12px;
  border-left: 2px solid var(--hairline);
  padding: 2px 0 2px 14px;
}

.reasoning--live { border-left-color: var(--terracotta); }

.reasoning__toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 9px;
  background: none;
  border: 1px solid var(--hairline-soft);
  border-radius: 7px;
  font: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-2);
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.reasoning__toggle:hover {
  color: var(--ink);
  border-color: var(--hairline);
  background: var(--hover);
}
.reasoning__toggle svg { width: 11px; height: 11px; transition: transform 0.15s ease; }
.reasoning__toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.reasoning__body {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-2);
  overflow-wrap: break-word;
  max-height: 320px;
  overflow-y: auto;
}
.reasoning__body > :first-child { margin-top: 0; }
.reasoning__body > :last-child { margin-bottom: 0; }
.reasoning__body p { margin: 0 0 8px; }

.msg__actions {
  display: flex;
  gap: 4px;
  margin-top: 8px;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.msg:hover .msg__actions,
.msg:focus-within .msg__actions { opacity: 1; }

@media (hover: none) { .msg__actions, .chat-item__actions { opacity: 1; } }

/* ---------- Nota de cambio de modelo ---------- */
/* Divisor silencioso en el flujo cuando el modelo cambia a mitad de chat:
   hairline que nace a la izquierda, etiqueta mono versalitas al centro (el JS
   pone el texto) y hairline que muere a la derecha. Un respiro de sección,
   no un banner — sin fondo, sin caja. El margen negativo compensa el gap de
   .messages (30px) para dejar 24px de aire a cada lado. */
.model-note {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: -6px 0;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
  animation: msg-in 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}

.model-note::before,
.model-note::after {
  content: "";
  height: 1px;
  flex: 1;
  min-width: 24px;
}

/* Nace transparente a la izquierda y llega hairline junto a la etiqueta */
.model-note::before { background: linear-gradient(to right, transparent, var(--hairline)); }
/* Muere transparente a la derecha */
.model-note::after { background: linear-gradient(to left, transparent, var(--hairline)); }

/* Si el JS inserta estructura, la etiqueta vive aquí; si inserta texto desnudo,
   hereda la voz mono versalitas del contenedor — las dos lecturas son idénticas */
.model-note__label { overflow: hidden; text-overflow: ellipsis; }

/* Markdown — jerarquía sans: títulos en peso 600, escala cómoda de lectura */
.msg__body > :first-child { margin-top: 0; }
.msg__body > :last-child { margin-bottom: 0; }
.msg__body p { margin: 0 0 12px; }
.msg__body h1, .msg__body h2, .msg__body h3, .msg__body h4 {
  margin: 22px 0 10px;
  letter-spacing: -0.01em;
  line-height: 1.3;
  font-weight: 600;
}
.msg__body h1 { font-size: 20px; } .msg__body h2 { font-size: 17px; }
.msg__body h3 { font-size: 15.5px; } .msg__body h4 { font-size: 14.5px; }
.msg__body ul, .msg__body ol { margin: 0 0 12px; padding-left: 24px; }
.msg__body li { margin: 4px 0; }
.msg__body a { color: var(--terracotta-text); text-underline-offset: 3px; }
.msg__body blockquote {
  margin: 0 0 12px;
  padding: 2px 0 2px 14px;
  border-left: 1px solid var(--hairline);
  color: var(--ink-2);
}
.msg__body hr { border: none; border-top: 1px solid var(--hairline); margin: 18px 0; }
.msg__body table {
  border-collapse: collapse;
  margin: 0 0 12px;
  font-size: 13.5px;
  width: 100%;
}
.msg__body th, .msg__body td {
  border: 1px solid var(--hairline);
  padding: 7px 11px;
  text-align: left;
}
.msg__body th {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: var(--panel);
}
.msg__body td { font-variant-numeric: tabular-nums; }

/* Código inline: chip de datos en mitad de prosa — fondo panel-2 + borde,
   el mismo vocabulario del tintero en miniatura. JetBrains Mono 13px. */
.msg__body code {
  font-family: var(--mono);
  font-size: 13px;
  background: var(--panel-2);
  border: 1px solid var(--hairline-soft);
  border-radius: 5px;
  padding: 1.5px 5px;
}

/* ---------- El tintero (bloques de código) ---------- */
/* Los bloques de código NO cambian de calibración: fondo #161616 y tiza clara
   en dark, light y amoled. Todo lo de dentro habla el dialecto --code-*, fijado
   por las variables de cada tema, para que el tema vendor de highlight.js
   (retintado sobre #161616) siga leyéndose igual en las tres calibraciones. */

.code {
  border: 1px solid var(--code-hairline);
  border-radius: 10px;
  overflow: hidden;
  margin: 0 0 12px;
  background: var(--code-bg);
}

.code__head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px 6px 14px;
  border-bottom: 1px solid var(--code-hairline-soft);
  background: var(--code-head);
}

.code__lang {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--code-ink-3);
  margin-right: auto;
}

.code__copy {
  background: none;
  border: none;
  font: inherit;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--code-ink-2);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 5px;
  transition: color 0.3s ease;
}
.code__copy:hover { background: var(--code-panel-2); color: var(--code-ink); }
/* Copiado reciente: la señal confirma en granate y se apaga sola */
.code__copy--done { color: var(--code-copy-done); }

/* Ejecutar Python: el botón que enciende el horno */
.code__run {
  background: none;
  border: 1px solid var(--code-hairline);
  border-radius: 6px;
  font: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--code-ink-2);
  cursor: pointer;
  padding: 3px 9px;
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.code__run:hover {
  color: var(--code-ink);
  border-color: var(--code-terracotta-dim);
  background: var(--code-terracotta-faint);
}
.code__run--running {
  color: var(--code-terracotta-text);
  border-color: var(--code-terracotta-dim);
  background: var(--code-terracotta-faint);
  cursor: default;
  animation: runpulse 1.2s ease-in-out infinite;
}
.code__run:disabled { cursor: default; }

@keyframes runpulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

/* Resultado de la ejecución: debajo del bloque, dentro del marco */
.code__result {
  border-top: 1px solid var(--code-hairline-soft);
  background: var(--code-result);
  padding: 10px 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.code__stdout,
.code__stderr {
  margin: 0;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  font-variant-numeric: tabular-nums;
}

.code__stdout { color: var(--code-ink); }
.code__stdout code { background: none; border: none; padding: 0; }

.code__stderr {
  color: var(--code-amber);
  background: rgba(232, 163, 61, 0.07);
  border: 1px solid rgba(232, 163, 61, 0.22);
  border-radius: 7px;
  padding: 9px 11px;
}

.code__imgs { display: flex; flex-wrap: wrap; gap: 10px; }
.code__imgs img {
  max-width: min(340px, 100%);
  max-height: 260px;
  border-radius: 8px;
  border: 1px solid var(--code-hairline);
  background: var(--code-bg);
  display: block;
}

.code__result-note {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--code-ink-3);
}

.code__meta {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: var(--code-ink-3);
  font-variant-numeric: tabular-nums;
}

.code pre { margin: 0; padding: 14px 16px; overflow-x: auto; }
/* JetBrains Mono es algo más estrecha que la mono anterior: 13px mantiene ~80
   columnas dentro del tintero sin desbordar la columna de 760px */
.code pre code { background: none; border: none; padding: 0; font-size: 13px; line-height: 1.55; }
/* Re-scoped del tema vendor: la base vive en el tintero, no en el tema de la página.
   Los tokens .hljs-* del vendor siguen mandando (paleta granate/carmesí sobre #161616). */
.hljs { background: transparent; color: var(--code-hljs-ink); }

.msg__imgs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.msg__imgs img {
  max-width: min(320px, 100%);
  max-height: 240px;
  border-radius: 10px;
  border: 1px solid var(--hairline);
  display: block;
}

.msg__files { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* ---------- Composer ---------- */

.composer {
  flex: none;
  max-width: var(--col-max);
  width: 100%;
  margin: 0 auto;
  padding: 6px 28px 14px;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 2px 10px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--panel);
  border: 1px solid var(--hairline-soft);
  border-radius: 8px;
  padding: 5px 8px 5px 10px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-2);
  max-width: 260px;
}

.chip__name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chip__size { color: var(--ink-3); flex: none; }

.chip__x {
  background: none; border: none; color: var(--ink-3);
  cursor: pointer; padding: 2px 4px; border-radius: 4px;
  font-size: 13px; line-height: 1;
}
.chip__x:hover { color: var(--ink); background: var(--panel-2); }

/* Superficie elevada del input — token por calibración */
.composer__box {
  background: var(--surface-elev);
  border: 1px solid var(--surface-elev-border);
  border-radius: 14px;
  transition: border-color 0.15s ease;
}

.composer__box:focus-within { border-color: var(--terracotta-dim); }

.composer__box textarea {
  display: block;
  width: 100%;
  background: none;
  border: none;
  resize: none;
  color: var(--ink);
  font: inherit;
  font-size: 15.5px;
  line-height: 1.55;
  padding: 14px 16px 6px;
  max-height: 220px;
}
.composer__box textarea::placeholder { color: var(--ink-3); }
.composer__box textarea:focus { outline: none; }

.composer__row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 8px;
}

.composer__spacer { flex: 1; }

.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.iconbtn svg { width: 17px; height: 17px; }
.iconbtn:hover { background: var(--panel-2); color: var(--ink); }

/* Model picker */
.modelpick { position: relative; }

.modelpick__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 6px 9px;
  color: var(--ink-2);
  cursor: pointer;
  font: inherit;
  transition: background 0.12s ease;
}
.modelpick__btn:hover { background: var(--panel-2); }
.modelpick__btn svg { width: 13px; height: 13px; }
.modelpick__name {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--ink);
  max-width: 150px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.modelpick__menu {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  min-width: 240px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 11px;
  box-shadow: 0 14px 40px var(--shadow);
  z-index: 30;
}

.modelpick__opt {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  background: none;
  border: none;
  border-radius: 7px;
  padding: 8px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--ink-2);
  cursor: pointer;
  text-align: left;
}
.modelpick__opt:hover, .modelpick__opt.hl { background: var(--panel-2); color: var(--ink); }
.modelpick__opt[aria-selected="true"] { color: var(--ink); }
.modelpick__opt[aria-selected="true"]::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 5px var(--terracotta-glow);
  flex: none;
}
.modelpick__opt .opt-id {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-3);
}

/* Etiqueta de tier gratuito: metadato quieto junto al nombre, mono pequeño */
.modelpick__opt .opt-free {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-3);
}

/* Reasoning picker — gemelo del model picker, misma mecánica de menú */
.reasoningpick { position: relative; }

.reasoningpick__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 6px 9px;
  color: var(--ink-2);
  cursor: pointer;
  font: inherit;
  transition: background 0.12s ease;
}
.reasoningpick__btn:hover { background: var(--panel-2); }
.reasoningpick__btn svg { width: 13px; height: 13px; }
.reasoningpick__name {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--ink);
  max-width: 130px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reasoningpick__menu {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  min-width: 200px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 11px;
  box-shadow: 0 14px 40px var(--shadow);
  z-index: 30;
}

.reasoningpick__title { display: block; padding: 6px 10px 5px; font-size: 9.5px; color: var(--ink-3); }

.reasoningpick__opt {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  background: none;
  border: none;
  border-radius: 7px;
  padding: 8px 10px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  cursor: pointer;
  text-align: left;
}
.reasoningpick__opt:hover, .reasoningpick__opt.hl { background: var(--panel-2); color: var(--ink); }
.reasoningpick__opt[aria-selected="true"] { color: var(--ink); }
.reasoningpick__opt[aria-selected="true"]::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--terracotta);
  box-shadow: 0 0 5px var(--terracotta-glow);
  flex: none;
}

/* Send orb */
.orb {
  width: 36px; height: 36px;
  flex: none;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: var(--terracotta);
  color: #121212;
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.15s ease, filter 0.15s ease;
}
.orb svg { width: 17px; height: 17px; }
.orb:hover { filter: brightness(1.12); }
.orb:active { transform: scale(0.96); }
.orb:disabled { opacity: 0.32; cursor: default; filter: none; transform: none; }
.orb__stop { display: none; }
.orb.streaming .orb__send { display: none; }
.orb.streaming .orb__stop { display: block; }
.orb.streaming:disabled { opacity: 1; cursor: pointer; }

/* Telemetry — etiquetas en sans, valores en mono: la línea donde el instrumento
   mide. Los valores son datos verdaderos y hablan JetBrains Mono tabular. */
.telemetry {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 4px 0;
  font-family: var(--sans);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tel__val {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
}

.tel__val { color: var(--ink-2); }
.tel__val.live { color: var(--terracotta-text); }
.tel__val.warn { color: var(--amber); }
.tel__sep { color: var(--ink-3); }

/* USO y TAVILY: contadores compactos que abren el panel de consumo */
.tel__btn {
  background: none;
  border: none;
  font: inherit;
  color: var(--ink-2);
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 6px;
  transition: background 0.12s ease, color 0.4s ease;
}
.tel__btn:hover { background: var(--panel); color: var(--ink); }
/* Gancho para la vía de cableado: cuando el total crece, marca la señal viva */
.tel__btn--live { color: var(--terracotta-text); }

/* Panel de uso: anclado sobre la barra de telemetría, misma capa que los menús */
.usage {
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  min-width: 310px;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 11px;
  box-shadow: 0 14px 40px var(--shadow);
  padding: 13px 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 30;
}

.usage__title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }

.usage__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 3px 0;
  font-size: 12.5px;
  color: var(--ink-3);
}

.usage__label {
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--ink-2);
  flex: none;
}

.usage__vals {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--ink-2);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Valor vivo de la señal en granate texto (p. ej. RESTANTES de Tavily) */
.usage__vals--live { color: var(--terracotta-text); }

.usage__section {
  margin-top: 6px;
  padding: 8px 0 2px;
  border-top: 1px solid var(--hairline-soft);
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
}

/* ---------- Toast ---------- */

.toast {
  position: fixed;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 12px 14px;
  max-width: min(92vw, 500px);
  box-shadow: 0 14px 40px var(--shadow);
  z-index: 60;
}

.toast__lamp {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 8px var(--amber-dim);
  flex: none;
}
.toast--info .toast__lamp {
  background: var(--terracotta);
  box-shadow: 0 0 8px var(--terracotta-glow);
}

.toast__title { font-size: 12px; font-weight: 600; letter-spacing: 0.1em; }
.toast__detail { font-size: 12.5px; color: var(--ink-2); margin-top: 1px; }

.toast__action {
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 7px;
  padding: 6px 10px;
  cursor: pointer;
  color: var(--ink);
  flex: none;
}
.toast__action:hover { border-color: var(--terracotta-dim); color: var(--terracotta-text); }

.toast__close { width: 26px; height: 26px; flex: none; }
.toast__close svg { width: 13px; height: 13px; }

/* ---------- Modal ---------- */

.modal {
  position: fixed;
  inset: 0;
  background: var(--backdrop);
  display: grid;
  place-items: center;
  padding: 20px;
  z-index: 50;
}

.modal__panel {
  width: min(560px, 100%);
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 22px;
  box-shadow: 0 24px 64px var(--shadow-strong);
}

.modal__title { margin: 0; font-size: 12px; font-weight: 600; letter-spacing: 0.16em; }
.modal__body { margin: 8px 0 0; font-size: 14px; color: var(--ink-2); }

.modal__field input,
.modal__textarea {
  width: 100%;
  margin-top: 14px;
  background: var(--ground);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  color: var(--ink);
  font: inherit;
  font-size: 14.5px;
  padding: 10px 12px;
}
.modal__textarea { min-height: 120px; resize: vertical; line-height: 1.55; }
.modal__field input:focus, .modal__textarea:focus { outline: none; border-color: var(--terracotta-dim); }
.modal__field input::placeholder, .modal__textarea::placeholder { color: var(--ink-3); }

.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
}

/* ---------- Panel de administración de usuarios ---------- */
/* Mismo vocabulario modal: panel radius 14px, sombra de modal, hairlines.
   Filas separadas por hairline, datos en mono tabular, acciones mínimas. */

.admin__panel { width: min(480px, 100%); }

.admin__title { margin: 0; font-size: 12px; font-weight: 600; letter-spacing: 0.16em; }

.admin__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

/* Capacidad: lectura de instrumento — "1/5 CUENTA" en mono tabular */
.admin__count {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.admin__count-label {
  font-family: var(--sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
}

/* Filas de usuario: separadas por hairline, como las filas del panel de uso */
.admin__list {
  display: flex;
  flex-direction: column;
}

.adminrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-top: 1px solid var(--hairline-soft);
}

.adminrow:first-child { border-top: none; }

.adminrow__name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-right: auto;
}

.adminrow__role {
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  flex: none;
}

.adminrow__reset {
  background: none;
  border: none;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--ink-2);
  cursor: pointer;
  padding: 3px 6px;
  border-radius: 5px;
  flex: none;
  transition: color 0.12s ease, background 0.12s ease;
}
.adminrow__reset:hover { color: var(--terracotta-text); background: var(--terracotta-faint); }

/* Baja de cuenta: el ámbar avisa que la acción es destructiva */
.adminrow__del {
  width: 24px; height: 24px;
  flex: none;
  color: var(--amber);
}
.adminrow__del svg { width: 12px; height: 12px; }
.adminrow__del:hover { color: var(--amber); background: rgba(232, 163, 61, 0.1); }

/* Alta de cuenta: entradas estilo puerta pero sobre panel */
.admin__add {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
}

.admin__field {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.admin__input {
  width: 100%;
  background: var(--ground);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
  padding: 9px 11px;
}
.admin__input:focus { outline: none; border-color: var(--terracotta-dim); }
.admin__input::placeholder { color: var(--ink-3); }

.admin__add .btn { align-self: flex-end; flex: none; }

.btn {
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-radius: 8px;
  padding: 9px 14px;
  cursor: pointer;
  transition: filter 0.12s ease, border-color 0.12s ease;
}

.btn--ghost { background: none; border: 1px solid var(--hairline); color: var(--ink-2); }
.btn--ghost:hover { color: var(--ink); border-color: var(--surface-elev-border); }

.btn--solid { background: var(--terracotta); border: 1px solid var(--terracotta); color: #F2F2F2; }
.btn--solid:hover { background: var(--terracotta-bright); border-color: var(--terracotta-bright); filter: none; }

.btn--danger { background: none; border: 1px solid var(--amber-dim); color: var(--amber); }
.btn--danger:hover { background: var(--terracotta-faint); }

/* Rename inline */
.rename-input {
  width: 100%;
  background: var(--ground);
  border: 1px solid var(--terracotta-dim);
  border-radius: 6px;
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
  padding: 4px 8px;
}
.rename-input:focus { outline: none; }

/* ---------- Puerta de acceso (login / primer encendido) ---------- */
/* Capa más alta del sistema: mientras está puesta, el banco no existe todavía.
   El suelo de la puerta es el mismo suelo del tema activo — la casa te recibe
   con su propia luz antes de pedirte la clave. */

.gate {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  padding: 20px;
  background: var(--ground);
  overflow: hidden;
}

.gate__inner {
  width: min(400px, 100%);
  display: flex;
  flex-direction: column;
  text-align: center;
  animation: gate-in 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes gate-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

.gate__brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.gate__brand .brand__name { font-size: 22px; }

.gate__sub {
  margin: 10px 0 0;
  font-size: 13.5px;
  color: var(--ink-2);
}

.gate__form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 30px;
  text-align: left;
}

.gate__label { margin-bottom: -2px; }

.gate__input {
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--hairline);
  border-radius: 9px;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  padding: 11px 13px;
}
.gate__input:focus { outline: none; border-color: var(--terracotta-dim); }
.gate__input::placeholder { color: var(--ink-3); }

.gate__error {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--amber);
}

.gate__submit { margin-top: 10px; padding: 11px 14px; }

.gate__setup-note {
  background: var(--panel);
  border: 1px solid var(--hairline-soft);
  border-radius: 9px;
  padding: 10px 12px;
  margin-bottom: 4px;
}
.gate__setup-note .micro { color: var(--terracotta-text); }
.gate__setup-text { margin: 4px 0 0; font-size: 12.5px; color: var(--ink-2); }

/* ---------- Responsive ---------- */

@media (max-width: 767px) {
  .topbar { display: flex; }

  .sidebar {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    z-index: 40;
    width: min(300px, 84vw);
    transform: translateX(-103%);
    transition: transform 0.24s ease;
  }
  .app.nav-open .sidebar { transform: none; }

  .chat__inner { padding: 24px 16px 20px; }
  .composer { padding: 4px 12px 10px; }
  .msg--user { padding-left: 0; }
  .msg--assistant { padding-left: 12px; }
  .empty { padding: 32px 12px; }
}

@media (max-width: 480px) {
  .modelpick__name { max-width: 96px; }
  .reasoningpick__name { max-width: 72px; }
  .telemetry { font-size: 9.5px; }
  .usage { min-width: 270px; right: -4px; }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  .stream-cursor { animation: none; opacity: 1; }
  .msg--locked::before { animation: none; opacity: 0; }
  .code__run--running { animation: none; }
  .thinking__lamp { animation: none; opacity: 1; }
  .sidebar { transition: none; }
  body { transition: none; }
}

/* ---------- Matemáticas (KaTeX) ---------- */

.katex-display {
  margin: 0.75em 0;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.15em 0;
}

.katex { font-size: 1.05em; }

/* El panel del usuario también puede contener fórmulas */
.msg--user .katex-display { margin: 0.5em 0; }

/* ---------- Búsqueda web ---------- */

/* Toggle del composer: estado activo con la señal viva del sistema */
.iconbtn.is-on {
  color: var(--terracotta-text);
  background: var(--terracotta-faint);
}
.iconbtn.is-on:hover { color: var(--terracotta-text); background: var(--terracotta-faint); }
.iconbtn:disabled { opacity: 0.35; cursor: default; }
.iconbtn:disabled:hover { background: none; color: var(--ink-2); }

/* Fuentes de la búsqueda: tira compacta al inicio del mensaje del asistente */
.msg-search {
  margin: 0 0 14px;
  padding: 10px 12px;
  background: var(--panel);
  border: 1px solid var(--hairline-soft);
  border-radius: 10px;
}

.msg-search__head {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 8px;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--ink-3);
}

.msg-search__label {
  font-weight: 600;
  text-transform: uppercase;
  color: var(--ink-2);
}

.msg-search__query {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.msg-search__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.msg-search__chip {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  max-width: 100%;
  padding: 4px 9px;
  background: var(--ground);
  border: 1px solid var(--hairline);
  border-radius: 7px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--ink-2);
  text-decoration: none;
  transition: border-color 0.12s ease, color 0.12s ease;
}
.msg-search__chip:hover { border-color: var(--terracotta-dim); color: var(--ink); }

.msg-search__n {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--terracotta-text);
  flex: none;
}

.msg-search__t {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Aviso cuando la búsqueda falla: la generación continúa sin contexto externo */
.msg-search-error {
  margin: 0 0 12px;
  font-size: 12.5px;
  font-style: italic;
  color: var(--ink-3);
}

/* ---------- Chat temporal ---------- */
/* Motivo propio: contorno DISCONTINUO — lo efímero se dibuja con trazo que
   no llega a cerrarse, a diferencia de los chats persistidos (borde sólido).
   El granate (variable --terracotta) solo aparece cuando el chat temporal
   está vivo y abierto.
   El toggle del composer no necesita CSS propio: hereda .iconbtn.is-on. */

/* Item de la sidebar: dashed 1px + reloj pequeño + texto atenuado.
   El hover lo despierta; activo, el granate marca que la señal vive. */
.chat-item--temporal { margin-bottom: 6px; }

.chat-item--temporal .chat-item__btn {
  border: 1px dashed var(--hairline);
  padding: 7px 30px 7px 11px;
  color: var(--ink-3);
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.chat-item--temporal .chat-item__btn:hover {
  background: var(--hover);
  color: var(--ink-2);
  border-color: var(--ink-3);
}

.chat-item--temporal.active .chat-item__btn {
  background: var(--active);
  color: var(--ink);
  border-color: var(--terracotta-dim);
}

/* El LED granate del item activo no encaja aquí: el chat no está persistido.
   En su lugar el reloj hereda la señal viva. */
.chat-item--temporal.active .chat-item__title::before { display: none; }

.chat-item--temporal .chat-item__title {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.chat-item--temporal .chat-item__clock {
  width: 12px; height: 12px;
  flex: none;
  color: var(--ink-3);
  transition: color 0.12s ease;
}

.chat-item--temporal:hover .chat-item__clock,
.chat-item--temporal.active .chat-item__clock { color: var(--terracotta-text); }

.chat-item--temporal .chat-item__meta { color: var(--ink-3); }

/* Sin acciones de renombrar: solo el descarte, siempre a la vista */
.chat-item--temporal .chat-item__actions { opacity: 1; }
.chat-item--temporal .chat-item__actions .iconbtn:hover {
  color: var(--amber);
  background: rgba(232, 163, 61, 0.1);
}

/* Insignia TEMPORAL del topbar: microetiqueta de instrumento con contorno
   discontinuo, junto al título y antes del LED */
.topbar__badge-temporal {
  flex: none;
  padding: 2px 7px;
  border: 1px dashed var(--terracotta-dim);
  border-radius: 5px;
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--terracotta-text);
  font-variant-numeric: tabular-nums;
}

/* Aviso bajo el saludo cuando el modo está armado y no hay chat abierto */
.empty__temporal-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 0;
  padding: 6px 14px;
  border: 1px dashed var(--hairline);
  border-radius: 8px;
  font-size: 12.5px;
  color: var(--ink-3);
}

.empty__temporal-hint svg { width: 14px; height: 14px; flex: none; color: var(--ink-3); }

@media (max-width: 480px) {
  .topbar__badge-temporal { display: none; }
}

/* ---------- Modo panel lateral (Firefox sidebar) ---------- */
/* La app clavada en la barra lateral del navegador (~320-450px): una sola
   columna de chat. El <html data-mode="sidebar"> lo activa el JS al cargar.
   Todo va bajo [data-mode="sidebar"] y por tanto ignora el viewport: el
   atributo es la fuente de verdad, no la anchura de la ventana. Las tres
   calibraciones ([data-theme]) siguen mandando — aquí solo se compacta. */

/* Shell: la nav se esconde (la columna es toda la ventana) y se abre como
   overlay con el menú — misma mecánica que el móvil, sin condición de ancho. */
[data-mode="sidebar"] .sidebar {
  position: fixed;
  top: 0; bottom: 0; left: 0;
  z-index: 40;
  width: min(300px, 88vw);
  transform: translateX(-103%);
  transition: transform 0.24s ease;
}
[data-mode="sidebar"] .app.nav-open .sidebar { transform: none; }

/* Sin botón de plegar a rail: dentro de un panel no hay sitio para dos columnas */
[data-mode="sidebar"] #collapseBtn { display: none; }

/* Topbar compacto: siempre visible (aquí es la única puerta a la nav), menos
   aire, título con elipsis e insignia TEMPORAL visible — la regla del
   @media 480px que la esconde no gobierna este contexto. */
[data-mode="sidebar"] .topbar { display: flex; gap: 8px; padding: 7px 10px; }
[data-mode="sidebar"] .topbar__badge-temporal { display: inline-block; }
[data-mode="sidebar"] .topbar__title {
  min-width: 0;
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
}

/* Columna de chat: paddings a la mitad, el suelo sigue plano */
[data-mode="sidebar"] .chat__inner { padding: 20px 12px 16px; }
[data-mode="sidebar"] .empty { padding: 28px 10px; }
[data-mode="sidebar"] .empty__title { font-size: clamp(22px, 6vw, 28px); }
[data-mode="sidebar"] .empty__temporal-hint { margin-top: 10px; padding: 5px 10px; font-size: 11.5px; gap: 6px; }
[data-mode="sidebar"] .empty__temporal-hint svg { width: 12px; height: 12px; }

/* Mensajes: medida de lectura menor y menos aire lateral */
[data-mode="sidebar"] .msg--user { padding-left: 14px; }
[data-mode="sidebar"] .msg--user .msg__body { padding: 9px 12px; }
[data-mode="sidebar"] .msg--assistant { padding-left: 10px; }
[data-mode="sidebar"] .msg__body { font-size: 14px; line-height: 1.55; }
[data-mode="sidebar"] .msg__body h1 { font-size: 17px; }
[data-mode="sidebar"] .msg__body h2 { font-size: 15.5px; }
[data-mode="sidebar"] .msg__body h3, [data-mode="sidebar"] .msg__body h4 { font-size: 14px; }
[data-mode="sidebar"] .msg__body ul, [data-mode="sidebar"] .msg__body ol { padding-left: 20px; }
[data-mode="sidebar"] .msg__body table { display: block; overflow-x: auto; }
[data-mode="sidebar"] .msg__actions { opacity: 1; }

/* Bloques que no caben: scroll interno, nunca desbordar la columna */
[data-mode="sidebar"] .code pre { padding: 10px 12px; }
[data-mode="sidebar"] .code pre code { font-size: 12px; }
[data-mode="sidebar"] .code__head { flex-wrap: wrap; gap: 4px; padding: 5px 8px 5px 10px; }
[data-mode="sidebar"] .code__stdout, [data-mode="sidebar"] .code__stderr { font-size: 11.5px; }
[data-mode="sidebar"] .reasoning__body { max-height: 240px; overflow-x: auto; }
[data-mode="sidebar"] .msg__imgs img { max-width: min(220px, 100%); max-height: 170px; }
[data-mode="sidebar"] .msg-search { padding: 8px 10px; }
[data-mode="sidebar"] .msg-search__head { flex-wrap: wrap; }

/* Composer: aire mínimo y controles en una línea — a 320px los iconbtn de
   28px + los pickers con nombre corto caben; la fila no se envuelve para no
   robar altura al input. */
[data-mode="sidebar"] .composer { padding: 4px 10px 8px; }
[data-mode="sidebar"] .composer__box textarea { padding: 10px 12px 4px; font-size: 14.5px; }
[data-mode="sidebar"] .composer__row { gap: 2px; padding: 3px 5px 6px; }
[data-mode="sidebar"] .composer__row .iconbtn { width: 28px; height: 28px; }
[data-mode="sidebar"] .composer__row .iconbtn svg { width: 15px; height: 15px; }

/* Pickers: sin microetiqueta (el icono del reasoning y la posición ya dicen
   qué son) y nombre con elipsis corto — el menú desplegable muestra el resto */
[data-mode="sidebar"] .modelpick__btn .micro,
[data-mode="sidebar"] .reasoningpick__btn .micro { display: none; }
[data-mode="sidebar"] .modelpick__name { max-width: 88px; font-size: 10.5px; }
[data-mode="sidebar"] .reasoningpick__name { max-width: 64px; font-size: 10.5px; }
[data-mode="sidebar"] .modelpick__btn, [data-mode="sidebar"] .reasoningpick__btn { padding: 5px 6px; gap: 5px; }
[data-mode="sidebar"] .orb { width: 32px; height: 32px; }

/* Menús anclados a la izquierda del picker: a 320px "left: 0" se sale por la
   derecha — se anclan a la derecha del botón y limitan su ancho a la ventana */
[data-mode="sidebar"] .modelpick__menu,
[data-mode="sidebar"] .reasoningpick__menu {
  left: auto;
  right: 0;
  max-width: calc(100vw - 16px);
}
[data-mode="sidebar"] .modelpick__opt .opt-id { display: none; }

/* Telemetría: solo la medición esencial (MODELO · T/S · CTX · TOK); TAVILY y
   OR viven en el panel de uso, que sigue accesible desde el contador TOK */
[data-mode="sidebar"] #telTavily, [data-mode="sidebar"] #telOR { display: none; }
[data-mode="sidebar"] .telemetry { gap: 7px; padding: 7px 2px 0; font-size: 9.5px; overflow: hidden; }
[data-mode="sidebar"] .tel__val { font-size: 9px; }
[data-mode="sidebar"] .tel__btn { padding: 2px 5px; }

/* Panel de uso: ancho de ventana menos el aire del composer */
[data-mode="sidebar"] .usage {
  min-width: 0;
  width: calc(100vw - 20px);
  max-width: 310px;
  right: 0;
}

/* Modal y toast: caben en el panel sin tocar los bordes */
[data-mode="sidebar"] .modal { padding: 10px; }
[data-mode="sidebar"] .modal__panel { padding: 16px; }
[data-mode="sidebar"] .modal__field input, [data-mode="sidebar"] .modal__textarea { font-size: 16px; }
[data-mode="sidebar"] .toast { bottom: 16px; padding: 10px 12px; gap: 8px; max-width: min(94vw, 500px); }
[data-mode="sidebar"] .toast__title { font-size: 11px; }

/* Panel de administración y puerta: ya limitan con min(…, 100%) — solo aire */
[data-mode="sidebar"] .admin__panel { padding: 16px; }
[data-mode="sidebar"] .adminrow__reset { padding: 5px 8px; font-size: 9px; }
[data-mode="sidebar"] .gate { padding: 14px; }
[data-mode="sidebar"] .gate__inner { width: min(340px, 100%); }

/* Item temporal de la sidebar (overlay): la fila dashed cabe sin recortes */
[data-mode="sidebar"] .chat-item--temporal .chat-item__btn { padding: 7px 26px 7px 9px; }
[data-mode="sidebar"] .chat-item--temporal .chat-item__title { max-width: 170px; }

/* Reduced motion: sin transición del overlay de nav tampoco aquí */
@media (prefers-reduced-motion: reduce) {
  [data-mode="sidebar"] .sidebar { transition: none; }
}