/* Orbot web UI
 *
 * Tokens first: every color, radius, shadow and duration below comes from a
 * custom property, so the light theme is a token swap. The theme is chosen
 * by theme-init.js before first paint ([data-theme] on <html>).
 *
 * CSP note: style-src is 'self' (+ Google Fonts), so no inline <style> or
 * style="" attributes. JS sets per-element values (avatar hue, menu
 * position) through CSSOM, which CSP allows.
 */

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: dark;

  --font-sans: 'Geist', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, 'SF Mono', 'Cascadia Code', Menlo, Consolas, monospace;
  /* legacy aliases */
  --sans: var(--font-sans);
  --mono: var(--font-mono);

  --bot-hue: 160;              /* set per bot by bots.js */
  --col: 768px;                /* reading column */
  --sidebar-width: 284px;
  --header-h: 56px;

  --bg: #0d0e12;
  --bg-sidebar: #111217;
  --surface: #17181e;
  --surface-2: #1e1f26;
  --surface-3: #272932;
  --surface-menu: #1a1b22;
  --bubble: #23252e;
  --code-bg: #13141a;
  --border: #25272f;
  --border-strong: #343743;
  --text: #ececf1;
  --text-2: #b3b6c1;
  --text-3: #868a97;
  --accent: #3fd99a;
  --accent-text: #5fe3ad;
  --on-accent: #03140c;
  --accent-soft: color-mix(in oklab, var(--accent) 14%, transparent);
  --ring: color-mix(in oklab, var(--accent) 60%, transparent);
  --danger: #f87171;
  --danger-soft: color-mix(in oklab, var(--danger) 12%, transparent);
  --warn: #f5b950;
  --warn-soft: color-mix(in oklab, var(--warn) 14%, transparent);
  --overlay: rgb(3 4 8 / 0.6);
  --scrollbar: #2e3039;

  --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3);
  --shadow-md: 0 8px 24px -8px rgb(0 0 0 / 0.55);
  --shadow-lg: 0 18px 50px -12px rgb(0 0 0 / 0.7), 0 0 0 1px rgb(255 255 255 / 0.03);

  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;

  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --dur: 160ms;
}

[data-theme="light"] {
  color-scheme: light;
  --bg: #fbfbfa;
  --bg-sidebar: #f4f4f2;
  --surface: #ffffff;
  --surface-2: #f0f0ee;
  --surface-3: #e7e7e4;
  --surface-menu: #ffffff;
  --bubble: #efefec;
  --code-bg: #f6f6f4;
  --border: #e3e3df;
  --border-strong: #d2d2cd;
  --text: #1b1c1f;
  --text-2: #4a4c54;
  --text-3: #6c6f79;
  --accent: #0f7a55;
  --accent-text: #0d7350;
  --on-accent: #ffffff;
  --danger: #c4321f;
  --warn: #9a6200;
  --overlay: rgb(20 20 24 / 0.32);
  --scrollbar: #d6d6d1;
  --shadow-sm: 0 1px 2px rgb(16 18 24 / 0.06);
  --shadow-md: 0 8px 24px -10px rgb(16 18 24 / 0.18);
  --shadow-lg: 0 18px 48px -14px rgb(16 18 24 / 0.25), 0 0 0 1px rgb(16 18 24 / 0.04);
}

/* ------------------------------------------------------------------ base */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.6;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent;
}

* { scrollbar-width: thin; scrollbar-color: var(--scrollbar) transparent; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
button:disabled { cursor: default; }

:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}
:focus:not(:focus-visible) { outline: none; }

.hidden { display: none !important; }

/* Shared icon button: quiet square, chrome on hover. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--r-sm);
  color: var(--text-2);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn svg { width: 18px; height: 18px; }

/* Bot avatar: a gradient orb in the bot's hue with its initial. */
.avatar {
  --hue: var(--bot-hue);
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.25);
  background:
    radial-gradient(circle at 30% 22%, oklch(0.86 0.11 var(--hue)) 0%, transparent 55%),
    linear-gradient(145deg, oklch(0.66 0.16 var(--hue)) 0%, oklch(0.5 0.15 calc(var(--hue) + 35)) 100%);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.14);
  user-select: none;
}
.avatar:empty { visibility: hidden; }
.avatar-xs { width: 20px; height: 20px; font-size: 10px; }
.avatar-sm { width: 30px; height: 30px; font-size: 13px; }
.avatar-xl {
  width: 64px;
  height: 64px;
  font-size: 26px;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16), 0 14px 40px -12px oklch(0.6 0.17 var(--hue) / 0.7);
}

.badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.5;
  white-space: nowrap;
  flex-shrink: 0;
}
.badge-warn { background: var(--warn-soft); color: var(--warn); }
.badge-muted { background: var(--surface-2); color: var(--text-3); }

/* ------------------------------------------------------------------ layout */

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

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  width: 100%;
  background: var(--bg);
}

/* ------------------------------------------------------------------ sidebar */

.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 10px 10px;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  overflow: hidden;
}

.sidebar-top {
  display: flex;
  align-items: center;
  gap: 4px;
}

.bot-switcher {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  text-align: left;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.bot-switcher:not(:disabled):hover,
.bot-switcher[aria-expanded="true"] {
  background: var(--surface-2);
  border-color: var(--border);
}
.bot-switcher .avatar { width: 36px; height: 36px; font-size: 15px; }
.bot-switcher-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.bot-switcher-name {
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bot-switcher-desc {
  font-size: 12.5px;
  color: var(--text-3);
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bot-switcher-desc:empty { display: none; }
.bot-switcher-chevron { color: var(--text-3); flex-shrink: 0; }
.bot-switcher.single .bot-switcher-chevron { display: none; }

.sidebar-close { display: none; }

.new-chat-sidebar-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  box-shadow: var(--shadow-sm);
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.new-chat-sidebar-btn:hover { background: var(--surface-2); border-color: var(--border-strong); }
.new-chat-sidebar-btn svg { color: var(--text-2); }

/* Chats | Scheduled segmented control */
.history-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  padding: 3px;
  background: var(--surface-2);
  border-radius: 10px;
}
.history-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 30px;
  background: none;
  border: none;
  border-radius: 7px;
  color: var(--text-3);
  font-size: 13px;
  font-weight: 500;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.history-tab:hover { color: var(--text); }
.history-tab[aria-selected="true"] {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm), 0 0 0 1px var(--border);
}
[data-theme="light"] .history-tab[aria-selected="true"] { box-shadow: var(--shadow-sm), 0 0 0 1px var(--border); }
.tab-count {
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: 11px;
  line-height: 18px;
  text-align: center;
}
.tab-count:empty { display: none; }

.sidebar-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  margin: 0 -10px;
  padding: 0 10px 12px;
}

.nav-section + .nav-section { margin-top: 10px; }

