:root {
  --bg: #f7f6f3; --panel: #ffffff; --text: #1d1d1f; --muted: #6b6b70;
  --border: #e3e1dc; --accent: #3d5afe; --accent-text: #ffffff;
  --mine: #e8ecff; --theirs: #ffffff; --error: #c62828; --code: #f0efeb;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #141416; --panel: #1c1c1f; --text: #ececf0; --muted: #9a9aa3;
    --border: #2c2c31; --accent: #7c8dff; --accent-text: #0e0e10;
    --mine: #262b45; --theirs: #1f1f23; --error: #ff7a7a; --code: #26262b;
  }
}
:root[data-theme="dark"] {
  --bg: #141416; --panel: #1c1c1f; --text: #ececf0; --muted: #9a9aa3;
  --border: #2c2c31; --accent: #7c8dff; --accent-text: #0e0e10;
  --mine: #262b45; --theirs: #1f1f23; --error: #ff7a7a; --code: #26262b;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg); color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
  display: flex; flex-direction: column;
}
header {
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  border-bottom: 1px solid var(--border); background: var(--panel);
}
header h1 { font-size: 17px; margin: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
header button { white-space: nowrap; }
.spacer { flex: 1; }
#who { color: var(--muted); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
button, .button {
  font: inherit; font-size: 13px; color: var(--text); background: transparent;
  border: 1px solid var(--border); border-radius: 8px; padding: 5px 10px;
  cursor: pointer; text-decoration: none;
}
button:hover, .button:hover { border-color: var(--muted); }
.primary { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
a.primary { display: inline-block; padding: 9px 16px; border-radius: 8px; text-decoration: none; }
.icon { border: none; font-size: 17px; padding: 2px 6px; }
.muted { color: var(--muted); }
a { color: var(--accent); }
#notice { padding: 8px 16px; background: var(--mine); font-size: 14px; }
#notice.error { color: var(--error); }
#signin { flex: 1; display: grid; place-items: center; padding: 16px; }
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 28px; max-width: 420px; }
.card h2 { margin-top: 0; font-size: 20px; }
#app { flex: 1; display: flex; min-height: 0; }
#sidebar {
  width: 260px; border-right: 1px solid var(--border); background: var(--panel);
  padding: 12px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px;
}
#conversations { list-style: none; margin: 0; padding: 0; }
#conversations li {
  padding: 7px 9px; border-radius: 8px; cursor: pointer; font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#conversations li:hover { background: var(--bg); }
#conversations li.active { background: var(--mine); }
#chat { flex: 1; display: flex; flex-direction: column; min-width: 0; }
#messages { flex: 1; overflow-y: auto; padding: 20px 16px; display: flex; flex-direction: column; gap: 12px; }
.msg { max-width: min(720px, 88%); padding: 10px 14px; border-radius: 14px; border: 1px solid var(--border); overflow-wrap: anywhere; }
.msg.user { align-self: flex-end; background: var(--mine); border-color: transparent; }
.msg.assistant { align-self: flex-start; background: var(--theirs); }
.msg p { margin: 0 0 8px; } .msg p:last-child { margin-bottom: 0; }
.msg pre { background: var(--code); padding: 10px; border-radius: 8px; overflow-x: auto; font-size: 13px; }
.msg code { background: var(--code); padding: 1px 4px; border-radius: 4px; font-size: 13px; }
.msg pre code { padding: 0; background: none; }
.msg .error { color: var(--error); font-size: 13px; margin-top: 6px; }
.tool { font-size: 12px; color: var(--muted); margin: 0 0 6px; }
.empty { margin: auto; color: var(--muted); text-align: center; }
.cursor::after { content: "▍"; animation: blink 1s steps(2) infinite; color: var(--muted); }
@keyframes blink { 50% { opacity: 0; } }
#composer { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--border); background: var(--panel); }
#input {
  flex: 1; resize: none; font: inherit; color: var(--text); background: var(--bg);
  border: 1px solid var(--border); border-radius: 10px; padding: 9px 12px; max-height: 200px;
}
#input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
/* Every view but the chat is a page in here — one scroller, so a long diff
   or a 3 000-line document scrolls the way a document does. */
