:root {
  --bg: #fbfbfa; --panel: #ffffff; --ink: #1c1b1a; --muted: #6b6864;
  --line: #e4e2de; --accent: #3b5bdb; --ok: #2f9e44; --warn: #e8a13a;
  --bad: #d9480f; --code: #f4f3f1;
  --radius: 10px;
  /* How wide the conversation may grow. Full width: a fixed 880px left two
     inches of empty margin either side on a large display. */
  --content-max: 100%;
  color-scheme: light dark;
}
:root:not([data-theme="light"]) {
  @media (prefers-color-scheme: dark) {}
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #17181a; --panel: #1f2023; --ink: #e8e6e3; --muted: #9a958e;
    --line: #2e3034; --accent: #7a95ff; --ok: #51cf66; --warn: #ffc078;
    --bad: #ff8787; --code: #26282c;
  }
}
* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 14px/1.55 ui-sans-serif, -apple-system, "Segoe UI", system-ui, sans-serif;
}
#app { display: flex; flex-direction: column; height: 100vh; }
#app[hidden] { display: none; }

#signin { min-height: 100vh; display: grid; place-items: center; padding: 16px; }
#signin[hidden] { display: none; }
#signin form {
  width: min(420px, 100%); background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 24px; display: flex; flex-direction: column; gap: 12px;
}
#signin h1 { margin: 0; font-size: 20px; }
#signin p { margin: 0; color: var(--muted); }
#signin pre { margin: 0; padding: 8px 10px; background: var(--code); border-radius: 6px; overflow-x: auto; }
#signin-code {
  font: 600 22px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.12em;
  text-align: center; text-transform: uppercase; padding: 10px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
}
#signin button {
  font: inherit; font-weight: 600; padding: 10px; border: 0; border-radius: 8px;
  background: var(--accent); color: #fff; cursor: pointer;
}
#signin button:disabled { opacity: 0.6; cursor: default; }
#signin button.secondary { background: none; color: var(--accent); border: 1px solid var(--line); }
#signin button[hidden] { display: none; }
#signin .signin-error { color: var(--bad); }
#signin .signin-note { font-size: 12.5px; }

header {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--panel);
}
.brand { font-weight: 650; letter-spacing: -0.01em; }
nav { margin-left: auto; display: flex; gap: 4px; }
nav button {
  background: none; border: 1px solid transparent; color: var(--muted);
  padding: 5px 11px; border-radius: 7px; cursor: pointer; font: inherit;
}
nav button:hover { color: var(--ink); }
nav button.active { background: var(--bg); border-color: var(--line); color: var(--ink); }

.pill { font-size: 12px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--line); }
.pill.ok { color: var(--ok); } .pill.warn { color: var(--warn); } .pill.bad { color: var(--bad); }

/* A `display` rule beats the `hidden` attribute -- the same trap the document
   panel fell into. The header nav is a fallback, not a second navigation. */
header nav[hidden] { display: none; }

/* Rail beside everything else, header above both. */
.shell { flex: 1; display: flex; min-height: 0; overflow: hidden; }
main { flex: 1; overflow: hidden; min-width: 0; }
/* One view fills the main area now, and the workbench manages its own
   scrolling -- `overflow: auto` here would give the page a second scrollbar. */
.tab { display: none; height: 100%; overflow: hidden; flex-direction: column; }
.tab.active { display: flex; flex-direction: column; }

/* chat */
.transcript { flex: 1; overflow-y: auto; padding: 18px 16px 6px; }
/* The last reply ends close to what is under it: the working line or the box. */
.transcript > .turn:last-child { margin-bottom: 4px; }
.turn { max-width: var(--content-max); margin: 0 auto 20px; }
.turn .meta {
  font-size: 12px; color: var(--muted); margin-bottom: 6px;
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
}
.turn .who { font-weight: 600; color: var(--ink); }
.turn .body { white-space: pre-wrap; word-break: break-word; }

/* Agent prose, rendered from markdown. Spacing is tight on purpose: this is
   a conversation, not a document, and a heading's usual margins would push
   the answer off the screen it is answering on. */
