/* ==========================================================================
   Basalt — local model console
   ========================================================================== */

@layer reset, base, layout, components, overlays;

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; padding: 0; }
  button, input, textarea, select { font: inherit; color: inherit; background: none; border: none; }
  button { cursor: pointer; }
  svg { display: block; }
  [hidden] { display: none !important; }
  h1,h2,h3,h4 { font-weight: 500; letter-spacing: -0.022em; }
}

/* --------------------------------------------------------------------------
   tokens
   -------------------------------------------------------------------------- */
@layer base {
:root {
  --bg:        #08080A;
  --bg-1:      #0E0E11;
  --bg-2:      #141418;
  --bg-3:      #1C1C21;
  --line:      rgba(255,255,255,.075);
  --line-2:    rgba(255,255,255,.14);
  --fg:        #F1EFEC;
  --fg-2:      #A5A29C;
  --fg-3:      #87847E;   /* 4.55:1 on the darkest surface it lands on */
  --fg-4:      #565350;
  --ember:     #FF5D2E;
  --ember-lo:  #FF5D2E22;
  --ember-2:   #FFA05B;
  --mint:      #5FE3B6;
  --mint-lo:   #5FE3B61A;
  --violet:    #A98CFF;
  --amber:     #FFC65C;
  --red:       #FF6B6B;

  --shadow-1: 0 1px 2px rgba(0,0,0,.5), 0 8px 24px -12px rgba(0,0,0,.7);
  --shadow-2: 0 24px 70px -20px rgba(0,0,0,.85), 0 2px 8px rgba(0,0,0,.4);

  --sans: "Segoe UI Variable Display", "Inter", "Segoe UI", -apple-system, system-ui, sans-serif;
  --mono: "Cascadia Code", "JetBrains Mono", "SF Mono", Consolas, ui-monospace, monospace;

  --r-sm: 7px; --r: 11px; --r-lg: 16px; --r-xl: 22px;
  --ease: cubic-bezier(.2,.8,.2,1);
  --spring: cubic-bezier(.34,1.56,.64,1);
  --rail-w: 58px; --side-w: 264px; --insp-w: 348px;
  --grain: .035;
  color-scheme: dark;
}

/* Light is not the dark ramp inverted. On a light ground there is far less
   luminance headroom below the background, so the neutral ramp has to fall
   away much faster — a mirrored ramp puts every micro-label at ~2:1 and it
   disappears. Every value below clears WCAG AA (4.5:1, or 3:1 for the purely
   decorative step) against all four surfaces, measured, not eyeballed.
   Hue is held warm to match the dark theme rather than drifting blue. */
:root[data-theme="light"] {
  --bg:        #F8F6F3;   /* page: warm off-white, never pure white — cuts glare */
  --bg-1:      #FEFDFB;   /* panels sit above the page, but warm — pure white
                             next to a warm page reads as a cold hole */
  --bg-2:      #F3F1EC;   /* subtle fill */
  --bg-3:      #ECE9E3;   /* hover/active: a nudge, not a hole */
  /* softer hairlines — at .13 every rule read as a hard pencil line */
  --line:      rgba(60,50,35,.10);
  --line-2:    rgba(60,50,35,.17);
  --fg:        #23201A;   /* eased off near-black; still ~13:1 */
  --fg-2:      #565247;
  --fg-3:      #696559;
  --fg-4:      #837F74;
  --ember:     #BC380C;   /* deepened: the dark-mode ember is 2.4:1 on white */
  --ember-lo:  #BC380C14;
  --ember-2:   #9A4708;
  --mint:      #0A7357;
  --mint-lo:   #0A735712;
  --violet:    #5B37C4;
  --amber:     #845A00;
  --red:       #B92B2B;
  /* warm-tinted shadows; neutral black reads as dirt on a warm ground */
  --shadow-1: 0 1px 2px rgba(60,45,30,.07), 0 6px 18px -10px rgba(60,45,30,.16);
  --shadow-2: 0 20px 50px -18px rgba(60,45,30,.22), 0 2px 6px rgba(60,45,30,.07);
  --grain: .015;
  color-scheme: light;
}

html, body { height: 100%; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
  font-synthesis-weight: none;
}

::selection { background: color-mix(in srgb, var(--ember) 30%, transparent); color: inherit; }
/* keyboard-focus ring for controls only — text fields style their own container,
   otherwise the ring stacks on top of the field's focus treatment */
:focus-visible { outline: 2px solid color-mix(in srgb, var(--fg) 45%, transparent); outline-offset: 2px; border-radius: 5px; }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 99px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--fg-4); background-clip: content-box; border: 3px solid transparent; }

.grain {
  position: fixed; inset: 0; width: 100%; height: 100%;
  opacity: var(--grain); pointer-events: none; z-index: 9999; mix-blend-mode: overlay;
}
.ember-glow {
  position: fixed; top: -340px; left: 50%; width: 900px; height: 620px;
  transform: translateX(-50%);
  background: radial-gradient(closest-side, var(--ember) 0%, transparent 72%);
  opacity: .05; pointer-events: none; z-index: 0;
  transition: opacity .9s var(--ease);
}
body.is-generating .ember-glow { opacity: .16; animation: breathe 3.4s ease-in-out infinite; }
@keyframes breathe { 0%,100% { opacity:.10 } 50% { opacity:.20 } }
}

/* --------------------------------------------------------------------------
   boot
   -------------------------------------------------------------------------- */
@layer base {
.boot {
  position: fixed; inset: 0; z-index: 500; background: var(--bg);
  display: grid; place-content: center; justify-items: center; gap: 14px;
  transition: opacity .42s var(--ease), visibility .42s;
}
.boot.gone { opacity: 0; visibility: hidden; }
.boot-mark { display: flex; gap: .06em; font-size: clamp(30px, 6vw, 54px); font-weight: 300; letter-spacing: .3em; }
.boot-mark span { display: inline-block; opacity: 0; transform: translateY(14px); animation: bootIn .5s var(--ease) forwards; }
.boot-mark span:nth-child(1){animation-delay:.01s} .boot-mark span:nth-child(2){animation-delay:.04s}
.boot-mark span:nth-child(3){animation-delay:.07s} .boot-mark span:nth-child(4){animation-delay:.10s}
.boot-mark span:nth-child(5){animation-delay:.13s} .boot-mark span:nth-child(6){animation-delay:.16s}
.boot-mark span:nth-child(4) { color: var(--ember); }
@keyframes bootIn { to { opacity: 1; transform: none; } }
.boot-sub { font-family: var(--mono); font-size: 10.5px; letter-spacing: .34em; text-transform: uppercase; color: var(--fg-3);
  opacity: 0; animation: bootIn .5s var(--ease) .3s forwards; }
}

/* --------------------------------------------------------------------------
   layout
   -------------------------------------------------------------------------- */
@layer layout {
.app {
  position: relative; z-index: 1; height: 100dvh; display: grid;
  grid-template-columns: var(--rail-w) var(--side-w) minmax(0,1fr) var(--insp-w);
  grid-template-rows: minmax(0, 1fr);      /* row must not grow past the viewport */
  overflow: hidden;
  transition: grid-template-columns .42s var(--ease);
}
/* every grid/flex child that owns a scroll area needs an explicit zero minimum,
   otherwise it sizes to its content and the scroll never engages */
.rail, .sidebar, .main, .inspector { min-height: 0; min-width: 0; }
.app.no-side { --side-w: 0px; }
.app.no-insp { --insp-w: 0px; }

.rail {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 14px 0 16px; border-right: 1px solid var(--line); background: var(--bg);
}
.rail-logo { color: var(--ember); padding: 6px; border-radius: var(--r-sm); transition: transform .5s var(--spring); }
.rail-logo:hover { transform: rotate(-12deg) scale(1.08); }
.rail-group { display: flex; flex-direction: column; gap: 2px; margin-top: 18px; }
.rail-spacer { flex: 1; }
.rail-btn {
  width: 36px; height: 36px; display: grid; place-items: center; border-radius: var(--r-sm);
  color: var(--fg-3); transition: color .2s, background .2s, transform .2s var(--spring); position: relative;
}
.rail-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.rail-btn:hover { color: var(--fg); background: var(--bg-2); }
.rail-btn:active { transform: scale(.92); }
.rail-btn.is-on { color: var(--ember); }
.rail-btn.is-on::before { content: ""; position: absolute; left: -11px; width: 2px; height: 15px; border-radius: 2px; background: var(--ember); }

.sidebar {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  border-right: 1px solid var(--line); background: var(--bg-1);
}
.main { display: flex; flex-direction: column; min-width: 0; position: relative; background: var(--bg); }
.inspector {
  position: relative;
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  border-left: 1px solid var(--line); background: var(--bg-1);
}

/* panel widths are driven by JS (paintPanels) so drag-resize and the stored
   preference survive a viewport change — see PANELS in app.js */
}

/* --------------------------------------------------------------------------
   sidebar
   -------------------------------------------------------------------------- */
@layer components {
.side-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 14px 10px; gap: 8px; }
.side-head-acts { display: flex; align-items: center; gap: 4px; }

/* collapse / reveal ------------------------------------------------------- */
.collapse-btn { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 6px;
  color: var(--fg-4); flex: none; transition: color .18s, background .18s; }
.collapse-btn svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.collapse-btn:hover { color: var(--fg); background: var(--bg-2); }

.reveal-tab {
  position: fixed; top: 50%; translate: 0 -50%; z-index: 30;
  width: 17px; height: 62px; display: grid; place-items: center;
  background: var(--bg-2); border: 1px solid var(--line-2); color: var(--fg-3);
  border-radius: 0 8px 8px 0; border-left: none; transition: all .2s var(--ease);
}
.reveal-tab.right { right: 0; left: auto; border-radius: 8px 0 0 8px; border-left: 1px solid var(--line-2); border-right: none; }
.reveal-tab:not(.right) { left: var(--rail-w); }
.reveal-tab svg { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.reveal-tab:hover { color: var(--fg); background: var(--bg-3); width: 22px; }

/* Generous grab area straddling the panel edge, quiet until you reach for it.
   Both the line and the grip are centred on the border via 50% so they stay
   centred whatever the hit-area width is. */
.resize-handle {
  position: absolute; top: 0; bottom: 0; left: -11px; width: 22px; z-index: 25;
  cursor: col-resize; background: transparent;
}
.resize-handle::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 1px); width: 2px;
  background: transparent; transition: background .18s var(--ease);
}
.resize-handle::before {
  content: ""; position: absolute; top: 50%; left: calc(50% - 2.5px);
  width: 5px; height: 46px; translate: 0 -50%; border-radius: 3px;
  background: var(--line-2); opacity: 0; transition: opacity .18s var(--ease);
}
.resize-handle:hover::before { opacity: 1; }
.resize-handle:hover::after { background: var(--line-2); }
.resize-handle.dragging::after { background: var(--ember); }
.resize-handle.dragging::before { opacity: 0; }
body.resizing { cursor: col-resize; user-select: none; }
body.resizing * { pointer-events: none; }
.wordmark { font-size: 16px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; }
.wordmark::after { content: "·"; color: var(--ember); margin-left: 4px; }