#page { flex: 1; overflow: auto; min-height: 0; }
.page { padding: 16px 20px 40px; max-width: 1100px; font-size: 14px; }
.page h2 { font-size: 19px; margin: 0 0 4px; }
.page h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); margin: 22px 0 6px; }
.page table { border-collapse: collapse; width: 100%; }
.page > table td, .status table td { padding: 3px 8px 3px 0; vertical-align: top; }
.status table td:first-child { color: var(--muted); white-space: nowrap; width: 1%; }
.pagehead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
#nav { display: flex; gap: 2px; margin-left: 6px; }
#nav a { font-size: 13px; color: var(--muted); text-decoration: none;
  padding: 4px 9px; border-radius: 8px; }
#nav a:hover { background: var(--bg); color: var(--text); }
#nav a.on { background: var(--mine); color: var(--text); }
.bar { height: 6px; background: var(--border); border-radius: 3px; overflow: hidden; margin-top: 3px; }
.bar > span { display: block; height: 100%; background: var(--accent); }
.bad { color: var(--error); }
.bar.big { height: 8px; border-radius: 4px; margin: 10px 0 6px; }
.bar.big > span { transition: width .8s ease; }
.small { font-size: 13px; }
a.primary.disabled { opacity: .45; pointer-events: none; }
@media (max-width: 720px) {
  #sidebar { position: fixed; top: 49px; bottom: 0; left: 0; z-index: 5; transform: translateX(-100%); transition: transform .2s; }
  #sidebar.open { transform: none; box-shadow: 0 0 24px rgb(0 0 0 / .2); }
  #who { display: none; }
  .msg { max-width: 94%; }
}

/* Pictures the agent sends, and the picture strip in the status panel. */
.pic { margin: 8px 0 0; }
.pic img { max-width: 100%; border-radius: 8px; display: block; }
.pic figcaption { font-size: 12px; opacity: .7; margin-top: 4px; }
.pics { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.pics a { display: block; }
.pics img { height: 64px; width: 64px; object-fit: cover; border-radius: 6px; }

/* What was retrieved into the prompt, under each answer. */
.ctx { margin-top: 8px; font-size: 12px; opacity: .75; }
.ctx summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; }
.ctx summary::-webkit-details-marker { display: none; }
.ctx .bar { flex: 1; max-width: 120px; height: 4px; border-radius: 2px; background: rgba(128,128,128,.25); }
.ctx .bar i { display: block; height: 100%; border-radius: 2px; background: currentColor; opacity: .5; }
.ctx .ms { opacity: .6; }
.ctxbody { margin-top: 6px; }
.ctxtable { width: 100%; border-collapse: collapse; }
.ctxtable td { padding: 1px 6px 1px 0; vertical-align: top; }
/* One line a row: the panel is a list to scan, not prose to read. */
.ctxtable .ref { max-width: 0; width: 100%; }
.ctxtable .ref span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctxtable .why { opacity: .6; white-space: nowrap; }
.ctxtable .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* The channels dialog: every conversation, and what produced each answer. */
.chans { width: 100%; border-collapse: collapse; font-size: 13px; }
.chans th { text-align: left; font-weight: 600; opacity: .6; padding: 2px 8px 6px 0; }
.chans td { padding: 5px 8px 5px 0; border-top: 1px solid var(--line, rgba(128,128,128,.2)); }
.chans tbody tr { cursor: pointer; }
.chans tbody tr:hover { background: rgba(128,128,128,.08); }
.chans .num { text-align: right; font-variant-numeric: tabular-nums; }
.dbglog { display: flex; flex-direction: column; gap: 10px; }
.dbgturn { font-size: 13px; }
.dbgturn.user { opacity: .8; }
.dbgturn.assistant { border-left: 2px solid rgba(128,128,128,.3); padding-left: 10px; }
.dbg { font-size: 12px; margin-top: 4px; opacity: .8; }
.dbg summary { cursor: pointer; }
.dbg pre, .prompt { white-space: pre-wrap; word-break: break-word; font-size: 11px;
  max-height: 340px; overflow: auto; background: rgba(128,128,128,.08);
  padding: 6px; border-radius: 6px; margin: 4px 0; }
.toolcall { margin: 6px 0; }