.md { white-space: normal; line-height: 1.5; }
.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md p { margin: 0 0 8px; }
.md h1, .md h2, .md h3, .md h4, .md h5, .md h6 {
  margin: 14px 0 6px; line-height: 1.3; font-weight: 600; color: var(--ink);
}
.md h1 { font-size: 1.3em; }
.md h2 { font-size: 1.15em; }
.md h3 { font-size: 1.05em; }
.md h4, .md h5, .md h6 { font-size: 1em; }
.md ul, .md ol { margin: 0 0 8px; padding-left: 22px; }
.md li { margin: 2px 0; }
.md li > ul, .md li > ol, .md li > p { margin: 2px 0; }
.md code {
  font-family: ui-monospace, monospace; font-size: 0.9em;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 4px; padding: 0 4px;
}
.md pre.md-code {
  margin: 0 0 10px; padding: 10px 12px; overflow-x: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  white-space: pre; line-height: 1.45;
}
.md pre.md-code code { background: none; border: 0; padding: 0; font-size: 12.5px; }
.md blockquote {
  margin: 0 0 8px; padding: 2px 0 2px 12px;
  border-left: 3px solid var(--line); color: var(--muted);
}
.md hr { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }
.md a { color: var(--accent, #58a6ff); text-decoration: none; }
.md a:hover { text-decoration: underline; }
.md .md-table { overflow-x: auto; margin: 0 0 10px; }
/* Words break at spaces here, never mid-word: a column squeezed until "2696"
   splits in two is worse than a table that scrolls sideways. */
.md table { border-collapse: collapse; font-size: 0.95em; word-break: normal; overflow-wrap: normal; }
.md th { white-space: nowrap; }
.md th, .md td {
  border: 1px solid var(--line); padding: 5px 10px; text-align: left; vertical-align: top;
}
.md th { background: var(--panel); font-weight: 600; }
/*
 * Who said what, at a glance: you on the right in a solid blue bubble, as
 * iMessage does; agents on the left, full width -- their replies carry tables
 * and code that a bubble would squeeze -- under a clear edge. Automated
 * prompts sit centred and quiet between them.
 */
.turn.user { display: flex; flex-direction: column; align-items: flex-end; }
.turn.user .body {
  background: #1f7aec; color: #fff; border: 0;
  border-radius: 18px 18px 4px 18px; padding: 9px 14px;
  max-width: min(75%, 1100px); white-space: normal;
}
.turn.user .body.md a { color: #fff; text-decoration: underline; }
.turn.user .body.md code { background: rgba(255,255,255,.18); border-color: transparent; color: #fff; }
.turn.user .body.md pre.md-code { background: rgba(0,0,0,.22); border-color: transparent; }
.turn.user .body.md pre.md-code code { background: none; }
.turn.user .body.md th, .turn.user .body.md td { border-color: rgba(255,255,255,.35); }
.turn.user .body.md th { background: rgba(255,255,255,.12); }
.turn.agent { border-left: 3px solid var(--accent); padding-left: 12px; }
.turn.agent .meta .who { color: var(--accent); }

.turn.auto { display: flex; flex-direction: column; align-items: center; margin: 4px auto 14px; }
.turn.auto .autohead {
  display: flex; gap: 6px; align-items: baseline; max-width: 100%;
  background: var(--code); border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 12px; font: inherit; font-size: 12.5px; color: var(--muted); cursor: pointer;
}
.turn.auto .autohead:hover { color: var(--ink); }
.turn.auto .autowhat { color: var(--ink); font-weight: 500; white-space: nowrap; }
.turn.auto .autosum { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.turn.auto .autobody {
  width: 100%; margin-top: 8px; padding: 10px 14px; border-radius: var(--radius);
  background: var(--panel); border: 1px dashed var(--line); white-space: normal;
}
.tool {
  font-size: 12.5px; color: var(--muted); border-left: 2px solid var(--line);
  padding: 2px 0 2px 10px; margin: 6px 0; font-family: ui-monospace, monospace;
}
.tool.bad { color: var(--bad); border-color: var(--bad); }
.err { color: var(--bad); }
.warnline { color: var(--warn); font-size: 12.5px; }

.pending {
  max-width: var(--content-max); margin: 0 auto 12px; padding: 12px 14px;
  border: 1px solid var(--warn); border-radius: var(--radius); background: var(--panel);
}
.pending button { margin-right: 8px; }

form#composer { border-top: 1px solid var(--line); background: var(--panel); padding: 10px 16px 14px; }
/*
 * Composer: the box, then a quiet strip of settings under it.
 *
 * The strip is deliberately understated -- borderless, muted, small. These
 * are six real choices, but they are chosen rarely and read constantly, and
 * chrome that competes with the conversation for attention loses either way.
 */
.controls {
  display: flex; gap: 2px; flex-wrap: wrap; align-items: center;
  max-width: var(--content-max); margin: 5px auto 0; padding: 0 2px;
}
.controls select {
  background: none; border: 1px solid transparent; color: var(--muted);
  font-size: 12px; padding: 3px 4px; border-radius: 6px; cursor: pointer;
  max-width: 190px;
}
.controls select:hover { color: var(--fg); background: var(--panel); }
.controls select:focus-visible { border-color: var(--accent); outline: none; }

/*
 * The composer's row, scoped.
 *
 * Unscoped, this centred every `.row` on the page at 880px and bottom-aligned
 * it -- which is why the file tree sat in the middle of its own panel with
 * its carets hanging off the baseline.
 */
#composer .row {
  display: flex; gap: 8px; max-width: var(--content-max); margin: 0 auto; align-items: flex-end;
}
/* Grows with what is typed instead of reserving three rows for one line. */
#prompt {
  resize: none; overflow-y: auto; max-height: 40vh; min-height: 0;
  padding: 10px 12px; line-height: 1.45;
}
/*
 * Folder picker.
 *
 * Opens upward: it hangs off a control at the bottom of the window, and a
 * menu that drops below the viewport is a menu you have to scroll to use.
 */
.folderwrap { position: relative; display: inline-flex; }
.folderwrap[hidden] { display: none; }
.folderbtn {
  background: none; border: 1px solid transparent; color: var(--muted);
  font-size: 12px; padding: 3px 6px; border-radius: 6px; cursor: pointer;
  max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.folderbtn:hover { color: var(--fg); background: var(--panel); }
/* A folder open in restricted mode says so where the folder is named. */
.folderbtn.restricted::after { content: ' · restricted'; color: var(--warn, #d29922); }
.folderbtn[aria-expanded="true"] { color: var(--fg); background: var(--panel); }
.folderpop {
  /*
   * Fixed, not absolute: the composer sits inside a panel with
   * `overflow: hidden`, which clipped the menu at the panel's edge. Its
   * coordinates are set when it opens.
   */
  position: fixed; z-index: 40;
  width: 330px; max-height: 340px; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 10px 30px rgb(0 0 0 / 45%);
}
.folderpop[hidden] { display: none; }
.folderpop .head {
  display: flex; gap: 6px; align-items: center; padding: 7px 8px;
  border-bottom: 1px solid var(--line); flex: none;
}
.folderpop .crumb {
  flex: 1; min-width: 0; font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl;
  text-align: left;
}
.folderpop .dirs { overflow-y: auto; flex: 1; padding: 4px 0; }
.folderpop .dirs .row {
  padding: 5px 10px; cursor: pointer; font-size: 12.5px;
  display: flex; gap: 6px; align-items: center;
}
.folderpop .dirs .row:hover { background: var(--bg); }
.folderpop .foot {
  padding: 7px 8px; border-top: 1px solid var(--line); flex: none;
  display: flex; gap: 6px;
}
.folderpop .foot button { flex: 1; padding: 7px; font-size: 12.5px; cursor: pointer; }
.folderpop .foot button.pill { flex: 0 0 auto; }
.folderpop .head button { flex: none; padding: 2px 8px; cursor: pointer; }

/* Offered above the box, because the box is at the bottom of the window. */
.slashmenu {
  max-width: var(--content-max); margin: 0 auto 6px; padding: 4px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 35%);
}
.slashmenu[hidden] { display: none; }
.slashrow {
  padding: 5px 9px; border-radius: 5px; cursor: pointer; font-size: 12.5px;
  font-family: var(--mono, ui-monospace, monospace); color: var(--muted);
}
.slashrow.on, .slashrow:hover { background: var(--bg); color: var(--fg); }

/* Pasted files, shown before they are sent so a mis-paste can be removed. */
.attachments {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-width: var(--content-max); margin: 0 auto 6px; padding: 0 2px;
}
.attachments[hidden] { display: none; }
.attach {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 3px 6px 3px 4px; color: var(--muted); max-width: 220px;
}
.attach img {
  width: 26px; height: 26px; object-fit: cover; border-radius: 4px; flex: none;
}
.attach .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach button {
  flex: none; background: none; border: none; color: var(--muted);
  cursor: pointer; font-size: 14px; line-height: 1; padding: 0 2px;
}
.attach button:hover { color: var(--bad); }
.attach.failed { border-color: var(--bad); color: var(--bad); }

/* Vendor-side notices: quieter than output, louder than nothing. */
.noticeline {
  color: var(--muted); font-size: 12.5px; margin: 4px 0;
  padding-left: 10px; border-left: 2px solid var(--line);
}

/* Reads as one of the settings, not as a form field. */
.toggle {
  display: inline-flex; align-items: center; gap: 4px; font-size: 12px;
  color: var(--muted); cursor: pointer; padding: 3px 6px; border-radius: 6px;
}
.toggle:hover { color: var(--fg); background: var(--panel); }
.toggle input { margin: 0; cursor: pointer; }
.toggle:has(input:checked) { color: var(--fg); }

/* An arrow, not a word: the button is never the thing being read. */
#send, #stop {
  flex: none; width: 38px; height: 38px; padding: 0; font-size: 17px;
  display: flex; align-items: center; justify-content: center;
}
#send[hidden], #stop[hidden] { display: none; }
textarea, input, select {
  font: inherit; color: var(--ink); background: var(--bg);
  border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px;
}
textarea { flex: 1; resize: vertical; }
.check { display: flex; align-items: center; gap: 5px; color: var(--muted); font-size: 13px; }
button {
  font: inherit; cursor: pointer; border-radius: 8px; padding: 8px 16px;
  /* A button reads as one against its panel: its own edge and a lifted fill, not the hairline of a divider. */
  border: 1px solid color-mix(in srgb, var(--ink) 32%, var(--bg)); background: color-mix(in srgb, var(--ink) 9%, var(--bg)); color: var(--ink);
}
button:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 15%, var(--bg)); }
#send { background: var(--accent); color: #fff; border-color: transparent; font-weight: 550; }
button:disabled { opacity: .5; cursor: default; }

/* fleet */
.cards { display: grid; gap: 12px; padding: 16px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; }
.card h3 { margin: 0 0 2px; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.card .sub { color: var(--muted); font-size: 12px; margin-bottom: 10px; }
.bar { height: 7px; background: var(--code); border-radius: 999px; overflow: hidden; margin: 8px 0 4px; }
.bar > i { display: block; height: 100%; background: var(--ok); }
.bar.mid > i { background: var(--warn); } .bar.high > i { background: var(--bad); }
/* A subscription's measured windows: name, bar with a pace mark, percent, reset. */
.pacegrid { display: grid; grid-template-columns: auto minmax(60px, 1fr) auto; gap: 2px 8px; align-items: center; margin: 8px 0 4px; }
.pacegrid > .win { grid-column: 1 / -1; margin: -2px 0 4px; }
.pacegrid .pacebar { margin: 0; position: relative; overflow: visible; }
.pacegrid .pacebar > i { border-radius: 999px; }
.pacebar > b { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: var(--ink); opacity: .55; border-radius: 1px; }
.pacename { font-size: 12px; white-space: nowrap; }
.pacepct { font-size: 12px; font-variant-numeric: tabular-nums; text-align: right; }
.pacepct.warn { color: var(--warn); } .pacepct.err { color: var(--bad); }
.win.warn { color: var(--warn); }
.win { font-size: 12px; color: var(--muted); font-family: ui-monospace, monospace; }

/* lists */
.list { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.item {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 10px 13px; cursor: pointer; display: flex; gap: 12px; align-items: baseline;
}
.item:hover { border-color: var(--accent); }
/* The node strip is informational, not a list of things to click. */
#nodes .item { cursor: default; }
#nodes .item:hover { border-color: var(--line); }
.item .title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dot { width: 8px; height: 8px; border-radius: 999px; background: var(--muted); flex: none; }
.dot.running { background: var(--ok); } .dot.crashed { background: var(--bad); }
.dot.awaiting_permission { background: var(--warn); }
.dot.sched-on { background: var(--accent); } .dot.sched-off { background: transparent; border: 1px solid var(--muted); }

table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 7px 12px; border-bottom: 1px solid var(--line); }
th { color: var(--muted); font-weight: 500; font-size: 12px; }
td.num { text-align: right; font-family: ui-monospace, monospace; }
#usage { padding: 16px; }
/* The subscriptions overview: what a glance from the side panel should answer. */
.ushead { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; flex-wrap: wrap; }
.ushead .ustitle { font-weight: 600; flex: 1 1 8em; min-width: 0; }
.ushead .usstamp { display: block; font-weight: 400; }
.ushead button { padding: 2px 8px; font-size: 12px; flex: none; }
.ussection { margin: 14px 0 6px; font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.ussection:first-child { margin-top: 4px; }
.uspicks { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 8px 10px 6px; }
.uspicks .ussection { margin: 0 0 4px; }
.uspick { display: flex; gap: 10px; align-items: baseline; padding: 2px 0; font-size: 13px; }
.uspickclass { width: 64px; flex: none; color: var(--muted); }
.uspickwho { min-width: 0; overflow-wrap: anywhere; }
.uspickwho .warn { color: var(--warn); }
.uscard { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 8px 10px; margin-bottom: 8px; }
.uscard.down { opacity: .7; }
.uscardhead { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; }
.usmeta { margin: 0 0 2px 14px; }
.usgrid { display: grid; grid-template-columns: auto minmax(40px, 1fr) 2.6em 4.6em; gap: 3px 8px; align-items: center; margin: 6px 0 2px; }
.usgrid .pacebar { margin: 0; position: relative; overflow: visible; }
.usreset { text-align: right; white-space: nowrap; }
.plugin-dialog.wide { width: min(980px, calc(100vw - 32px)); }
.usdetails h4:first-child { margin-top: 0; }
h4 { margin: 22px 0 8px; font-size: 13px; color: var(--muted); font-weight: 600; }

/* permission cards */
.permcard { border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 10px; }
.permcard:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }
.permhead { font-weight: 600; margin-bottom: 2px; }
.permactions { margin-top: 8px; display: flex; gap: 8px; }
.permactions button.ok { background: var(--ok); color: #fff; border-color: transparent; }
pre.diff {
  margin: 8px 0 0; padding: 8px 10px; background: var(--code); border-radius: 8px;
  overflow-x: auto; font: 12.5px/1.45 ui-monospace, monospace; max-height: 320px;
}
pre.diff .dl { white-space: pre; }
pre.diff .add { color: var(--ok); }
pre.diff .del { color: var(--bad); }

/* Stop takes Send's place, at Send's size, while a run is going. */
#stop { background: var(--bad); color: #fff; border-color: transparent; font-size: 15px; line-height: 1; }

.files {
  max-width: var(--content-max); margin: 0 auto 8px; display: flex; gap: 6px;
  flex-wrap: wrap; align-items: center;
}
.files[hidden] { display: none; }
.files .chip {
  font: 12px ui-monospace, monospace; background: var(--code);
  border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px;
}
.filterbar { padding: 16px 16px 0; }
.filterbar input { width: 100%; max-width: 420px; }
/* Under the search box: which conversations, in what state. Quiet, so the box stays the point. */
.filterrow { display: flex; gap: 6px; margin-top: 6px; }
.filterrow .quietselect { max-width: none; padding: 2px 4px; }
#sessions .item.archived .title { color: var(--muted); }
/*
 * Two lines in the narrow explorer: the title has the first to itself, the
 * account, state and any button share the second. On one line the meta text
 * wrapped and squeezed the title out entirely.
 */
#sessions .item { flex-wrap: wrap; row-gap: 2px; align-items: center; }
#sessions .item .title { flex: 1 1 calc(100% - 24px); }
#sessions .item > .win { flex: 1 1 auto; min-width: 0; padding-left: 16px; }
#sessions .item > button { margin-left: auto; }


/* ---------------- open sessions ---------------- */

/*
 * A strip of what is open, not a list of everything that exists.
 *
 * The Sessions tab is the history; this is the handful you are working with
 * right now. Several agents run at once, and flipping between them should cost
 * a click rather than a search.
 */
/* The open tab joins what is below it: a line in the accent runs along the
   strip's foot, under every tab but the open one, which stands 1px lower and
   covers it in the page's own colour -- so the tab and its content read as one
   surface. Drawn as an inset shadow rather than a border, so the open tab can
   cover it without overflowing a strip that scrolls sideways. */
.tabstrip {
  display: flex; gap: 6px; padding: 8px 12px 0; overflow-x: auto;
  box-shadow: inset 0 -1px 0 var(--accent); flex: none;
  /* A scrollbar here sat between the tabs and the line. It still scrolls
     sideways, and the open tab is kept in view. */
  scrollbar-width: none;
}
.tabstrip::-webkit-scrollbar { display: none; }
.tabstrip .stab {
  display: flex; align-items: center; gap: 7px; flex: none;
  padding: 4px 10px; border: 1px solid var(--line); border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--panel); color: var(--muted);
  font-size: 13px; cursor: pointer; max-width: 230px; margin-bottom: 1px;
}
/* Two lines: the title, and under it the machine the conversation runs on,
   small and quiet. The column, not the title, takes the ellipsis. */
.tabstrip .stab .text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.tabstrip .stab .sub {
  font-size: 10px; color: var(--muted); opacity: .8;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabstrip .stab.active .sub { opacity: .7; }
/* The New control has one line; it sits at the foot of the strip with the others. */
.tabstrip .newtab { align-self: flex-end; padding-top: 6px; padding-bottom: 6px; }
.tabstrip .stab:hover { color: var(--fg); }
.tabstrip .stab.active { background: var(--bg); color: var(--fg); border-color: var(--accent); margin-bottom: 0; }
.tabstrip .stab .label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A close control that only appears on the tab you are pointing at: always
   visible, it invites the one click you cannot undo. */
.tabstrip .stab .x { opacity: 0; font-size: 15px; line-height: 1; padding: 0 2px; }
.tabstrip .stab:hover .x, .tabstrip .stab.active .x { opacity: 0.55; }
.tabstrip .stab .x:hover { opacity: 1; color: var(--bad); }
.tabstrip .newtab { color: var(--muted); border-style: dashed; }
/* Stop is destructive in a way close is not, so it reads differently. */
.tabstrip .stab .stop { font-size: 11px; }
.tabstrip .stab .stop:hover { color: var(--bad); opacity: 1; }

button.ghost {
  background: color-mix(in srgb, var(--ink) 7%, transparent); border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent); color: var(--ink);
  border-radius: var(--radius); padding: 3px 10px; font-size: 12px; cursor: pointer;
}
button.ghost:hover { color: var(--bad); border-color: var(--bad); }
button.ghost:disabled { opacity: 0.4; cursor: default; }

/* ---------------- workbench ---------------- */

/*
 * The side panel, then the editor: groups of tabs, split side by side or
 * stacked however they were dragged. The chat is a tab like the rest.
 */
#workbench { display: flex; flex: 1; min-height: 0; overflow: hidden; }

.explorer {
  width: 230px; flex: none; display: flex; flex-direction: column;
  border-right: 1px solid var(--line); min-width: 0;
}
.explorer.collapsed { display: none; }

/*
 * Activity bar.
 *
 * Icons rather than labels because this strip is permanent -- it is the one
 * piece of chrome that never gets to justify its width with content. The
 * active view carries a left accent bar, which is what tells you at a glance
 * whether the panel beside it is the file tree or the changes.
 *
 * Two groups, split by a rule: first the views of the conversation in front
 * of you (its files, changes, agents, terminals), then the views of Bob as a
 * whole (sessions, schedules, fleet, usage, plugins, devices).
 */
.activity {
  flex: none; width: 48px; display: flex; flex-direction: column; align-items: center;
  padding: 6px 0; gap: 2px; border-right: 1px solid var(--line); background: var(--panel);
}
/*
 * Separates the conversation's own views (above) from the ones about all of
 * Bob (below). It was a hairline in --line, which on the panel's background
 * is the same grey as nothing, so nobody could see there were two groups.
 * The muted ink at half strength reads as a rule without competing with the
 * icons.
 */
.actgap {
  width: 30px; height: 2px; border-radius: 1px; background: var(--muted); opacity: .5;
  margin: 8px 0; flex: none;
}
/*
 * Every pane gets the panel's width and scrolls inside it.
 *
 * Fleet and Usage were built for a full window and are dense; in 230px they
 * have to wrap and scroll rather than push the panel wider, or the sash stops
 * meaning anything.
 */
.expane { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
.expane[hidden] { display: none; }
/* Cards stack in a narrow panel instead of sitting in a grid. */
.explorer .cards { grid-template-columns: 1fr; padding: 8px; gap: 8px; }
.explorer .list { padding: 6px 8px; }
.explorer .filterbar { padding: 8px 8px 4px; margin: 0; max-width: none; flex: none; }
.explorer .filterbar input { width: 100%; max-width: none; }
.explorer #usage { padding: 8px; }
.explorer .turn, .explorer .cards, .explorer .list { max-width: none; margin: 0; }
.actbtn {
  position: relative; width: 48px; height: 44px; display: flex;
  align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--muted);
  border-left: 2px solid transparent;
}
.actbtn svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.actbtn:hover { color: var(--fg); }
/* Active means "this view is showing" -- so a collapsed panel shows none. */
.actbtn.active { color: var(--fg); border-left-color: var(--accent); }
.actbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/*
 * Tooltips.
 *
 * Built rather than left to the browser's `title`, which waits about a second
 * and renders as an OS tooltip -- too slow to help someone scanning a column
 * of unlabelled icons, which is exactly when a label is needed.
 */
.actbtn::after {
  content: attr(data-tip);
  position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%);
  background: var(--panel); color: var(--fg); border: 1px solid var(--line);
  padding: 5px 9px; border-radius: 6px; font-size: 12px; white-space: nowrap;
  opacity: 0; pointer-events: none; transition: opacity 90ms ease 120ms;
  box-shadow: 0 6px 18px rgb(0 0 0 / 40%); z-index: 50;
}
.actbtn:hover::after, .actbtn:focus-visible::after { opacity: 1; }
/* Changed-file count, the one number worth carrying on the icon itself. */
.actbadge {
  position: absolute; right: 6px; bottom: 6px; min-width: 15px; height: 15px;
  padding: 0 3px; border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 10px; line-height: 15px; text-align: center; font-weight: 600;
}
.actbadge[hidden] { display: none; }

.extitle {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); padding: 4px 2px;
}
/* Staged and unstaged, each with the action that moves a file between them. */
.changegroup { margin-bottom: 4px; }
.grouphead {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px 4px; font-size: 11px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted);
}
.linkish {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-size: 11px; text-transform: none; letter-spacing: 0; padding: 2px 4px;
}
.linkish:hover { color: var(--accent); text-decoration: underline; }
/* The conversation a watch wakes, inline after "wakes" and left-aligned, not a centered line of its own. */
.watchrow .linkish { display: inline; text-align: left; padding: 0; margin: 0; white-space: normal; }