/* No outline. A bordered box for every small action turned the header into a
   row of chiclets; these read as actions by being legible and responding to the
   pointer, not by being fenced. */
.btn-ghost {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px;
  border: 1px solid transparent; border-radius: 7px; color: var(--fg-3);
  font-size: 12px; transition: color .16s, background .16s;
}
.btn-ghost svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.btn-ghost:hover { color: var(--fg); background: var(--bg-2); }
/* the one that starts something gets the accent, still without a box */
.btn-ghost.sm { padding: 5px 9px; font-size: 11.5px; }
.btn-ghost.wide { width: 100%; justify-content: center; border-radius: 7px; padding: 9px; }
.btn-solid {
  background: var(--ember); color: #fff; border-radius: 7px; padding: 7px 15px;
  font-size: 12.5px; font-weight: 500; transition: filter .2s, transform .12s;
}
.btn-solid:hover { filter: brightness(1.1); } .btn-solid:active { transform: scale(.97); }
.btn-solid.sm { padding: 6px 13px; font-size: 12px; }
.btn-solid[disabled] { opacity: .45; pointer-events: none; }

.side-search {
  display: flex; align-items: center; gap: 8px; margin: 0 12px 10px; padding: 7px 11px;
  background: var(--bg-2); border: 1px solid transparent; border-radius: 8px;
  color: var(--fg-3); transition: border-color .2s, background .2s;
}
.side-search:focus-within { border-color: var(--line-2); background: var(--bg-3); }
.side-search svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; flex: none; }
.side-search input { flex: 1; min-width: 0; font-size: 12.5px; color: var(--fg); }
.side-search input::placeholder { color: var(--fg-4); }
.side-search.flat { margin: 0; flex: 1; }

.convo-list { flex: 1; min-height: 0; overflow-y: auto; padding: 0 8px 10px; display: flex; flex-direction: column; gap: 1px; }
.convo {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: var(--r-sm);
  color: var(--fg-2); position: relative; transition: background .16s, color .16s;
}
/* The active chat is marked by a rule and a brighter title, not by a filled
   block — a list of filled blocks is the pill look this interface keeps away
   from, and it flattens the difference between "selected" and "hovered". */
.convo:hover { background: var(--bg-2); color: var(--fg); }
.convo.is-on { background: none; color: var(--fg); }
.convo.is-on .convo-t { color: var(--fg); font-weight: 450; }
.convo.is-on::before { content:""; position:absolute; left:-8px; top:7px; bottom:7px;
  width:2px; background: var(--ember); }
.convo.is-on:hover { background: var(--bg-2); }
.convo-t { font-size: 12.8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.convo-m { font-family: var(--mono); font-size: 10px; color: var(--fg-4); letter-spacing: .02em;
  display: flex; gap: 7px; margin-top: 2px; }
.convo-x { position: absolute; right: 6px; top: 50%; translate: 0 -50%; opacity: 0; padding: 4px;
  color: var(--fg-3); border-radius: 5px; transition: opacity .15s, color .15s; }
.convo:hover .convo-x { opacity: 1; }
.convo-x:hover { color: var(--red); background: var(--bg); }
.side-empty { padding: 22px 14px; color: var(--fg-4); font-size: 12px; line-height: 1.7; }

.side-foot { padding: 10px 14px 14px; border-top: 1px solid var(--line); }
.ident { display: flex; align-items: center; gap: 8px; width: 100%; padding: 3px 0;
  border-radius: 0; font-family: var(--mono); font-size: 11px; color: var(--fg-3);
  transition: color .16s; }
.ident:hover { color: var(--fg); }
.ident:hover .ident-id { text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: var(--line-2); }
.ident .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-4); flex: none;
  transition: background .3s, box-shadow .3s; }
.ident.live .dot { background: var(--mint); box-shadow: 0 0 0 3px var(--mint-lo); }
.ident.down .dot { background: var(--red); box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 14%, transparent); }
.ident-id { flex: 1; text-align: left; letter-spacing: .04em; }
.ident-id .mask { font-size: 13px; line-height: 0; letter-spacing: .04em;
  vertical-align: -0.5px; font-weight: 400; }
.ident-lock { font-size: 10px; opacity: .85; }
.ident-edit { width: 100%; padding: 5px 6px; border-radius: 6px; background: var(--bg-2);
  border: 1px solid var(--ember); font-family: var(--mono); font-size: 11px; color: var(--fg);
  letter-spacing: .04em; }
.ident-note { font-size: 10px; line-height: 1.5; color: var(--fg-4); margin-top: 6px; }
.ident-note:empty { display: none; }
.ident-note b { color: var(--amber); font-weight: 500; }
}

/* --------------------------------------------------------------------------
   top bar
   -------------------------------------------------------------------------- */
@layer components {
.top {
  display: flex; align-items: center; gap: 12px; padding: 11px 18px;
  border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: blur(14px); position: relative; z-index: 5;
}
.model-pill {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px 5px 4px;
  border: none; border-radius: 6px; background: none;
  transition: background .2s var(--ease); max-width: 380px;
}
.model-pill:hover { background: var(--bg-2); }
.model-pill:hover .mp-chev { stroke: var(--fg-2); }
.model-pill .pip { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-4); flex: none; transition: background .3s, box-shadow .3s; }
.model-pill .pip.warm { background: var(--mint); box-shadow: 0 0 0 3px var(--mint-lo); }
.mp-name { font-size: 12.8px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-meta { font-family: var(--mono); font-size: 10px; color: var(--fg-3); white-space: nowrap; }
.mp-chev { fill: none; stroke: var(--fg-3); stroke-width: 2; stroke-linecap: round; flex: none; }
.top-title { flex: 1; text-align: center; font-size: 12.5px; color: var(--fg-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top-actions { display: flex; gap: 5px; }
.top-actions .btn-ghost { padding: 6px; border-radius: var(--r-sm); }
}

/* --------------------------------------------------------------------------
   thread
   -------------------------------------------------------------------------- */
@layer components {
/* No `scroll-behavior: smooth` here. Following the model as it writes means
   assigning scrollTop on almost every frame, and with smooth scrolling each of
   those assignments starts a fresh animation the next one interrupts — so the
   view slides continuously even when it is already pinned to the bottom and has
   nowhere to go. Programmatic follow is instant; the one place a glide belongs
   is the jump-to-bottom button, which asks for it explicitly. */
.stream { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; position: relative;
  overscroll-behavior: contain; }
.thread { max-width: 800px; margin: 0 auto; padding: 30px 28px 14px; display: flex; flex-direction: column; gap: 26px; }

.msg { display: grid; grid-template-columns: 66px minmax(0,1fr); gap: 16px; animation: msgIn .45s var(--ease) both; }
@keyframes msgIn { from { opacity: 0; transform: translateY(9px); } }
/* Anchors the label to the right of the rail and lets it overflow *leftwards*.
   `text-align: right` cannot do this: alignment only distributes leftover
   space, and a name wider than the 66px column has none — so the line started
   at the left edge and spilled right, printing over the message body. A flex
   item at `flex-end` overflows past the start edge instead, which is the
   direction wanted here. */
.msg-rail { padding-top: 2px; display: flex; justify-content: flex-end; align-items: flex-start; }
/* One line, growing leftwards into the margin.
   The name is already cut somewhere deliberate by modelLabel(); letting the
   66px column cut it again gave "FABLE-FU…", and wrapping it gave "AGENTWORL"
   over "D", which is worse — a word broken mid-letter reads as damage. So it is
   anchored to the right edge, against the message body, and anything longer
   than the rail runs out into the empty gutter where there is nothing to hit. */
/* One line, growing leftwards into the margin.
   The name is already cut somewhere deliberate by modelLabel(); letting the
   66px column cut it again gave "FABLE-FU…", and wrapping it gave "AGENTWORL"
   over "D", which is worse — a word broken mid-letter reads as damage. So it
   runs out into the empty gutter instead, where there is nothing to hit.
   `flex: 0 0 auto` keeps it at its natural width rather than being squeezed
   back into the column, and the padding stops the last letter sitting flush
   against whatever the message starts with. */
.msg-who { font-family: var(--mono); font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--fg-4); white-space: nowrap; flex: 0 0 auto; padding-right: 3px; }
.msg.user .msg-who { color: var(--fg-3); }
.msg.assistant .msg-who { color: var(--ember); }
.msg-body { min-width: 0; }

.msg.user .prose { color: var(--fg); }
.msg.user .prose p { margin: 0 0 .5em; }
.msg-acts { display: flex; gap: 2px; margin-top: 9px; opacity: 0; transition: opacity .2s; }
.msg:hover .msg-acts, .msg:focus-within .msg-acts { opacity: 1; }
.act {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 8px; border-radius: 6px;
  font-size: 11px; color: var(--fg-4); transition: color .15s, background .15s;
}
.act svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.act:hover { color: var(--fg); background: var(--bg-2); }
.act.danger:hover { color: var(--red); }

/* attachments on a message */
.msg-files { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 10px; }
.msg-file { display: flex; align-items: center; gap: 9px; padding: 7px 11px 7px 9px;
  border: 1px solid var(--line-2); border-radius: 8px; max-width: 290px; min-width: 0; }
.mf-ico { display: grid; place-items: center; width: 24px; height: 24px; flex: none;
  border: 1px solid var(--line-2); border-radius: 6px; color: var(--fg-3); }
.mf-ico svg { width: 12px; height: 12px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.mf-text { min-width: 0; }
.mf-name { display: block; font-size: 12px; color: var(--fg-2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.mf-meta { display: block; font-family: var(--mono); font-size: 9.5px; color: var(--fg-4); margin-top: 2px; }
.msg-img { max-width: 230px; max-height: 200px; border-radius: var(--r); border: 1px solid var(--line); object-fit: cover; cursor: zoom-in; }

/* thinking — a quiet line, not a box. collapsed unless you ask for it. */
.think-block { margin: 0 0 10px; }
.think-head {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 0;
  font-size: 11.5px; color: var(--fg-4); transition: color .18s;
}
.think-head:hover { color: var(--fg-2); }
.think-head .chev { transition: transform .25s var(--ease); fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .8; }
.think-block.open .chev { transform: rotate(180deg); }
.think-block.live .think-head {
  background: linear-gradient(90deg, var(--fg-4) 18%, var(--fg) 44%, var(--fg-4) 70%);
  background-size: 220% 100%; -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: shimmer 1.8s linear infinite;
}
.think-block.live .chev { color: var(--fg-3); -webkit-text-fill-color: initial; }
@keyframes shimmer { to { background-position: -220% 0; } }
.think-body {
  display: none; margin: 8px 0 0 5px; padding: 2px 0 2px 14px; border-left: 1px solid var(--line-2);
  font-size: 12.2px; line-height: 1.72; color: var(--fg-3); white-space: pre-wrap; word-break: break-word;
  max-height: 320px; overflow-y: auto;
}
.think-block.open .think-body { display: block; }

/* tool calls — a disclosure line, same flat treatment as thinking */
.tool-card { margin: 0 0 10px; }
.tool-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 2px 0; text-align: left;
  color: var(--fg-3); transition: color .18s; }
.tool-head:hover { color: var(--fg); }
.tool-ico { width: 13px; height: 13px; flex: none; color: var(--mint); }
.tool-ico svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.tool-name { font-family: var(--mono); font-size: 11.5px; color: var(--fg-2); flex: none; }
.tool-head:hover .tool-name { color: var(--fg); }
.tool-sum { font-size: 11.5px; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.tool-ms { font-family: var(--mono); font-size: 10px; color: var(--fg-4); flex: none; }
.tool-card .chev { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  flex: none; opacity: .8; transition: transform .25s var(--ease); }
.tool-card.open .chev { transform: rotate(180deg); }
.tool-body { display: none; margin: 8px 0 0 6px; padding-left: 14px; border-left: 1px solid var(--line-2); }
.tool-card.open .tool-body { display: block; }
.tool-sec { padding: 0 0 10px; }
.tool-lbl { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-4); margin-bottom: 5px; }
.tool-pre { font-family: var(--mono); font-size: 11.3px; line-height: 1.65; color: var(--fg-3);
  white-space: pre-wrap; word-break: break-word; max-height: 300px; overflow-y: auto; }
.spin { width: 13px; height: 13px; border: 1.6px solid var(--line-2); border-top-color: var(--mint);
  border-radius: 50%; animation: spin .7s linear infinite; flex: none; }
@keyframes spin { to { transform: rotate(360deg); } }

/* a tool that hasn't come back yet says what it's doing, and counts */
.tool-run { display: flex; align-items: center; gap: 9px; padding: 3px 0; }
.tool-verb { font-size: 12px; color: var(--fg-2);
  background: linear-gradient(90deg, var(--fg-3) 20%, var(--fg) 46%, var(--fg-3) 72%);
  background-size: 220% 100%; -webkit-background-clip: text; background-clip: text;
  color: transparent; animation: shimmer 1.8s linear infinite; }
.tool-el { font-family: var(--mono); font-size: 10.5px; color: var(--fg-4);
  font-variant-numeric: tabular-nums; }

/* stats */
.stats { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--line); }
.stat { display: flex; flex-direction: column; gap: 1px; }
.stat b { font-family: var(--mono); font-size: 12.5px; font-weight: 500; color: var(--fg-2); font-variant-numeric: tabular-nums; }
.stat span { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-4); }
.stat.hero b { color: var(--ember); font-size: 14px; }

/* ---- displayed images ---------------------------------------------------- */
/* No panel, no fill, no frame: a chart saved with transparent:true should read
   as part of the page in either theme. That's the whole incentive. */
.shot-wrap { margin: 10px 0 4px; }
.shot { display: grid; gap: 10px; }
.shot.multi { grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr)); }
.shot-fig { min-width: 0; margin: 0; }
.shot img {
  display: block; width: 100%; height: auto; max-height: 460px; object-fit: contain;
  border-radius: 4px; cursor: zoom-in; transition: opacity .18s var(--ease);
}
.shot:not(.multi) img { width: auto; max-width: 100%; }
.shot img:hover { opacity: .88; }
.shot-name { font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; color: var(--fg-4);
  margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shot-cap { font-size: 11.5px; color: var(--fg-3); margin-top: 9px; line-height: 1.5; }
@media (max-width: 620px) { .shot.multi { grid-template-columns: 1fr; } }

.lightbox { position: fixed; inset: 0; z-index: 600; display: grid; grid-template-rows: 1fr auto;
  background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(14px);
  animation: fade .2s var(--ease); cursor: zoom-out; }
.lb-img { display: grid; place-items: center; padding: 32px 32px 8px; min-height: 0; }
.lb-img img { max-width: 100%; max-height: 100%; object-fit: contain; cursor: default; }
.lb-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 26px 20px; }
.lb-n { font-family: var(--mono); font-size: 11px; color: var(--fg-3); }
.lb-x { font-size: 12px; color: var(--fg-2); padding: 6px 12px; border: 1px solid var(--line-2);
  border-radius: 6px; transition: all .18s; }