.nav-heading {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 8px 10px 4px;
  background: var(--bg-sidebar);
  color: var(--text-3);
  font-size: 12px;
  font-weight: 500;
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  padding: 0 10px;
  border-radius: var(--r-sm);
  color: var(--text-2);
  font-size: 13.5px;
  text-decoration: none;
  transition: background-color 120ms var(--ease), color 120ms var(--ease);
}
.nav-item:hover { background: var(--surface-2); color: var(--text); }
.nav-item.active {
  background: var(--surface-3);
  color: var(--text);
  font-weight: 500;
}
.nav-item-title {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Row action floats over the title's end (behind a fade) so titles keep
   their full width until hover. */
.nav-item-action {
  --fade: var(--surface-2);
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: inline-grid;
  place-items: center end;
  width: 52px;
  padding: 0 10px 0 0;
  background: linear-gradient(90deg, transparent, var(--fade) 45%);
  border: none;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--text-3);
  opacity: 0;
  transition: opacity 120ms var(--ease), color 120ms var(--ease);
}
.nav-item:hover .nav-item-action,
.nav-item-action:focus-visible { opacity: 1; }
.nav-item.active .nav-item-action { --fade: var(--surface-3); }
.nav-item-action:hover { color: var(--danger); }
@media (hover: none) {
  .nav-item.active .nav-item-action { opacity: 1; }
}

.sidebar-empty {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 12px 4px;
  padding: 18px 16px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  color: var(--text-3);
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
}
.sidebar-empty strong { color: var(--text-2); font-weight: 600; font-size: 13.5px; }

.nav-skeleton { display: flex; flex-direction: column; gap: 10px; padding: 12px 10px; }
.nav-skeleton span {
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-2), var(--surface-3), var(--surface-2));
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
}
.nav-skeleton span:nth-child(odd) { width: 78%; }
.nav-skeleton span:nth-child(3n) { width: 56%; }
@keyframes shimmer { to { background-position: -200% 0; } }

/* Scheduled: one collapsible group per cron job */
.job-group { margin-top: 4px; }
.job-group + .job-group { margin-top: 6px; }

.job-head {
  display: flex;
  align-items: flex-start;
  border-radius: var(--r-sm);
  transition: background-color 120ms var(--ease);
}
.job-head:hover { background: var(--surface-2); }

.job-toggle {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 8px 4px 8px 6px;
  background: none;
  border: none;
  border-radius: var(--r-sm);
  color: var(--text);
  text-align: left;
}
.job-chevron {
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 20px;
  flex-shrink: 0;
  color: var(--text-3);
  transition: transform var(--dur) var(--ease);
}
.job-toggle[aria-expanded="true"] .job-chevron { transform: rotate(90deg); }
.job-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.job-name-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.job-name {
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 20px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.job-schedule,
.job-status {
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.45;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.job-status { display: flex; gap: 6px; }
.job-status > * + *::before { content: '·'; margin-right: 6px; }
.job-next { color: var(--accent-text); font-weight: 500; }
.job-warn { color: var(--warn); overflow: hidden; text-overflow: ellipsis; }
.job-alert {
  font-size: 12px;
  line-height: 1.45;
  color: var(--danger);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.job-more {
  width: 30px;
  height: 30px;
  margin: 5px 4px 0 0;
  color: var(--text-3);
}
.job-more[aria-expanded="true"] { background: var(--surface-3); color: var(--text); }

.job-runs {
  margin: 0 0 4px 14px;
  padding-left: 8px;
  border-left: 1px solid var(--border);
}
.job-group.collapsed .job-runs { display: none; }

.run-item { min-height: 32px; font-size: 13px; padding-left: 8px; }
.run-dot {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--border-strong);
}
.run-dot.run-completed { background: var(--accent); }
.run-dot.run-failed,
.run-dot.run-dispatch_failed { background: var(--danger); }
.run-dot.run-fired,
.run-dot.run-pending { background: var(--warn); animation: pulse 1.6s ease-in-out infinite; }
.run-dot.run-cancelled,
.run-dot.run-skipped { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-3); }
.run-tag {
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: 10.5px;
  line-height: 17px;
  flex-shrink: 0;
}
.run-num {
  margin-left: auto;
  padding-right: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-3);
  flex-shrink: 0;
}
.job-empty { padding: 4px 10px 8px; font-size: 12.5px; color: var(--text-3); }
.show-more {
  margin: 2px 0 4px;
  padding: 5px 8px;
  background: none;
  border: none;
  border-radius: var(--r-xs);
  color: var(--accent-text);
  font-size: 12.5px;
  font-weight: 500;
}
.show-more:hover { background: var(--accent-soft); }

/* Sidebar footer: signed-in identity */
.sidebar-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 4px 0;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.user-chip {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: 12px;
  font-weight: 600;
}
.sidebar-user {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.signout-btn {
  padding: 4px 10px;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--r-xs);
  color: var(--text-2);
  font-size: 12px;
  flex-shrink: 0;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.signout-btn:hover { border-color: var(--border-strong); color: var(--text); }

/* ------------------------------------------------------------------ header */

.header {
  display: flex;
  align-items: center;
  gap: 6px;
  height: var(--header-h);
  padding: 0 12px 0 20px;
  flex-shrink: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
}

.hamburger { display: none; }

.header-title {
  min-width: 0;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.header-title:empty { display: none; }
.header-spacer { flex: 1; }

/* Bot chip in the header: phones (no sidebar) and shared views. */
.header-bot {
  display: none;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 4px 8px 4px 4px;
  background: none;
  border: none;
  border-radius: var(--r-md);
  text-align: left;
  transition: background-color var(--dur) var(--ease);
}
.header-bot:hover { background: var(--surface-2); }
.header-bot .avatar { width: 30px; height: 30px; font-size: 13px; }
.header-bot-text { display: flex; flex-direction: column; min-width: 0; }
.header-bot-name {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
}
.header-bot-sub {
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.header-bot-sub:empty { display: none; }
.header-bot-name-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
.header-bot-chevron { color: var(--text-3); flex-shrink: 0; }
.header-bot.single .header-bot-chevron { display: none; }

/* Share button (created by chat.js with an emoji label): render an icon
   instead; the label stays as the accessible name. */
.share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--r-sm);
  color: var(--text-2);
  font-size: 0;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.share-btn::before {
  content: '';
  width: 18px;
  height: 18px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12v7a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='m16 6-4-4-4 4'/%3E%3Cpath d='M12 2v13'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12v7a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='m16 6-4-4-4 4'/%3E%3Cpath d='M12 2v13'/%3E%3C/svg%3E") center / contain no-repeat;
}
.share-btn:hover { background: var(--surface-2); color: var(--text); }
/* After a click chat.js swaps the title ("Link copied!" or the URL). */
.share-btn:not([title="Share conversation"]) { color: var(--accent-text); }
.share-btn:not([title="Share conversation"])::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}

.theme-toggle svg { width: 18px; height: 18px; }

/* Context bar for a scheduled-run conversation */
.run-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(var(--col), calc(100% - 32px));
  margin: 12px auto 0;
  padding: 9px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: 13px;
  flex-shrink: 0;
}
.run-banner-icon {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-text);
}
.run-banner-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.35; }
.run-banner-text strong { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.run-banner-meta { color: var(--text-3); font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.run-banner-link {
  flex-shrink: 0;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-2);
  font-size: 12.5px;
  text-decoration: none;
}
.run-banner-link:hover { color: var(--text); border-color: var(--border-strong); }

/* ------------------------------------------------------------------ chat */

.chat {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 28px max(20px, calc((100% - var(--col)) / 2)) 24px;
}

/* Welcome / empty state */
.welcome {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 100%;
  padding: 24px 0 40px;
  text-align: center;
  animation: rise 0.35s var(--ease);
}
.welcome .avatar-xl { margin-bottom: 8px; }
.welcome h2 {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.2;
}
.welcome-desc {
  max-width: 46ch;
  color: var(--text-2);
  font-size: 15px;
  line-height: 1.55;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.welcome-tip {
  max-width: 46ch;
  color: var(--text-3);
  font-size: 13px;
}
.bot-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  max-width: 560px;
  margin-top: 18px;
}
.bot-chips-label { width: 100%; color: var(--text-3); font-size: 12.5px; }
.bot-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 100%;
  padding: 4px 12px 4px 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.bot-chip:hover { border-color: var(--border-strong); background: var(--surface-2); transform: translateY(-1px); }
.bot-chip .badge { margin-left: 2px; }

/* Turns */
.turn {
  margin-bottom: 28px;
  animation: rise 0.22s var(--ease);
}
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.turn-label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 24px;
  margin-bottom: 8px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
}
.turn-label.assistant { color: var(--text); }
.turn-label.assistant::before {
  content: '';
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 30% 22%, oklch(0.86 0.11 var(--bot-hue)) 0%, transparent 55%),
    linear-gradient(145deg, oklch(0.66 0.16 var(--bot-hue)) 0%, oklch(0.5 0.15 calc(var(--bot-hue) + 35)) 100%);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.14);
}
.turn-label.error { color: var(--danger); }