/* Per-row actions appear on hover: they are for the file under the pointer,
   and showing every one at rest turns a file list into a control panel. */
.rowact {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0 5px; opacity: 0; flex: none;
}
.filetree .row:hover .rowact, .rowact:focus-visible { opacity: 1; }
.rowact:hover { color: var(--fg); }
.rowact.danger:hover { color: var(--bad); }
.filetree .row .name { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }

.commitbox { display: flex; flex-direction: column; gap: 6px; padding: 6px 8px 10px; }
.commitmsg {
  width: 100%; resize: vertical; min-height: 42px; padding: 6px 8px;
  font-size: 12.5px; font-family: inherit;
}
.commitbox button { padding: 6px; font-size: 12.5px; cursor: pointer; }

/* Caret column keeps file and folder names on the same left edge. */
/*
 * Carets, drawn rather than typed.
 *
 * The glyph characters render at wildly different sizes across fonts and were
 * illegible at the size a tree row wants. A rotated border is the same shape
 * at any zoom and turns to point down when the folder opens.
 */
.filetree .caret {
  width: 16px; height: 16px; flex: none; position: relative;
}
.filetree .row.dir > .caret::before {
  content: ''; position: absolute; left: 4px; top: 50%;
  width: 5px; height: 5px;
  border-right: 1.6px solid var(--muted); border-bottom: 1.6px solid var(--muted);
  transform: translateY(-50%) rotate(-45deg);
  transition: transform 90ms ease;
}
.filetree .row.dir.open > .caret::before {
  transform: translate(-1px, -60%) rotate(45deg);
}
.filetree .row:hover .caret::before { border-color: var(--fg); }
.filetree .row { display: flex; align-items: center; gap: 4px; min-width: 0; }
.filetree .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exhead { display: flex; gap: 2px; padding: 6px 8px 0; flex: none; }
.exbtn {
  background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--muted); padding: 5px 9px; font-size: 12.5px; cursor: pointer;
}
.exbtn:hover { color: var(--fg); }
.exbtn.active { color: var(--fg); border-bottom-color: var(--accent); }

.chatpanel {
  flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
}
/* Behind another tab of its group. A `display` rule beats the attribute. */
.chatpanel[hidden] { display: none; }
/* Tabs and the panes they belong to, all of it to the right of the side
   panel so opening the panel moves the whole editor rather than half of it. */
.editorarea { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.editorrow { flex: 1; min-height: 0; display: flex; }

/*
 * Groups and splits.
 *
 * A split lays its members out along its direction, each with its share as
 * flex-grow; a group is a strip of tabs over the one thing it shows. The
 * minimums are on the members, not the split, so a stack of three gets a
 * sliver each rather than one of them nothing.
 */
.psplit { display: flex; flex: 1; min-width: 0; min-height: 0; overflow: hidden; }
.psplit.row { flex-direction: row; }
.psplit.column { flex-direction: column; }
.pgroup {
  display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0;
  overflow: hidden; position: relative;
}
.psplit > .pgroup, .psplit > .psplit { flex: 1 1 0px; }
.gcontent { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; }
.docbox { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.docbox[hidden] { display: none; }
.docview { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; }

/* Where a dragged tab would land: the middle joins the group, an edge splits it. */
.dropzone {
  position: absolute; inset: 0; z-index: 30; pointer-events: none;
  background: rgb(122 149 255 / 18%); border: 1px solid var(--accent);
  transition: inset 80ms ease;
}
.dropzone[hidden] { display: none; }
.dropzone.left { inset: 0 50% 0 0; }
.dropzone.right { inset: 0 0 0 50%; }
.dropzone.top { inset: 0 0 50% 0; }
.dropzone.bottom { inset: 50% 0 0 0; }

/*
 * The divider between two members of a split, in either direction. As with
 * the side panel's, the line is one pixel and the grab is thirteen.
 */
/* Wider and lighter than the side panel's: at one pixel of border grey the
   join between two groups was easy to miss, and a group boundary is a thing
   you need to see to drag. */
.psash { flex: none; background: color-mix(in srgb, var(--muted) 55%, var(--line)); position: relative; z-index: 15; }
.psash.v { width: 3px; cursor: col-resize; }
.psash.h { height: 3px; cursor: row-resize; }
.psash::before { content: ''; position: absolute; }
.psash.v::before { top: 0; bottom: 0; left: -6px; right: -6px; }
.psash.h::before { left: 0; right: 0; top: -6px; bottom: -6px; }
.psash::after { content: ''; position: absolute; background: transparent; transition: background 90ms ease; }
.psash.v::after { top: 0; bottom: 0; left: -1px; right: -1px; }
.psash.h::after { left: 0; right: 0; top: -1px; bottom: -1px; }
.psash:hover::after, .psash.dragging::after, .psash:focus-visible::after { background: var(--accent); }
.psash:hover, .psash.dragging, .psash:focus-visible { background: var(--accent); outline: none; }
body.sashing-row { user-select: none; cursor: row-resize; }
body.near-divider-row, body.near-divider-row * { cursor: row-resize !important; }

.explorer { width: var(--explorer-w, 230px); }

/*
 * Sashes.
 *
 * Four pixels of hit area is too few to grab reliably, so the divider paints
 * one pixel and listens across nine, overhanging its neighbours.
 */
.sash {
  flex: none; width: 1px; background: var(--line); position: relative;
  cursor: col-resize; z-index: 15;
}
/*
 * The grab area, which is much wider than the line.
 *
 * Nine pixels was a consistent target at every height -- measured -- and
 * still too small to point at: the cursor changed back and forth as the hand
 * drifted across the edge. Thirteen is the width at which that stops without
 * swallowing a useful amount of the text beside it.
 */
.sash::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: -6px; right: -6px;
}

/*
 * Widen the LINE on hover too, not just the hit area.
 *
 * An invisible target that is wider than it looks leaves you guessing where
 * it is; this says "here", and says it before the drag rather than after.
 */
.sash::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: -1px; right: -1px;
  background: transparent; transition: background 90ms ease;
}
.sash:hover::after, .sash.dragging::after, .sash:focus-visible::after {
  background: var(--accent);
}
.sash:hover, .sash.dragging, .sash:focus-visible {
  background: var(--accent); outline: none;
}
.sash[hidden] { display: none; }
/* A sash for a panel that is not showing would resize nothing. */
.explorer.collapsed + .sash[data-sash="explorer"] { display: none; }
/* Text selection across a drag turns the whole window blue. */
body.sashing { user-select: none; cursor: col-resize; }