.lb-x:hover { color: var(--fg); background: var(--bg-2); }

/* ---- custom tools in the inspector --------------------------------------- */
.tool-group { display: flex; align-items: baseline; gap: 8px; padding: 18px 2px 7px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--fg-4); border-bottom: 1px solid var(--line); }
.tool-group span { margin-left: auto; }
.tool-empty { font-size: 11.5px; line-height: 1.6; color: var(--fg-3); padding: 12px 2px; }
.tool-empty b { color: var(--fg-2); font-weight: 500; }
.tr-del { opacity: 0; color: var(--fg-4); padding: 3px; align-self: center;
  transition: opacity .15s, color .15s; }
.tool-row:hover .tr-del { opacity: 1; }
.tr-del:hover { color: var(--red); }

/* ---- diffs --------------------------------------------------------------- */
.diff-wrap { padding-bottom: 10px; }
.diff-head { padding: 0 0 8px; font-size: 11.5px; color: var(--fg-2); }
.diff-warn { margin: 0 0 9px; padding: 6px 9px; font-size: 11px; line-height: 1.5;
  color: var(--amber); border-left: 2px solid color-mix(in srgb, var(--amber) 50%, transparent);
  background: color-mix(in srgb, var(--amber) 8%, transparent); white-space: pre-wrap; }
.diff { font-family: var(--mono); font-size: 11.6px; line-height: 1.62; overflow-x: auto;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  max-height: 420px; overflow-y: auto; }
.d-row { display: grid; grid-template-columns: 44px 44px 16px minmax(0,1fr); align-items: baseline; }
.d-n { text-align: right; padding-right: 9px; color: var(--fg-4); font-size: 10.5px;
  user-select: none; font-variant-numeric: tabular-nums; }
.d-g { text-align: center; color: var(--fg-4); user-select: none; }
.d-c { white-space: pre; padding-right: 14px; color: var(--fg-2); }
.d-add { background: color-mix(in srgb, var(--mint) 11%, transparent); }
.d-add .d-g, .d-add .d-c { color: var(--mint); }
.d-del { background: color-mix(in srgb, var(--red) 11%, transparent); }
.d-del .d-g, .d-del .d-c { color: var(--red); }
.d-hunk { background: var(--bg-2); }
.d-hunk .d-c { color: var(--fg-4); font-size: 10.5px; }

.err-box { border: none; border-left: 2px solid color-mix(in srgb, var(--red) 55%, transparent);
  background: none; color: var(--red); padding: 2px 0 2px 12px; font-size: 12.5px;
  font-family: var(--mono); line-height: 1.6; }

.caret { display: inline-block; width: 6px; height: .95em; background: var(--ember); vertical-align: -.12em;
  margin-left: 3px; border-radius: 1px; animation: blink 1.05s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* "New" — the primary action in the sidebar, so let it read like one */
/* No outline and no filled chip. The accent colour and the rotating cross are
   enough to say "this starts something" — the border and tinted background were
   the two things making it read as a pill. */
#newChat {
  border-color: transparent; background: none;
  color: var(--ember); font-weight: 500; padding: 6px 12px 6px 9px;
}
#newChat:hover { background: color-mix(in srgb, var(--ember) 13%, transparent);
  border-color: transparent; color: var(--ember); box-shadow: none; }
#newChat svg { stroke-width: 2.2; transition: transform .3s var(--spring); }
#newChat:hover svg { transform: rotate(90deg); }

.jump {
  position: absolute; bottom: 128px; left: 50%; translate: -50% 0; z-index: 6;
  width: 30px; height: 30px; display: grid; place-items: center; border-radius: 8px;
  background: var(--bg-2); border: 1px solid var(--line-2); color: var(--fg-2); box-shadow: var(--shadow-1);
  animation: msgIn .3s var(--ease);
}
.jump svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.jump:hover { background: var(--bg-3); color: var(--fg); }
}

/* --------------------------------------------------------------------------
   empty state
   -------------------------------------------------------------------------- */
@layer components {
.empty { position: absolute; inset: 0; display: grid; place-items: center; padding: 30px; pointer-events: none; }
.empty[hidden] { display: none; }
.empty-inner { max-width: 560px; pointer-events: auto; }
.empty-eyebrow { font-family: var(--mono); font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--fg-4); margin-bottom: 18px; animation: msgIn .6s var(--ease) .05s both; }
.empty-title { font-size: clamp(30px, 4.4vw, 46px); line-height: 1.06; letter-spacing: -.035em; font-weight: 400;
  animation: msgIn .7s var(--ease) .12s both; }
.empty-title em { font-style: italic; color: var(--ember); }
.empty-body { color: var(--fg-2); margin: 16px 0 26px; max-width: 42ch; font-size: 13.5px;
  animation: msgIn .7s var(--ease) .2s both; }
.starters { display: grid; border-top: 1px solid var(--line); animation: msgIn .7s var(--ease) .28s both; }
.starter {
  display: flex; align-items: center; gap: 14px; padding: 12px 2px; text-align: left;
  border: none; border-bottom: 1px solid var(--line); background: none;
  transition: color .2s var(--ease), padding-left .2s var(--ease);
}
.starter:hover { padding-left: 8px; }
.starter .k { font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ember); width: 62px; flex: none; }
.starter .t { font-size: 12.8px; color: var(--fg-2); }
.starter:hover .t { color: var(--fg); }
}

/* --------------------------------------------------------------------------
   composer
   -------------------------------------------------------------------------- */
@layer components {
.composer-wrap { padding: 0 28px 16px; max-width: 800px; width: 100%; margin: 0 auto; position: relative; z-index: 4; }
.composer {
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--bg-1);
  box-shadow: var(--shadow-1); transition: border-color .25s, box-shadow .25s;
}
.composer:focus-within { border-color: color-mix(in srgb, var(--fg) 22%, transparent);
  box-shadow: var(--shadow-1), 0 0 0 4px color-mix(in srgb, var(--fg) 4%, transparent); }