.turn-content {
  min-width: 0;
  word-break: break-word;
  overflow-wrap: anywhere;
}

/* User turn: a right-aligned bubble; the "You" label is implicit. */
.turn:has(> .turn-content.user) {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.turn-label.user { display: none; }
.turn-content.user {
  max-width: min(85%, 620px);
  padding: 10px 16px;
  background: var(--bubble);
  border-radius: 20px 20px 6px 20px;
  font-size: 15.5px;
  line-height: 1.55;
  white-space: pre-wrap;
}
.turn-content.user .turn-images:first-child { margin-top: 2px; }

/* Queued message (sent mid-turn): dashed bubble with a cancel control. */
.turn-label.user:has(.queued-cancel) {
  display: flex;
  margin-bottom: 4px;
  font-size: 0;
}
.turn-label.user:has(.queued-cancel)::before {
  content: 'Queued — sends when the current step finishes';
  font-size: 12px;
  font-weight: 500;
  color: var(--text-3);
}
.queued-cancel {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-left: 4px;
  background: var(--surface-2);
  border: none;
  border-radius: 50%;
  color: var(--text-2);
  font-size: 11px;
}
.queued-cancel:hover { color: var(--danger); background: var(--danger-soft); }
.turn-content.queued {
  opacity: 0.65;
  background: transparent;
  outline: 1.5px dashed var(--border-strong);
  outline-offset: -1.5px;
}

/* Assistant prose */
.turn-content.assistant {
  font-size: 15.5px;
  line-height: 1.7;
  color: var(--text);
}

.turn-content.error {
  padding: 10px 14px;
  background: var(--danger-soft);
  border: 1px solid color-mix(in oklab, var(--danger) 30%, transparent);
  border-radius: var(--r-md);
  color: var(--danger);
  font-size: 14px;
  white-space: pre-wrap;
}

/* Copy button — revealed on turn hover. It always occupies its slot
   (visibility, not display) so revealing it never reflows the label.
   Slot order is fixed in CSS because the streaming and reload paths append
   the two controls in different DOM orders. */
/* chat.js labels it "copy"/"copied!"; draw an icon, keep the text as the
   accessible name. */
.copy-btn {
  order: 1;
  visibility: hidden;
  opacity: 0;
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--r-xs);
  color: var(--text-3);
  font-size: 0;
  transition: opacity 120ms var(--ease), background-color 120ms var(--ease);
}
.copy-btn::before {
  content: '';
  width: 15px;
  height: 15px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='12' height='12' rx='2'/%3E%3Cpath d='M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='12' height='12' rx='2'/%3E%3Cpath d='M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1'/%3E%3C/svg%3E") center / contain no-repeat;
}
.copy-btn.copied::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}
.turn:hover .copy-btn,
.step-turn:hover .copy-btn,
.copy-btn:focus-visible,
.copy-btn.copied { visibility: visible; opacity: 1; }
@media (hover: none) {
  .copy-btn { visibility: visible; opacity: 0.7; }
}
.copy-btn:hover { color: var(--text); background: var(--surface-2); }
.copy-btn.copied { color: var(--accent-text); }

/* "N steps" disclosure — a quiet pill at the right of the label. */
.step-toggle {
  order: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 2px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: none;
  color: var(--text-3);
  font-size: 12px;
  font-weight: 500;
  line-height: inherit;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.step-toggle::after {
  content: '';
  width: 5px;
  height: 5px;
  margin-top: -3px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--dur) var(--ease);
}
.step-toggle:hover { color: var(--text); border-color: var(--border-strong); }
.step-toggle.active { color: var(--text-2); background: var(--surface-2); }
.step-toggle.active::after { transform: rotate(-135deg); margin-top: 3px; }

/* Step groups (reasoning + tool calls): collapsed by default, visible while
   streaming or when expanded — drawn as a quiet timeline. */
.step-group { display: none; }
.step-group.step-streaming,
.step-group.step-expanded {
  display: block;
  margin: 0 0 22px 10px;
  padding-left: 18px;
  border-left: 1.5px solid var(--border);
}
.step-group.step-expanded { animation: rise 0.2s var(--ease); }
/* Once a reply exists its steps live inside the turn, under the label that
   holds the toggle. While they're open the label sticks to the top of the
   chat, so the toggle stays reachable however far down the steps you read. */
.turn > .step-group.step-expanded { margin: 2px 0 18px 10px; }
.turn:has(> .step-group.step-expanded) > .turn-label {
  position: sticky;
  /* Sticky offsets count from inside .chat's padding (28px, 20px on
     mobile); pin to its visible top edge so nothing shows above the band. */
  top: -28px;
  z-index: 2;
  /* Same footprint as the plain label (margin-bottom 8px), plus an opaque
     band so steps scrolling underneath don't show through. */
  margin: -8px -8px 0;
  padding: 8px;
  background: var(--bg);
}
@media (max-width: 768px) {
  .turn:has(> .step-group.step-expanded) > .turn-label { top: -20px; }
}
/* Collapsing from deep scrolls the label back into view; land it where the
   stuck band held it, so the toggle stays under the pointer. */
.turn > .turn-label:has(> .step-toggle) { scroll-margin-top: 8px; }
.step-turn.step-hidden { display: none; }
.step-turn { position: relative; margin-bottom: 14px; animation: none; }
.step-turn:last-child { margin-bottom: 4px; }

.step-turn > .turn-label {
  gap: 6px;
  min-height: 20px;
  margin-bottom: 4px;
  color: var(--text-3);
  font-size: 12.5px;
  font-weight: 500;
}
/* Timeline node */
.step-turn > .turn-label::before {
  content: '';
  position: absolute;
  left: -23.5px;
  top: 6px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bg);
  box-shadow: inset 0 0 0 1.5px var(--border-strong);
}
.step-turn > .turn-label.tool::before { box-shadow: inset 0 0 0 1.5px var(--text-3); }
.step-streaming > .step-turn:last-child > .turn-label::before {
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.turn-content.reasoning,
.turn-content.tool {
  position: relative;
  max-height: 180px;
  overflow: hidden;
}
.turn-content.reasoning {
  color: var(--text-3);
  font-size: 13.5px;
  line-height: 1.6;
  white-space: pre-wrap;
}
.turn-content.tool {
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.6;
  white-space: pre-wrap;
}
.turn-content.tool .tool-name { color: var(--text); font-weight: 500; }
.turn-content.tool .tool-output {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  color: var(--text-3);
}
.turn-content.subagent {
  color: var(--text-3);
  font-size: 13px;
  font-style: italic;
}
.turn-content.subagent.subagent-running { animation: pulse 1.6s ease-in-out infinite; }

/* During streaming, allow more room but still constrain height */
.step-streaming > .step-turn:not(.step-hidden) > .turn-content.reasoning,
.step-streaming > .step-turn:not(.step-hidden) > .turn-content.tool {
  max-height: 40vh;
  overflow-y: auto;
}

/* Expanded individual content box */
.turn-content.content-expanded { max-height: none !important; }
.turn-content.content-truncated { cursor: pointer; }
.turn-content.content-truncated::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 44px;
  pointer-events: none;
}
.turn-content.reasoning.content-truncated::after { background: linear-gradient(transparent, var(--bg)); }
.turn-content.tool.content-truncated::after { background: linear-gradient(transparent, var(--surface)); }