/* The line under every message, and the panel it opens. */
.msg .meta { font-size: 11px; opacity: .55; margin-top: 6px; font-variant-numeric: tabular-nums; }
.msg.user .meta { text-align: right; }
.detail > summary { font-size: 11px; opacity: .6; cursor: pointer; margin-top: 2px; }
.round { border-left: 2px solid rgba(128,128,128,.25); padding-left: 8px; margin: 8px 0; }
.roundhead { display: flex; align-items: center; gap: 6px; font-size: 12px; margin-bottom: 4px; }
.roundhead .spacer { flex: 1; }
.rates td { font-size: 11px; }

/* ── the state explorer ─────────────────────────────────────────────────── */

.roots { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; margin: 12px 0; }
.rootcard { display: block; padding: 12px 14px; border: 1px solid var(--border);
  border-radius: 12px; background: var(--panel); text-decoration: none; color: var(--text); }
.rootcard:hover { border-color: var(--accent); }
.rootcard .nums { font-size: 12px; margin-top: 6px; font-variant-numeric: tabular-nums; }
.rootcard .path { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; }
.badge { font-size: 11px; border: 1px solid var(--border); border-radius: 5px;
  padding: 0 5px; color: var(--muted); vertical-align: 1px; }
.badge.warn { color: var(--error); border-color: currentColor; }
.badge.soft { border-style: dashed; }
.rulelist { padding-left: 22px; margin: 14px 0; }
.rulelist li { margin-bottom: 10px; }
.rulelist li div { color: var(--text); }
.decisions tr.reply td, .decisions tr.comment td { background: var(--mine); }
.decisions tr.stop td:nth-child(3) { color: var(--error); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px;
  text-decoration: none; color: var(--text); }
.chip:hover { border-color: var(--accent); }
.chip.on { background: var(--mine); border-color: transparent; }

.explorer { display: flex; height: 100%; min-height: 0; }
.tree { width: 270px; flex: none; border-right: 1px solid var(--border);
  background: var(--panel); overflow: auto; padding-bottom: 20px; font-size: 13px; }
.treehead { display: flex; gap: 8px; align-items: center; padding: 8px 10px;
  border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--panel); }
.treehead .up { font-size: 12px; text-decoration: none; }
.titem { display: flex; gap: 6px; align-items: center; text-decoration: none;
  color: var(--text); padding: 3px 8px 3px calc(8px + var(--depth) * 13px); }
.titem:hover { background: var(--bg); }
.titem.active { background: var(--mine); }
.titem .tname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.titem .tsize { margin-left: auto; font-size: 11px; font-variant-numeric: tabular-nums;
  white-space: nowrap; flex: none; }