.composer.drag { border-color: var(--ember); border-style: dashed; }
.composer textarea {
  width: 100%; padding: 14px 16px 6px; resize: none; font-size: 14px; line-height: 1.62;
  max-height: 260px; overflow-y: auto; color: var(--fg); background: none;
}
.composer textarea::placeholder { color: var(--fg-4); }
.composer-bar { display: flex; align-items: center; justify-content: space-between; padding: 6px 9px 9px 11px; gap: 10px; }
.cb-left, .cb-right { display: flex; align-items: center; gap: 5px; }
.chip-btn {
  display: inline-flex; align-items: center; gap: 5px; padding: 5px 8px; border-radius: 6px;
  border: none; color: var(--fg-3); font-size: 11.5px; transition: color .18s, background .18s;
}
.chip-btn svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.chip-btn:hover { color: var(--fg); background: var(--bg-2); }
.chip-btn.is-on { color: var(--ember); background: var(--ember-lo); }
.chip-btn.is-on#thinkBtn { color: var(--violet); background: color-mix(in srgb, var(--violet) 12%, transparent); }
.tok-est { font-family: var(--mono); font-size: 10px; color: var(--fg-4); font-variant-numeric: tabular-nums; }
.send {
  width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%;
  background: var(--ember); color: #fff; transition: all .22s var(--ease);
}
.send svg { fill: none; stroke: currentColor; stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; grid-area: 1/1; }
.send .i-stop { display: none; }
.send[disabled] { background: var(--bg-3); color: var(--fg-4); }
.send:not([disabled]):hover { filter: brightness(1.12); transform: scale(1.06); }
body.is-generating .send, body.is-compacting .send { background: var(--fg); color: var(--bg); }
body.is-generating .send .i-send, body.is-compacting .send .i-send { display: none; }
body.is-generating .send .i-stop, body.is-compacting .send .i-stop { display: block; }
/* reserves no space when there's nothing to say */
.composer-hint { font-family: var(--mono); font-size: 10px; color: var(--fg-4); text-align: center;
  margin-top: 7px; letter-spacing: .02em; }
.composer-hint:empty { display: none; }

.attachments { display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 14px 0; }
/* Attachments read as things with weight, not chips. A hairline card, the
   name at full contrast, and underneath it the only fact that matters before
   sending: how much of the window this is going to want. */
.att { display: flex; align-items: center; gap: 9px; padding: 7px 8px 7px 10px;
  border: 1px solid var(--line-2); border-radius: 8px; background: none;
  max-width: 300px; min-width: 0; transition: border-color .18s, background .18s; }
.att:hover { border-color: var(--fg-4); background: var(--bg-2); }
.att-ico { display: grid; place-items: center; width: 26px; height: 26px; flex: none;
  border: 1px solid var(--line-2); border-radius: 6px; color: var(--fg-3); }
.att-ico svg { width: 13px; height: 13px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.att-img img { width: 34px; height: 34px; border-radius: 6px; object-fit: cover;
  border: 1px solid var(--line-2); flex: none; }
.att-text { min-width: 0; display: block; }
.att-name { display: block; font-size: 12px; line-height: 1.3; color: var(--fg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.att-meta { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em;
  color: var(--fg-4); margin-top: 2px; white-space: nowrap; }
.att-img .att-name { font-size: 12px; }
.att-x { color: var(--fg-4); padding: 3px; line-height: 0; border-radius: 5px;
  margin-left: auto; flex: none; transition: color .16s; }
.att-x:hover { color: var(--red); }
.att.is-pending .att-ico { color: var(--ember); animation: cmp-pulse 1.3s ease-in-out infinite; }
.att.is-bad { border-color: color-mix(in srgb, var(--red) 45%, var(--line-2)); }
.att.is-bad .att-meta { color: var(--red); }
}

/* --------------------------------------------------------------------------
   inspector
   -------------------------------------------------------------------------- */
@layer components {
.insp-tabs { display: flex; padding: 12px 12px 0; gap: 2px; border-bottom: 1px solid var(--line); }
.insp-tab { flex: 1; padding: 8px 4px 10px; font-size: 11.5px; color: var(--fg-3); position: relative;
  transition: color .18s; border-radius: var(--r-sm) var(--r-sm) 0 0; }
.insp-tab:hover { color: var(--fg-2); }
.insp-tab.is-on { color: var(--fg); }
.insp-tab.is-on::after { content: ""; position: absolute; left: 10%; right: 10%; bottom: -1px; height: 2px;
  border-radius: 2px 2px 0 0; background: var(--ember); }
.insp-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
.insp-pane { display: none; padding: 16px 16px 26px; }
.insp-pane.is-on { display: block; animation: msgIn .3s var(--ease); }
.insp-note { font-size: 11.5px; color: var(--fg-3); line-height: 1.65; margin-bottom: 14px; }
.insp-note code { font-family: var(--mono); font-size: 10.5px; background: var(--bg-2); padding: 1px 5px; border-radius: 4px; color: var(--fg-2); }

.field { margin-bottom: 20px; }
.field label { display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--fg-2); margin-bottom: 8px; }
.field label b { font-family: var(--mono); font-size: 11.5px; font-weight: 500; color: var(--fg);
  font-variant-numeric: tabular-nums; }
.fdesc { font-size: 11px; line-height: 1.6; color: var(--fg-3); margin-top: 7px; }
.fdesc b { color: var(--fg-2); font-family: var(--mono); font-size: 10.5px; font-weight: 500; }
.fwarn { font-size: 11px; line-height: 1.55; color: var(--amber); margin-top: 8px;
  padding: 2px 0 2px 10px; border-left: 2px solid color-mix(in srgb, var(--amber) 45%, transparent); }
.field.row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px; }
.field.row label { margin: 0; } .field.row .fdesc { grid-column: 1/-1; margin-top: 2px; }
.num { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 5px 9px; font-family: var(--mono); font-size: 11.5px; width: 118px; color: var(--fg); }
.num:focus { border-color: var(--line-2); }
select.num { cursor: pointer; }

input[type=range] { width: 100%; height: 18px; -webkit-appearance: none; appearance: none; background: none; cursor: pointer; }
input[type=range]::-webkit-slider-runnable-track { height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, var(--ember) var(--pct,50%), var(--bg-3) var(--pct,50%)); }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 13px; height: 13px; margin-top: -5px;
  border-radius: 50%; background: var(--fg); border: 2px solid var(--bg-1); box-shadow: 0 1px 4px rgba(0,0,0,.4);
  transition: transform .16s var(--spring); }
input[type=range]:hover::-webkit-slider-thumb { transform: scale(1.22); }
input[type=range]:active::-webkit-slider-thumb { background: var(--ember); }

.ctx-field { padding: 0 0 4px; border: none; background: none; }
.ctx-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
.mini-btn { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 5px; border: 1px solid var(--line-2); color: var(--fg-3); transition: all .18s; }
.mini-btn:hover { color: var(--fg); border-color: var(--fg-4); }
.mini-btn.is-on { background: var(--ember); border-color: var(--ember); color: #fff; }
.ctx-meter { font-family: var(--mono); font-size: 10px; color: var(--fg-4); font-variant-numeric: tabular-nums; }
.ctx-meter.hot { color: var(--ember); }

/* ---------------------------------------------------------------- folding
   A fold is a seam in the transcript, not a hole in it. What the fold contains
   is the model's copy and stays out of sight — the turns it stands for are
   right below it, unchanged. All the seam offers is a way back. */
.fold { display: flex; align-items: center; gap: 12px; margin: 22px 0 10px; }
.fold-rule { flex: 1; height: 1px; background: var(--line-2); }
.fold-label { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-4); white-space: nowrap; }
.fold-undo { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-4); border: none; background: none;
  padding: 0; cursor: pointer; white-space: nowrap;
  opacity: 0; translate: -4px 0; transition: opacity .2s, translate .2s var(--spring), color .18s; }
.fold:hover .fold-undo { opacity: 1; translate: 0 0; }
.fold-undo:hover { color: var(--red); }
.fold-undo.tight { margin: 0 0 0 auto; opacity: 1; translate: 0 0; }
/* Folded turns are still readable and still yours — the automatic pass is meant
   to be unobtrusive, so this is a settled-back tint, not a disabled state. */
.msg.is-folded { opacity: .74; transition: opacity .25s; }
.msg.is-folded:hover { opacity: 1; }

/* ------------------------------------------------------ compaction marker */
.cmp { margin: 20px 0; padding: 0 0 0 2px; }
.cmp-row { display: flex; align-items: center; gap: 9px; }
.cmp-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--fg-4); flex: none; }
.cmp.is-live .cmp-dot { background: var(--ember); animation: cmp-pulse 1.4s ease-in-out infinite; }
@keyframes cmp-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
.cmp-head { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--fg-3); white-space: nowrap; }
.cmp-detail { font-size: 11.5px; color: var(--fg-4); min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.cmp-pct { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--ember);
  font-variant-numeric: tabular-nums; }
.cmp-track { height: 1px; margin-top: 9px; background: var(--line); overflow: hidden; }
.cmp-track i { display: block; height: 100%; background: var(--ember); transition: width .3s var(--spring); }
.cmp:not(.is-live) .cmp-track i { background: var(--line-2); }

/* ------------------------------------------------- permission, in-composer
   Raises the composer's upper edge instead of opening over the conversation.
   grid-template-rows 0fr → 1fr animates to the content's real height, so it
   grows to fit whatever the model asked without a magic max-height. */
/* Height is animated from a measured pixel value rather than the usual
   0fr→1fr grid trick. In a container whose own height is indefinite — which the
   composer's is — an fr track has no free space to claim and resolves to zero
   in both states, so the trick silently does nothing here. */
.perm { opacity: 0; transition: opacity .2s; }
.perm.is-on { opacity: 1; }
.perm-inner { height: 0; overflow: hidden; transition: height .34s var(--spring); }
.perm-pad { padding: 14px 16px 12px; border-bottom: 1px solid var(--line); }
.perm-head { display: flex; align-items: center; gap: 8px; }
.perm-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ember);
  flex: none; animation: cmp-pulse 1.4s ease-in-out infinite; }
.perm-what { font-family: var(--mono); font-size: 9.5px; letter-spacing: .11em;
  text-transform: uppercase; color: var(--fg-3); }
.perm-clock { margin-left: auto; font-family: var(--mono); font-size: 10px;
  color: var(--fg-4); font-variant-numeric: tabular-nums; }
.perm-why { margin: 7px 0 0; font-size: 13px; line-height: 1.55; color: var(--fg-2); }
.perm-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 11px; }

/* ------------------------------------------------------------ ask dialog */
.ask { place-self: center; width: min(460px, 92vw); border-radius: 12px; padding: 24px; }
.ask-eyebrow { font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--fg-4); margin-bottom: 9px; }
.ask-title { font-size: 18px; font-weight: 500; line-height: 1.3; letter-spacing: -.01em; margin: 0 0 11px; }
.ask-body { font-size: 13px; line-height: 1.6; color: var(--fg-3); max-height: 52vh; overflow-y: auto; }
.ask-body b { color: var(--fg); font-weight: 500; }
.ask-foot { display: flex; justify-content: flex-end; gap: 9px; margin-top: 22px; }