.content-toggle {
  display: inline-block;
  margin-top: 4px;
  padding: 2px 6px;
  background: none;
  border: none;
  border-radius: var(--r-xs);
  color: var(--text-3);
  font-size: 12px;
}
.content-toggle:hover { color: var(--text); background: var(--surface-2); }

/* Thinking indicator: a breathing orb in the bot's hue + dots */
.thinking-indicator {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0 20px;
  animation: rise 0.2s var(--ease);
}
.thinking-indicator::before {
  content: '';
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 30% 22%, oklch(0.86 0.11 var(--bot-hue)) 0%, transparent 55%),
    linear-gradient(145deg, oklch(0.66 0.16 var(--bot-hue)) 0%, oklch(0.5 0.15 calc(var(--bot-hue) + 35)) 100%);
  animation: breathe 1.8s ease-in-out infinite;
}
.step-group .thinking-indicator { padding: 0 0 4px; }
.step-group .thinking-indicator::before { display: none; }
.thinking-dots { display: flex; gap: 5px; }
.thinking-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-3);
  animation: thinkPulse 1.4s ease-in-out infinite;
}
.thinking-dots span:nth-child(2) { animation-delay: 0.2s; }
.thinking-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes thinkPulse {
  0%, 80%, 100% { opacity: 0.25; transform: scale(0.8); }
  40% { opacity: 1; transform: scale(1); }
}
@keyframes breathe {
  0%, 100% { transform: scale(0.9); opacity: 0.75; }
  50% { transform: scale(1); opacity: 1; }
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

.chat-notice {
  width: fit-content;
  max-width: 100%;
  margin: 4px auto 24px;
  padding: 7px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-2);
  font-size: 13px;
  text-align: center;
}

/* First message of a scheduled run: preamble folded away */
.run-preamble {
  margin-bottom: 8px;
  font-size: 12.5px;
  color: var(--text-3);
}
.run-preamble summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  user-select: none;
}
.run-preamble summary::-webkit-details-marker { display: none; }
.run-preamble summary::before {
  content: '';
  width: 5px;
  height: 5px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--dur) var(--ease);
}
.run-preamble[open] summary::before { transform: rotate(45deg); }
.run-preamble summary:hover { color: var(--text-2); }
.run-preamble-body {
  margin-top: 6px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background: color-mix(in oklab, var(--bg) 40%, transparent);
  white-space: pre-wrap;
  line-height: 1.5;
}

/* Images attached to a user message or returned by a tool. */
.turn-images {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.turn-images img.chat-image { margin: 0; max-height: 240px; }
.tool-output + .turn-images { margin-top: 8px; }

img.chat-image {
  display: block;
  max-width: min(100%, 420px);
  max-height: 320px;
  margin: 8px 0;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  cursor: zoom-in;
}

/* ------------------------------------------------------------------ markdown */

.turn-content.assistant > :first-child { margin-top: 0; }
.turn-content.assistant > :last-child { margin-bottom: 0; }
.turn-content.assistant p { margin: 0 0 14px; }
.turn-content.assistant p:last-child { margin-bottom: 0; }

.turn-content.assistant h1,
.turn-content.assistant h2,
.turn-content.assistant h3,
.turn-content.assistant h4,
.turn-content.assistant h5,
.turn-content.assistant h6 {
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.015em;
  margin: 26px 0 10px;
}
.turn-content.assistant h1 { font-size: 1.45em; }
.turn-content.assistant h2 { font-size: 1.25em; }
.turn-content.assistant h3 { font-size: 1.1em; }
.turn-content.assistant h4 { font-size: 1em; }

.turn-content.assistant ul,
.turn-content.assistant ol {
  margin: 0 0 14px;
  padding-left: 24px;
}
.turn-content.assistant li { margin-bottom: 4px; }
.turn-content.assistant li::marker { color: var(--text-3); }
.turn-content.assistant li:last-child { margin-bottom: 0; }

.turn-content.assistant blockquote {
  margin: 14px 0;
  padding: 2px 0 2px 16px;
  border-left: 3px solid var(--border-strong);
  color: var(--text-2);
}

.turn-content.assistant code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  background: var(--surface-2);
  padding: 2px 6px;
  border-radius: var(--r-xs);
}

.turn-content.assistant pre {
  margin: 14px 0;
  padding: 14px 16px;
  background: var(--code-bg);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow-x: auto;
}
/* Code block with a header bar (markdown.js wraps each <pre>) */
.turn-content.assistant .code-block {
  margin: 14px 0;
  background: var(--code-bg);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.turn-content.assistant .code-block pre {
  margin: 0;
  padding: 12px 16px 14px;
  border: none;
  border-radius: 0;
  background: none;
}
.code-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 6px 4px 14px;
  border-bottom: 1px solid var(--border);
  background: color-mix(in oklab, var(--surface-2) 60%, transparent);
}
.code-lang {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-3);
  text-transform: lowercase;
}
.code-copy {
  padding: 3px 8px;
  background: none;
  border: none;
  border-radius: var(--r-xs);
  color: var(--text-3);
  font-size: 12px;
}
.code-copy:hover { color: var(--text); background: var(--surface-3); }
.code-copy.copied { color: var(--accent-text); }
.turn-content.assistant pre code {
  background: none;
  padding: 0;
  border-radius: 0;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre;
  tab-size: 4;
}

/* Tables scroll inside their wrapper rather than widening the page. */
.turn-content.assistant .table-wrap {
  max-width: 100%;
  overflow-x: auto;
  margin: 14px 0;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.turn-content.assistant table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}
.turn-content.assistant th,
.turn-content.assistant td {
  padding: 8px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
.turn-content.assistant th + th,
.turn-content.assistant td + td { border-left: 1px solid var(--border); }
.turn-content.assistant tr:last-child td { border-bottom: none; }
.turn-content.assistant th {
  background: var(--surface-2);
  font-weight: 600;
  font-size: 13px;
}

.turn-content.assistant hr {
  margin: 20px 0;
  border: none;
  border-top: 1px solid var(--border);
}
.turn-content.assistant a {
  color: var(--accent-text);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--accent-text) 35%, transparent);
  text-underline-offset: 3px;
}
.turn-content.assistant a:hover { text-decoration-color: currentColor; }
.turn-content.assistant strong { font-weight: 600; }
.turn-content.assistant img { max-width: 100%; border-radius: var(--r-sm); }

/* ------------------------------------------------------------------ composer */

.input-area {
  position: relative; /* anchors .jump-latest */
  flex-shrink: 0;
  padding: 8px max(16px, calc((100% - var(--col)) / 2)) calc(16px + env(safe-area-inset-bottom, 0px));
}