/*
 * Held while the pointer is near a divider, released only once it is well
 * clear. Applied to everything so the cursor does not change as the pointer
 * crosses onto the panel or the editor beside it.
 */
body.near-divider, body.near-divider * { cursor: col-resize !important; }

/* Tabs reorder by dragging, like any editor. */
.doctab.dragging { opacity: 0.4; }
.doctab.dropbefore { box-shadow: inset 2px 0 0 var(--accent); }
.doctab.dropafter { box-shadow: inset -2px 0 0 var(--accent); }

.filetree[hidden] { display: none; }
/* As the conversation strip above: a line runs along the strip's foot, and
   the open tab stands 1px lower and covers it in the page's own colour, so
   the tab and what is under it read as one surface. The line is in the
   accent for the group documents open into, and the same accent at half
   strength for the others -- so every open tab is plainly tied to what is
   under it, and the focused one is plainly the focused one. */
.pgroup { --accent-dim: color-mix(in srgb, var(--accent) 50%, var(--line)); }
.doctabs {
  display: flex; gap: 4px; padding: 6px 8px 0; overflow-x: auto; flex: none;
  box-shadow: inset 0 -1px 0 var(--accent-dim);
  scrollbar-width: none;
}
.doctabs::-webkit-scrollbar { display: none; }
.doctabs[hidden] { display: none; }
.pgroup.focused .doctabs { box-shadow: inset 0 -1px 0 var(--accent); }
.doctab {
  display: flex; align-items: center; gap: 7px; flex: none; max-width: 210px;
  padding: 5px 10px; border-radius: var(--radius) var(--radius) 0 0;
  border: 1px solid var(--line); border-bottom: none; margin-bottom: 1px;
  background: var(--panel); color: var(--muted); font-size: 12.5px; cursor: pointer;
}
.doctab:hover { color: var(--fg); }
.doctab.active { color: var(--fg); background: var(--bg); margin-bottom: 0; border-color: var(--accent-dim); }
.pgroup.focused .doctab.active { border-color: var(--accent); }
.doctab .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doctab .x { opacity: 0; font-size: 14px; line-height: 1; }
.doctab:hover .x, .doctab.active .x { opacity: 0.5; }
.doctab .x:hover { opacity: 1; color: var(--bad); }