.pane { flex: 1; min-width: 0; overflow: auto; padding: 14px 18px 40px; }
.crumbs { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.crumbs a { text-decoration: none; }
.filehead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.filehead h2 { margin: 0; font-size: 18px; overflow-wrap: anywhere; }
.listing { width: 100%; border-collapse: collapse; font-size: 13px; }
.listing th { text-align: left; font-weight: 600; color: var(--muted); padding: 2px 8px 6px 0; }
.listing td { padding: 4px 8px 4px 0; border-top: 1px solid var(--border); vertical-align: top; }
.listing td a { text-decoration: none; }
.listing .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.costs tr.total td { font-weight: 600; border-top: 2px solid var(--border); }
.costs { max-width: 760px; overflow-x: auto; display: block; }
.sha { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.add { color: #2e7d32; } .del { color: var(--error); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .add { color: #7bc67e; } }
.lastchange { border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px;
  margin: 10px 0; background: var(--panel); }
.clabel { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.why { white-space: pre-wrap; overflow-wrap: anywhere; }

/* A file's contents. `pre` rather than wrapping, so the gutter's line numbers
   stay opposite the lines they count. */
.filebody { margin-top: 10px; }
.code { display: flex; border: 1px solid var(--border); border-radius: 10px;
  overflow: auto; background: var(--code); max-height: 70vh; }
.code pre { margin: 0; padding: 8px 0; font-size: 12.5px; line-height: 1.5; }
.code .gutter { padding-left: 10px; padding-right: 10px; color: var(--muted);
  text-align: right; user-select: none; border-right: 1px solid var(--border);
  position: sticky; left: 0; background: var(--code); }
.code .body { padding-left: 12px; padding-right: 12px; flex: 1; }
.code.wrap .body { white-space: pre-wrap; overflow-wrap: anywhere; }
.tabs { display: flex; gap: 4px; margin-bottom: 8px; }
.tab { font-size: 12px; }
.tab.active { background: var(--mine); border-color: transparent; }
.reading { max-width: 780px; }
.reading img { max-width: 100%; border-radius: 8px; }
.reading pre { background: var(--code); padding: 10px; border-radius: 8px; overflow-x: auto; }
.reading code { background: var(--code); padding: 1px 4px; border-radius: 4px; }
.reading blockquote { border-left: 3px solid var(--border); margin: 8px 0; padding-left: 10px; color: var(--muted); }

.t-key { color: #8250df; } .t-str { color: #0a6e44; } .t-num { color: #0550ae; }
.t-lit { color: #953800; } .t-punct { opacity: .55; } .t-comment { opacity: .55; font-style: italic; }
.t-head { color: #0550ae; font-weight: 600; } .t-bold { font-weight: 600; }
.t-em { font-style: italic; } .t-code { color: #0a6e44; } .t-link { color: var(--accent); }
.t-fence, .t-bullet, .t-quote { opacity: .6; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --t-key: #d2a8ff; --t-str: #7ee787; --t-num: #79c0ff; --t-lit: #ffa657; --t-head: #79c0ff;
  }
  :root:not([data-theme="light"]) .t-key { color: #d2a8ff; }
  :root:not([data-theme="light"]) .t-str, :root:not([data-theme="light"]) .t-code { color: #7ee787; }
  :root:not([data-theme="light"]) .t-num { color: #79c0ff; }
  :root:not([data-theme="light"]) .t-lit { color: #ffa657; }
  :root:not([data-theme="light"]) .t-head { color: #79c0ff; }
}
.dline { display: block; }
.dline.dadd { background: rgba(46, 160, 67, .15); }
.dline.ddel { background: rgba(248, 81, 73, .15); }
.dline.dhunk { color: var(--accent); }
.dline.dhead { opacity: .6; }

/* A .jsonl is read a record at a time. */
.jsonl { display: flex; flex-direction: column; gap: 2px; }
.jsonrow { display: flex; gap: 8px; border-top: 1px solid var(--border); padding: 3px 0; font-size: 13px; }
.jsonrow .n { color: var(--muted); font-size: 11px; min-width: 2.2em; text-align: right;
  font-variant-numeric: tabular-nums; padding-top: 2px; }
.jsonrow .jval { min-width: 0; flex: 1; }
.jnode > summary { cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jkids { padding-left: 14px; border-left: 1px solid var(--border); margin-left: 3px; }
.jrow { overflow-wrap: anywhere; }
.jlong > summary { cursor: pointer; }
.jlong pre { white-space: pre-wrap; overflow-wrap: anywhere; background: var(--code);
  padding: 8px; border-radius: 8px; max-height: 400px; overflow: auto; }
.picfile img { max-width: 100%; max-height: 60vh; border-radius: 10px; border: 1px solid var(--border); }
.kv { margin-top: 10px; }
.kv td { padding: 3px 10px 3px 0; vertical-align: top; }
.kv td:first-child { color: var(--muted); white-space: nowrap; width: 1%; }
ul.plain { margin: 0; padding-left: 16px; }
.filehistory { margin-top: 18px; }
.filehistory > summary { cursor: pointer; font-size: 13px; color: var(--muted); }

/* ── history ────────────────────────────────────────────────────────────── */

.filters { display: flex; gap: 8px; align-items: center; margin: 10px 0; flex-wrap: wrap; }
.filters input { font: inherit; font-size: 13px; padding: 6px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel); color: var(--text); min-width: 260px; }
.commits { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.commit { display: block; text-decoration: none; color: var(--text); padding: 9px 12px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
.commit:hover { border-color: var(--accent); }
.chead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chead h2 { margin: 0; }
.commit .subject { font-weight: 600; }
.commit .why { font-size: 13px; color: var(--muted); margin: 4px 0 0;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.cfoot code { font-size: 11px; background: var(--code); padding: 0 4px; border-radius: 4px; }
.kind { font-size: 11px; border-radius: 999px; padding: 1px 8px; background: var(--code); white-space: nowrap; }
.whybox { border-left: 3px solid var(--accent); padding: 6px 0 6px 10px; margin: 10px 0; }
.facts caption { text-align: left; }
.filediff { margin: 10px 0; border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; }
.filediff > summary { cursor: pointer; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.filediff > summary a { text-decoration: none; }
.pager { display: flex; gap: 8px; }

@media (max-width: 560px) {
  /* At this width the navigation is worth more than the name: the name is
     also the page title, and the tabs are the only way between views. */
  header h1 { display: none; }
}
@media (max-width: 760px) {
  .explorer { flex-direction: column; }
  .tree { width: auto; max-height: 34vh; border-right: none; border-bottom: 1px solid var(--border); }
  #nav a { padding: 4px 6px; }
}

/* ── search ───────────────────────────────────────────────────────────── */
.search #sbox { flex: 1; min-width: 260px; font-size: 15px; }
.sgroup { margin: 18px 0 0; }
.sgroup h3 { display: flex; align-items: baseline; gap: 8px; }
.hits { list-style: none; margin: 0; padding: 0; }
.hit { border-top: 1px solid var(--border); padding: 8px 0; }
.hit-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.hit-head a { text-decoration: none; font-weight: 600; }
.hit-text { margin: 4px 0 0; font-size: 13px; line-height: 1.55;
            overflow-wrap: anywhere; }
/* A highlight has to survive both themes, so it is a tint of the accent
   rather than the yellow a browser paints by default. */
.hit-text mark, .around mark {
  background: var(--mine); color: inherit; border-radius: 3px; padding: 0 2px;
}
.hit-more { margin-top: 4px; }
.linky { background: none; border: 0; padding: 0; font: inherit; font-size: 12px;
         color: var(--accent); cursor: pointer; text-decoration: underline; }
.around { margin: 6px 0 0; padding-left: 20px; font-size: 13px; }
.around li { padding: 2px 0; }
.shelp { margin-top: 14px; font-size: 13px; }
.shelp table td { padding: 2px 14px 2px 0; }
.shelp code { background: var(--code); border-radius: 4px; padding: 1px 5px; }

/* A run in progress: a bar with a phase under it. `indeterminate` is for a
   phase whose total nobody knows yet — it animates rather than claiming a
   percentage that was never measured. */
.run { margin: 2px 0 6px; }
.run .bar.big { margin: 4px 0 4px; }
.run .bar.indeterminate > span {
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: sweep 1.4s linear infinite;
}
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* Lost contact with the server. Loud on purpose: the page underneath is
   still rendered and still looks right, and that is exactly the problem. */
#offline {
  padding: 9px 16px; font-size: 13px; line-height: 1.5;
  background: var(--error); color: #fff;
}
#offline a { color: #fff; text-decoration: underline; }

/* ── voice ──────────────────────────────────────────────────────────────
   The microphone and the "read it aloud" switch, beside the composer. Both
   are plain buttons whose state is one class, because the state a person
   needs is only ever "is it listening" and "will I hear the answer". */
#voice-controls { display: flex; align-items: flex-end; gap: 2px; }
#voice-controls button { align-self: center; line-height: 1; }
#voice-controls button.on { background: var(--mine); border-radius: 6px; }
#voice-controls button:disabled { opacity: 0.35; cursor: not-allowed; }

/* Listening: a ring that follows the level, so it is visible that the
   microphone is hearing *you* and not the room. `--level` is set from the
   meter on every frame; a ring rather than a moving bar because it has to
   read at a glance from across a room. */
.mic.on {
  box-shadow: 0 0 0 calc(2px + var(--level, 0) * 7px) var(--mine);
  border-radius: 50%;
}
.mic.working { animation: micwork 1s ease-in-out infinite; }
@keyframes micwork { 50% { opacity: 0.4; } }

/* A question that was spoken rather than typed: the words are what the model
   understood, which is not always what was said, so the bubble says so. */
.msg.user.spoken { border-left: 2px solid var(--accent); }