/* One rounded box: pending files, the textarea, and a toolbar of icon
   affordances (attach, reasoning effort) plus send/stop. */
.composer {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-md);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.composer:focus-within {
  border-color: color-mix(in oklab, var(--accent) 28%, var(--border-strong));
  box-shadow: var(--shadow-md), 0 0 0 3px color-mix(in oklab, var(--accent) 8%, transparent);
}

.composer textarea {
  width: 100%;
  min-height: 48px;
  max-height: 200px;
  padding: 13px 16px 4px;
  background: transparent;
  border: none;
  outline: none;
  resize: none;
  color: var(--text);
  font-size: 16px; /* >=16px keeps iOS from zooming on focus */
  line-height: 1.5;
}
.composer textarea::placeholder { color: var(--text-3); }

.composer-bar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px 8px 8px;
}
.composer-spacer { flex: 1; }

.composer-bar button.attach-btn,
.composer-bar .thinking-tool {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  flex-shrink: 0;
  background: none;
  border: none;
  border-radius: 50%;
  color: var(--text-3);
  cursor: pointer;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.composer-bar button.attach-btn:hover,
.composer-bar .thinking-tool:hover { color: var(--text); background: var(--surface-2); }
.composer-bar button.attach-btn.hidden { display: none; }

/* The reasoning selector stays a native <select> — phones get their own
   picker — but it sits invisibly over the icon. A set override tints it. */
.thinking-tool { position: relative; }
.thinking-tool .thinking-select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  font-size: 16px;
}
.thinking-tool:has(.thinking-select.hidden) { display: none !important; }
.thinking-tool:has(.thinking-select.overridden) { color: var(--accent-text); background: var(--accent-soft); }
.thinking-tool:has(.thinking-select:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }

/* Send / Stop: chat.js sets the label text ("Send"/"Stop") and the .cancel
   class; we draw an icon and keep the text as the accessible name. */
.composer-bar button#sendBtn {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  flex-shrink: 0;
  background: var(--accent);
  border: none;
  border-radius: 50%;
  color: var(--on-accent);
  font-size: 0;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), transform 120ms var(--ease);
}
.composer-bar button#sendBtn::before {
  content: '';
  width: 18px;
  height: 18px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 19V5'/%3E%3Cpath d='m5 12 7-7 7 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 19V5'/%3E%3Cpath d='m5 12 7-7 7 7'/%3E%3C/svg%3E") center / contain no-repeat;
}
.composer-bar button#sendBtn:hover { filter: brightness(1.08); }
.composer-bar button#sendBtn:active { transform: scale(0.94); }
.composer-bar button#sendBtn:disabled { opacity: 0.4; }
/* Nothing to send yet: a muted button. */
.composer:has(textarea:placeholder-shown):not(:has(.file-chip)) button#sendBtn:not(.cancel) {
  background: var(--surface-3);
  color: var(--text-3);
}
.composer-bar button#sendBtn.cancel { background: var(--text); color: var(--bg); }
.composer-bar button#sendBtn.cancel::before {
  width: 12px;
  height: 12px;
  -webkit-mask: none;
  mask: none;
  border-radius: 2.5px;
}

#fileInput { display: none; }