/* Run controls, in the bar of the file they belong to. */
.sqlrun { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.sqlrun select {
  background: none; border: 1px solid var(--line); color: var(--muted);
  font-size: 11.5px; padding: 2px 4px; border-radius: 5px; max-width: 160px;
}
.sqlrun button { padding: 3px 10px; font-size: 12px; cursor: pointer; }

/* Results: a table that scrolls inside itself rather than widening the pane. */
.sqlscroll { flex: 1; min-height: 0; overflow: auto; }
.sqltable { border-collapse: collapse; font-size: 12.5px; width: max-content; min-width: 100%; }
.sqltable th, .sqltable td {
  border-bottom: 1px solid var(--line); padding: 4px 10px; text-align: left;
  white-space: nowrap; max-width: 420px; overflow: hidden; text-overflow: ellipsis;
}
.sqltable th {
  position: sticky; top: 0; background: var(--panel); color: var(--muted);
  font-weight: 600; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
}
.sqltable td { font-family: var(--mono, ui-monospace, monospace); }
.sqltable tr:hover td { background: var(--panel); }

/* A terminal: output that scrolls, and one line to type into. */
.termwrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.termwrap > .bar {
  display: flex; align-items: center; gap: 10px; flex: none;
  padding: 5px 10px; border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}
.termwrap > .bar > span:first-child { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; }
.termout {
  flex: 1; min-height: 0; overflow: auto; margin: 0; padding: 8px 10px;
  font-family: var(--mono, ui-monospace, monospace); font-size: 12.5px;
  line-height: 1.45; white-space: pre-wrap; word-break: break-word;
  background: #0b0e13;
}
.xtermhost { flex: 1; min-height: 0; padding: 4px 0 0 8px; background: #0b0e13; overflow: hidden; }
.xtermhost .xterm { height: 100%; }
.termcmd { color: var(--fg); margin-top: 6px; }
.termcmd .sigil { color: var(--accent); }

/* An editable file: a header that says where it stands, then the text. */
.fileedit { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.fileedit > .bar {
  display: flex; align-items: center; gap: 10px; flex: none;
  padding: 5px 10px; border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}
.fileedit > .bar > span:first-child {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; direction: rtl; text-align: left;
}
.fileedit > .bar button { padding: 3px 12px; font-size: 12px; cursor: pointer; }
textarea.fileview {
  flex: 1; min-height: 0; width: 100%; resize: none; border: none;
  background: none; color: var(--fg); padding: 10px 12px;
  font-family: var(--mono, ui-monospace, monospace); font-size: 12.5px;
  line-height: 1.5; white-space: pre; overflow: auto; tab-size: 2;
}
textarea.fileview:focus { outline: none; }

/* The choice, offered where the conflict happened. */
.conflict {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: none;
  padding: 7px 10px; font-size: 12px;
  background: color-mix(in srgb, var(--warn, #d29922) 12%, transparent);
  border-bottom: 1px solid var(--line);
}
.conflict .msg { flex: 1; min-width: 200px; color: var(--fg); }
.conflict button { padding: 3px 10px; font-size: 12px; cursor: pointer; }
textarea.fileview[readonly] { color: var(--muted); }

/*
 * Root header: which folder this is, and what you can do to the view of it.
 *
 * The name matters most when several sessions are open on different folders:
 * without it the tree is a list of directories that could be anywhere.
 */
.treehead {
  display: flex; align-items: center; gap: 4px; flex: none;
  padding: 4px 6px 4px 8px; border-bottom: 1px solid var(--line);
}
.treehead .name {
  flex: 1; min-width: 0; font-size: 11.5px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.treehead button {
  flex: none; width: 24px; height: 24px; padding: 0; background: none;
  border: none; border-radius: 4px; cursor: pointer; color: var(--muted);
  display: flex; align-items: center; justify-content: center;
}
.treehead button:hover { color: var(--fg); background: var(--panel); }
.treehead button svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}

.filetree { flex: 1; overflow: auto; padding: 4px 4px 8px; font-size: 13px; min-height: 0; }
.filetree .row {
  padding: 3px 6px; border-radius: 4px; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.filetree .row:hover { background: var(--panel); }
.filetree .row.sel { background: var(--panel); color: var(--accent); }
.filetree .row.dir { color: var(--fg); }
.filetree .row.file { color: var(--muted); }
/* The files an agent actually wrote, marked where you are already looking. */
.filetree .row.touched::after { content: ' \25cf'; color: var(--accent); font-size: 10px; }
/* Git status carries its own vocabulary; reusing it beats inventing one. */
.filetree .row .code {
  font-family: var(--mono, ui-monospace, monospace); font-size: 11px;
  color: var(--muted); margin-right: 6px;
}
.filetree .row.added .code { color: var(--ok); }
.filetree .row.modified .code { color: var(--warn); }
.filetree .row.deleted .code { color: var(--bad); }

.fileview {
  margin: 0; padding: 12px 16px; overflow: auto;
  font-size: 12.5px; line-height: 1.55; white-space: pre; tab-size: 2;
}
.fileview .add { color: var(--ok); }
.fileview .del { color: var(--bad); }
.fileview .hunk { color: var(--accent); }
.fileview .meta { color: var(--muted); }

/* The browser view an agent drives: streamed live, and usable by a person. */
.browserview { display: flex; flex-direction: column; height: 100%; }
.browserview img { max-width: 100%; align-self: flex-start; }
.browserview.live .stage { position: relative; flex: 1; min-height: 0; overflow: auto; padding: 6px; }
.browserview.live .stage img { display: block; width: 100%; height: auto; outline: none; cursor: default; border: 1px solid var(--line); }
.browserview.live .stage img:focus { border-color: var(--accent, #4a8cff); }
.browserview .bar { flex-wrap: wrap; flex: none; min-height: 34px; }
.browserview .bar .lvbtn { flex: none; min-width: 28px; height: 26px; padding: 0 8px; font-size: 14px; line-height: 1; color: var(--ink); background: var(--panel, var(--bg)); border: 1px solid var(--line); border-radius: 5px; cursor: pointer; }
.browserview .bar .lvbtn:hover { border-color: var(--accent, #4a8cff); }
.browserview .bar .addr { height: 26px; color: var(--ink); background: var(--bg); border: 1px solid var(--line); border-radius: 5px; padding: 0 8px; }
.browserview .bar .addr { flex: 1 1 160px; min-width: 120px; }
.browserview.live .bar .win { flex-basis: 100%; }
.browserview .bar {
  display: flex; gap: 8px; align-items: center; padding: 6px 10px;
  border-bottom: 1px solid var(--line); font-size: 12px; color: var(--muted);
}

/* ---------------- phone ---------------- */

/*
 * One layout, narrowed -- not a second UI.
 *
 * The interactions that matter away from a desk are reading a transcript and
 * answering an approval, so those keep full width and everything that competes
 * with them stacks or shrinks.
 */
@media (max-width: 640px) {
  header { flex-wrap: wrap; gap: 8px; padding: 10px 12px; }
  header nav { width: 100%; display: flex; }
  header nav button { flex: 1; }

  /* One line at every width: what does not fit goes into the ⋯ menu. */

  /* Thumb-reachable and unambiguous: an approval answered by accident is the
     one mistake this screen must not make easy. */
  .pending button { padding: 12px 16px; font-size: 15px; }

  .cards { grid-template-columns: 1fr; }
  /* A 260px tree beside a file leaves no room for either on a phone, so the
     tree goes full width and the file appears when one is chosen. */
  #pane-files { flex-direction: column; }
  .filetree { width: auto; max-height: 45%; border-right: none;
              border-bottom: 1px solid var(--line); }
  /* Narrower tabs on a phone, so three fit rather than one and a half. */
  .tabstrip .stab { max-width: 140px; font-size: 12px; padding: 3px 8px; }
  .tabstrip .stab .sub { font-size: 9px; }
  .list, .cards { padding: 12px; }

  /* Below 16px, iOS zooms the page on focus and never zooms back out. */
  textarea, input, select { font-size: 16px; }

  /*
   * The workbench on a phone.
   *
   * Three columns at 390px gives each of them too little to be worth having --
   * measured: explorer 230px, chat 177px, documents 1px. So the explorer
   * becomes an overlay you summon, and every tab, the chat included, shares
   * one group: opening a file moves you to it and the Chat tab brings you back.
   */
  #workbench { position: relative; }

  /* The activity bar survives the phone -- 48px is a price worth paying for
     the panel to stay reachable without a floating control over the chat. */
  .activity { width: 44px; }
  .actbtn { width: 44px; height: 42px; }

  /* The panel slides out OVER the conversation. Offset zero, not the width
     of the rail: the rail sits outside the workbench, so this box already
     begins where the rail ends, and 44px here counted it twice -- the panel
     opened 44px into the chat with its own left edge off screen. */
  .explorer {
    position: absolute; top: 0; bottom: 0; left: 0; z-index: 25;
    width: 78%; max-width: 300px; background: var(--panel);
    transform: translateX(-100%); transition: transform 140ms ease;
  }
  /* Drawn as what it is -- a panel on top -- not a chat cut off at the left. */
  .explorer.open { transform: none; box-shadow: 10px 0 28px rgb(0 0 0 / 45%); }
  /* The desktop collapse must not resurrect the overlay off-screen. */
  .explorer.collapsed { display: flex; }

}

/* Keep the composer clear of the home indicator on a home-screen install. */
@supports (padding: max(0px)) {
  form#composer { padding-bottom: max(14px, env(safe-area-inset-bottom)); }
}

/* schedules */
.schedform { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.schedform[hidden] { display: none; }
.schedform input:not([type=checkbox]), .schedform textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 13px;
  background: var(--bg); color: var(--ink); border: 1px solid var(--line);
  border-radius: 6px; padding: 6px 8px;
}
.schedform textarea { resize: vertical; }
.schedform label { font-size: 12.5px; color: var(--muted); display: flex; gap: 6px; align-items: center; }
.schedform .row, .item.sched .row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.item.sched { display: flex; flex-direction: column; align-items: stretch; gap: 3px; }
.item.sched .schedhead { display: flex; gap: 8px; align-items: center; }
.item.sched .row { margin-top: 4px; }

/* devices pane */
#pairform[hidden], .pairbox[hidden] { display: none; }
.pairbox {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  margin: 8px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
}
.pairbox svg { width: min(220px, 100%); height: auto; border-radius: 6px; }
.pairtitle { font-weight: 600; }
.paircode { font: 600 22px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.12em; user-select: all; }
#accesslist .audit { padding: 2px 10px; white-space: normal; }

/* terminals pane */
.listhead { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 10px 10px 4px; }
.item.agentshell { display: flex; flex-direction: column; align-items: stretch; gap: 2px; }
.item.agentshell .lastcmd {
  font-family: ui-monospace, monospace; font-size: 11.5px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; color: var(--ink);
}
.item.agentshell .lastcmd .sigil { color: var(--accent); }
.item.agentshell .lastcmd .bad { color: var(--bad); }
.termcmd .pill { margin-left: 8px; font-size: 10.5px; }

/* The mode picker, when a send is waiting on a choice. */

/* Composer chips: the settings row as words that open a menu. */
/* A chip's select stays as its source of truth, hidden, wherever the chip sits. */
#composer .native { display: none !important; }
.chip {
  background: none; border: 1px solid transparent; color: var(--ink);
  font: inherit; font-size: 12.5px; padding: 3px 8px; border-radius: 7px;
  cursor: pointer; white-space: nowrap; max-width: 260px;
  overflow: hidden; text-overflow: ellipsis;
}
.chip[hidden] { display: none; }
.chip:hover, .chip[aria-expanded="true"] { background: var(--code); }
.chip:focus-visible { border-color: var(--accent); outline: none; }
.chip.quiet { color: var(--muted); }
.chip.mode { font-weight: 500; }
.chip.mode.quiet { color: var(--warn); }
.chip.needs { outline: 2px solid var(--warn); outline-offset: 1px; }

.chipmenu {
  position: fixed; z-index: 50; min-width: 240px; max-width: 380px; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .28); padding: 6px;
}
.chipmenu-title { font-size: 12.5px; color: var(--muted); padding: 6px 10px 4px; }
.chipmenu-heading {
  font-size: 11px; color: var(--muted); padding: 8px 10px 2px;
  text-transform: uppercase; letter-spacing: .05em;
}
.chipmenu-sep { border-top: 1px solid var(--line); margin: 5px 4px; }
.chipmenu-item {
  display: grid; grid-template-columns: 1fr 18px 14px; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 8px; cursor: pointer;
}
.chipmenu-item.active { background: var(--code); }
.chipmenu-item.disabled { opacity: .45; cursor: default; }
.chipmenu-label { font-size: 13.5px; color: var(--ink); }
.chipmenu-desc { font-size: 12px; color: var(--muted); margin-top: 1px; }
.chipmenu-check { color: var(--accent); text-align: center; }
.chipmenu-key { font-size: 11.5px; color: var(--muted); text-align: right; }

/* agents pane */
.agentsfilter { display: flex; align-items: center; gap: 8px; padding: 12px 16px 0; font-size: 12px; color: var(--muted); cursor: pointer; }
#agentlist { min-width: 0; }
.item.agentrow { display: flex; flex-direction: column; align-items: stretch; gap: 2px; min-width: 0; overflow: hidden; }
.item.agentrow .schedhead { display: flex; align-items: center; gap: 8px; min-width: 0; }
.item.agentrow .title { min-width: 0; }
.item.agentrow .win { overflow-wrap: anywhere; }
.item.agentrow.current { cursor: default; border-color: var(--accent); }

/* A question from an agent: an answer, not allow/deny. */
.permcard.question .questiontext { font-size: 14px; color: var(--ink); margin: 6px 0 8px; white-space: pre-wrap; }
.permcard.question .questionrow { display: flex; gap: 6px; margin-top: 6px; }
.permcard.question .questionreply {
  flex: 1; font: inherit; font-size: 13px; padding: 6px 8px; border-radius: 6px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
}
/* A turn opened before its session's history replays holds nothing yet;
   with the agent edge on it, it drew a stray bar at the top. */
.turn.agent:has(> .meta:empty):has(> .body:empty) { display: none; }

/* Composer: add and dictate. */
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; border: 1px solid transparent; border-radius: 7px;
  background: none; color: var(--muted); cursor: pointer;
}
.iconbtn:hover, .iconbtn[aria-expanded="true"] { color: var(--ink); background: var(--bg); border-color: var(--line); }
.iconbtn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.iconbtn.caret { width: 18px; }
.iconbtn.caret svg { width: 13px; height: 13px; }
.micgroup { display: inline-flex; }
.micgroup[hidden] { display: none; }
#mic.listening { color: #fff; background: var(--bad); border-color: var(--bad); }

/* Changes pane: one heading per work tree. */
.repohead { display: flex; gap: 8px; align-items: baseline; padding: 10px 10px 2px; border-top: 1px solid var(--line); }
.repohead:first-child { border-top: 0; }
.repohead .reponame { font-weight: 600; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.repoempty { padding: 2px 10px 6px; }
.chipmenu-heading.path { text-transform: none; letter-spacing: 0; font-family: ui-monospace, monospace; }

/* A markdown file, shown rendered. */
.mdview { flex: 1; min-height: 0; overflow: auto; padding: 16px 22px 40px; max-width: 900px; }
.mdview[hidden], textarea.fileview[hidden] { display: none; }

/* The bar above the prompt: machine, folder, branch; what is uncommitted. */
#composer .context {
  display: flex; gap: 2px; align-items: center; flex-wrap: wrap;
  max-width: var(--content-max); margin: 0 auto 6px; padding: 0 2px; min-height: 26px;
}
#composer .context .grow { flex: 1; }
.gitbranch { font-family: ui-monospace, monospace; }
.gitbranch[hidden] { display: none; }
.gitstat { font-family: ui-monospace, monospace; }
.gitstat .add { color: var(--ok); }
.gitstat .del { color: var(--bad); }
#micnote { font-size: 12px; color: var(--warn); padding: 0 6px; }
#micnote[hidden] { display: none; }

/*
 * Until the page has restored the open conversation, the composer would show
 * defaults -- the laptop, the first folder, Any model -- and then change.
 * Instead none of it shows: a small spinner stands where it will be.
 */
#composer.booting > * { display: none !important; }
#composer.booting { display: flex; justify-content: center; align-items: center; min-height: 64px; }
#composer.booting::after {
  content: ''; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--accent);
  animation: composer-spin .8s linear infinite;
}
@keyframes composer-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { #composer.booting::after { animation-duration: 2.4s; } }

/* Agents pane: finished ones shown with "show all" are quieter. */
.item.agentrow.old { opacity: .6; }

/* The settings row: add, dictate and autonomy on the left; the rest right. */
.controls .grow { flex: 1; }

/* How full the context is: a ring that fills, and turns amber, then red. */
.ctxring svg { width: 18px; height: 18px; }
.ctxring .track { fill: none; stroke: var(--line); stroke-width: 3; }
.ctxring .fill { fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray .3s; }
.ctxring.warn .fill { stroke: var(--warn); }
.ctxring.bad .fill { stroke: var(--bad); }
.ctxring[hidden] { display: none; }
.ctxpop { padding: 8px 10px; min-width: 280px; display: flex; flex-direction: column; gap: 8px; }
.ctxpop .line { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; }
.ctxpop .muted { color: var(--muted); font-size: 12px; }
.ctxpop .bar { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.ctxpop .bar i { display: block; height: 100%; background: var(--accent); }
.ctxpop .bar.warn i { background: var(--warn); } .ctxpop .bar.bad i { background: var(--bad); }
.ctxpop button.linkish { align-self: flex-end; }
.ctx-warn { color: var(--warn); } .ctx-bad { color: var(--bad); }

/*
 * The settings row stays one line. What does not fit moves into the ⋯ menu,
 * from the right: the ring, then subscription, effort, model, autonomy.
 */
#composer .controls { flex-wrap: nowrap; overflow: hidden; }
#composer .controls > * { flex: none; }
#composer .controls .grow { flex: 1; min-width: 0; }
#composer .controls .overflowed { display: none !important; }
#moremenu[hidden] { display: none; }

/* A search found an agent, not a conversation: it says so, quietly. */
#sessions .item.agentof .title::before { content: '↳ '; color: var(--muted); }

/*
 * A question's options are answers, not an approval: plain buttons that are
 * easy to read, not white on bright green. Answer is the one highlighted.
 */
.permcard.question .permactions button.ok {
  background: var(--code); color: var(--ink); border: 1px solid var(--line); font-weight: 500;
}
.permcard.question .permactions button.ok:hover { border-color: var(--accent); }
.permcard.question .questionrow button { background: var(--accent); color: #fff; border-color: transparent; }
.permcard.question .judgeclock { margin-top: 8px; }

/* Likely replies: a row of chips above the box, only when there are some. */
.suggestrow {
  display: flex; gap: 6px; flex-wrap: wrap; max-width: var(--content-max); margin: 0 auto 6px; padding: 0 2px;
}
.suggestrow[hidden] { display: none; }
.chip.suggestion {
  border: 1px solid var(--line); background: var(--code); color: var(--ink);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip.suggestion:hover { border-color: var(--accent); }

/* Come and look: a finished reply, or a question waiting. */
.dot.attn-done { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); }
.dot.attn-asking { background: var(--warn); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn) 35%, transparent); animation: attn-pulse 1.4s ease-in-out infinite; }
@keyframes attn-pulse { 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--warn) 10%, transparent); } }
@media (prefers-reduced-motion: reduce) { .dot.attn-asking { animation: none; } }
header #soundbtn { margin-left: 2px; }
#soundbtn.muted .wave { opacity: 0; }
#soundbtn.muted { opacity: .55; }

/* Hooks, under the schedules. */
.hookshead { display: flex; justify-content: space-between; align-items: center; }
.item.hookrow { display: flex; flex-direction: column; align-items: stretch; gap: 3px; }
.hookurl { word-break: break-all; }
.hooksecret[hidden], .hooklog[hidden] { display: none; }
.hooksecret { margin-top: 6px; padding: 8px; border: 1px solid var(--warn); border-radius: 8px; display: flex; flex-direction: column; gap: 6px; }
.hooksecret .secretline { font-family: ui-monospace, monospace; font-size: 12px; word-break: break-all; user-select: all; }
.hooklog { margin-top: 4px; }

/* Tool lines: what ran, click for its output. */
.tool.clickable { cursor: pointer; }
.tool.clickable:hover { color: var(--ink); }
.tool .toolname { color: var(--ink); }
.tool .tooldetail { color: var(--muted); }
.tool.failed { border-color: var(--bad); }
.tool .tooljump { font-size: 11.5px; margin-left: 6px; opacity: 0; }
.tool:hover .tooljump { opacity: 1; }
pre.toolout {
  margin: 2px 0 8px 12px; padding: 8px 10px; max-height: 320px; overflow: auto;
  background: var(--code); border-radius: 6px; font-size: 12px; white-space: pre-wrap; word-break: break-word;
}
pre.toolout[hidden] { display: none; }

/* The working line: a mark that breathes, and what is happening. */
.workline {
  display: flex; gap: 10px; align-items: center; padding: 2px 18px 6px; font-size: 13px; color: var(--muted);
  max-width: var(--content-max); margin: 0 auto; width: 100%;
}
.workline[hidden] { display: none; }
.workline .workmark { color: #e8743b; font-size: 16px; display: inline-block; animation: work-breathe 1.6s ease-in-out infinite; }
@keyframes work-breathe { 0%, 100% { transform: scale(.75) rotate(0deg); opacity: .7; } 50% { transform: scale(1.15) rotate(45deg); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .workline .workmark { animation: none; } }

/* earlier turns of a long conversation, loaded on scrolling up */
.earlierbar { display: block; margin: 4px auto 10px; font-size: 12px; color: var(--muted); }
/* Over an archived transcript: a plain line, since nothing about it is urgent. */
.archivedbar { text-align: center; margin: 4px auto 10px; }
.archivedbar .linkish { font: inherit; }
/* Earlier turns are put in above the view and the position held by hand; the
   browser's own anchoring, on top of that, moved it twice. */
#transcript { overflow-anchor: none; }
.turn.agent .meta .when { color: var(--muted); font-variant-numeric: tabular-nums; }

/* what was pasted into a message, shown with it */
.sentfiles { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; margin-top: 6px; }
.sentimg {
  max-width: 260px; max-height: 160px;
  border: 1px solid var(--line); border-radius: var(--radius); cursor: zoom-in;
  background: var(--panel);
}
.sentfile { font-size: 12px; color: var(--muted); }
.imgshade {
  position: fixed; inset: 0; z-index: 1000; background: rgba(0, 0, 0, 0.8);
  display: flex; align-items: center; justify-content: center; cursor: zoom-out; padding: 24px;
}
.imgshade img { max-width: 100%; max-height: 100%; border-radius: var(--radius); }
/* Captioned underneath, not over it: on a short screenshot a label on top hid what it showed. */
.sentthumb { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.sentlabel { font-size: 11px; line-height: 1; color: var(--muted); }

/* health, at the top of Fleet */
.healthbox { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.healthbox .sectionhead { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.healthnode { border: 1px solid var(--line); border-radius: var(--radius); padding: 6px 8px; display: flex; flex-direction: column; gap: 3px; }
.healthnode.warn { border-color: var(--warn); }
.healthnode.bad { border-color: var(--bad); }
.healthhead { display: flex; align-items: center; gap: 7px; font-size: 13px; }
.healthname { font-weight: 600; flex: 1; }
.healthon { font-size: 11px; color: var(--muted); display: flex; align-items: center; gap: 4px; cursor: pointer; }
.hdot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok, #3fb950); flex: none; }
.hdot.warn { background: var(--warn); }
.hdot.bad { background: var(--bad); }
/* Label then detail as one run of text, so a long detail wraps under it rather than in a sliver beside it. */
.healthcheck { font-size: 12px; display: block; padding-left: 15px; line-height: 1.4; }
.healthcheck .healthlabel { font-weight: 600; margin-right: 6px; }
.healthcheck.warn .healthlabel { color: var(--warn); }
.healthcheck.bad .healthlabel { color: var(--bad); }
.healthcheck .healthdetail { color: var(--muted); }
/* A dot on the Fleet button when anything is amber or red. */
.actbtn.health-warn, .actbtn.health-bad { position: relative; }
.actbtn.health-warn::before, .actbtn.health-bad::before {
  content: ''; position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--warn); box-shadow: 0 0 0 2px var(--bg);
}
.actbtn.health-bad::before { background: var(--bad); }
.healthtop { display: flex; align-items: center; justify-content: space-between; }
.healthtest { font-size: 11px; }
/* a schedule's settings, two to a row */
.schgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 8px; }
.schgrid label { flex-direction: column; align-items: stretch; gap: 2px; }
.schgrid select, .schgrid input { width: 100%; box-sizing: border-box; font: inherit; font-size: 12.5px; }
#sch-pacing { font-size: 12.5px; }
#sch-pacing summary { cursor: pointer; color: var(--muted); }
#sch-pacing > * + * { margin-top: 6px; }
.schedform input.short { width: 64px; }
.machinecmd { font: 12px ui-monospace, monospace; white-space: pre-wrap; word-break: break-all; background: var(--code); border: 1px solid var(--line); border-radius: 6px; padding: 8px; margin: 6px 0; user-select: all; }
.quietselect { font: inherit; font-size: 11.5px; max-width: 45%; background: transparent; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; }
.healthhead .healthtest { font-size: 11px; }
.healthcheck input[type=password] { font: inherit; font-size: 12px; width: 50%; margin: 0 6px; }
/* text size for one conversation */
.zoomctl { display: inline-flex; gap: 2px; }
.zoomctl .chip { padding-left: 6px; padding-right: 6px; font-size: 11.5px; }
.workline.clickable { cursor: pointer; }

/* Plugins: the pane's rows, and a plugin's own panel as a tab. */
.pluginrow .warnline { white-space: pre-wrap; }
.plsettings, #pl-inspect { display: flex; flex-direction: column; gap: 6px; }
.plfields label { display: flex; flex-direction: column; gap: 2px; }
.plfields label:has(> input[type=checkbox]) { flex-direction: row; align-items: center; gap: 6px; }
.plperms ul { margin: 2px 0 4px; padding-left: 18px; color: var(--muted); font-size: 12px; }
.plperms .listhead { padding: 0; }
.plpanel { padding: 10px 14px; display: flex; flex-direction: column; gap: 12px; }
.plhead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.plhead .row { margin-left: auto; display: flex; gap: 6px; }
.plsection h3 { font-size: 13px; margin: 0 0 6px; }
.plfold > summary { font-size: 13px; font-weight: 600; cursor: pointer; margin: 0 0 6px; }
.plfold > summary button.plhead { font-weight: 500; margin-left: 12px; vertical-align: middle; }
.pltext { white-space: pre-wrap; }
.pltable { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.pltable th { text-align: left; font-weight: 600; color: var(--muted); border-bottom: 1px solid var(--line); padding: 4px 8px; }
.pltable td { border-bottom: 1px solid var(--line); padding: 4px 8px; vertical-align: top; }
.pltable td.placts { white-space: nowrap; text-align: right; vertical-align: top; width: 1%; }
.pltable td.placts .plstack { display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
.pltable td.placts .plstack button { text-align: center; }
.pltable td.placts .plicons { display: flex; justify-content: flex-end; gap: 4px; margin-top: 4px; }
.pltable td.placts button.ghost { padding: 1px 8px; }
.pltable td.placts .iconbtn { width: 24px; height: 24px; vertical-align: middle; }
.pltable td.placts .iconbtn svg { width: 15px; height: 15px; }
.plfacts { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 0; }
.plfacts > div { display: flex; gap: 6px; align-items: baseline; }
.plfacts dt { color: var(--muted); }
.plfacts dd { margin: 0; }
.plfile { padding: 10px 14px; display: flex; flex-direction: column; gap: 8px; }
.plfile .mdview { max-width: 80ch; }
.tone-ok { color: var(--ok); } .tone-warn { color: var(--warn); } .tone-bad { color: var(--bad); } .tone-muted { color: var(--muted); }
.pllog summary { cursor: pointer; color: var(--muted); }
.pllog pre { max-height: 320px; overflow: auto; }
@media (max-width: 640px) { .pltable { display: block; overflow-x: auto; } }
#pl-inspect .schedhead { display: flex; gap: 8px; align-items: baseline; }
/* Model classes: a grid of inputs, class by provider. */
.clscard { padding: 6px 0; border-bottom: 1px solid var(--line); }
.clsrow { display: grid; grid-template-columns: 88px 1fr; gap: 6px; align-items: center; padding: 2px 0; }
.clsrow input { min-width: 0; }
.clsrow .win { grid-column: 2; }
#classbox .row { display: flex; gap: 8px; align-items: center; padding: 6px 0; }
.item.found { flex-wrap: wrap; row-gap: 2px; }
.item.found .title { flex: 1 1 calc(100% - 24px); min-width: 0; }
.item.found > .win { flex-basis: 100%; padding-left: 16px; }
.item .excerpt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 11.5px; }
/* Usage by day: a bar per day. */
.daybars { display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.dayrow { display: grid; grid-template-columns: 92px 1fr 88px; gap: 6px; align-items: center; }
.daytrack { height: 8px; background: color-mix(in srgb, var(--muted) 18%, transparent); border-radius: 4px; overflow: hidden; }
.daybar { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.daylabel { color: var(--muted); }
.brand { display: inline-flex; align-items: center; gap: 7px; }
.brand img { border-radius: 5px; }
.signin-logo { display: block; margin: 0 auto 10px; }
/* Condensed transcript: steps folded behind a one-line summary. */
#transcript.condensed .tool:not(.unfolded), #transcript.condensed .toolout:not(.unfolded),
.agenttranscript.condensed .tool:not(.unfolded), .agenttranscript.condensed .toolout:not(.unfolded) { display: none; }
.stepsum { display: block; font-size: 12px; color: var(--muted); padding: 2px 0; text-align: left; }
.stepsum.bad { color: var(--bad); }
.stab.dragging { opacity: .45; }
.stab.dropbefore { box-shadow: inset 2px 0 0 var(--accent); }
.stab.dropafter { box-shadow: inset -2px 0 0 var(--accent); }
.tabrename { font: inherit; width: 16em; padding: 1px 4px; background: var(--panel); color: var(--ink); border: 1px solid var(--accent); border-radius: 4px; }
.permfields { display: grid; grid-template-columns: max-content 1fr; gap: 2px 12px; margin: 6px 0; font-size: 12.5px; }
.permfields dt { color: var(--muted); }
.permfields dd { margin: 0; white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.permfrom { display: block; font-size: 12px; color: var(--muted); margin: 2px 0 6px; text-align: left; }

.plugin-dialog { width: min(680px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); padding: 24px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel); color: var(--ink); overflow: auto; }
.plugin-dialog::backdrop { background: rgb(0 0 0 / 50%); }
.plugin-dialog-head { display: flex; justify-content: space-between; align-items: start; gap: 16px; margin-bottom: 16px; }
.plugin-dialog h2 { font-size: 18px; margin: 0; }
.plugin-dialog-body form { display: grid; gap: 16px; }
.plugin-dialog .plfields { margin: 0; }
@media (max-width: 540px) { .plugin-dialog .plfields { grid-template-columns: minmax(0, 1fr); } }

.reviewer-card { min-width: 0; overflow-wrap: anywhere; }
.reviewer-card .row { flex-wrap: wrap; }

/*
 * A plugin's panel opens on its last look, marked as updating, or -- the first
 * time -- on a spinner and the shape of what is coming, never on bare text.
 */
.plspin {
  display: inline-block; flex: none; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--accent);
  animation: composer-spin .8s linear infinite;
}
.plupdating { display: flex; align-items: center; gap: 8px; }
.plloading { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.plloadhead { display: flex; align-items: center; gap: 10px; }
.plbar {
  height: 14px; border-radius: 6px; max-width: 100%;
  background: linear-gradient(90deg, var(--line) 25%, color-mix(in srgb, var(--line) 50%, transparent) 50%, var(--line) 75%);
  background-size: 200% 100%; animation: plbar-shimmer 1.4s ease-in-out infinite;
}
@keyframes plbar-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) { .plspin, .plbar { animation-duration: 4s; } }

.plform { display: grid; gap: 12px; }
.plfield { display: grid; gap: 4px; }
.plfield .pllabel { font-weight: 600; font-size: 13px; }
.plfield textarea, .plfield input, .plfield select { width: 100%; box-sizing: border-box; font: inherit; }

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

.plbusy { display: inline-flex; align-items: center; gap: 6px; }
.plspin { width: 10px; height: 10px; flex: none; border-radius: 999px; border: 2px solid color-mix(in srgb, var(--ok) 30%, transparent); border-top-color: var(--ok); animation: plspin 0.9s linear infinite; }
@keyframes plspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .plspin { animation: none; border-top-color: var(--ok); background: var(--ok); } }

.agentitem { margin-left: 10px; }
.agentitem > summary { font-weight: 500; }

/* Resets on a subscription's card: a count, and small text buttons. */
.usresets .linkbtn { background: none; border: 0; padding: 0; color: var(--accent, #4f8cff); cursor: pointer; font: inherit; text-decoration: underline; }
.usresets .linkbtn:empty { display: none; }

/* A message that did not send: kept in the transcript with Retry and Edit. */
.failedsend { border: 1px solid var(--err, #e5736d); border-radius: 10px; padding: 10px 12px; margin: 8px 0; background: color-mix(in srgb, var(--err, #e5736d) 8%, transparent); }
.failedsend .failedhead { font-weight: 600; margin-bottom: 6px; }
.failedsend .failedtext { white-space: pre-wrap; word-break: break-word; margin: 0 0 8px; font: inherit; opacity: 0.9; max-height: 14em; overflow: auto; }
.failedsend .failedrow { display: flex; gap: 8px; margin-top: 8px; }
.failedsend.retrying { opacity: 0.5; }

/* A message sent to an agent that is working: waiting to be read, then picked up. */
.noticeline.steerwait { opacity: 0.85; }
.noticeline.steerdone { font-size: 0.85em; opacity: 0.7; }

/* A conversation on its way: the tab has already switched. */
.loadingtab { display: flex; align-items: center; gap: 10px; padding: 28px 20px; color: var(--muted, #8b93a1); }
.loadingtab .spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: loadspin 0.8s linear infinite; }
@keyframes loadspin { to { transform: rotate(360deg); } }

/* The row's own buttons above a file opened from it. */
.plfilebar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 0 10px; position: sticky; top: 0; background: var(--bg, #1a1b1e); z-index: 1; }

/* An agent's tab: its conversation, read and steered beside the one it belongs to. */
.agentview { display: block; flex: 0 0 auto; }
.agentbar { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--border, #333); position: sticky; top: 0; background: var(--bg); z-index: 1; }
.agentbar .title { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agentbar .agentfold { margin-left: auto; }
.agenttranscript { padding: 8px 12px; }
.agentcompose { position: sticky; bottom: 0; display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px; background: var(--bg); border-top: 1px solid var(--border, #333); }
.agentcompose textarea { flex: 1; min-width: 0; resize: none; font: inherit; }

/* A press that is going: its button, its row, and what the plugin is doing about it. */
button.plpressing { cursor: progress; opacity: .8; }
button.plpressing:not(.iconbtn)::before { content: ''; display: inline-block; width: 10px; height: 10px; margin-right: 6px; vertical-align: -1px; border-radius: 999px; border: 2px solid color-mix(in srgb, currentColor 30%, transparent); border-top-color: currentColor; animation: plspin 0.9s linear infinite; }
button.plpressing.iconbtn { animation: plpulse 1s ease-in-out infinite; }
tr.plpending > td, .plpending.plfilebar { background: color-mix(in srgb, var(--accent, #58b8bf) 8%, transparent); }
.plstatus { margin-top: 4px; font-size: 12px; color: var(--muted, inherit); max-width: 28ch; }
.plstatus.err { color: var(--bad, #c0392b); }
@keyframes plpulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { button.plpressing.iconbtn { animation: none; } }

/* A confirmation or notice in the page, in place of the browser's. */
dialog.confirm-dialog { border: 1px solid var(--line, #444); border-radius: 12px; background: var(--panel, #1d1d20); color: inherit; padding: 18px 20px; width: min(440px, calc(100vw - 32px)); box-shadow: 0 18px 60px rgba(0,0,0,.5); }
dialog.confirm-dialog::backdrop { background: rgba(0,0,0,.45); }
dialog.confirm-dialog h2 { font-size: 15px; margin: 0 0 8px; }
.confirm-text p { margin: 0 0 6px; line-height: 1.45; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.confirm-actions button.danger { background: var(--bad, #c0392b); border-color: var(--bad, #c0392b); color: #fff; }
dialog.detail-dialog { width: min(820px, calc(100vw - 32px)); max-height: calc(100vh - 64px); }
dialog.detail-dialog .plugin-dialog-body { overflow: auto; max-height: calc(100vh - 160px); }

/* A folded run of one schedule's follow-ups. */
.followgroup { margin: 4px auto 14px; display: flex; flex-direction: column; align-items: center; }
.followgroup .followhead { border-style: dashed; }
.followgroup .followbody { width: 100%; margin-top: 8px; opacity: .85; }

/* The last message to the agent, kept at the top of the view while it is scrolled out of sight. Zero high, so it moves nothing. */
.chatpanel { position: relative; }
.stickyprompt { position: absolute; top: 0; left: 0; right: 0; height: 0; z-index: 6; pointer-events: none; }
.stickyprompt > .stickybox { pointer-events: auto; }
.stickyprompt[hidden] { display: none; }
.stickybox { position: absolute; left: 0; right: 0; top: 0; display: flex; gap: 10px; align-items: baseline; text-align: left; width: 100%;
  padding: 7px 16px; border: 0; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--panel) 94%, transparent); backdrop-filter: blur(6px);
  color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; box-shadow: 0 6px 14px rgb(0 0 0 / 18%); }
.stickybox:hover { color: var(--ink); }
.stickywho { flex: none; color: var(--ink); font-weight: 600; }
.stickytext { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; min-width: 0; }

/* A row's buttons on one line; the rest under a menu. */
.pltable td.placts { white-space: nowrap; text-align: right; vertical-align: top; width: 1%; position: relative; }
.plrowbtns { display: flex; align-items: center; justify-content: flex-end; gap: 3px; flex-wrap: nowrap; }
.plmoreholder { position: relative; display: inline-block; }
.plmore { padding: 1px 10px; font-weight: 700; letter-spacing: 1px; }
.plmenu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 190px; display: flex; flex-direction: column; gap: 2px; padding: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 10px 30px rgb(0 0 0 / 40%); }
.plmenu[hidden] { display: none; }
.plmenu button { text-align: left; border: 0; background: transparent; padding: 7px 10px; border-radius: 6px; width: 100%; color: var(--ink); }
.plmenu button:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 10%, transparent); }

/* The confirmation's own buttons: the action is filled, Cancel has an edge. */
.confirm-actions button { padding: 8px 18px; font-weight: 550; }
.confirm-actions button.ghost { color: var(--ink); }
.confirm-actions button:not(.ghost):not(.danger) { background: var(--accent); border-color: transparent; color: #fff; }
.confirm-actions button:not(.ghost):not(.danger):hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 85%, #fff); }
.confirm-actions button.danger { background: #d9534f; border-color: transparent; color: #fff; }

td.pldetailcell { cursor: pointer; }
td.pldetailcell:hover { text-decoration: underline; text-underline-offset: 3px; }
/* Icon buttons in a row: the same edge and fill as a button, or they vanish into the table. */
.pltable td.placts .iconbtn { border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent); background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); border-radius: 8px; }
.pltable td.placts .iconbtn:hover:not(:disabled) { background: color-mix(in srgb, var(--ink) 16%, transparent); }
.pltable td.placts .iconbtn.icon-check { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.pltable td.placts .iconbtn.icon-check:hover:not(:disabled) { background: color-mix(in srgb, var(--ok) 24%, transparent); }

table.pltable.plfixed { table-layout: fixed; width: 100%; }
table.pltable.plfixed td, table.pltable.plfixed th { overflow-wrap: anywhere; }
table.pltable.plfixed td.placts { width: auto; }

.pltable td.placts .iconbtn.icon-wrench { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 55%, transparent); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.pltable td.placts .iconbtn.icon-wrench:hover:not(:disabled) { background: color-mix(in srgb, var(--warn) 24%, transparent); }

.plslot { display: inline-block; width: 24px; height: 24px; flex: none; }

/* Dialogs stand off from the page behind them: a visible edge. */
dialog.confirm-dialog, dialog.plugin-dialog { border: 1px solid color-mix(in srgb, var(--ink) 30%, var(--panel)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent), 0 18px 60px rgb(0 0 0 / 55%); }

/* A row's press message floats over the table instead of adding to the row, so nothing moves while it shows. */
td.placts > .plstatus { position: absolute; right: 8px; top: calc(100% - 6px); z-index: 15; max-width: 260px; white-space: normal; text-align: left; padding: 5px 10px; margin: 0;
  background: var(--panel); border: 1px solid color-mix(in srgb, var(--ink) 30%, var(--panel)); border-radius: 8px; box-shadow: 0 8px 24px rgb(0 0 0 / 40%); font-size: 12px; }

.plpressmsg { color: var(--accent); font-weight: 550; }
.plpressmsg.err { color: var(--bad); }

.pltable td.placts .iconbtn.icon-x { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 50%, transparent); background: color-mix(in srgb, var(--bad) 10%, transparent); }
.pltable td.placts .iconbtn.icon-x:hover:not(:disabled) { background: color-mix(in srgb, var(--bad) 22%, transparent); }

.plgrip { cursor: grab; color: var(--muted); letter-spacing: -2px; margin-right: 6px; user-select: none; }
.plgrip:active { cursor: grabbing; }
tr.pldragging { opacity: .45; }
tr.pldropabove > td { box-shadow: inset 0 2px 0 var(--accent); }
tr.pldropbelow > td { box-shadow: inset 0 -2px 0 var(--accent); }

/* Every icon button in a row is the same square, whatever room the row has: they do not shrink to fit. */
.plrowbtns > * { flex: none; }
.pltable td.placts .iconbtn, .plslot { width: 24px; height: 24px; min-width: 24px; padding: 0; display: inline-flex; align-items: center; justify-content: center; }
.pltable td.placts .iconbtn svg { width: 14px; height: 14px; }

/* "Something is working" is the chat's own mark, not a different circle: the orange asterisk that breathes. */
.plspin { width: auto; height: auto; border: 0; border-radius: 0; animation: none; display: inline-flex; align-items: center; justify-content: center; }
.plspin::before { content: '✻'; color: #e8743b; font-size: 15px; line-height: 1; display: inline-block; animation: work-breathe 1.6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .plspin::before { animation: none; } }

/* The working column: an agent, or only code. */
.plmark { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; }
.plmark-agent::before { content: '✻'; color: #e8743b; font-size: 15px; line-height: 1; display: inline-block; animation: work-breathe 1.6s ease-in-out infinite; }
.plmark-code::before { content: '⚙︎'; color: var(--accent); font-size: 16px; line-height: 1; display: inline-block; animation: plspin 3.2s linear infinite; }
@media (prefers-reduced-motion: reduce) { .plmark::before { animation: none; } }
.plmark-link { cursor: pointer; border-radius: 6px; }
.plmark-link:hover { background: color-mix(in srgb, var(--ink) 14%, transparent); }

/* Compact: every button is behind the ⋯, which is all the button column holds. */
.plcompactonly { display: none; }
table.plcompact .plcompactonly { display: block; }
table.plcompact .plmoreholder.plcompactonly { display: inline-block; }
table.plcompact .plrowbtns > :not(.plmoreholder) { display: none; }

/* Compact: the columns are only as wide as what is in them (the title takes the rest), not the widths of the full layout. */
table.pltable.plfixed.plcompact { table-layout: auto; }
table.pltable.plfixed.plcompact col { width: auto !important; }
table.pltable.plfixed.plcompact td, table.pltable.plfixed.plcompact th { white-space: nowrap; overflow-wrap: normal; }
table.pltable.plfixed.plcompact td[data-col="title"], table.pltable.plfixed.plcompact th[data-col="title"] { white-space: normal; min-width: 160px; }
table.pltable.plfixed.plcompact td.placts { width: 1%; }

.pltable td.placts { padding-left: 4px; padding-right: 8px; }

.plmenu button { display: flex; align-items: center; gap: 10px; }
.plmenuicon { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.plmenuicon.icon-check { color: var(--ok); }
.plmenuicon.icon-x { color: var(--bad); }
.plmenuicon.icon-wrench { color: var(--warn); }

/* The agent's pointer over the live view. */
.lvcursor { position: absolute; width: 0; height: 0; pointer-events: none; color: #ff8a1f; opacity: 0; z-index: 3;
  transition: left 0.35s ease-out, top 0.35s ease-out, opacity 0.4s; filter: drop-shadow(0 1px 2px rgb(0 0 0 / 55%)); }
.lvcursor.on { opacity: 1; }
.lvcursor svg { position: absolute; left: -2px; top: -1px; }
.lvring { position: absolute; left: -14px; top: -14px; width: 28px; height: 28px; border-radius: 50%; border: 3px solid #ff3b30;
  animation: lvring 0.8s ease-out forwards; }
.lvring.type { border-color: #4a8cff; }
@keyframes lvring { from { transform: scale(0.3); opacity: 1; } to { transform: scale(1.8); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .lvcursor { transition: none; } .lvring { animation-duration: 0.01s; } }

/* The usage pane: a line a subscription, a click to open it. */
.usline { display: flex; flex-direction: column; gap: 3px; cursor: pointer; }
.usline:focus-visible { outline: 2px solid var(--accent, #4a8cff); outline-offset: 2px; border-radius: 4px; }
.ustop { display: flex; align-items: center; gap: 8px; min-height: 22px; }
.usname { display: flex; align-items: center; gap: 6px; flex: 1 1 0; min-width: 0; overflow: hidden; white-space: nowrap; font-size: 13px; }
.usname b { flex: none; }
.usname .usmeta { margin: 0; overflow: hidden; text-overflow: ellipsis; }
/* The meter: the bar takes what is left of the line; the share, the time left and any flag keep their size. */
.usmeter { display: flex; align-items: center; gap: 8px; padding-left: 14px; min-width: 0; }
.usline .pacebar { flex: 1 1 40px; min-width: 40px; margin: 0; position: relative; overflow: visible; }
.usline .pacepct { flex: none; width: 2.6em; text-align: right; }
.usline .usreset { flex: none; width: 4.4em; text-align: right; }
.usline .usnoread { flex: none; }
.usflags { display: flex; gap: 4px; flex: none; }
.uschev { flex: none; width: 28px; height: 22px; line-height: 22px; text-align: center; font-size: 18px; color: var(--muted); border-radius: 4px; }
.usline:hover .uschev { color: var(--ink); background: var(--bg); }
.uscard:not(.open) { padding-top: 6px; padding-bottom: 6px; margin-bottom: 6px; }
.usfull { margin: 4px 0 0 14px; padding-top: 4px; border-top: 1px solid var(--line); }
.usworth { margin-top: 4px; }
input.usprice { width: 5em; }

.ushead select.usfilter { flex: 1 1 100%; padding: 3px 6px; font-size: 12px; }
.ushead select.usfilter option { background: var(--panel); color: var(--ink); }

/* People and access dialog */
dialog.access-dialog { width: min(1040px, calc(100vw - 32px)); height: min(720px, calc(100dvh - 32px)); display: flex; flex-direction: column; }
dialog.access-dialog:not([open]) { display: none; }
.access-dialog .plugin-dialog-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 12px; }
.access-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); }
.access-tabs button { background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 0; color: var(--muted, inherit); padding: 8px 12px; }
.access-tabs button.active { color: var(--ink); border-bottom-color: var(--accent, #8b8bff); }
.access-pane { flex: 1; min-height: 0; display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 20px; }
.access-list { overflow: auto; display: flex; flex-direction: column; gap: 4px; padding-right: 4px; }
.access-item { text-align: left; background: none; border: 1px solid transparent; border-radius: 8px; padding: 8px 10px; color: inherit; }
.access-item:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
.access-item.active { border-color: var(--accent, #8b8bff); background: color-mix(in srgb, var(--accent, #8b8bff) 12%, transparent); }
.access-item-top { display: flex; justify-content: space-between; gap: 8px; align-items: center; }
.access-item-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.access-item-sub { font-size: 12px; opacity: .7; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.access-detail { overflow: auto; padding-right: 4px; }
.access-head { margin-bottom: 12px; }
.access-head h3 { margin: 0 0 4px; font-size: 17px; }
.access-section { border-top: 1px solid var(--line); padding: 12px 0; display: grid; gap: 6px; }
.access-section h3 { margin: 0; font-size: 14px; }
.access-hint { font-size: 12px; opacity: .7; margin: 0; }
.access-warn { color: var(--warn); margin: 0; }
.access-summary { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0; }
.access-summary dt { opacity: .7; }
.access-summary dd { margin: 0; }
.access-check { display: flex; gap: 8px; align-items: baseline; padding: 3px 0; cursor: pointer; }
.access-check input { flex: none; }
.access-all { font-weight: 600; }
.access-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0 16px; }
.access-grid.disabled { opacity: .45; }
.access-policy input:not([type]), .access-policy input[type=text] { width: 100%; max-width: 360px; }
.access-actions { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 12px; border-top: 1px solid var(--line); }
.access-invite { display: grid; gap: 6px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
button.danger.ghost { color: var(--bad); }
@media (max-width: 720px) {
  dialog.access-dialog { height: calc(100dvh - 16px); width: calc(100vw - 16px); padding: 16px; }
  .access-pane { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .access-list { max-height: 30dvh; }
}