.tool-list { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.tool-row { display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: start;
  padding: 11px 2px; border: none; border-bottom: 1px solid var(--line); background: none;
  transition: background .2s; }
.tool-row:hover { background: var(--bg-2); }
.tool-row.is-on { background: none; }
.tool-row .tr-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fg-4); margin-top: 6px; transition: background .2s; }
.tool-row.is-on .tr-dot { background: var(--mint); box-shadow: 0 0 0 3px var(--mint-lo); }
.tr-label { font-size: 12.5px; color: var(--fg); display: flex; align-items: center; gap: 7px; }
.tr-hint { font-size: 11px; color: var(--fg-3); line-height: 1.55; margin-top: 3px; }
.tag-danger { font-family: var(--mono); font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--amber); border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
  padding: 1px 5px; border-radius: 3px; }
.switch { width: 32px; height: 18px; border-radius: 99px; background: var(--bg-3); position: relative;
  border: 1px solid var(--line); transition: background .22s var(--ease); flex: none; margin-top: 2px; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--fg-3); transition: transform .24s var(--spring), background .22s; }
.tool-row.is-on .switch { background: var(--mint); border-color: transparent; }
.tool-row.is-on .switch::after { transform: translateX(14px); background: #061410; }

.preset-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.preset { font-size: 11px; padding: 4px 10px; border-radius: 6px; border: 1px solid var(--line);
  color: var(--fg-3); transition: all .18s; }
.preset:hover { color: var(--fg); border-color: var(--line-2); background: var(--bg-2); }
.preset.is-on { color: var(--ember); border-color: color-mix(in srgb, var(--ember) 40%, transparent); background: var(--ember-lo); }
/* fill the panel instead of being hand-resized — the drag handle just meant
   the box was always the wrong size */
.insp-pane[data-pane="system"].is-on {
  display: flex; flex-direction: column; height: 100%; min-height: 0;
}
.sys-area { width: 100%; flex: 1; min-height: 220px; padding: 2px 0 2px 12px; border: none;
  border-left: 1px solid var(--line-2); background: none; font-family: var(--mono); font-size: 11.5px;
  line-height: 1.7; color: var(--fg-2); resize: none; }
.sys-area:focus { border-color: var(--line-2); color: var(--fg); }

.model-detail { font-size: 12px; }
.md-name { font-family: var(--mono); font-size: 12.5px; color: var(--fg); word-break: break-all; margin-bottom: 4px; }
.md-caps { display: flex; flex-wrap: wrap; gap: 5px; margin: 10px 0 16px; }
.md-grid { display: block; margin-bottom: 14px; border-top: 1px solid var(--line); }
.md-cell { display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid var(--line); }
.md-cell span { font-size: 11.5px; color: var(--fg-3); }
.md-cell b { font-family: var(--mono); font-size: 11.5px; font-weight: 500; color: var(--fg);
  font-variant-numeric: tabular-nums; text-align: right; }
.md-sec { margin-bottom: 14px; }
.md-sec h4 { font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--fg-4); margin-bottom: 7px; }
.md-pre { font-family: var(--mono); font-size: 10.8px; line-height: 1.7; color: var(--fg-3); background: none;
  border: none; border-left: 1px solid var(--line-2); padding: 2px 0 2px 12px; max-height: 190px; overflow: auto; white-space: pre-wrap; }
.md-acts { display: flex; gap: 6px; margin-top: 14px; }

.cap { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 4px; border: 1px solid var(--line-2); color: var(--fg-3); cursor: help; }
.cap[data-c="tools"]    { color: var(--mint);   border-color: color-mix(in srgb, var(--mint) 38%, transparent); }
.cap[data-c="vision"]   { color: var(--violet); border-color: color-mix(in srgb, var(--violet) 38%, transparent); }
.cap[data-c="thinking"] { color: var(--amber);  border-color: color-mix(in srgb, var(--amber) 38%, transparent); }
.cap[data-c="cloud"]    { color: var(--ember);  border-color: color-mix(in srgb, var(--ember) 38%, transparent); }
/* The other two modalities. Same family as vision, since they arrive through
   the same projector and mean the same kind of thing: it can take more than text. */
.cap[data-c="audio"]    { color: var(--violet); border-color: color-mix(in srgb, var(--violet) 38%, transparent); }
.cap[data-c="video"]    { color: var(--violet); border-color: color-mix(in srgb, var(--violet) 38%, transparent); }
}

/* --------------------------------------------------------------------------
   overlays
   -------------------------------------------------------------------------- */
@layer overlays {
.overlay { position: fixed; inset: 0; z-index: 200; display: grid; }
.overlay[hidden] { display: none; }
.ov-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.52);
  backdrop-filter: blur(9px); animation: fade .28s var(--ease); }
@keyframes fade { from { opacity: 0; } }
.ov-panel { position: relative; z-index: 1; background: var(--bg-1); border: 1px solid var(--line-2);
  box-shadow: var(--shadow-2); animation: panelIn .38s var(--ease); }
@keyframes panelIn { from { opacity: 0; transform: translateY(14px) scale(.985); } }

.gal { place-self: center; width: min(1060px, 92vw); max-height: 86vh; border-radius: 12px;
  display: flex; flex-direction: column; overflow: hidden; }
.gal-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 22px 24px 14px; }
.gal-eyebrow { font-family: var(--mono); font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--fg-4); }
.gal-title { font-size: 26px; letter-spacing: -.03em; margin-top: 5px; font-weight: 400; }
.gal-controls { display: flex; gap: 10px; padding: 0 24px 12px; align-items: center; flex-wrap: wrap; }
.filters { display: flex; gap: 5px; }
.filt { font-size: 11.5px; padding: 6px 12px; border-radius: 6px; border: 1px solid var(--line);
  color: var(--fg-3); transition: all .18s; }
.filt:hover { color: var(--fg); border-color: var(--line-2); }
.filt.is-on { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.gal-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; padding: 0 24px 12px;
  font-size: 11px; color: var(--fg-3); line-height: 1.9; }
.gal-legend b { color: var(--fg-2); font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase; }
.gal-legend .mc-warm { display: inline-block; }
/* The list ends flush against the footer, so a list that continues below looks
   exactly like a list that has finished — you find out it scrolls only by
   trying it, which reads as a bug rather than as more content. The mask fades
   the last few pixels while there is anything left to reach, and resolves to
   nothing once you are at the end, so a list that really is complete stays
   crisp. `scroll-timeline` isn't needed for this — the fade is applied
   unconditionally and the scrollbar's absence is what tells you it fits. */