/* Pending files, inside the composer above the textarea */
.file-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 10px 0;
}
.file-chips:empty { display: none; }
.file-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 240px;
  padding: 4px 6px 4px 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 13px;
  animation: rise 0.18s var(--ease);
}
.file-chip:not(:has(.file-chip-thumb))::before {
  content: '';
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  background: var(--text-3);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/%3E%3Cpath d='M14 3v5h5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/%3E%3Cpath d='M14 3v5h5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.file-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-chip-remove {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  padding: 0;
  background: none;
  border: none;
  border-radius: 50%;
  color: var(--text-3);
  font-size: 11px;
  line-height: 1;
}
.file-chip-remove:hover { color: var(--danger); background: var(--danger-soft); }
.file-chip-thumb {
  width: 24px;
  height: 24px;
  object-fit: cover;
  border-radius: var(--r-xs);
  flex-shrink: 0;
}

/* ------------------------------------------------------------------ menus */

.menu {
  position: fixed;
  z-index: 200;
  min-width: 200px;
  max-width: min(380px, calc(100vw - 16px));
  max-height: min(70vh, 520px);
  overflow-y: auto;
  padding: 6px;
  background: var(--surface-menu);
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(-4px) scale(0.98);
  transform-origin: top left;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.menu.open { opacity: 1; transform: none; }

.menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 9px;
  color: var(--text);
  font-size: 14px;
  text-align: left;
}
.menu-item:hover,
.menu-item:focus-visible { background: var(--surface-2); outline: none; }
.menu-item.danger { color: var(--danger); }
.menu-item.danger:hover,
.menu-item.danger:focus-visible { background: var(--danger-soft); }
.menu-icon { display: inline-grid; place-items: center; width: 18px; color: var(--text-3); }
.menu-item.danger .menu-icon { color: inherit; }
.menu-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.menu-label { display: flex; align-items: center; gap: 6px; font-weight: 500; line-height: 1.35; }
.menu-sub {
  color: var(--text-3);
  font-size: 12.5px;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.menu-check { color: var(--accent-text); display: inline-grid; flex-shrink: 0; }
.menu-sep { height: 1px; margin: 5px 6px; background: var(--border); }
.menu-heading { padding: 6px 10px 4px; font-size: 12px; color: var(--text-3); }
.bot-menu .menu-item { padding: 8px; }

/* Bottom sheet variant (phones) */
.menu-backdrop {
  position: fixed;
  inset: 0;
  z-index: 199;
  background: var(--overlay);
  opacity: 0;
  transition: opacity 200ms var(--ease);
}
.menu-backdrop.open { opacity: 1; }
.menu.menu-sheet {
  left: 0 !important;
  right: 0;
  top: auto !important;
  bottom: 0;
  width: auto !important;
  max-width: none;
  max-height: 80dvh;
  padding: 6px 8px calc(12px + env(safe-area-inset-bottom, 0px));
  border-width: 1px 0 0;
  border-radius: 22px 22px 0 0;
  transform: translateY(100%);
  transition: transform 260ms var(--ease);
}
.menu.menu-sheet.open { transform: none; }
.menu-grabber {
  width: 36px;
  height: 4px;
  margin: 4px auto 10px;
  border-radius: 2px;
  background: var(--border-strong);
}
.menu-title {
  padding: 0 10px 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.menu-sheet .menu-item { min-height: 48px; padding: 10px 12px; font-size: 15px; }

/* Toast */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(124px + env(safe-area-inset-bottom, 0px));
  z-index: 300;
  max-width: min(440px, calc(100vw - 32px));
  padding: 10px 16px;
  background: var(--text);
  color: var(--bg);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  font-size: 13.5px;
  font-weight: 500;
  opacity: 0;
  transform: translate(-50%, 8px);
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
  pointer-events: none;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
@media (min-width: 769px) {
  /* Center over the conversation, not the whole window. */
  .toast { left: calc(50% + var(--sidebar-width) / 2); }
}
.toast.error { background: var(--danger); color: #fff; }

/* ------------------------------------------------------------------ auth */

.auth-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background:
    radial-gradient(60% 50% at 50% 35%, color-mix(in oklab, var(--accent) 12%, transparent), transparent 70%),
    var(--bg);
}
.auth-overlay.hidden { display: none; }
.auth-box {
  width: min(380px, 100%);
  padding: 36px 28px 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 22px;
  box-shadow: var(--shadow-lg);
  text-align: center;
  animation: rise 0.35s var(--ease);
}
.auth-orb {
  width: 56px;
  height: 56px;
  margin: 0 auto 18px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 30% 22%, oklch(0.88 0.1 160) 0%, transparent 55%),
    linear-gradient(145deg, oklch(0.7 0.15 160) 0%, oklch(0.5 0.15 230) 100%);
  box-shadow: 0 14px 40px -12px oklch(0.6 0.15 180 / 0.7), inset 0 0 0 1px rgb(255 255 255 / 0.16);
}
.auth-box h2 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}
.auth-box p {
  font-size: 14px;
  color: var(--text-2);
  margin-bottom: 24px;
}
.google-signin-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: 46px;
  padding: 0 24px;
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  color: var(--text);
  font-size: 14.5px;
  font-weight: 500;
  text-decoration: none;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.google-signin-btn:hover { background: var(--surface-3); }
.auth-box .token-toggle {
  margin-top: 16px;
  padding: 4px 8px;
  background: none;
  border: none;
  color: var(--text-3);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.auth-box .token-toggle:hover { color: var(--text); }
.auth-box .token-auth { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.auth-box .token-auth.hidden { display: none; }
.auth-box input {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 16px;
  outline: none;
}
.auth-box input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.auth-box #authSubmitBtn {
  height: 44px;
  background: var(--accent);
  border: none;
  border-radius: var(--r-md);
  color: var(--on-accent);
  font-size: 14.5px;
  font-weight: 600;
}
.auth-box #authSubmitBtn:hover { filter: brightness(1.08); }
.auth-box .auth-error {
  display: none;
  margin-top: 12px;
  color: var(--danger);
  font-size: 13px;
}

/* ------------------------------------------------------------------ shared view */

/* Hide chrome instantly (theme-init.js tags <html> before paint) */
.shared-view .sidebar,
.shared-view .input-area,
.shared-view .hamburger { display: none !important; }
.shared-view .header-bot { display: flex; pointer-events: none; }
.shared-view .header-bot-chevron,
.shared-view .header-bot-sub { display: none; }
.shared-view .header-title { display: none; }

.shared-banner {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 0 28px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  text-align: center;
}
.shared-banner strong { font-size: 18px; font-weight: 600; letter-spacing: -0.015em; }
.shared-banner span { color: var(--text-3); font-size: 13px; }

/* ------------------------------------------------------------------ code */

pre code.hljs { background: transparent; padding: 0; }
.hljs-keyword, .hljs-selector-tag, .hljs-type { color: #c792ea; }
.hljs-string, .hljs-addition { color: #a5d6a7; }
.hljs-comment, .hljs-quote { color: #6b7080; font-style: italic; }
.hljs-number, .hljs-literal { color: #f4b07b; }
.hljs-title, .hljs-section { color: #82aaff; }
.hljs-built_in { color: #ffcb6b; }
.hljs-attr, .hljs-attribute { color: #f4b07b; }
.hljs-variable, .hljs-template-variable { color: #f07178; }
.hljs-deletion { color: #f07178; }
.hljs-meta { color: #82aaff; }
.hljs-name, .hljs-tag { color: #f07178; }
.hljs-regexp, .hljs-link { color: #89ddff; }
.hljs-symbol, .hljs-bullet { color: #c792ea; }

[data-theme="light"] .hljs-keyword,
[data-theme="light"] .hljs-selector-tag,
[data-theme="light"] .hljs-type { color: #a626a4; }
[data-theme="light"] .hljs-string,
[data-theme="light"] .hljs-addition { color: #3f8a3e; }
[data-theme="light"] .hljs-comment,
[data-theme="light"] .hljs-quote { color: #8a8c93; font-style: italic; }
[data-theme="light"] .hljs-number,
[data-theme="light"] .hljs-literal { color: #986801; }
[data-theme="light"] .hljs-title,
[data-theme="light"] .hljs-section { color: #3266d6; }
[data-theme="light"] .hljs-built_in { color: #a86e00; }
[data-theme="light"] .hljs-attr,
[data-theme="light"] .hljs-attribute { color: #986801; }
[data-theme="light"] .hljs-variable,
[data-theme="light"] .hljs-template-variable { color: #d2483c; }
[data-theme="light"] .hljs-deletion { color: #d2483c; }
[data-theme="light"] .hljs-meta { color: #3266d6; }
[data-theme="light"] .hljs-name,
[data-theme="light"] .hljs-tag { color: #d2483c; }
[data-theme="light"] .hljs-regexp,
[data-theme="light"] .hljs-link { color: #0b7aa8; }
[data-theme="light"] .hljs-symbol,
[data-theme="light"] .hljs-bullet { color: #a626a4; }

/* ------------------------------------------------------------------ mobile */

.sidebar-overlay {
  position: fixed;
  inset: 0;
  z-index: 49;
  background: var(--overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms var(--ease);
}
.sidebar-overlay.visible { opacity: 1; pointer-events: auto; }

@media (max-width: 768px) {
  :root { --header-h: 56px; }

  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 50;
    width: min(86vw, 330px);
    padding: calc(10px + env(safe-area-inset-top, 0px)) 10px calc(10px + env(safe-area-inset-bottom, 0px)) calc(10px + env(safe-area-inset-left, 0px));
    border-right: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    transform: translateX(-102%);
    transition: transform 280ms var(--ease);
    visibility: hidden;
  }
  .sidebar.open { transform: none; visibility: visible; }
  .sidebar:not(.open) { transition: transform 240ms var(--ease), visibility 0s linear 240ms; }
  .sidebar-close { display: inline-flex; }
  .nav-item { min-height: 42px; font-size: 14.5px; }
  .run-item { min-height: 40px; font-size: 14px; }
  .history-tab { height: 34px; font-size: 14px; }

  .header {
    padding: env(safe-area-inset-top, 0px) 8px 0 6px;
    height: calc(var(--header-h) + env(safe-area-inset-top, 0px));
  }
  .hamburger { display: inline-flex; }
  .header-bot { display: flex; }
  .header-title { display: none; }

  .chat { padding: 20px 16px 16px; }
  .run-banner { width: calc(100% - 24px); margin-top: 8px; }
  .turn-content.user { max-width: 88%; }
  .turn-content.assistant { font-size: 16px; }
  .step-group.step-streaming,
  .step-group.step-expanded { margin-left: 6px; padding-left: 14px; }
  .step-turn > .turn-label::before { left: -19.5px; }

  .input-area { padding: 6px 10px calc(10px + env(safe-area-inset-bottom, 0px)); }
  .composer { border-radius: 24px; }
  .welcome h2 { font-size: 24px; }
  .toast { bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
}

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------------ files */

/* Presented files (files.js). A present_file call renders a card in the
   transcript, hoisted after the step group so it stays visible when the
   steps collapse; consecutive cards in one turn share a grid. A card opens
   the file panel: beside the chat on wide screens (resizable, maximizable),
   a sheet over the chat on mid widths, full screen on phones. */

/* Per-class tint for card and empty-state icons, readable in both themes. */
:root { --file-l: 0.8; --file-c: 0.11; }
[data-theme="light"] { --file-l: 0.5; --file-c: 0.13; }
.class-markdown { --file-h: 255; }
.class-text { --file-h: 215; }
.class-html { --file-h: 165; }
.class-image,
.class-svg { --file-h: 330; }
.class-pdf { --file-h: 25; }
.class-audio { --file-h: 75; }
.class-video { --file-h: 290; }
.class-other { --file-c: 0; }

.turn.file-turn { margin: -6px 0 24px; }

.file-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 248px), 1fr));
  gap: 8px;
}

.file-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 10px 12px 10px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.file-card:hover { border-color: var(--border-strong); background: color-mix(in oklab, var(--surface) 55%, var(--surface-2)); }
.file-card:focus-visible { outline-offset: 1px; }
.file-card.active {
  border-color: color-mix(in oklab, var(--accent) 55%, var(--border-strong));
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.file-card-icon,
.file-card-thumb {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: var(--r-sm);
}
.file-card-icon {
  display: grid;
  place-items: center;
  --file-fg: oklch(var(--file-l) var(--file-c) var(--file-h, 0));
  background: color-mix(in oklab, var(--file-fg) 14%, transparent);
  color: var(--file-fg);
}
.file-card-icon svg { width: 20px; height: 20px; }
.file-card-thumb {
  object-fit: cover;
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--border);
}

.file-card-body { flex: 1; min-width: 0; line-height: 1.35; }
.file-card-title,
.file-card-desc,
.file-card-meta {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.file-card-title { font-size: 14px; font-weight: 600; letter-spacing: -0.005em; color: var(--text); }
.file-card-desc { margin-top: 1px; font-size: 13px; color: var(--text-2); }
.file-card-meta { margin-top: 2px; font-family: var(--font-mono); font-size: 11.5px; color: var(--text-3); }

/* Card actions float over the end of the text behind a fade, so revealing
   them never reflows the card. Touch devices skip them: a tap opens the
   panel (or downloads), which carries the same actions. */
.file-card-actions {
  position: absolute;
  top: 50%;
  right: 6px;
  display: flex;
  gap: 1px;
  padding-left: 20px;
  background: linear-gradient(to right, transparent, var(--card-bg, var(--surface)) 20px);
  transform: translateY(-50%);
  visibility: hidden;
  opacity: 0;
  transition: opacity 120ms var(--ease);
}
.file-card:hover { --card-bg: color-mix(in oklab, var(--surface) 55%, var(--surface-2)); }
.file-card:hover .file-card-actions,
.file-card:focus-within .file-card-actions { visibility: visible; opacity: 1; }
.file-card-actions .icon-btn { width: 30px; height: 30px; color: var(--text-3); }
.file-card-actions .icon-btn:hover { color: var(--text); background: var(--surface-3); }
.file-card-actions .icon-btn svg { width: 16px; height: 16px; }
@media (hover: none) {
  .file-card-actions { display: none; }
}

/* Icon-button states used by files.js (base .icon-btn is in base). */
.icon-btn:disabled { opacity: 0.35; }
.icon-btn:disabled:hover { background: none; color: var(--text-2); }
.icon-btn.active { color: var(--accent-text); }

/* ---- panel */

.file-panel {
  display: none;
  position: relative;
  flex-direction: column;
  flex-shrink: 0;
  width: 45%;
  min-width: 360px;
  max-width: 100%;
  background: var(--bg);
  border-left: 1px solid var(--border);
  overflow: hidden;
}
.file-panel.open { display: flex; }

.file-panel.max {
  position: fixed;
  inset: 0;
  z-index: 60;
  width: auto !important;
  min-width: 0;
  border-left: none;
  animation: fp-fade 160ms var(--ease);
}
@keyframes fp-fade { from { opacity: 0; } }

/* Drag handle on the left edge: a wide hit area, a thin rule when active. */
.file-panel-resizer {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 8px;
  cursor: col-resize;
  z-index: 2;
  touch-action: none;
}
.file-panel-resizer::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: -1px;
  width: 2px;
  background: transparent;
  transition: background-color var(--dur) var(--ease);
}
.file-panel-resizer:hover::after,
.file-panel.resizing .file-panel-resizer::after { background: var(--ring); }
.file-panel.max .file-panel-resizer { display: none; }
/* While dragging, an iframe below would swallow pointer events. */
.file-panel.resizing { user-select: none; }
.file-panel.resizing .file-panel-body { pointer-events: none; }

/* Title bar: the app header's height and rule, so the two line up. */
.file-panel-header {
  display: flex;
  align-items: center;
  gap: 6px;
  height: var(--header-h);
  padding: 0 10px 0 18px;
  flex-shrink: 0;
  border-bottom: 1px solid color-mix(in oklab, var(--border) 70%, transparent);
}
.fp-back { display: none; }
.fp-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.fp-title {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fp-meta {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fp-window { display: flex; gap: 2px; flex-shrink: 0; }

/* Toolbar: prev / "n of m" / next as one pill, file actions on the right. */
.file-panel-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  padding: 6px 10px 6px 12px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
}
.fp-nav {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  height: 32px;
  padding: 0 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
}
.fp-nav .icon-btn { width: 28px; height: 28px; border-radius: 50%; }
.fp-nav .icon-btn svg { width: 16px; height: 16px; }
.fp-count {
  min-width: 52px;
  padding: 0 2px;
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
  text-align: center;
  white-space: nowrap;
}
.fp-count:empty { display: none; }
.fp-actions { display: flex; gap: 2px; flex-shrink: 0; margin-left: auto; }
.fp-actions .icon-btn,
.fp-window .icon-btn { width: 34px; height: 34px; }

/* Public-share bar: an inset card under the toolbar. */
.file-panel-share {
  flex-shrink: 0;
  margin: 10px 12px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  font-size: 13px;
  animation: rise 0.18s var(--ease);
}
.file-panel-share[data-shared="1"] { border-color: color-mix(in oklab, var(--accent) 35%, var(--border)); }
.fp-share-note { margin-bottom: 10px; color: var(--text-2); line-height: 1.5; }
.fp-share-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.fp-share-url {
  flex: 1 1 180px;
  min-width: 0;
  height: 34px;
  padding: 0 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 12.5px;
  outline: none;
}
.fp-share-url:focus { border-color: var(--border-strong); box-shadow: 0 0 0 3px var(--accent-soft); }
.fp-share-btn {
  height: 34px;
  padding: 0 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.fp-share-btn:hover { background: var(--surface-3); border-color: var(--border-strong); }
.fp-share-btn:disabled { opacity: 0.5; }
/* "Create public link" is the bar's primary action; "Stop sharing" is a
   quiet destructive one. */
.fp-share-toggle { background: var(--accent); border-color: transparent; color: var(--on-accent); }
.fp-share-toggle:hover { background: color-mix(in oklab, var(--accent) 88%, var(--text)); border-color: transparent; }
.file-panel-share[data-shared="1"] .fp-share-toggle { background: none; border-color: var(--border); color: var(--danger); }
.file-panel-share[data-shared="1"] .fp-share-toggle:hover { background: var(--danger-soft); border-color: color-mix(in oklab, var(--danger) 35%, transparent); }

.file-panel-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  position: relative;
  background: var(--bg);
}

.file-panel-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 120px;
}

.file-panel-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  height: 100%;
  min-height: 220px;
  padding: 24px;
  color: var(--text-2);
  font-size: 14px;
  text-align: center;
}
.file-panel-empty-icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: var(--r-lg);
  --file-fg: oklch(var(--file-l) var(--file-c) var(--file-h, 0));
  background: color-mix(in oklab, var(--file-fg) 12%, transparent);
  color: var(--file-fg);
}
.file-panel-empty-icon svg { width: 28px; height: 28px; }

/* Sandboxed documents (html, pdf) fill the body; the frame stays white
   because most presented pages assume it. */
.file-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: none;
  background: #fff;
}

/* Rendered markdown reuses the assistant prose styles. */
.file-md.turn-content.assistant {
  max-width: var(--col);
  margin: 0 auto;
  padding: 24px 28px 48px;
}

.file-source {
  min-height: 100%;
  margin: 0;
  padding: 18px 22px 48px;
  background: var(--code-bg);
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.6;
  white-space: pre;
  color: var(--text);
}
.file-source code { font-family: inherit; background: none; padding: 0; }

/* Text files: markdown.js wraps the <pre> in a code block (language label
   + Copy); here it fills the body and its header stays put on scroll. */
.file-panel-body > .code-block {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  background: var(--code-bg);
}
.file-panel-body > .code-block .code-head {
  position: sticky;
  top: 0;
  z-index: 1;
  padding-left: 22px;
  background: var(--surface);
}
.file-panel-body > .code-block .file-source { flex: 1; min-height: 0; }

/* Images sit centered on a soft checkerboard (transparency shows); a click
   toggles fit / natural size. margin:auto centers without clipping when the
   natural size overflows. */
.file-panel-body.class-image,
.file-panel-body.class-svg {
  display: flex;
  padding: 20px;
  background-color: var(--bg);
  background-image: conic-gradient(var(--surface) 25%, transparent 0 50%, var(--surface) 0 75%, transparent 0);
  background-size: 20px 20px;
}
.file-image {
  display: block;
  max-width: 100%;
  margin: auto;
  border-radius: var(--r-xs);
  box-shadow: var(--shadow-md);
  cursor: zoom-in;
}
.file-image.natural { max-width: none; cursor: zoom-out; }
/* SVGs often assume a white page. */
.class-svg .file-image { background: #fff; }

.file-panel-body.class-audio,
.file-panel-body.class-video { display: flex; padding: 20px; }
.file-media { display: block; width: 100%; margin: auto; border-radius: var(--r-md); }
.class-video .file-media { background: #000; box-shadow: var(--shadow-md); }
.class-audio .file-media { max-width: 560px; }

/* ---- mid widths: a sheet over the chat, the sidebar stays put */

@media (min-width: 769px) and (max-width: 1099px) {
  .file-panel.open:not(.max) {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    width: min(680px, calc(100vw - var(--sidebar-width))) !important;
    min-width: 0;
    box-shadow: var(--shadow-lg);
    animation: fp-slide 220ms var(--ease);
  }
  .file-panel-resizer { display: none; }
}
@keyframes fp-slide { from { transform: translateX(32px); opacity: 0; } }

/* ---- phones: full screen, back button instead of close/maximize */

@media (max-width: 768px) {
  .file-panel.open {
    position: fixed;
    inset: 0;
    z-index: 60;
    width: auto !important;
    min-width: 0;
    border-left: none;
    animation: fp-slide 220ms var(--ease);
  }
  .file-panel-resizer,
  .fp-max,
  .fp-close { display: none; }
  .fp-back { display: inline-flex; }
  .file-panel-header {
    height: calc(var(--header-h) + env(safe-area-inset-top, 0px));
    padding: env(safe-area-inset-top, 0px) 12px 0 6px;
  }
  .file-panel-toolbar { padding: 6px 8px; }
  .fp-actions .icon-btn { width: 40px; height: 40px; }
  .fp-nav { height: 38px; }
  .fp-nav .icon-btn { width: 34px; height: 34px; }
  .file-panel-body { padding-bottom: env(safe-area-inset-bottom, 0px); }
  .file-md.turn-content.assistant { padding: 20px 18px 40px; }
  .file-source { padding: 14px 16px 40px; }
  .fp-share-url { flex-basis: 100%; }
  .fp-share-btn { flex: 1; }
  .turn.file-turn { margin-top: -4px; }
}

/* ------------------------------------------------------------------ orbotui */

/* Everything below is orbotui-only (not in orbot's embedded UI): the busy
   dot for turns left running in the background, the PWA reload control,
   and Web Push (the footer toggle and the Scheduled-tab nudge). */

/* chat.js follows the stream only while the reader is pinned to the bottom,
   and reads any scroll event that leaves them >48px up as "the reader
   scrolled away". Browser scroll anchoring produces exactly such events
   when content above shrinks (the step group collapsing as the reply
   starts, file cards hoisted above it), unpinning the view mid-turn. Let
   the scroll position clamp instead. */
.chat { overflow-anchor: none; }

/* A turn still running where the user isn't looking (chat.js detach()). */
.nav-item-busy {
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.6s ease-in-out infinite;
}

/* Reload: installed PWA only (no browser chrome), or lit up when a new
   deploy landed while a turn or a draft was in progress. */
.refresh-btn.update-ready {
  color: var(--accent-text);
  background: var(--accent-soft);
  animation: pulse 1.6s ease-in-out infinite;
}

/* Jump to latest: floats just above the composer, centered over the
   column, while the reader is scrolled up and new content has arrived. */
.jump-latest {
  position: absolute;
  top: -44px;
  left: 50%;
  z-index: 5;
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  transform: translateX(-50%);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  color: var(--text-2);
  box-shadow: var(--shadow-md);
  animation: jump-in 200ms var(--ease);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
@keyframes jump-in { from { opacity: 0; transform: translate(-50%, 6px); } }
.jump-latest:hover { background: var(--surface-2); color: var(--text); }
.jump-latest svg { width: 18px; height: 18px; }

/* Notifications toggle in the sidebar footer. */
.sidebar-footer .notify-btn { width: 30px; height: 30px; color: var(--text-3); }
.sidebar-footer .notify-btn:hover { color: var(--text); }
.sidebar-footer .notify-btn svg { width: 17px; height: 17px; }
.notify-btn.active { color: var(--accent-text); }
.notify-btn.active:hover { color: var(--accent-text); background: var(--accent-soft); }
.notify-btn.blocked { opacity: 0.55; }
.notify-btn:disabled { cursor: progress; }

/* Scheduled tab: "get run results as notifications" nudge. */
.push-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 8px;
  padding: 7px 4px 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-2);
  font-size: 12.5px;
  line-height: 1.4;
}
.push-hint-icon { display: inline-grid; place-items: center; flex-shrink: 0; color: var(--accent-text); }
.push-hint-icon svg { width: 15px; height: 15px; }
.push-hint-text { flex: 1; min-width: 0; }
.push-hint-action {
  flex-shrink: 0;
  padding: 3px 9px;
  background: var(--accent-soft);
  border: none;
  border-radius: var(--r-xs);
  color: var(--accent-text);
  font-size: 12.5px;
  font-weight: 500;
  transition: background-color var(--dur) var(--ease);
}
.push-hint-action:hover { background: color-mix(in oklab, var(--accent) 24%, transparent); }
.push-hint-close {
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--r-xs);
  color: var(--text-3);
}
.push-hint-close:hover { background: var(--surface-2); color: var(--text); }
.push-hint-close svg { width: 14px; height: 14px; }
@media (max-width: 768px) {
  .sidebar-footer .notify-btn { width: 36px; height: 36px; }
  .push-hint { font-size: 13.5px; }
  .push-hint-action { padding: 5px 11px; font-size: 13.5px; }
  .push-hint-close { width: 32px; height: 32px; }
}