.gal-grid { flex: 1; min-height: 0; overflow-y: auto; padding: 0 24px 8px;
  --fade: 22px;
  mask-image: linear-gradient(to bottom, #000 calc(100% - var(--fade)), transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--fade)), transparent 100%); }
/* Nothing to scroll to: no fade. Set by JS, which is the only thing that can
   compare scrollHeight to clientHeight. */
.gal-grid.at-end, .gal-grid.fits { mask-image: none; -webkit-mask-image: none; }
/* the footer supplies the closing rule — a second hairline under the last row doubles up */
.mrow:last-child { border-bottom: none; }
.gal-none { color: var(--fg-3); font-size: 12.5px; padding: 26px 2px; }
.gal-none code { font-family: var(--mono); font-size: 11px; background: var(--bg-2); padding: 2px 6px; border-radius: 5px; color: var(--fg-2); }

/* a plain aligned table — no cards, no nested boxes, one hairline per row */
/* header and rows are separate grid containers, so every column except the name
   must be a fixed width — an `auto` track resolves differently in each and the
   columns drift apart. */
.mr-hd, .mrow {
  display: grid; align-items: center;
  /* The capability column is sized to hold every chip a model can earn, not
     the number it happened to have when this was written. At 186px a fourth
     chip pushed the first one under `overflow: hidden` and "vision" rendered
     as "N" — the capability was detected correctly and then silently cropped
     away. Five chips (vision, audio, video, tools, thinking) measure ~277px. */
  grid-template-columns: 10px minmax(0,1fr) 62px 74px 68px 74px 282px 26px;
  gap: 14px; padding: 0 10px;
}
.mr-hd {
  height: 26px; font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--fg-4); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--bg-1); z-index: 2;
}
.mr-hd .mr-num, .mrow .mr-num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.mrow {
  width: 100%; text-align: left; height: 46px; border-bottom: 1px solid var(--line);
  color: var(--fg-2); transition: background .14s, color .14s; position: relative;
}
.mrow:hover { background: var(--bg-2); color: var(--fg); }
.mrow.is-on { background: color-mix(in srgb, var(--ember) 7%, transparent); color: var(--fg); }
.mrow.is-on::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 2px; background: var(--ember); }
.mr-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-4); justify-self: center; }
.mr-dot.on { background: var(--mint); box-shadow: 0 0 0 3px var(--mint-lo); }
.mr-id { min-width: 0; }
.mr-name { display: block; font-size: 13px; line-height: 1.25; color: var(--fg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mr-sub { display: block; font-size: 10.5px; color: var(--fg-4); line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mrow .mr-num { font-size: 11.5px; color: var(--fg-2); }
.mrow .mr-num.dim { color: var(--fg-4); }
.mc-warm { width: 6px; height: 6px; border-radius: 50%; background: var(--mint); box-shadow: 0 0 0 3px var(--mint-lo); }
.mr-caps { display: flex; gap: 4px; justify-content: flex-end; overflow: hidden; }
/* Never squashed to fit. A chip narrowed to half its text is worse than one
   that runs out of room, because it still looks like a word. */
.mr-caps .cap { flex: 0 0 auto; }
.mc-del { opacity: 0; color: var(--fg-4); transition: opacity .14s, color .14s; justify-self: center; }
.mrow:hover .mc-del { opacity: 1; }
.mc-del:hover { color: var(--red); }
.mc-del svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }

.gal-foot { border-top: 1px solid var(--line); padding: 12px 24px 12px; background: var(--bg-1); }
.pull-row { display: flex; gap: 8px; }
.pull-row input { flex: 1; background: var(--bg-2); border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 15px; font-size: 12.5px; color: var(--fg); font-family: var(--mono); }
.pull-row input:focus { border-color: var(--line-2); }
/* reserves nothing while there's no pull in progress */
.pull-status { font-family: var(--mono); font-size: 10.5px; color: var(--fg-3); margin-top: 9px; }
.pull-status:empty { display: none; }
.pull-bar { height: 2px; background: var(--bg-3); border-radius: 2px; margin-top: 7px; overflow: hidden; }
.pull-bar i { display: block; height: 100%; background: var(--ember); transition: width .3s var(--ease); }

.pal { place-self: start center; margin-top: 11vh; width: min(660px, 93vw); border-radius: 12px;
  overflow: hidden; display: flex; flex-direction: column; max-height: 74vh; }
.pal-head { display: flex; align-items: center; gap: 10px; padding: 0 20px; flex: none;
  background: var(--bg-1); border-bottom: 1px solid var(--line); position: relative; z-index: 2; }
.pal-crumb {
  flex: none; font-size: 11.5px; padding: 3px 8px; border-radius: 5px;
  background: var(--ember-lo); color: var(--ember); border: 1px solid color-mix(in srgb, var(--ember) 30%, transparent);
  transition: all .16s;
}
.pal-crumb::after { content: " ×"; opacity: .6; }
.pal-crumb:hover { background: var(--ember); color: #fff; border-color: var(--ember); }
.pal input {
  flex: 1; min-width: 0; padding: 18px 0; font-size: 15px; color: var(--fg); background: none;
}
.pal-chev { color: var(--fg-4); font-size: 17px; line-height: 1; flex: none; margin-left: 2px; }
.pal-item:hover .pal-chev, .pal-item.cursor .pal-chev { color: var(--ember); }
.pal-foot { flex: none; display: flex; gap: 16px; padding: 9px 20px; border-top: 1px solid var(--line);
  background: var(--bg-1); font-size: 10.5px; color: var(--fg-4); }
.pal-foot span { display: inline-flex; align-items: center; gap: 5px; }
.pal-foot kbd { font-family: var(--mono); font-size: 9.5px; line-height: 1; color: var(--fg-3);
  background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 4px; padding: 3px 5px; }
.pal input:focus-visible { outline: none; }          /* the panel itself is the focus affordance */
.pal input::placeholder { color: var(--fg-4); }
.pal-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; scroll-padding: 30px 0 8px; }

.pal-group {
  position: sticky; top: 0; z-index: 1; background: var(--bg-1);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--fg-4); padding: 9px 12px 6px;
}
.pal-group:first-child { padding-top: 4px; }

.pal-item {
  display: grid; grid-template-columns: 26px minmax(0,1fr) auto; align-items: center; gap: 12px;
  width: 100%; text-align: left; padding: 9px 12px; border-radius: var(--r-sm);
  color: var(--fg-2); transition: background .13s var(--ease), color .13s;
}
.pal-item:hover, .pal-item.cursor { background: var(--bg-3); color: var(--fg); }
.pal-ico { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 6px;
  background: var(--bg-2); border: 1px solid var(--line); color: var(--fg-3); transition: all .13s; }
.pal-ico svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round; }
.pal-item:hover .pal-ico, .pal-item.cursor .pal-ico { color: var(--ember); border-color: color-mix(in srgb, var(--ember) 34%, transparent); }
.pal-text { min-width: 0; display: block; }
.pal-t { display: block; font-size: 13px; line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pal-d { display: block; font-size: 11px; line-height: 1.4; color: var(--fg-4); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pal-item:hover .pal-d, .pal-item.cursor .pal-d { color: var(--fg-3); }

/* keybinds stay out of the way until the row is under the cursor — set as plain
   letterspaced mono, not boxed key-caps */
.pal-keys { display: flex; gap: 5px; align-items: center; flex: none;
  opacity: 0; translate: 5px 0; transition: opacity .18s var(--ease), translate .18s var(--ease); }
.pal-item:hover .pal-keys, .pal-item.cursor .pal-keys { opacity: 1; translate: 0 0; }
.pal-keys kbd {
  font-family: var(--mono); font-size: 10.5px; line-height: 1; color: var(--fg-3);
  letter-spacing: .06em; background: none; border: none; padding: 0;
}
.pal-item.cursor .pal-keys kbd { color: var(--ember); }

/* ---- tooltip ------------------------------------------------------------- */
/* small, single-line-ish, and unobtrusive — a hint, not a panel */
.tip {
  position: fixed; z-index: 9998; pointer-events: none; max-width: 220px;
  padding: 5px 8px; border-radius: 5px; background: var(--bg-3);
  border: 1px solid var(--line); box-shadow: var(--shadow-1);
  font-size: 11px; line-height: 1.45; color: var(--fg-2); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  opacity: 0; translate: 0 3px; transition: opacity .13s var(--ease), translate .13s var(--ease);
}
.tip.wrap { white-space: normal; }
.tip.on { opacity: 1; translate: 0 0; }
.tip b { color: var(--fg); font-weight: 500; }
.tip .tip-k { display: block; margin-top: 4px; font-family: var(--mono); font-size: 10px;
  letter-spacing: .1em; color: var(--fg-4); }
.pal-empty { padding: 30px; text-align: center; color: var(--fg-4); font-size: 12.5px; }

.toasts { position: fixed; bottom: 20px; right: 20px; z-index: 400; display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.toast { display: flex; align-items: center; gap: 9px; padding: 10px 14px; border-radius: 8px;
  background: var(--bg-2); border: 1px solid var(--line-2); box-shadow: var(--shadow-1);
  font-size: 12.5px; color: var(--fg); animation: toastIn .4s var(--spring); max-width: 420px; }
.toast.out { animation: toastOut .3s var(--ease) forwards; }
.toast-undo { font: inherit; font-weight: 500; color: var(--ember); background: none; border: none;
  padding: 0 0 0 6px; margin-left: 2px; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px; flex: none; }
.toast-undo:hover { color: var(--fg); }
.toast i { width: 6px; height: 6px; border-radius: 50%; background: var(--mint); flex: none; }
.toast.bad i { background: var(--red); }
@keyframes toastIn { from { opacity: 0; transform: translateX(28px); } }
@keyframes toastOut { to { opacity: 0; transform: translateX(28px); } }
}

/* --------------------------------------------------------------------------
   prose (rendered markdown)
   -------------------------------------------------------------------------- */
@layer components {
.prose { font-size: 14.5px; line-height: 1.75; color: var(--fg); overflow-wrap: break-word; }
.prose > *:first-child { margin-top: 0; }
.prose > *:last-child { margin-bottom: 0; }
.prose p { margin: 0 0 1.05em; }

/* Hold running text to a readable measure (~68 characters). Code blocks and
   tables are exempt — they need the width. */
.prose > p, .prose > ul, .prose > ol, .prose > blockquote,
.prose > h1, .prose > h2, .prose > h3, .prose > h4 { max-width: 68ch; }
.prose h1 { font-size: 1.42em; margin: 1.5em 0 .5em; letter-spacing: -.024em; }
.prose h2 { font-size: 1.22em; margin: 1.45em 0 .45em; letter-spacing: -.02em; }
.prose h3 { font-size: 1.06em; margin: 1.35em 0 .4em; }
.prose h4 { font-size: .96em; margin: 1.25em 0 .35em; color: var(--fg-2); }
.prose ul, .prose ol { margin: 0 0 .95em; padding-left: 1.35em; }
.prose li { margin-bottom: .3em; }
.prose li::marker { color: var(--fg-4); }
.prose ul ul, .prose ol ol, .prose ul ol, .prose ol ul { margin-bottom: .2em; margin-top: .3em; }
.prose blockquote { margin: 0 0 .95em; padding: .15em 0 .15em 1.05em; border-left: 2px solid var(--line-2); color: var(--fg-2); }
.prose hr { border: none; border-top: 1px solid var(--line); margin: 1.7em 0; }
.prose a { color: var(--ember); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--ember) 34%, transparent); }
.prose a:hover { border-bottom-color: var(--ember); }
.prose strong { font-weight: 600; }
.prose code { font-family: var(--mono); font-size: .875em; background: var(--bg-2);
  border: 1px solid var(--line); padding: .1em .38em; border-radius: 5px; color: var(--fg); }
/* hollow tables: horizontal rules only, no cell boxes, no zebra fill */
.prose table { border-collapse: collapse; width: 100%; margin: 0 0 1.2em; font-size: .9em; display: block; overflow-x: auto; }
.prose th, .prose td { border: none; border-bottom: 1px solid var(--line); padding: 8px 16px 8px 0; text-align: left; }
.prose th { font-family: var(--mono); font-weight: 500; font-size: .82em; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-4); border-bottom-color: var(--line-2); }
.prose tbody tr:last-child td { border-bottom: none; }
.prose img { max-width: 100%; border-radius: var(--r-sm); }

/* hollow code: a rule down the side, the language and copy as plain marginalia */
.codeblock { margin: 0 0 1.2em; }
.cb-head { display: flex; align-items: center; gap: 10px; padding: 0 0 6px; }
.cb-lang { font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--fg-4); }
.cb-copy { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; color: var(--fg-4);
  margin-left: auto; opacity: 0; transition: color .15s, opacity .15s; }
.codeblock:hover .cb-copy { opacity: 1; }
.cb-copy:hover { color: var(--fg); }
.cb-copy svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.codeblock pre { margin: 0; padding: 2px 0 2px 14px; overflow-x: auto; border-left: 1px solid var(--line-2); }
.codeblock code { font-family: var(--mono); font-size: 12.2px; line-height: 1.7; background: none;
  border: none; padding: 0; color: var(--fg-2); }
.prose code { background: none; border: none; padding: 0 .1em; color: var(--fg);
  font-family: var(--mono); font-size: .88em; }
.prose code::before, .prose code::after { content: "`"; color: var(--fg-4); }
.prose pre code::before, .prose pre code::after { content: none; }

/* deliberately restrained: four hues, everything else inherits the body colour */
.tk-kw  { color: #E9967F; }
.tk-str { color: #94C89A; }
.tk-num { color: #D9B57C; }
.tk-com { color: var(--fg-4); font-style: italic; }
.tk-fn  { color: #8FB6E8; }
:root[data-theme="light"] {
  --tk-kw: #B03A18;
}
:root[data-theme="light"] .tk-kw  { color: #B03A18; }
:root[data-theme="light"] .tk-str { color: #2C6E3F; }
:root[data-theme="light"] .tk-num { color: #8A5A00; }
:root[data-theme="light"] .tk-fn  { color: #2A5DA8; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .stream { scroll-behavior: auto; }
}


/* ---- live-run indicators ------------------------------------------------- */
@layer components {
.run-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ember);
  margin-right: 7px; vertical-align: 1px; animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.8); } }
.convo.busy .convo-t { color: var(--fg); }
.convo.busy .convo-m span:first-child { color: var(--ember); }
.rail-btn.busy::after { content: ""; position: absolute; top: 6px; right: 6px; width: 5px; height: 5px;
  border-radius: 50%; background: var(--ember); animation: pulse 1.4s ease-in-out infinite; }
}

/* ==========================================================================
   Phone. Unlayered on purpose: these must beat every @layer rule above,
   including the inline --side-w / --insp-w the panel code sets.
   ========================================================================== */
@media (max-width: 780px) {
  .app { grid-template-columns: 1fr !important; }

  /* rail becomes a bottom bar — thumbs are at the bottom of the phone */
  .rail {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; height: 54px;
    flex-direction: row; align-items: center; justify-content: space-around;
    gap: 0; padding: 0 6px env(safe-area-inset-bottom); z-index: 60;
    border-right: none; border-top: 1px solid var(--line);
    background: color-mix(in srgb, var(--bg) 92%, transparent); backdrop-filter: blur(14px);
  }
  .rail-logo, .rail-spacer { display: none; }
  .rail-group { flex-direction: row; margin: 0; gap: 0; flex: 1; justify-content: space-around; }
  .rail-btn { width: 46px; height: 42px; }
  .rail-btn svg { width: 19px; height: 19px; }
  .rail-btn.is-on::before { left: 50%; top: -1px; translate: -50% 0; width: 16px; height: 2px; }

  /* panels slide over the conversation instead of squeezing it */
  .sidebar, .inspector {
    position: fixed; top: 0; bottom: 54px; width: min(88vw, 360px); z-index: 55;
    box-shadow: var(--shadow-2); transition: transform .3s var(--ease);
  }
  .sidebar { left: 0; transform: translateX(-102%); }
  .inspector { right: 0; transform: translateX(102%); }
  .app.force-side .sidebar, .app.force-insp .inspector { transform: none; }
  .app.force-side::after, .app.force-insp::after {
    content: ""; position: fixed; inset: 0 0 54px 0; z-index: 50;
    background: color-mix(in srgb, var(--bg) 55%, transparent); backdrop-filter: blur(2px);
  }
  .reveal-tab, .resize-handle { display: none; }

  .main { padding-bottom: 54px; }
  .thread { padding: 18px 16px 10px; gap: 20px; }
  .composer-wrap { padding: 0 12px 10px; }

  /* the label rail costs too much width on a phone — stack it */
  .msg { grid-template-columns: 1fr; gap: 6px; }
  .msg-rail { padding: 0; }
  /* Stacked, the rail is a full-width row above the message, so the label
     belongs at its start. Anchoring right would strand it across the page. */
  .msg-rail { justify-content: flex-start; }
  .msg-acts { opacity: 1; }              /* no hover on touch */
  .act { padding: 6px 10px; }

  .top { padding: 9px 12px; gap: 8px; }
  .top-title { display: none; }
  .model-pill { max-width: 60vw; }
  .prose > p, .prose > ul, .prose > ol, .prose > blockquote,
  .prose > h1, .prose > h2, .prose > h3, .prose > h4 { max-width: none; }
  .stats { gap: 10px; }

  /* overlays go full-bleed */
  .gal { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; }
  .gal-head { padding: 16px 16px 10px; }
  .gal-title { font-size: 20px; }
  .gal-controls, .gal-legend { padding-left: 16px; padding-right: 16px; }
  .gal-grid { padding: 0 16px 12px; }
  .gal-foot { padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); }
  /* the full spec table can't fit — keep the name, the size and the badges.
     Hidden by explicit class: :nth-of-type counts by tag and every cell here
     is a <span>, so it hides the wrong ones. */
  .mr-hd, .mrow { grid-template-columns: 10px minmax(0,1fr) 56px; gap: 10px; height: auto; }
  .c-disk, .c-ctx, .c-vram, .c-del { display: none; }
  .mrow { padding: 9px 10px; align-items: center; }
  .mr-hd { padding-top: 2px; padding-bottom: 6px; }
  /* badges drop under the name rather than fighting for width */
  .mr-caps { grid-column: 2 / -1; justify-content: flex-start; margin-top: 5px; overflow: visible; }
  .mr-name { white-space: normal; overflow-wrap: anywhere; }

  .pal { width: 100vw; max-width: 100vw; margin-top: 0; height: 100dvh; max-height: 100dvh; border-radius: 0; }
  .pal-list { max-height: none; }

  .lb-img { padding: 16px 12px 4px; }
  .shot.multi { grid-template-columns: 1fr; }
  .toasts { left: 12px; right: 12px; bottom: 66px; align-items: stretch; }
  .toast { max-width: none; }
  .tip { display: none; }                /* tooltips are meaningless on touch */
}

@media (max-width: 780px) and (display-mode: browser) {
  /* iOS zooms the page when a font under 16px gets focus */
  .composer textarea, .pal input, .side-search input, .pull-row input,
  .ident-edit, .num, .sys-area { font-size: 16px; }
}

/* ==========================================================================
   Light mode, softened.
   Colour alone didn't do it — what reads as "hard" in light mode is geometry
   and edge contrast: crisp 1px rules everywhere, flat fills, and shadows that
   sit right on the element. Dark mode hides all of that because there's less
   luminance separation to begin with. So: lift the panels off the page with a
   diffuse warm shadow instead of a border, round the surfaces a touch more,
   and let the rules fade rather than stop.
   Unlayered so it beats the @layer rules above.
   ========================================================================== */
:root[data-theme="light"] {
  --line:   rgba(72,60,42,.085);
  --line-2: rgba(72,60,42,.145);
}
:root[data-theme="light"] body { background:
  radial-gradient(1200px 600px at 50% -10%, #FFFDFA 0%, transparent 60%), var(--bg); }

/* panels: no hard border, a soft warm lift instead */
:root[data-theme="light"] .sidebar { border-right: none; box-shadow: 1px 0 0 rgba(72,60,42,.05), 6px 0 20px -18px rgba(90,70,45,.5); }
:root[data-theme="light"] .inspector { border-left: none; box-shadow: -1px 0 0 rgba(72,60,42,.05), -6px 0 20px -18px rgba(90,70,45,.5); }
:root[data-theme="light"] .rail { border-right: none; box-shadow: 1px 0 0 rgba(72,60,42,.045); }
:root[data-theme="light"] .top { border-bottom: none; box-shadow: 0 1px 0 rgba(72,60,42,.05), 0 8px 18px -20px rgba(90,70,45,.55); }

/* floating surfaces: rounder, softer, no crisp outline */
:root[data-theme="light"] .composer {
  border-color: transparent;
  border-radius: 18px;
  background: #FFFEFC;
  box-shadow: 0 0 0 1px rgba(72,60,42,.06), 0 2px 4px -2px rgba(90,70,45,.10), 0 10px 26px -16px rgba(90,70,45,.30);
}
:root[data-theme="light"] .composer:focus-within {
  border-color: transparent;
  box-shadow: 0 0 0 1px rgba(72,60,42,.12), 0 3px 8px -3px rgba(90,70,45,.14), 0 14px 32px -16px rgba(90,70,45,.34);
}
:root[data-theme="light"] .ov-panel {
  border-color: transparent; border-radius: 16px;
  box-shadow: 0 0 0 1px rgba(72,60,42,.07), 0 30px 70px -28px rgba(80,62,40,.34), 0 6px 16px -10px rgba(80,62,40,.14);
}
:root[data-theme="light"] .tip, :root[data-theme="light"] .toast {
  border-color: transparent; border-radius: 9px; background: #FFFEFC;
  box-shadow: 0 0 0 1px rgba(72,60,42,.07), 0 8px 22px -12px rgba(80,62,40,.3);
}
:root[data-theme="light"] .ov-backdrop { background: rgba(28,24,20,.34); }

/* rules fade out at the ends instead of stopping dead */
:root[data-theme="light"] .mrow, :root[data-theme="light"] .mr-hd,
:root[data-theme="light"] .tool-row, :root[data-theme="light"] .starter,
:root[data-theme="light"] .md-cell {
  border-bottom-color: transparent;
  border-image: linear-gradient(90deg, transparent, rgba(72,60,42,.13) 12%, rgba(72,60,42,.13) 88%, transparent) 1;
  border-image-slice: 1;
  border-bottom-width: 1px; border-bottom-style: solid;
}

/* fills get a hint of warmth so they don't read as grey holes */
:root[data-theme="light"] .side-search,
:root[data-theme="light"] .num,
:root[data-theme="light"] .pull-row input { background: #F4F2EE; border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(72,60,42,.07); }
:root[data-theme="light"] .side-search:focus-within,
:root[data-theme="light"] .num:focus { box-shadow: inset 0 0 0 1px rgba(72,60,42,.16); }

/* softer selected/hover states */
:root[data-theme="light"] .convo.is-on { background: none; }
:root[data-theme="light"] .mrow.is-on { background: rgba(188,56,12,.05); }
:root[data-theme="light"] .mrow:hover, :root[data-theme="light"] .pal-item:hover,
:root[data-theme="light"] .pal-item.cursor { background: rgba(72,60,42,.045); }
:root[data-theme="light"] .codeblock pre { border-left-color: rgba(72,60,42,.13); }
:root[data-theme="light"] .diff { border-top-color: rgba(72,60,42,.09); border-bottom-color: rgba(72,60,42,.09); }
:root[data-theme="light"] .d-add { background: rgba(10,115,87,.07); }
:root[data-theme="light"] .d-del { background: rgba(185,43,43,.06); }

/* Text that runs straight into a tool call needs air — the prose ends and the
   tool line begins with nothing between them. */
.msg-body > .prose + .tool-card,
.msg-body > .prose + .think-block,
.msg-body > .prose + .shot-wrap { margin-top: 14px; }
.msg-body > .tool-card + .prose { margin-top: 12px; }

/* ---- math ---------------------------------------------------------------- */
.math { font-family: "Cambria Math", "Latin Modern Math", Georgia, serif;
  font-size: 1.06em; white-space: nowrap; }
.math.block { display: block; text-align: center; margin: 1.1em 0; font-size: 1.16em;
  white-space: normal; overflow-x: auto; }
.math sub, .math sup { font-size: .68em; }
.math .mup { font-family: var(--sans); font-size: .92em; }

/* stacked fraction */
.frac { display: inline-flex; flex-direction: column; vertical-align: -0.52em;
  text-align: center; margin: 0 .18em; }
.frac .fnum { display: block; padding: 0 .3em; border-bottom: 1px solid currentColor; line-height: 1.35; }
.frac .fden { display: block; padding: 0 .3em; line-height: 1.35; }

/* radical with an overbar so the operand is visibly under the root */
.sqrt { display: inline-flex; align-items: flex-start; }
.sqrt .srad { font-size: 1.1em; line-height: 1; }
.sqrt .sund { border-top: 1px solid currentColor; padding: .1em .22em 0 .12em; margin-top: .12em; }
.sqrt .sroot { font-size: .6em; margin-right: -.42em; align-self: flex-start; }

/* big operator with limits above and below */
.bigop { display: inline-flex; flex-direction: column; align-items: center;
  vertical-align: -0.42em; margin: 0 .2em; line-height: 1.05; }
.bigop .bsym { font-size: 1.5em; line-height: .9; }
.bigop sub, .bigop sup { font-size: .58em; }

/* a tool result that got compacted for future turns */
.tool-compact { font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em;
  color: var(--mint); flex: none; opacity: .85; cursor: help; }

/* The end-of-stream re-render replays the entry animation on every message,
   which reads as the whole chat flickering. Only animate what is genuinely new. */
.msg.settled { animation: none; }

/* dragging a file over the window at all */
body.dropping .composer { border-color: var(--ember); border-style: dashed; }
/* Sits directly above the composer rather than at a fixed offset from the
   bottom, which landed it on top of the streaming hint. bottom:100% anchors it
   to the composer's own top edge, so it clears whatever height that is. */
body.dropping .composer-wrap::before {
  content: "Drop to attach";
  position: absolute; bottom: 100%; left: 0; right: 0; margin-bottom: 10px;
  pointer-events: none; text-align: center;
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ember);
}
body.dropping .composer-hint { visibility: hidden; }

.mc-del.busy { opacity: .4; pointer-events: none; }

/* ------------------------------------------------- model loading progress
   Weights arriving on the card. A hairline along the bottom edge of the model
   pill, filling left to right, with the real percentage in mono beside it. No
   spinner and no pulse — the bar only moves when the disk actually moves, and
   a stalled read should look stalled rather than reassuring. */
.model-pill { position: relative; }
.mp-pct { font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em;
  color: var(--ember); font-variant-numeric: tabular-nums; white-space: nowrap;
  max-width: 0; overflow: hidden; opacity: 0;
  transition: max-width .3s var(--spring), opacity .2s; }
.model-pill.is-loading .mp-pct { max-width: 110px; opacity: 1; margin-left: 2px; }
.mp-load { position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  overflow: hidden; border-radius: 0 0 var(--r) var(--r);
  opacity: 0; transition: opacity .25s; }
.model-pill.is-loading .mp-load { opacity: 1; }
.mp-load i { display: block; height: 100%; width: 100%; background: var(--ember);
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s cubic-bezier(.22,.61,.36,1); }
/* the leading edge glows just enough to read as motion without animating */
.mp-load i::after { content: ""; position: absolute; top: 0; bottom: 0; width: 26px;
  right: 0; background: linear-gradient(90deg, transparent, var(--ember));
  filter: blur(3px); opacity: .7; }
.model-pill.is-loading { border-color: color-mix(in srgb, var(--ember) 38%, var(--line-2)); }

/* ------------------------------------------------- grouped tool calls
   A run of the same tool is still a tool row — same hairline language, same
   spacing, no card around it. The only additions are a count and the combined
   time. Boxing it made a group look like a different kind of object. */
.tgroup { margin: 0; }
.tg-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 2px 0;
  text-align: left; background: none; border: none; cursor: pointer;
  color: var(--fg-3); transition: color .18s; }
.tg-head:hover { color: var(--fg); }
.tg-head .tool-ico { color: var(--mint); }
.tg-head .tool-name { font-family: var(--mono); font-size: 11.5px; color: var(--fg-2); flex: none; }
.tg-head:hover .tool-name { color: var(--fg); }
.tg-count { font-family: var(--mono); font-size: 10.5px; color: var(--fg-4);
  flex: none; letter-spacing: .02em; }
.tgroup .chev { margin-left: 4px; flex: none; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; opacity: .8;
  transition: transform .25s var(--ease); }
.tgroup.open .chev { transform: rotate(180deg); }
.tg-body { display: none; margin: 4px 0 8px; padding-left: 14px;
  border-left: 1px solid var(--line); }
.tgroup.open .tg-body { display: block; }

/* ------------------------------------------------------- context ring
   How full the window is, next to the send button, because that is the moment
   you would want to know. Neutral until it matters: amber past 75%, red past
   90%, where folding starts. */
.ctx-ring { position: relative; display: grid; place-items: center; width: 26px; height: 26px;
  border: none; background: none; padding: 0; cursor: pointer; flex: none; }
.ctx-ring svg { transform: rotate(-90deg); overflow: visible; }
.cr-track { fill: none; stroke: var(--line-2); stroke-width: 3; }
.cr-fill { fill: none; stroke: var(--fg-4); stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 81.68; stroke-dashoffset: 81.68;
  transition: stroke-dashoffset .45s var(--ease), stroke .3s; }
.ctx-ring[data-level="warn"] .cr-fill { stroke: #E0A030; }
.ctx-ring[data-level="hot"]  .cr-fill { stroke: var(--red); }
.cr-pct { position: absolute; font-family: var(--mono); font-size: 8px; letter-spacing: -.02em;
  color: var(--fg-4); opacity: 0; transition: opacity .2s; pointer-events: none; }
.ctx-ring:hover .cr-pct { opacity: 1; }
.ctx-ring[data-level="hot"] .cr-pct { opacity: 1; color: var(--red); }

/* --------------------------------------------------- context breakdown
   The window as one rule across the top, then what fills it. Same language as
   everything else: hairlines, mono numerals, the accent doing the work. */
.cs { display: flex; height: 3px; border-radius: 2px; overflow: hidden; margin: 4px 0 9px;
  background: var(--line); }
.cs-seg { display: block; height: 100%; background: var(--ember); }
.cs-seg[data-k="1"] { background: color-mix(in srgb, var(--ember) 72%, var(--bg)); }
.cs-seg[data-k="2"] { background: color-mix(in srgb, var(--ember) 50%, var(--bg)); }
.cs-seg[data-k="3"] { background: color-mix(in srgb, var(--ember) 34%, var(--bg)); }
.cs-seg[data-k="4"] { background: color-mix(in srgb, var(--ember) 22%, var(--bg)); }
.cs-seg[data-k="5"] { background: color-mix(in srgb, var(--ember) 14%, var(--bg)); }
.cs-free { display: block; height: 100%; background: none; }
.cs-legend { display: flex; justify-content: space-between; font-family: var(--mono);
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-4);
  margin-bottom: 14px; }
.cs-legend b { color: var(--fg-2); font-weight: 500; }

.cb { display: flex; flex-direction: column; }
.cb-row { display: grid; grid-template-columns: 6px 1fr auto 48px; align-items: center;
  gap: 11px; padding: 8px 0; border-top: 1px solid var(--line); }
.cb-row:first-child { border-top: none; }
.cb-key { width: 6px; height: 6px; border-radius: 50%; background: var(--ember); }
.cb-key[data-k="1"] { background: color-mix(in srgb, var(--ember) 72%, var(--bg)); }
.cb-key[data-k="2"] { background: color-mix(in srgb, var(--ember) 50%, var(--bg)); }
.cb-key[data-k="3"] { background: color-mix(in srgb, var(--ember) 34%, var(--bg)); }
.cb-key[data-k="4"] { background: color-mix(in srgb, var(--ember) 22%, var(--bg)); }
.cb-key[data-k="5"] { background: color-mix(in srgb, var(--ember) 14%, var(--bg)); }
.cb-label { font-size: 13px; color: var(--fg-2); }
.cb-n { font-family: var(--mono); font-size: 11.5px; color: var(--fg); font-variant-numeric: tabular-nums; }
.cb-pct { font-family: var(--mono); font-size: 10.5px; color: var(--fg-4);
  text-align: right; font-variant-numeric: tabular-nums; }
.cb-note { font-size: 11.5px; line-height: 1.55; color: var(--fg-4); margin: 15px 0 0; }

/* ------------------------------------------------------- slash commands
   Grows out of the top of the composer, like the permission prompt — the list
   belongs where you are already typing, not in an overlay across the page. */
.slash { border-bottom: 1px solid var(--line); }
.slash[hidden] { display: none; }
.slash-list { max-height: 268px; overflow-y: auto; padding: 6px; }
.slash-item { display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 7px 9px; border-radius: 7px; text-align: left; background: none;
  border: none; cursor: pointer; color: var(--fg-3); transition: background .14s, color .14s; }
.slash-item.cursor { background: var(--bg-3); color: var(--fg); }
.slash-ico { width: 24px; height: 24px; flex: none; display: grid; place-items: center;
  border: 1px solid var(--line-2); border-radius: 6px; color: var(--fg-4); }
.slash-ico svg { width: 12px; height: 12px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.slash-item.cursor .slash-ico { color: var(--ember);
  border-color: color-mix(in srgb, var(--ember) 34%, transparent); }
.slash-text { min-width: 0; flex: 1; }
.slash-name { display: block; font-family: var(--mono); font-size: 12px; color: var(--fg-2); }
.slash-item.cursor .slash-name { color: var(--fg); }
.slash-name em { font-style: normal; color: var(--ember); }
.slash-desc { display: block; font-size: 11px; color: var(--fg-4); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slash-foot { display: flex; gap: 14px; padding: 7px 14px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 9.5px; color: var(--fg-4); }
.slash-foot kbd { font-family: var(--mono); font-size: 9px; color: var(--fg-3);
  border: 1px solid var(--line-2); border-radius: 3px; padding: 1px 4px; margin-right: 3px; }
.slash-empty { padding: 16px; text-align: center; font-size: 12px; color: var(--fg-4); }

/* while what you have typed is a real command */
.composer.is-cmd { border-color: color-mix(in srgb, var(--ember) 42%, var(--line-2)); }
.composer.is-cmd textarea { font-family: var(--mono); color: var(--ember); }

/* ---- refused from outside ------------------------------------------------ */
/* Covers the app rather than sitting beside it: nothing behind this works, and
   a half-usable interface behind a warning invites people to try anyway. */
.gate { position: fixed; inset: 0; z-index: 900; display: grid; place-items: center;
  background: color-mix(in srgb, var(--bg-0) 88%, transparent); backdrop-filter: blur(7px); }
.gate-card { max-width: 460px; padding: 30px 32px; border: 1px solid var(--line);
  border-radius: 14px; background: var(--bg-1); box-shadow: 0 20px 60px rgba(0,0,0,.28); }
.gate-eyebrow { font-family: var(--mono); font-size: 10px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ember); }
.gate-card h2 { font-size: 22px; font-weight: 400; letter-spacing: -.02em; margin: 8px 0 10px; }
.gate-card p { color: var(--fg-3); font-size: 13.5px; line-height: 1.65; margin: 0 0 18px; }
.gate-label { font-family: var(--mono); font-size: 10px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--fg-4); margin-bottom: 7px; }
.gate-id { display: block; width: 100%; font-family: var(--mono); font-size: 15px;
  letter-spacing: .06em; padding: 13px 14px; border: 1px dashed var(--line);
  border-radius: 9px; background: var(--bg-2); color: var(--fg); cursor: pointer; }
.gate-id:hover { border-color: var(--ember); color: var(--ember); }
.gate-foot { font-size: 12px; color: var(--fg-4); margin: 16px 0 0; }
.gate-foot code { font-family: var(--mono); font-size: 11px; background: var(--bg-2);
  padding: 2px 6px; border-radius: 5px; color: var(--fg-3); }
