/*
 * app/src/cora.css — Cora, read out of `docs/design/cora.html`.
 *
 * The token values, radii, weights and the outlined-button rule are COPIED, not
 * re-derived: deep navy with a bloom falling from directly above, pale
 * platinum-blue as the only colour, radii 4/7/10, display weight 300, nothing
 * bolder than 500, and no filled buttons anywhere — Send sits on the app's own
 * ground behind a 1px accent frame.
 *
 * Dark is primary. Light is the same room with the lights on: identical
 * structure and hairline placement, with the blue dropped so a 1px frame and
 * its label still clear contrast on white.
 *
 * WHICH THEME IS IN FORCE IS DECIDED BY ONE THING ONLY: the `data-theme`
 * attribute on <html>. `prefers-color-scheme` is not consulted anywhere in this
 * file, and that is the owner's decision rather than an omission — a first-time
 * user starts dark whatever their machine prefers, and the switch in the rail
 * is what changes it.
 *
 * That is also a BUG FIX. Light used to live only inside
 * `@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) }`,
 * which made the attribute a dark OPT-OUT rather than a light OPT-IN: measured
 * in a browser, `data-theme="light"` on a machine set to dark resolved
 * `--surface` to #080d19. A switch built on that would have appeared to work
 * for whoever tested it on a light Mac and done nothing for everybody else.
 *
 * `color-scheme` is declared in BOTH blocks. Without it the UA paints a white
 * canvas before `body`'s background lands, and draws the thin scrollbar and the
 * <textarea> in whichever mode the OS prefers — which is the one part of the
 * theme JavaScript cannot fix afterwards.
 *
 * The contrast figures quoted below are ratios against the ground the element
 * actually sits on, computed from the composited pixel rather than the token.
 */

@import url("./ui/gateways.css");
@import url("./developer-credentials.css");
@import url("./developer-oauth.css");

:root {
  /* Structural, and deliberately NOT repeated in the light block: they carry no
     colour, so they cascade. `app/tests/theme.test.ts` pins that list, so a
     colour token can never hide among them. */
  --r-sm: 4px;
  --r-md: 7px;
  --r-lg: 10px;
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* dark — primary, and the default for everyone on first run */
  color-scheme: dark;
  --bg: radial-gradient(150% 120% at 50% -26%, #17264e 0%, #0c1530 38%, #060b1a 68%, #03060f 100%);
  --grad-panel: linear-gradient(180deg, rgba(159, 192, 232, 0.055), rgba(159, 192, 232, 0) 62%);
  --grad-card: linear-gradient(180deg, rgba(159, 192, 232, 0.05), rgba(159, 192, 232, 0) 70%);
  --hair: rgba(159, 192, 232, 0.2);
  --halo: rgba(107, 168, 255, 0.2);
  --surface: #080d19;
  --surface-2: #05090f;
  --surface-3: #101a2d;
  --ink: #f3f6fb;
  --ink-2: #a7b5cc;
  --ink-3: #7c8aa4;
  --line: rgba(160, 190, 235, 0.085);
  --line-2: rgba(160, 190, 235, 0.17);
  --accent: #9fc0e8;
  --accent-soft: rgba(159, 192, 232, 0.1);
  /* --p0 was #69768f, which is 4.24:1 on --surface — under AA at FULL opacity,
     before the chip's own dimming. 6.36:1 now. Light has the same fix. */
  --p0: #8a94a8;
  --p1: #7e9ac4;
  --p2: #a9c3e6;
}

/*
 * Light. The selector is the ATTRIBUTE, with no media query anywhere near it —
 * see the file header. Every colour token in `:root` is restated here; nothing
 * else is.
 */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: radial-gradient(150% 120% at 50% -26%, #ffffff 0%, #f5f9fd 42%, #e9eff7 100%);
  --grad-panel: linear-gradient(180deg, rgba(53, 102, 144, 0.045), rgba(53, 102, 144, 0) 62%);
  --grad-card: linear-gradient(180deg, rgba(53, 102, 144, 0.032), rgba(53, 102, 144, 0) 70%);
  --hair: rgba(53, 102, 144, 0.22);
  /* was 0.14 — the hover glow measured 1.21:1 on white, which made `.btn:hover`
     pixel-indistinguishable from rest. 1.46:1, against dark's 1.39:1. */
  --halo: rgba(53, 102, 144, 0.26);
  --surface: #ffffff;
  --surface-2: #f6f8fb;
  /* was #edf1f6 — the rail's icon tile measured 1.01:1 against the rail's own
     ground, so the glyphs floated with no container at all. 1.06:1 puts light
     level with dark's 1.07:1; the visible container is the new 1px frame on
     `.ic` below. */
  --surface-3: #e6ecf3;
  --ink: #0c1420;
  --ink-2: #47546a;
  /* was #5f6c7e, AND DARKENING --surface-3 ABOVE IS WHAT BROKE IT. The rail's
     glyphs are --ink-3 sitting ON --surface-3, so moving the tile from #edf1f6
     to #e6ecf3 to make the tile visible took the glyph on it from 4.71:1 to
     4.49:1 — under AA by a hundredth, measured in the browser and reproduced
     from the tokens. Nothing tested it, because §7 only ever measured inks
     against --surface, where this token reads 5.34:1 and always passed.
     #5c6877 is 4.77:1 on --surface-3, 5.33:1 on --surface-2 and 5.67:1 on
     --surface, and stays a clear step lighter than --ink-2 (1.35:1 between
     them, against 1.42:1 before) so the three-level ink hierarchy still reads.
     Dark is untouched: its own pairing is already 4.99:1. */
  --ink-3: #5c6877;
  /* the two hairline alphas were 0.10 / 0.18, which read fainter on white than
     their dark counterparts do on near-black. 1.33 / 1.74 against dark's
     1.14 / 1.37. Neither theme reaches the 3:1 that WCAG 1.4.11 asks of a
     component boundary — that is the design's hairline register, unchanged and
     recorded here rather than quietly fixed in one theme only. */
  --line: rgba(18, 30, 52, 0.14);
  --line-2: rgba(18, 30, 52, 0.26);
  /* was #3a6e9e. That put the sign-in button's label at 4.74:1 and its refusal
     text at 4.65:1 on the body gradient — passing AA by three percent. 5.26:1
     on the worst ground in the viewport, 6.08:1 on --surface. */
  --accent: #356690;
  --accent-soft: rgba(53, 102, 144, 0.16);
  /* was #6e7a90 — 4.33:1, under AA. 7.29:1 selected, 4.63:1 dimmed. */
  --p0: #4e5766;
  --p1: #33486b;
  --p2: #1b2f52;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  /* The macOS traffic lights sit over a transparent titlebar. */
  user-select: none;
}

#root {
  height: 100%;
  display: flex;
  flex-direction: column;
  isolation: isolate;
}

.app {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* ── rail ─────────────────────────────────────────────────────────────────── */

.rail {
  width: 56px;
  flex: none;
  background: var(--grad-panel), var(--surface-2);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  /* clear of the traffic lights */
  padding: 34px 0 14px;
  -webkit-app-region: drag;
}

.rail .ic {
  -webkit-app-region: no-drag;
}

.ic {
  width: 26px;
  height: 26px;
  border-radius: var(--r-sm);
  background: var(--surface-3);
  flex: none;
  /* WAS `transparent`. The tile alone measured 1.07:1 on dark and 1.01:1 on
     light against the rail's own ground — on light the glyphs floated with no
     container at all. The hairline is the design's own device, and `.ic.on`
     still overrides it with the accent. */
  border: 1px solid var(--line-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  font-size: 15px;
  line-height: 1;
  cursor: default;
  padding: 0;
}

button.ic {
  font-family: var(--font-ui);
  cursor: pointer;
}

.ic.on {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), 0 0 14px var(--halo);
}

.ic.sp {
  margin-top: auto;
}

/*
 * THE APP'S MARK IN THE RAIL. Sized a little under the tile's own 26px so the
 * three discs sit inside the frame with air around them rather than touching
 * it — the tile is a container and the mark is its contents, and at 26px the
 * difference between those two readings is about two pixels.
 */
.cmark {
  display: block;
  width: 17px;
  height: 17px;
}

/*
 * EVERY icon in a rail tile, not only the conversation mark.
 *
 * The Skills tile shipped with an unclassed `<svg><use href="#i-skills"/></svg>`
 * and therefore fell back to the SVG default box rather than the 17px the mark
 * beside it uses — which is why it read as noticeably larger than its
 * neighbours. Owner, 2026-08-27: *"the skills svg is not sized correctly
 * compared to the other logo svg in left rail"*.
 *
 * Fixed on the CONTAINER rather than by adding `.cmark` to that one element, so
 * the next icon added to the rail is the right size without anybody remembering
 * to say so. `.cmark` keeps its own rule because it is used outside the rail too.
 */
.ic svg {
  display: block;
  width: 17px;
  height: 17px;
}

/*
 * WHAT PUSHES THE BOTTOM CLUSTER TO THE BOTTOM, now that the theme switch has
 * left the rail and taken its `margin-top: auto` with it. See the comment on
 * this element in `app/index.html` for why the margin could not simply move to
 * `#rail-update`: that tile is `hidden` most of the time, and a `display: none`
 * element's margin pushes nothing.
 *
 * `min-height: 0` so it collapses rather than forcing the rail taller in a very
 * short window; its whole job is to give away space it is not using.
 */
.railgap {
  flex: 1;
  min-height: 0;
}

/*
 * THE UPDATE INDICATOR — `#rail-update`, and DELIBERATELY NOT `.ic.on`.
 *
 * `.on` means "this is the view you are looking at" and is worn by `#rail-chat`.
 * Borrowing it would tie the update state to the selection state, so a later
 * change to how selection looks would silently change what "a new version is
 * available" looks like. Its 14px `--halo` also reads as CURRENT rather than
 * NEW, which is the opposite of what this tile says.
 *
 * So: the same accent frame and the same 3px soft ring the design already uses
 * for attention, and no glow. Measured on the rail's own composited ground
 * (`--grad-panel` over `--surface-2`, sampled at both ends of the gradient):
 * 9.92:1 → 10.62:1 dark, 5.38:1 → 5.71:1 light. The 1px frame clears 3:1 as a
 * component boundary in both.
 *
 * THE UNHAPPY STATES WEAR NO CLASS AT ALL — plain `.ic`, `--ink-3` on
 * `--surface-3`, 4.99:1 dark and 4.77:1 light. That is the point: a failing
 * check and a refused update are not good news dressed in accent, and colour is
 * never what tells them apart. The GLYPH does (`↑` against `!`) and the
 * accessible name does, both written from `presentUpdate` in
 * `app/core/update.ts`.
 *
 * NOTHING HERE MOVES. `@media (prefers-reduced-motion: reduce)` at the foot of
 * this file kills every animation in the app, so a pulse would be the only
 * signal for most people and no signal at all for the rest.
 */
.ic.upd {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ── the conversation panel ───────────────────────────────────────────────────
 *
 * Owner: *"why is my left rail still not expandable and collapsible"*. It never
 * was. This is the expanded state, and it is a SEPARATE COLUMN beside the rail
 * rather than the rail growing.
 *
 * WHY NOT WIDEN THE RAIL, which is the obvious reading of the request: the rail
 * is a fixed 56px flex item holding centred 26px tiles, and every one of them —
 * the mark, the update indicator, the version, sign out — is positioned by that
 * centring. Growing it to 260px would re-centre all six in a wide column and
 * turn a tidy strip into a sparse one, so the two controls would need separate
 * layouts for the two states. A second column leaves the rail exactly as it is
 * in both, which is also why closing the panel cannot disturb anything.
 *
 * `display: none` WHEN CLOSED, via `.hidden`, and not width 0 or a transform.
 * A panel that is merely invisible still holds Tab stops, so a keyboard user
 * would tab through a list of conversations they cannot see. That is the same
 * argument `#rail-update` already carries.
 */
.panel {
  width: 236px;
  flex: none;
  background: var(--grad-panel), var(--surface-2);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* clear of the traffic lights, matching the rail's own top padding */
  padding: 34px 0 14px;
  -webkit-app-region: drag;
}

.panel > * {
  -webkit-app-region: no-drag;
}

.panel-h {
  margin: 0 14px 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  -webkit-app-region: drag;
}

.panel-list {
  margin: 0;
  padding: 0 8px;
  list-style: none;
  overflow-y: auto;
  min-height: 0;
  scrollbar-width: thin;
}

.panel-tabs {
  display: flex;
  gap: 5px;
  margin: 0 14px 9px;
}

.panel-tabs button,
.panel-actions button {
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-3);
  border-radius: var(--r-sm);
  font: inherit;
  font-size: 10.5px;
  cursor: pointer;
  padding: 4px 6px;
}

.panel-tabs button[aria-pressed="true"] {
  border-color: var(--line-2);
  color: var(--ink);
}

.panel-item {
  margin-bottom: 4px;
}

.panel-item .panel-row {
  margin-bottom: 0;
}

.panel-actions {
  display: flex;
  justify-content: flex-end;
  gap: 2px;
  padding: 1px 4px 0;
  opacity: 0.25;
}

.panel-item:hover .panel-actions,
.panel-actions:focus-within {
  opacity: 1;
}

.panel-actions button:hover,
.panel-actions button:focus-visible {
  color: var(--accent);
  border-color: var(--line-2);
  outline: none;
}

/*
 * A BUTTON INSIDE THE LIST ITEM, not a clickable `<li>`. An `li` with a click
 * handler is not focusable, not operable by Return, and announces nothing; the
 * button is all three for free. `text-align: left` because a button centres its
 * text by default and a title is not a label.
 */
.panel-row {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  padding: 7px 9px;
  margin-bottom: 2px;
  cursor: pointer;
  font-family: var(--font-ui);
  color: var(--ink-2);
  font-size: 12.5px;
  line-height: 1.35;
  /* One line. A wrapped title makes the rows different heights, which turns a
     scannable list into a ragged one. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.panel-row:hover {
  background: var(--surface-3);
  color: var(--ink);
}

/*
 * THE CURRENT CONVERSATION, and it does not rely on colour alone. The accent
 * frame is the same device `.ic.on` uses for "this is the view you are looking
 * at", and `aria-current="true"` carries the same fact to anyone not seeing it.
 */
.panel-row.on {
  border-color: var(--accent);
  color: var(--ink);
  background: transparent;
}

.permission-row {
  cursor: default;
}

.panel-when {
  display: block;
  font-size: 10.5px;
  color: var(--ink-3);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}

.panel-empty {
  margin: 4px 14px;
  font-size: 12px;
  color: var(--ink-3);
  line-height: 1.45;
}

/* ── main column ──────────────────────────────────────────────────────────── */

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

.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--line);
  flex: none;
  -webkit-app-region: drag;
}

.topbar button,
.topbar .chip {
  -webkit-app-region: no-drag;
}

.crumb {
  font-size: 12px;
  color: var(--ink-3);
  letter-spacing: 0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.crumb b {
  color: var(--ink);
  font-weight: 500;
}

.grow {
  flex: 1;
  min-width: 0;
}

/* ── Skills workspace, 0.8.5 ──────────────────────────────────────────────
 *
 * This is deliberately a surface inside the existing main column, not a
 * second application shell. It inherits the Cora gradient, hairlines, type,
 * and outlined actions. Imported Markdown is shown in a textarea only; there
 * is no HTML sink in this surface.
 */
.skills-surface {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 32px clamp(18px, 4vw, 56px) 42px;
  background: var(--grad-panel), var(--surface);
  scrollbar-width: thin;
}

.skills-shell {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
}

.skills-heading,
.skills-section-head,
.skills-card-head,
.skills-editor-actions,
.skills-history-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.skills-history-row:is(button) {
  width: 100%;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.skills-history-row:is(button):hover,
.skills-history-row:is(button):focus-visible {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  outline: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  outline-offset: -1px;
}

.skills-heading,
.skills-section-head {
  justify-content: space-between;
}

.skills-heading {
  align-items: flex-start;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--line);
}

.skills-kicker {
  display: block;
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.skills-heading h1,
.skills-section-head h2,
.skills-history h3,
.skills-card h3 {
  margin: 0;
  color: var(--ink);
  font-weight: 500;
}

.skills-heading h1 {
  margin-top: 3px;
  font-size: clamp(24px, 3vw, 34px);
  letter-spacing: -0.02em;
}

.skills-heading p,
.skills-section-head p,
.skills-editor-note {
  margin: 5px 0 0;
  color: var(--ink-2);
  font-size: 12px;
}

.skills-status {
  margin: 14px 0 0;
  padding: 9px 11px;
  border-left: 2px solid var(--accent);
  background: var(--accent-soft);
  color: var(--ink-2);
  font-size: 12px;
}

.skills-layout {
  display: grid;
  grid-template-columns: minmax(240px, 0.85fr) minmax(360px, 1.15fr);
  gap: 20px;
  padding-top: 24px;
}

.skills-catalog,
.skills-editor {
  min-width: 0;
}

.skills-section-head {
  align-items: flex-end;
  margin-bottom: 12px;
}

.skills-section-head h2 {
  font-size: 16px;
}

.skills-list {
  display: grid;
  gap: 8px;
}

.skills-card {
  padding: 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--grad-card), color-mix(in srgb, var(--surface-3) 24%, transparent);
}

.skills-card.is-selected {
  border-color: var(--line-2);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.skills-card-head {
  justify-content: space-between;
}

.skills-card h3 {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--font-mono);
  font-size: 13px;
}

.skills-state,
.skills-name-chip {
  flex: none;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--ink-3);
  font-size: 10px;
  padding: 2px 7px;
  white-space: nowrap;
}

.skills-state.is-active {
  border-color: color-mix(in srgb, #54d79b 70%, transparent);
  color: #54d79b;
}

.skills-state.is-archived {
  color: var(--ink-3);
}

.skills-card p {
  margin: 8px 0 10px;
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1.45;
}

.skills-card-meta {
  display: block;
  margin-bottom: 10px;
  color: var(--ink-3);
  font-size: 10px;
}

.skills-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.skills-empty {
  margin: 18px 0;
  padding: 16px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink-2);
  font-size: 12px;
}

.skills-editor {
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-card), var(--surface-2);
}

.skills-editor .skills-section-head {
  align-items: flex-start;
}

.skills-field {
  display: grid;
  gap: 5px;
  margin-top: 14px;
  color: var(--ink-2);
  font-size: 11px;
}

.skills-field select,
.skills-field textarea {
  width: 100%;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
}

.skills-field select {
  padding: 8px 9px;
}

.skills-field textarea {
  min-height: 250px;
  padding: 11px;
  resize: vertical;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.55;
  user-select: text;
}

.skills-field select:focus-visible,
.skills-field textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.skills-editor-actions {
  flex-wrap: wrap;
  margin-top: 14px;
}

.skills-editor-actions .danger {
  color: #ef6b73;
}

.skills-history {
  margin-top: 22px;
  padding-top: 15px;
  border-top: 1px solid var(--line);
}

.skills-history h3 {
  font-size: 13px;
}

.skills-history-row {
  justify-content: space-between;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  color: var(--ink-2);
  font-family: var(--font-mono);
  font-size: 11px;
}

.skills-history-row span:last-child {
  color: var(--accent);
}

.skills-history-row {
  align-items: flex-start;
}

.skills-history-row span:last-child {
  max-width: 72%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* SKL-P8: the class picker is a chip row, not a `<select>`, so its label is a
   `<span>` and needs the weight the `<label>` wrapper used to give it. */
.skills-field-label {
  display: block;
  margin-bottom: 6px;
}

.skills-field .pv-row {
  margin: 0;
}

/* ── Memory 2.0 workspace, 0.8.13 ─────────────────────────────────────── */

.memory-surface {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 32px clamp(18px, 4vw, 56px) 42px;
  background: var(--grad-panel), var(--surface);
  scrollbar-width: thin;
}

.memory-shell {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
}

.memory-heading,
.memory-heading-actions,
.memory-toolbar,
.memory-card-head,
.memory-detail-head,
.memory-detail-actions,
.memory-forget-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.memory-heading {
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}

.memory-kicker {
  display: block;
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.memory-heading h1 {
  margin: 3px 0 0;
  color: var(--ink);
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 500;
  letter-spacing: -0.02em;
}

.memory-heading p {
  margin: 5px 0 0;
  color: var(--ink-2);
  font-size: 12px;
}

.memory-toolbar {
  flex-wrap: wrap;
  justify-content: space-between;
  padding: 18px 0;
}

.memory-filter {
  display: flex;
  min-width: 0;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}

.memory-filter button,
.mobile-thread-tabs button {
  min-height: 34px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  font-size: 10.5px;
  cursor: pointer;
}

.memory-filter button[aria-pressed="true"],
.mobile-thread-tabs button[aria-pressed="true"] {
  border-color: transparent;
  background: var(--surface-3);
  color: var(--ink);
}

/* MEM2-06: the per-class settings block. Mode chips reuse .memory-filter so
   the three chip rows on this page look and read the same. */
.memory-settings {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}

.memory-settings-head h2 {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

.memory-settings-head p {
  margin: 4px 0 8px;
  color: var(--ink-2);
  font-size: 12px;
}

.memory-setting-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}

.memory-setting-name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 132px;
}

.memory-setting-state {
  color: var(--ink-3);
  font-size: 11px;
}

.memory-setting-row[data-memory-setting-enabled="false"] .memory-setting-state {
  color: var(--ink-2);
  font-weight: 600;
}

.memory-setting-confirm,
.memory-setting-retention {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  color: var(--ink-2);
  font-size: 12px;
}

.memory-setting-retention input {
  width: 68px;
  min-height: 34px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
}

.memory-status {
  margin: 0 0 14px;
  padding: 9px 11px;
  border-left: 2px solid var(--accent);
  background: var(--accent-soft);
  color: var(--ink-2);
  font-size: 12px;
}

.memory-layout {
  display: grid;
  grid-template-columns: minmax(260px, 0.86fr) minmax(360px, 1.14fr);
  gap: 20px;
}

.memory-list {
  display: grid;
  align-content: start;
  gap: 8px;
  min-width: 0;
}

.memory-deleted-heading {
  margin: 14px 2px 2px;
  color: var(--ink-3);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.memory-deleted-card {
  border-style: dashed;
}

.memory-card {
  width: 100%;
  min-width: 0;
  padding: 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--grad-card), color-mix(in srgb, var(--surface-3) 24%, transparent);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.memory-card:hover,
.memory-card:focus-visible,
.memory-card.is-selected {
  border-color: var(--line-2);
  outline: none;
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.memory-card-head,
.memory-detail-head {
  justify-content: space-between;
  align-items: flex-start;
}

.memory-card h3,
.memory-detail h2 {
  min-width: 0;
  margin: 0;
  overflow: hidden;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.memory-card p {
  display: -webkit-box;
  margin: 8px 0 10px;
  overflow: hidden;
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1.45;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

.memory-origin-chip,
.memory-class-chip,
.memory-mode-locked {
  flex: none;
  padding: 2px 7px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--ink-3);
  font-size: 9.5px;
  white-space: nowrap;
}

.memory-origin-chip.is-saved {
  border-color: color-mix(in srgb, #54d79b 65%, transparent);
  color: #54d79b;
}

.memory-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  color: var(--ink-3);
  font-size: 10px;
}

.memory-empty {
  margin: 0;
  padding: 18px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink-2);
  font-size: 12px;
}

.memory-detail {
  min-width: 0;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-card), var(--surface-2);
}

.memory-detail-copy {
  display: grid;
  gap: 12px;
  margin-top: 16px;
}

.memory-detail-copy label {
  display: grid;
  gap: 5px;
  color: var(--ink-2);
  font-size: 11px;
}

.memory-detail-copy input,
.memory-detail-copy textarea {
  width: 100%;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  user-select: text;
}

.memory-detail-copy input {
  min-height: 40px;
  padding: 0 11px;
}

.memory-detail-copy textarea {
  min-height: 190px;
  padding: 11px;
  resize: vertical;
  line-height: 1.55;
}

.memory-detail-copy :is(input, textarea):read-only {
  color: var(--ink-2);
  cursor: default;
}

.memory-detail-actions {
  flex-wrap: wrap;
  margin-top: 14px;
}

.memory-detail-actions .danger,
.memory-forget-confirm .danger {
  color: #ef6b73;
}

.memory-forget-confirm {
  margin-top: 14px;
  padding: 12px;
  border: 1px solid color-mix(in srgb, #ef6b73 45%, var(--line));
  border-radius: var(--r-md);
  background: color-mix(in srgb, #ef6b73 7%, transparent);
}

.memory-forget-confirm strong,
.memory-forget-confirm span {
  display: block;
}

.memory-forget-confirm span {
  margin: 4px 0 10px;
  color: var(--ink-2);
  font-size: 11px;
}

.memory-source-note {
  margin: 12px 0 0;
  color: var(--ink-3);
  font-size: 10.5px;
}

.memory-mode {
  width: min(620px, 100%);
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.memory-mode-label {
  display: block;
  margin-bottom: 8px;
  color: var(--ink-2);
  font-size: 11px;
}

.memory-mode-options {
  display: flex;
  gap: 6px;
}

.memory-mode-options button {
  min-height: 38px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}

.memory-mode-options button[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

.memory-mode p {
  margin: 7px 0 0;
  color: var(--ink-3);
  font-size: 10.5px;
}

.memory-mode-locked {
  margin-top: 16px;
  border-color: color-mix(in srgb, #54d79b 65%, transparent);
  color: #54d79b;
}

/* ── Content library, 0.8.11 ───────────────────────────────────────────── */

.depot-surface {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 32px clamp(18px, 4vw, 56px) 42px;
  background: var(--grad-panel), var(--surface);
  scrollbar-width: thin;
}

.depot-shell {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
}

.depot-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}

.depot-kicker {
  display: block;
  color: var(--accent);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.depot-heading h1 {
  margin: 3px 0 0;
  color: var(--ink);
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 500;
  letter-spacing: -0.02em;
}

.depot-heading p {
  margin: 5px 0 0;
  color: var(--ink-2);
  font-size: 12px;
}

.depot-toolbar,
.depot-mobile-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
}

.depot-filter,
.depot-view {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--surface-2) 84%, transparent);
}

.depot-view {
  margin-left: auto;
}

.depot-filter button,
.depot-view button,
.depot-actions button,
.depot-preview button {
  min-height: 30px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
}

.depot-filter button[aria-pressed="true"],
.depot-view button[aria-pressed="true"] {
  border-color: var(--line-2);
  background: var(--surface);
  color: var(--accent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--ink) 6%, transparent);
}

.depot-status {
  min-height: 20px;
  margin: 12px 0;
  color: var(--ink-2);
  font-size: 11px;
}

.depot-items {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 12px;
}

.depot-items[data-layout="list"] {
  grid-template-columns: minmax(0, 1fr);
}

.depot-card {
  display: grid;
  min-width: 0;
  grid-template-rows: auto minmax(52px, auto) auto;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-card), var(--surface-2);
}

.depot-items[data-layout="list"] .depot-card {
  grid-template-columns: 104px minmax(0, 1fr) auto;
  grid-template-rows: minmax(82px, auto);
  align-items: center;
}

.depot-thumb {
  display: grid;
  width: 100%;
  aspect-ratio: 16 / 10;
  place-items: center;
  overflow: hidden;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: color-mix(in srgb, var(--surface-3) 58%, transparent);
  color: var(--accent);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 13px;
}

.depot-items[data-layout="list"] .depot-thumb {
  height: 100%;
  aspect-ratio: auto;
  border-right: 1px solid var(--line);
  border-bottom: 0;
}

.depot-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.depot-copy {
  min-width: 0;
  padding: 12px 13px 9px;
}

.depot-card-head {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.depot-card-head strong {
  min-width: 0;
  overflow: hidden;
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.depot-origin {
  flex: none;
  padding: 2px 6px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--ink-3);
  font-size: 8px;
  white-space: nowrap;
}

.depot-origin.is-created {
  border-color: color-mix(in srgb, #54d79b 52%, var(--line));
  color: #54d79b;
}

:root[data-theme="light"] .depot-origin.is-created {
  border-color: color-mix(in srgb, #1f7254 62%, var(--line));
  color: #1f7254;
}

.depot-card p {
  margin: 7px 0 0;
  color: var(--ink-3);
  font-size: 9.5px;
}

.depot-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 0 9px 10px;
}

.depot-items[data-layout="list"] .depot-actions {
  justify-content: flex-end;
  padding: 10px;
}

.depot-actions button {
  min-height: 27px;
  padding-inline: 7px;
  border-color: var(--line);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
}

.depot-actions button:hover,
.depot-actions button:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.depot-actions button.danger {
  color: #ef6b73;
}

:root[data-theme="light"] .depot-actions button.danger {
  color: #a12d3a;
}

.depot-empty {
  display: grid;
  min-height: 280px;
  margin-top: 8px;
  place-items: center;
  align-content: center;
  padding: 36px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-lg);
  color: var(--ink-3);
  text-align: center;
}

.depot-empty svg {
  width: 38px;
  height: 38px;
  margin-bottom: 12px;
  color: var(--accent);
}

.depot-empty h2,
.depot-empty h3 {
  margin: 0;
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
}

.depot-empty p {
  margin: 5px 0 0;
  font-size: 11px;
}

.depot-more {
  display: block;
  margin: 18px auto 0;
}

.depot-preview {
  position: fixed;
  z-index: 120;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 30px;
  background: color-mix(in srgb, #000 76%, transparent);
  backdrop-filter: blur(12px);
}

.depot-preview-card {
  display: flex;
  width: min(980px, 94vw);
  max-height: 92vh;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line-2);
  border-radius: 14px;
  background: var(--surface-2);
  box-shadow: 0 24px 80px color-mix(in srgb, #000 52%, transparent);
}

.depot-preview-card header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}

.depot-preview-card header strong {
  flex: 1;
  overflow: hidden;
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.depot-preview-card header button {
  width: 34px;
  padding: 0;
  border-color: var(--line);
  font-size: 18px;
}

.depot-preview-card img {
  display: block;
  width: 100%;
  max-height: calc(92vh - 52px);
  min-height: 0;
  object-fit: contain;
  background: var(--surface);
}

/* ── thread ───────────────────────────────────────────────────────────────── */

.thread {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 22px 26px 8px;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
}

.threadinner {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
}

.bub {
  margin: 0 0 18px;
  max-width: 100%;
  user-select: text;
}

.bub-u {
  margin-left: auto;
  background: var(--grad-card), var(--surface-3);
  border-radius: var(--r-lg);
  padding: 10px 14px;
  max-width: 72%;
  width: fit-content;
}

.bub-image-anchor {
  display: none;
}

.bub-u p {
  margin: 0;
  font-size: 13.5px;
  color: var(--ink);
  line-height: 1.5;
  font-weight: 400;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.bub-a p {
  margin: 0;
  font-size: 13.5px;
  color: var(--ink-2);
  line-height: 1.65;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.bub-a.failed p,
.bub-a.cancelled p {
  color: var(--ink-3);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * PICTURES IN THE FEED — VS-17.
 *
 * NO NEW COLOUR TOKEN IS DEFINED HERE, and that is a rule rather than a
 * coincidence: `app/tests/theme.test.ts` asserts that every colour token in
 * `:root` is restated in the light block, so a token added for one theme and
 * forgotten in the other is a failing test. Everything below is built from
 * tokens that already exist in both.
 *
 * `.gallery` is EMPTY on nearly every message. `display: contents` would be the
 * tidy way to make an empty one weigh nothing, and it is wrong — it removes the
 * box, so `:empty` cannot be styled and the gap below would apply to the
 * children instead. `:empty { display: none }` is the version that actually
 * costs nothing when there is no picture.
 * ══════════════════════════════════════════════════════════════════════════ */

.gallery {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0 0 18px;
}

.gallery:empty {
  display: none;
}

.artifact-card {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: min(100%, 560px);
  padding: 12px;
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--grad-card), var(--surface-2);
  box-shadow: var(--shadow-1);
}

.artifact-mark {
  display: grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--line));
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent-soft) 52%, transparent);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 13px;
}

.artifact-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
}

.artifact-eyebrow {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

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

.artifact-detail {
  overflow: hidden;
  color: var(--ink-3);
  font-size: 10px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.artifact-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.artifact-open,
.artifact-comments-toggle {
  min-height: 34px;
  padding: 7px 10px;
  border-color: var(--line-2);
  background: transparent;
  color: var(--ink-2);
  white-space: nowrap;
}

.artifact-open:hover,
.artifact-open:focus-visible,
.artifact-comments-toggle:hover,
.artifact-comments-toggle:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.artifact-comments {
  grid-column: 1 / -1;
  min-width: 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.artifact-comments[hidden],
.artifact-comment-form[hidden] {
  display: none;
}

.artifact-comments-status {
  margin: 0 0 8px;
  color: var(--ink-3);
  font-size: 10px;
}

.artifact-comments-list {
  display: flex;
  max-height: 260px;
  flex-direction: column;
  gap: 7px;
  overflow-y: auto;
}

.artifact-comment {
  padding: 8px 9px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: color-mix(in srgb, var(--surface-3) 82%, transparent);
}

.artifact-comment.is-resolved {
  opacity: 0.72;
}

.artifact-comment-body {
  margin: 0;
  color: var(--ink-2);
  font-size: 11px;
  line-height: 1.45;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.artifact-comment-footer,
.artifact-comment-actions {
  display: flex;
  align-items: center;
}

.artifact-comment-footer {
  justify-content: space-between;
  gap: 8px;
  margin-top: 7px;
}

.artifact-comment-state {
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.artifact-comment-actions {
  gap: 5px;
}

.artifact-comment-actions button,
.artifact-comment-submit {
  min-height: 28px;
  padding: 4px 8px;
  border-color: var(--line-2);
  background: transparent;
  color: var(--ink-2);
  font-size: 10px;
}

.artifact-comment-actions button:hover,
.artifact-comment-actions button:focus-visible,
.artifact-comment-submit:hover,
.artifact-comment-submit:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.artifact-comment-actions .danger {
  color: #ef6b73;
}

:root[data-theme="light"] .artifact-comment-actions .danger {
  color: #a12d3a;
}

.artifact-comment-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 7px;
  margin-top: 9px;
}

.artifact-comment-input {
  min-height: 54px;
  max-height: 140px;
  resize: vertical;
  padding: 8px 9px;
  border: 1px solid var(--line-2);
  border-radius: 9px;
  outline: none;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
  line-height: 1.4;
}

.artifact-comment-input:focus {
  border-color: var(--accent);
}

.consent-host:empty {
  display: none;
}

.consent-host {
  margin: 0 0 18px;
}

.consent-card {
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--grad-card), var(--surface-2);
  padding: 14px 16px;
}

.consent-card h3 {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 500;
}

.consent-card > code {
  display: block;
  margin-bottom: 8px;
  overflow-wrap: anywhere;
  color: var(--ink-2);
  font-size: 11.5px;
}

.consent-card p {
  margin: 3px 0;
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1.5;
}

.consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
}

.consent-actions .btn {
  padding: 7px 11px;
}

.pic {
  margin: 0;
  border-radius: var(--r-lg);
  background: var(--surface-2);
  overflow: hidden;
  position: relative;
}

.pic-frame {
  display: flex;
  align-items: center;
  justify-content: center;
  /* A floor, so the placeholder and a very small picture both look deliberate
     rather than like a collapsed box. */
  min-height: 72px;
  background: var(--surface-2);
  border-radius: inherit;
  overflow: hidden;
}

/*
 * `max-height` AS WELL AS `max-width`. A tall narrow picture — a screenshot of
 * a phone, a chart — would otherwise push the composer off the bottom of the
 * window and take the scroll position with it, which is the one thing a
 * transcript must not do while an answer is arriving.
 */
.pic-img {
  display: block;
  max-width: 100%;
  max-height: 60vh;
  width: auto;
  height: auto;
}

.pic-gone {
  margin: 0;
  padding: 20px 14px;
  font-size: 12.5px;
  color: var(--ink-3);
  text-align: center;
}

/*
 * The strip under the picture. Right-aligned, because that is where the owner
 * asked for the control and where the work card's Cancel/Retry group already
 * sits — so a finished picture and one still being made put their actions in
 * the same place.
 */
.pic-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: var(--surface-2);
}

.pic-save {
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 6px 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  transition: color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}

.pic-save:hover:not(:disabled),
.pic-save:focus-visible {
  background: var(--surface);
}

.pic-save:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.pic-save:focus-visible {
  outline: none;
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.pic-save:disabled {
  color: var(--ink-3);
  cursor: default;
}

/*
 * `[hidden]` IS RESTATED, and the reason is written up at `.chip` above: the
 * user-agent rule for `[hidden]` is `display: none` at ELEMENT-selector
 * specificity, and any class rule that sets `display` beats it. `.pic-save`
 * does not set `display` today — this line is here so that the day somebody
 * makes it a flex row of two things, `button.hidden = true` in `render.ts`
 * still hides it rather than silently doing nothing.
 */
.pic-save[hidden] {
  display: none;
}

.pic-tool {
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  padding: 6px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.pic-tool:hover:not(:disabled),
.pic-tool:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--surface);
}

.pic-tool:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.pic-tool:disabled {
  color: var(--ink-3);
  cursor: default;
}

.pic-tool[hidden] {
  display: none;
}

.pic-versions {
  margin-right: auto;
}

.image-compare {
  position: fixed;
  z-index: 110;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 28px;
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(18px);
}

.image-compare-shell {
  width: min(1180px, 100%);
  max-height: calc(100dvh - 56px);
  overflow: hidden;
  border: 1px solid var(--line-2);
  border-radius: 20px;
  background: var(--surface);
  box-shadow: 0 24px 80px color-mix(in srgb, #000 52%, transparent);
}

.image-compare-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line-1);
}

.image-compare-header span {
  display: block;
  margin-bottom: 4px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--accent);
}

.image-compare-header h2 {
  margin: 0;
  font-size: 20px;
  color: var(--ink);
}

.image-compare-close {
  width: 34px;
  height: 34px;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-2);
  font-size: 22px;
  cursor: pointer;
}

.image-compare-body {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  min-height: 420px;
  max-height: calc(100dvh - 150px);
}

.image-version-tree {
  overflow: auto;
  padding: 16px 12px;
  border-right: 1px solid var(--line-1);
  background: var(--surface-2);
}

.image-version-tree > strong {
  display: block;
  padding: 0 8px 10px;
  color: var(--ink);
  font-size: 12px;
}

.image-version-item {
  display: grid;
  width: calc(100% - min(calc(var(--version-depth) * 12px), 48px));
  margin: 0 0 6px min(calc(var(--version-depth) * 12px), 48px);
  padding: 9px 10px;
  text-align: left;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.image-version-item small {
  margin-top: 3px;
  color: var(--ink-3);
  font-size: 10px;
}

.image-version-item[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}

.image-compare-panes {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  overflow: auto;
  padding: 20px;
}

.image-compare-pane {
  min-width: 0;
}

.image-compare-pane > span {
  display: block;
  margin-bottom: 8px;
  color: var(--ink-3);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.image-compare-frame {
  display: grid;
  place-items: center;
  width: 100%;
  max-height: calc(100dvh - 270px);
  overflow: hidden;
  border: 1px solid var(--line-2);
  border-radius: 14px;
  background: var(--surface-2);
}

.image-compare-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.image-version-choose {
  width: 100%;
  margin-top: 10px;
  padding: 9px 12px;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: transparent;
  color: var(--accent);
  font-weight: 650;
  cursor: pointer;
}

.image-version-choose:disabled {
  border-color: var(--line-2);
  color: var(--ink-3);
  cursor: default;
}

.image-compare-error {
  position: absolute;
  right: 20px;
  bottom: 18px;
  left: 20px;
  margin: 0;
  padding: 10px 12px;
  border: 1px solid #e56f76;
  border-radius: 10px;
  background: var(--surface);
  color: #e56f76;
}

body.image-compare-open {
  overflow: hidden;
}

@media (max-width: 760px) {
  .pic-actions {
    flex-wrap: wrap;
  }

  .pic-versions {
    flex-basis: 100%;
    margin-right: 0;
  }

  .image-compare {
    padding: 0;
  }

  .image-compare-shell {
    width: 100%;
    height: 100dvh;
    max-height: none;
    border: 0;
    border-radius: 0;
  }

  .image-compare-body {
    grid-template-columns: 1fr;
    max-height: calc(100dvh - 75px);
  }

  .image-version-tree {
    display: flex;
    gap: 7px;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--line-1);
  }

  .image-version-tree > strong {
    display: none;
  }

  .image-version-item {
    flex: 0 0 auto;
    width: auto;
    margin: 0;
  }

  .image-compare-panes {
    grid-template-columns: 1fr;
  }

  .image-compare-frame {
    max-height: 48dvh;
  }
}

/*
 * EXPAND — the quiet twin of `.pic-save`, on the opposite corner.
 *
 * The card's own caption says the picture is "ready to expand or save", so the
 * control has to exist wherever that caption does. It used to be `mobile-only`,
 * which meant every desktop reader was told about a button that CSS had hidden
 * from them, and a 1024-square picture stayed boxed at the width of the bubble.
 */
/*
 * OWNER, 2026-08-25: "the expand button is not visible enough, the arrow is not
 * contrasty, it need to look better".
 *
 * It was styled as a quiet CARD control — theme background, muted ink, and
 * `opacity: .35` until hover. That is the right treatment for a button on the
 * page's own surface and the wrong one for a button sitting ON A PHOTOGRAPH,
 * because the surface behind it is not the theme, it is whatever the picture
 * happens to be. On the owner's beach photo — pale sand, bright water — a grey
 * glyph at a third opacity had nothing to contrast against.
 *
 * So it stops borrowing the theme and brings its own: a dark scrim with a light
 * glyph, which is legible over ANY picture because it supplies both sides of
 * the contrast itself. The same reasoning the phone breakpoint already used;
 * this is that treatment applied everywhere, which is also one rule fewer.
 *
 * FULLY OPAQUE AND NOT HOVER-GATED. A control the reader cannot see until they
 * happen to hover is a control most readers never find — and this is the only
 * way to view a 1024-square picture at its own size.
 */
.pic-expand {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  font: inherit;
  /* The glyph is a hairline at small sizes; size and weight are what make it read. */
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  border: 1px solid rgba(255, 255, 255, 0.34);
  border-radius: 9px;
  background: rgba(8, 20, 30, 0.62);
  color: #f6fbff;
  cursor: pointer;
  /* Carries the button on light pictures; invisible on dark ones. */
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.34);
  backdrop-filter: blur(10px);
  transition: background 0.14s ease, border-color 0.14s ease, transform 0.14s ease;
}

.pic-expand:hover {
  background: rgba(8, 20, 30, 0.82);
  border-color: rgba(255, 255, 255, 0.6);
  transform: translateY(-1px);
}

.pic-expand:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), 0 1px 3px rgba(0, 0, 0, 0.34);
}

/*
 * The expanded picture is the SAME <img> lifted above the shell by CSS. No
 * second source is assigned, so expanding costs no request and cannot show a
 * different picture from the one already in the transcript.
 */
.pic.is-image-expanded {
  position: fixed;
  z-index: 90;
  inset: 0;
  display: flex;
  width: 100%;
  height: 100dvh;
  padding: 56px 48px 48px;
  flex-direction: column;
  justify-content: center;
  border-radius: 0;
  background: color-mix(in srgb, var(--surface) 97%, transparent);
  box-shadow: none;
  backdrop-filter: blur(18px);
}

.pic.is-image-expanded .pic-frame {
  width: 100%;
  min-height: min(70vh, 640px);
  max-height: calc(100dvh - 116px);
  border: 1px solid var(--line-2);
  border-radius: 17px;
}

.pic.is-image-expanded .pic-img {
  max-width: 100%;
  max-height: calc(100dvh - 118px);
}

.pic.is-image-expanded .pic-expand {
  position: fixed;
  top: 16px;
  left: 20px;
  opacity: 0.96;
}

/*
 * The actions strip SURVIVES expansion — it is the only way to download from
 * here, and it used to be hidden outright (`display: none` on the receipt),
 * which was survivable when Download floated over the picture and is not now
 * that it lives in the strip. The receipt's prose goes, because "Image ready"
 * is a status for a card in a transcript, not a caption for a picture filling
 * the screen; its buttons stay.
 */
.pic.is-image-expanded .image-work-receipt {
  background: transparent;
}

.pic.is-image-expanded .image-work-copy {
  display: none;
}

.pic.is-image-expanded .pic-actions,
.pic.is-image-expanded .image-work-receipt {
  justify-content: center;
  padding-top: 12px;
}

.pic.is-image-expanded .pic-actions {
  background: transparent;
}

/*
 * The overlay is `position: fixed`, so the transcript underneath keeps its own
 * scrollbar and scrolls under the picture on a wheel gesture. Locking the body
 * is what stops the reader losing their place while the picture is open. This
 * class was already being set on <body> by `render.ts` and matched no rule at
 * all, so the lock has never happened.
 */
body.image-open {
  overflow: hidden;
}

/*
 * A PICTURE THE PERSON SENT, INSIDE THEIR OWN MESSAGE.
 *
 * OWNER, 2026-08-25: "it doesnt need to be full size image just a middle sized
 * thumbnail, literally same how you visualize it claude client".
 *
 * Medium and capped rather than full-width: a user bubble is narrow and
 * right-aligned, and this picture is part of the sentence rather than the
 * answer to it. Generated pictures keep the full-width gallery below the
 * message — the two are different things and are drawn differently on purpose.
 */
.bub-attached {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

.bub-attached:not(:empty) {
  margin-bottom: 8px;
}

.bub-attached .pic-attached {
  width: auto;
  max-width: min(260px, 100%);
  border-radius: 12px;
  background: transparent;
}

.bub-attached .pic-attached .pic-frame {
  min-height: 0;
  border-radius: inherit;
}

.bub-attached .pic-attached .pic-img {
  max-height: 260px;
  border-radius: inherit;
}

/*
 * NO ACTION STRIP ON AN ATTACHMENT. Download and Expand belong to a picture
 * Cora produced — the person already has this one, on the machine they attached
 * it from, and offering to give it back to them is noise. The frame stays
 * clickable through the transcript's own affordances.
 */
.bub-attached .pic-attached .pic-actions,
.bub-attached .pic-attached .pic-expand {
  display: none;
}

/* the caret, while text is still arriving */
.caret {
  display: inline-block;
  width: 6px;
  height: 13px;
  margin-left: 2px;
  vertical-align: -2px;
  background: var(--accent);
  opacity: 0.85;
  animation: blink 1.1s steps(2, start) infinite;
}

@keyframes blink {
  to {
    opacity: 0.15;
  }
}

/* the "thinking" state, before the first token */
.waiting {
  display: inline-flex;
  gap: 5px;
  align-items: center;
  vertical-align: middle;
}

/*
 * THE PULSE RUNS DOWNWARDS, and the resting opacity is the readable one. It
 * used to rest at 0.3 and pulse UP to 0.95, which measured 1.93:1 on dark and
 * 1.52:1 on light — and on light no opacity at 0.3 can reach 3:1, because pure
 * black at 0.3 over white is 2.10:1. Worse, `prefers-reduced-motion` disables
 * the animation entirely, so a person who asked for less motion was left with
 * three invisible squares as the ONLY sign that anything was happening.
 * Resting at 0.85 matches `.caret` exactly: 7.66:1 on dark, 4.36:1 on light,
 * and still readable when it is frozen.
 */
.waiting i {
  width: 4px;
  height: 4px;
  border-radius: 1px;
  background: var(--accent);
  opacity: 0.85;
  animation: pulse 1.25s ease-in-out infinite;
}

.waiting i:nth-child(2) {
  animation-delay: 0.16s;
}

.waiting i:nth-child(3) {
  animation-delay: 0.32s;
}

@keyframes pulse {
  50% {
    opacity: 0.25;
  }
}

/* ── the entry hero ───────────────────────────────────────────────────────── */

.entry {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 24px;
  text-align: center;
}

.entry-q {
  font-size: 30px;
  font-weight: 300;
  letter-spacing: -0.022em;
  color: var(--ink);
  margin: 0;
  line-height: 1.22;
}

.pv-row {
  display: flex;
  gap: 7px;
  justify-content: center;
  flex-wrap: wrap;
}

.fine {
  font-size: 10.5px;
  color: var(--ink-3);
  line-height: 1.5;
  margin: 0;
  max-width: 34ch;
}

/* ── chips ────────────────────────────────────────────────────────────────── */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.09em;
  padding: 5px 9px;
  border-radius: var(--r-sm);
  border: 1px solid currentColor;
  background: transparent;
  white-space: nowrap;
  text-transform: uppercase;
  cursor: pointer;
  font-weight: 400;
  /*
   * WAS 0.55, AND THAT WAS A REAL FAILURE IN BOTH THEMES. These three name how
   * much of what you type leaves the machine, so an unreadable one is not a
   * cosmetic problem. At 0.55 on white even PURE BLACK tops out at 4.76:1, so
   * AA was unreachable at any token value: the unselected labels measured
   * 2.04 / 2.83 / 3.37 on light and 2.07 / 2.80 / 3.91 on dark.
   *
   * THEN IT WAS 0.82, AND THAT STILL FAILED — measured on the ground these
   * chips are actually on. 0.82 was checked against `--surface`: #ffffff in
   * light, where PUBLIC reads 4.63:1 and passes. But `.entry` sets no
   * background, so the picker sits on the BODY GRADIENT, and mid-viewport that
   * is rgb(238,243,250), not white. Public measured 4.31:1 there — under AA,
   * on the real pixels, while the arithmetic against the wrong ground said it
   * was fine. Sampled from a rasterised copy of the page's own computed
   * background, with a solid-colour control proving the sampler byte-exact.
   *
   * 0.90 clears AA on BOTH real grounds with room: the worst of all six is
   * 5.15:1 (light Public), against 4.29:1 before. Every colour token is
   * untouched — the ramp in `docs/design/cora.html` is deliberate and darkening
   * --p0 to fix this would have collapsed Public toward Business (a 1.26:1 step
   * down to 1.10:1) to repair something that was never the tokens' fault.
   *
   * The dim can afford to be this shallow now only because it no longer carries
   * selection — the frame below does. That is the whole reason 0.82 looked
   * necessary.
   */
  opacity: 0.9;
}

/*
 * THE FRAME IS WHICH ONE IS SELECTED. OPACITY CANNOT BE, AND THE ARITHMETIC
 * SAYS SO.
 *
 * Raising the dim from 0.55 to 0.82 above fixed a real AA failure and exposed a
 * worse one hiding behind it. Selection was being signalled by opacity alone —
 * 1.0 against 0.82, a ratio of 1.22 — while the three tones differ from each
 * other by much more than that, ON PURPOSE. `docs/design/cora.html`: "the
 * privacy ramp runs in opposite directions per theme — brightest means most
 * sealed in dark, darkest means most sealed in light — because in both cases
 * the strictest class has to be the one that claims the most attention."
 *
 * So the loudest chip is meant to be RESTRICTED, whether or not it is selected,
 * and a 1.22 dim can never outrank a ramp built to be read at a glance.
 * Measured on --surface in dark: Restricted UNSELECTED 7.46:1 against Business
 * SELECTED 6.75:1. The unselected chip won. Someone checking which privacy
 * class was armed — the control that names how much of what they type leaves
 * this machine — would have read the wrong one. At 0.55 the dim was steep
 * enough to hide this; the AA fix did not cause it, it uncovered it.
 *
 * The only mark left was `box-shadow: 0 0 0 3px var(--accent-soft)`, which is
 * 1.17:1 in dark and 1.26:1 in light. Not a mark. Reaching 3:1 with that ring
 * needs alpha 0.47 dark / 0.67 light, which is a glow, not this design.
 *
 * The reference already answers it, twice: `.conv.on` marks the active
 * conversation by its border, and the notes say "the rail's active mark is a
 * 1px frame rather than a filled tile" and "the frame is the affordance". So
 * the frame carries selection and the tone keeps carrying severity. The two
 * stop competing because they are no longer the same channel.
 *
 * Scoped to `[aria-pressed="false"]` and NOT to `.chip`, because `#class-lock`
 * in the topbar is a static indicator with no pressed state — the reference
 * draws that one framed, and it stays framed. `border-width` is untouched, so
 * nothing moves by a pixel when the selection changes.
 */
.chip[aria-pressed="false"] {
  border-color: transparent;
}

.chip[aria-pressed="true"] {
  opacity: 1;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.chip[disabled] {
  cursor: default;
  opacity: 1;
}

.chip .sw {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  flex: none;
}

/* The selected privacy class is healthy regardless of which class it is. */
.chip[aria-pressed="true"] .sw,
#class-lock .sw {
  background: #54d79b;
  box-shadow: 0 0 0 3px rgba(84, 215, 155, 0.12);
}

.pv0 {
  color: var(--p0);
}
.pv1 {
  color: var(--p1);
}
.pv2 {
  color: var(--p2);
}

/* ── notice ───────────────────────────────────────────────────────────────── */

.notice {
  flex: none;
  margin: 0 auto 2px;
  width: 100%;
  max-width: 760px;
  padding: 0 26px;
}

.notice-in {
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--grad-card), var(--surface-2);
  padding: 13px 16px;
  user-select: text;
}

.notice-in h4 {
  margin: 0 0 5px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -0.005em;
}

.notice-in p {
  margin: 0 0 3px;
  font-size: 12.5px;
  color: var(--ink-2);
  line-height: 1.55;
}

.notice-in p:last-child {
  margin-bottom: 0;
}

/*
 * The one button a notice can carry — today only the update panel's. It is
 * `.btn.quiet` (—ink-3 on a `--line-2` frame, 5.39:1 dark / 5.05:1 light on the
 * panel's own ground), because "Update and restart" is an offer and not the
 * thing the person came here to do; the composer's Send keeps the accent frame.
 *
 * `display: block` rather than the flex row the composer uses: there is one
 * button, and it belongs under the sentence that explains it rather than beside
 * it. When `presentUpdate` gives no action — the refused state, and all three
 * busy states — this element is `.hidden`, and there is then nothing in the
 * panel to press.
 */
.notice-act {
  display: block;
  margin-top: 11px;
  padding: 8px 13px;
}

/*
 * THE DOWNLOAD BAR, AND IT IS DECORATION. READ WHY BEFORE TRUSTING IT.
 *
 * The percentage is already on the screen as TEXT — `presentUpdate` puts it in
 * the panel heading and in the tile's own accessible name — and this is a
 * second view of that same number. That order is not a preference. The rule at
 * the foot of this file disables every animation and transition under
 * `prefers-reduced-motion`, and this app has been bitten by it once already:
 * `.waiting`'s three dots were the ONLY sign anything was happening and they
 * became three invisible squares. A progress bar as the only progress cue is
 * the identical mistake, so the bar carries `aria-hidden` in the markup and
 * nothing depends on seeing it move.
 *
 * NO `transition` ON THE WIDTH. It would be dropped under reduced motion
 * anyway, and the width already only changes on a whole-percent boundary — the
 * Rust side throttles to one event per percent, so there is nothing to smooth.
 *
 * Both tokens are defined in the `:root` and `:root[data-theme="light"]`
 * blocks, so one rule dresses both themes and there is no way to style one and
 * forget the other.
 */
.uprog {
  margin-top: 11px;
  height: 4px;
  border-radius: 2px;
  background: var(--line-2);
  overflow: hidden;
}

.uprog i {
  display: block;
  height: 100%;
  background: var(--accent);
}

/* ── composer ─────────────────────────────────────────────────────────────── */

.composer-wrap {
  flex: none;
  padding: 14px 26px 20px;
}

.composer {
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  display: flex;
  gap: 10px;
  align-items: flex-end;
}

.pending-files {
  width: 100%;
  max-width: 760px;
  margin: 0 auto 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pending-file {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-width: 0;
  max-width: 240px;
  gap: 7px;
  padding: 5px 7px 5px 9px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink-2);
  font-size: 11.5px;
}

.pending-file > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pending-file button {
  border: 0;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  padding: 0 2px;
  font: inherit;
}

/*
 * A STAGED PICTURE SHOWS THE PICTURE. Owner, 2026-08-25.
 *
 * Square, because a fixed square is the only shape that stays a grid when the
 * photographs are portrait, landscape and square in the same message —
 * `object-fit: cover` crops to it rather than letting each tile pick its own
 * width. The remove control sits ON the tile, top-right, so the tile stays the
 * size of the picture instead of a picture plus a column for a button.
 */
.pending-thumb {
  position: relative;
  width: 56px;
  height: 56px;
  max-width: none;
  padding: 0;
  overflow: visible;
  border-radius: 10px;
  border-color: var(--line-2);
}

.pending-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  display: block;
}

.pending-thumb .pending-remove {
  position: absolute;
  top: -6px;
  right: -6px;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 50%;
  /*
   * Opaque, not translucent. It overhangs the tile's corner, so half of it sits
   * on the composer's ground and half on the photograph — and a photograph can
   * be any colour, including the colour of an "×".
   */
  background: var(--surface);
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1;
}

.pending-thumb .pending-remove:hover,
.pending-thumb .pending-remove:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

/*
 * THE UPLOAD STATE, ON THE TILE.
 *
 * The file stays local until Send fixes the first conversation boundary. It
 * then shows progress while bytes are prepared and uploaded, so a stalled
 * first send does not look like a completed attachment.
 *
 * INDETERMINATE ON PURPOSE. The upload is a fetch with a JSON body and reports
 * no progress events, and even a perfect byte count would reach 100% and then
 * sit there through the provider's moderation call — an unbounded round trip to
 * somebody else. A bar that fills and stops is a worse lie than a bar that
 * never claimed a number. So this is a travelling sliver that says "working",
 * and it stops when the work does.
 *
 * NO NEW TOKEN. `theme.test.ts` requires any token defined in `:root` to be
 * restated in the light block, so a new one added for this and forgotten in the
 * other theme is a failing build. The travelling band is `--accent`; the failed
 * state is `#ef6b73`, the same error red this file already writes literally in
 * five other places, because there is no error token to reach for and inventing
 * one here would mean touching all six sites during a release.
 */
.pending-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  border-radius: 0 0 var(--r-md) var(--r-md);
  overflow: hidden;
  background: color-mix(in srgb, var(--ink-3) 28%, transparent);
  opacity: 0;
  transition: opacity 0.18s ease;
}

.pending-thumb .pending-progress {
  border-radius: 0 0 10px 10px;
}

.pending-file[data-state="preparing"] .pending-progress,
.pending-file[data-state="uploading"] .pending-progress {
  opacity: 1;
}

.pending-file[data-state="preparing"] .pending-progress::before,
.pending-file[data-state="uploading"] .pending-progress::before {
  content: "";
  position: absolute;
  inset: 0;
  width: 42%;
  border-radius: inherit;
  background: var(--accent);
  animation: pending-travel 1.05s ease-in-out infinite;
}

/* Stored is the resting state and says nothing — the picture IS the receipt. */
.pending-file[data-state="failed"] {
  border-color: color-mix(in srgb, #ef6b73 60%, var(--line-2));
}

.pending-file[data-state="failed"] .pending-progress {
  opacity: 1;
  background: color-mix(in srgb, #ef6b73 80%, transparent);
}

@keyframes pending-travel {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(238%); }
}

/*
 * A person who has asked for less movement gets a steady band instead of a
 * travelling one — still visibly "working", without the motion.
 */
@media (prefers-reduced-motion: reduce) {
  .pending-file[data-state="preparing"] .pending-progress::before,
  .pending-file[data-state="uploading"] .pending-progress::before {
    animation: none;
    width: 100%;
    opacity: 0.55;
  }
}

.drop-hint {
  width: 100%;
  max-width: 760px;
  margin: 0 auto 8px;
  padding: 12px;
  border: 1px dashed var(--accent);
  border-radius: var(--r-md);
  color: var(--accent);
  font-size: 12px;
  text-align: center;
}

.attach {
  width: 42px;
  height: 42px;
  padding: 0;
  font-size: 20px;
  line-height: 1;
}

.cinput {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--grad-card), var(--surface-2);
  box-shadow: 0 1px 0 var(--hair) inset;
  padding: 11px 13px;
  font-size: 13px;
  font-family: var(--font-ui);
  line-height: 1.5;
  color: var(--ink);
  resize: none;
  max-height: 180px;
  min-height: 42px;
  outline: none;
  user-select: text;
}

.cinput::placeholder {
  color: var(--ink-3);
}

.cinput:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft), 0 1px 0 var(--hair) inset;
}

/* NO FILLED BUTTONS ANYWHERE. The frame is the affordance. */
.btn {
  flex: none;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r-md);
  padding: 11px 17px;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  font-family: var(--font-ui);
  cursor: pointer;
  transition: box-shadow 0.14s ease;
}

.btn:hover {
  box-shadow: 0 0 0 3px var(--accent-soft), 0 0 14px var(--halo);
}

.btn:active {
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.btn.quiet {
  color: var(--ink-3);
  border-color: var(--line-2);
}

/* ── Sign in with Google ──────────────────────────────────────────────────
 * Google's own button is white, pill-shaped and set in Roboto, which is three
 * fights with a shell built around a 1px frame, small rounding and the site's
 * own ground. So this keeps Cora's button and carries Google's mark inside it —
 * the G geometry unchanged, but drawn in ONE colour through `currentColor`, so
 * it inherits the button's ink and shifts with the theme.
 *
 * That is a deliberate departure from Google's brand guidance, which expects
 * the four-colour mark. It is an owner decision for an internal, invite-only
 * app. If this ever faces the public, restore the four fills in
 * `app/index.html` — they are kept as four separate paths for exactly that.
 */
.btn-google {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 11px 19px;
}

.btn-google .g-mark {
  width: 15px;
  height: 15px;
  flex: none;
  display: block;
  /* Monochrome: the mark takes the button's colour, including on hover and in
   * whichever theme is resolved. Nothing here sets a colour of its own. */
  color: inherit;
}

.btn-google:disabled {
  opacity: 0.62;
  cursor: default;
  box-shadow: none;
}

.btn.quiet:hover {
  color: var(--ink-2);
  box-shadow: none;
}

.btn[disabled] {
  opacity: 0.4;
  cursor: default;
  box-shadow: none;
}

.hint {
  max-width: 760px;
  margin: 8px auto 0;
  font-size: 10.5px;
  color: var(--ink-3);
  text-align: center;
}

/* ── sign-in ──────────────────────────────────────────────────────────────── */

.signin {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 30px;
  text-align: center;
  -webkit-app-region: drag;
  /* Anchors `.theme-corner`. */
  position: relative;
  /*
   * THE SAME GRADIENT `body` ALREADY PAINTS, and it is here for the orb rather
   * than for the eye — the two boxes are both the full viewport, so this is
   * visually a no-op. `#root` sets `isolation: isolate`, which means the light
   * orb's `mix-blend-mode` below can only blend against a backdrop INSIDE
   * `#root`; without an opaque ground here that backdrop is transparent and the
   * blend silently does nothing.
   */
  background: var(--bg);
}

.signin > * {
  -webkit-app-region: no-drag;
}

/* The orb sits above the wordmark. Deliberately unstyled otherwise: no
 * background, no border, no radius, no overflow rule. The form feathers out
 * to nothing on its own, and any box decoration here reinstates the circular
 * edge that was removed on purpose. */
.orbwrap {
  width: 100%;
  max-width: 210px;
  aspect-ratio: 1;
  flex: none;
  /* Pulls the wordmark up into the orb's own fade, so the two read as one
   * object rather than a picture with a caption under it. */
  margin-bottom: -34px;
  pointer-events: none;
}

.orbwrap canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/*
 * THE LIGHT ORB'S GROUND, WHICH USED TO BE A VISIBLE WHITE DISC.
 *
 * `orb.ts` has to paint an opaque ground before it can `multiply`, and it paints
 * #FFFFFF. In the design artifact that canvas sat on a flat white panel, so the
 * fill was invisible. Here it sits on the `--bg` gradient: measured at the live
 * orb, the canvas centre was rgba(182,210,246,255) — fully opaque — and the ring
 * at 0.45R sampled pure white against a page ground of rgb(244,248,252). ΔR 11.
 * A white circular field with a soft edge, in a design whose first rule is that
 * there is no disc.
 *
 * Blending the whole canvas with `multiply` makes the white ground a NO-OP
 * against whatever is behind it — white multiplied by the page is the page —
 * while the ink still darkens exactly as `orb.ts` intends, at any window size.
 * It is scoped to light because dark composites with `lighter` onto a
 * transparent canvas and has no ground to cancel.
 */
:root[data-theme="light"] .orbwrap canvas {
  mix-blend-mode: multiply;
}

/*
 * THE THEME SWITCH. Two instances of one control: the right-hand end of the top
 * bar, and a corner of the sign-in screen — because the app screen only exists
 * once you are signed in, and somebody may want to change the theme before they
 * have an account. `main.ts` drives both from one handler and gives both the
 * same accessible name, which names the ACTION rather than the current state.
 *
 * ── OWNER, 2026-08-22 ──────────────────────────────────────────────────────
 * *"move the dark light toggle to the top right next to the right of where
 * business, etc chips are… make the toggle a sun and moon svg, just outline,
 * and no frame, same design on splash screen at login"*.
 *
 * SO IT IS NOT A TILE ANY MORE. It used to wear `.ic` — a 26px box with a
 * hairline border and a filled ground — which was correct while it lived in the
 * rail among three other tiles and wrong the moment it moved next to the
 * privacy chips, where a second boxed thing beside a chip reads as a second
 * chip. `.tsw` is the frameless version: no background, no border, no padding,
 * and the drawing IS the control.
 *
 * WHICH ONE IS SHOWING IS DECIDED IN CSS, NOT IN JAVASCRIPT. Both drawings are
 * always in the markup and `data-theme` hides one. That is what keeps the
 * picture and the accessible name from ever disagreeing: `main.ts` writes the
 * label off the same attribute the stylesheet reads, so there is no second
 * source of truth and no frame in which a sun sits above "switch to dark".
 *
 * THE SUN SHOWS ON DARK. The label names the action — on dark it says "Switch
 * to light theme" — so the glyph names the DESTINATION too, and the two agree.
 * Showing the current state instead would have the moon on dark, which reads as
 * "you are in dark" to some people and "press for dark" to others; a toggle
 * that is ambiguous in that direction has no non-arbitrary answer, and the
 * design already settled it once for the label.
 */
.tsw {
  -webkit-appearance: none;
  appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  flex: none;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  cursor: pointer;
  /* No visible corner — this exists only so `button:focus-visible`'s ring has a
     shape to follow rather than boxing a 20px square with square corners. */
  border-radius: var(--r-sm);
  transition: color 120ms ease;
}

.tsw:hover {
  color: var(--ink);
}

.tsw-i {
  display: block;
  width: 18px;
  height: 18px;
}

/*
 * `display: none`, NOT `visibility` or `opacity`. The hidden drawing must leave
 * the accessibility tree completely: both are `aria-hidden` already, but a
 * zero-opacity SVG still occupies its 18px in the flex line and would push the
 * visible one off centre inside a 20px button.
 */
[data-theme="dark"] .tsw-moon,
[data-theme="light"] .tsw-sun {
  display: none;
}

/*
 * The sign-in instance. Position only — `.tsw` already carries the whole
 * appearance, which is the mechanical half of *"same design on splash screen"*:
 * there is no second set of colours or sizes here that could drift from the one
 * in the top bar.
 */
.theme-corner {
  position: absolute;
  /* below the overlay titlebar's band, matching the rail's own top padding */
  top: 34px;
  right: 18px;
}

/*
 * THE SPRITE HOST. A definition, not a picture: `<symbol>` renders nothing on
 * its own, but the `<svg>` carrying it is a replaced element with a default
 * 300x150 box, which without this puts a large invisible gap above the app.
 * `overflow: hidden` as well as the zero size, because a `<symbol>`'s content
 * can still paint outside a zero-height box in some engines.
 */
.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.wordmark {
  font-size: 46px;
  font-weight: 300;
  letter-spacing: -0.03em;
  margin: 0;
  color: var(--ink);
  /* The badge sits ON the baseline beside the word, so the two are one object.
   * `inline-flex` rather than a floated child: the word must still wrap and
   * select as text, and a flex line keeps the badge from stretching the
   * heading's line box. */
  display: inline-flex;
  /* SUPERSCRIPT, so the badge hangs off the cap line rather than sitting beside
   * the word. `flex-start` aligns the tops of the two flex items; the exact
   * drop is applied on the mark itself, because aligning raw boxes puts the
   * badge above the cap of the C rather than level with it. */
  align-items: flex-start;
  gap: 0.10em;
}

/*
 * THE BADGE IS SIZED IN `em`, NOT PIXELS.
 *
 * It has to track the wordmark at every size — the sign-in hero is 46px today
 * and the same mark will be wanted smaller elsewhere. Height is tied to the
 * cap height rather than the font size so the box aligns with the C and the
 * sparkle clears the ascender, which a fixed pixel height stops doing the
 * moment the type scale changes.
 */
.ai-mark {
  /* Roughly half the wordmark, which is what makes it read as a superscript
   * rather than as a second word. Below about 0.45em the letters stop being
   * legible at the sizes this mark is used at. */
  height: 0.52em;
  width: auto;
  overflow: visible;
  /*
   * THE DROP IS MEASURED FROM THE CAP LINE, NOT GUESSED.
   *
   * `align-items: flex-start` aligns the two boxes' TOPS — but a heading's line
   * box starts above the cap of the C by the font's internal leading, so a
   * badge aligned to it floats visibly high. This nudges it back down so the
   * badge's top sits level with the cap of the C, which is where a superscript
   * belongs. Measured on the live screen at 46px and expressed in `em`, so it
   * holds at any size.
   */
  transform: translateY(0.30em);
}

.ai-letters {
  font-family: inherit;
  font-size: 21px;
  font-weight: 500;
  letter-spacing: 0.01em;
  fill: currentColor;
  /* The letters carry the mark; the surface behind them is decoration. Full
   * ink here and reduced opacity on the plate is what makes it read as glass
   * rather than as a grey box with grey text in it. */
  fill-opacity: 0.95;
}

/*
 * The badge is an OUTLINE now — no fill — so nothing here compensates for a
 * translucent plate reading differently against light and dark grounds. The
 * stroke is `currentColor`, so it simply takes the wordmark's ink in either
 * theme. The `prefers-reduced-transparency` override that used to sit here was
 * removed with the fill it existed to disable.
 */

.signin p {
  margin: 0;
  color: var(--ink-2);
  font-size: 13.5px;
  max-width: 40ch;
}

.signin .err {
  color: var(--ink-3);
  font-size: 12px;
  font-family: var(--font-mono);
  max-width: 52ch;
}

/*
 * FOCUS, VISIBLY, IN BOTH THEMES. There was no `:focus-visible` rule at all
 * before this, so a keyboard user had only the UA's default ring — which
 * `color-scheme` now moves around, and which is invisible against an accent
 * border at 1px. A 2px accent outline at 2px offset measures 10.33:1 on dark
 * and 6.08:1 on --surface in light, 9.92:1 and 5.38:1 on the rail. It is drawn
 * OUTSIDE the border box, so it never disturbs the 1px frames it sits around.
 */
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.hidden {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

/*
 * THE VERSION IN THE RAIL.
 *
 * Deliberately quiet: `--ink-3` and 9px, because it answers a question nobody
 * asks twice a day ("am I on the latest?") and must not compete with the four
 * controls above it. It is NOT a button — there is nothing to press — so it is
 * a span and takes no Tab stop.
 *
 * `font-variant-numeric: tabular-nums` so the width does not jitter between
 * 0.4.9 and 0.4.10, which in a 56px rail is visible.
 */
.rail-version {
  font-family: var(--font-mono);
  font-size: 9px;
  line-height: 1;
  color: var(--ink-3);
  text-align: center;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  padding: 2px 0 4px;
  user-select: text;
}

/*
 * INLINE FORMATTING IN A REPLY. Owner: "use formatting, bold, and regular, and
 * accent color for links + underlining".
 *
 * `strong` and `em` are left to the browser's own weight and slant rather than
 * restyled — the bubble already sets the family and size, and overriding weight
 * here would fight the font's real bold with a synthetic one.
 */
.bub .md-link {
  color: var(--accent);
  text-decoration: underline;
  /* Offset so the rule clears descenders instead of cutting through them. */
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  cursor: pointer;
}

.bub .md-link:hover {
  text-decoration-thickness: 2px;
}

/* Visible focus, because these are reachable by keyboard and the underline
 * alone does not say "this one". */
.bub .md-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.bub code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  /* A tint of the ink rather than a fixed grey, so it holds in both themes. */
  background: var(--accent-soft);
  padding: 0.1em 0.32em;
  border-radius: 4px;
}

/* ── 2026 workspace redesign ──
 *
 * These rules translate the approved conversation mock into the real shell.
 * The existing ids and state classes stay intact, so navigation, updates,
 * permissions, privacy, attachments and turn recovery keep their contracts.
 */

.app {
  position: relative;
  background: transparent;
}

.rail {
  width: 58px;
  gap: 11px;
  padding: 28px 0 14px;
  background: var(--grad-panel), var(--surface-2);
  border-color: var(--line);
}

.ic {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  border-color: transparent;
  background: transparent;
  color: var(--ink-3);
  transition: color 0.14s ease, background 0.14s ease, border-color 0.14s ease, transform 0.14s ease;
}

button.ic:hover {
  color: var(--ink);
  background: var(--surface-3);
  transform: translateY(-1px);
}

/* Conversational image work keeps this exact frame from request through final. */
.image-work {
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--line-2));
  background: color-mix(in srgb, var(--surface-2) 94%, var(--accent));
  overflow: hidden;
}

.image-work-frame {
  isolation: isolate;
  min-height: 280px;
  border-radius: 0;
  background:
    radial-gradient(circle at 18% 18%, color-mix(in srgb, var(--accent) 26%, transparent), transparent 34%),
    linear-gradient(148deg, color-mix(in srgb, var(--surface-3) 76%, var(--accent)), var(--surface-2));
}

.image-work-liquid {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(circle at 42% 42%, color-mix(in srgb, var(--accent) 17%, transparent), transparent 34%),
    linear-gradient(145deg, color-mix(in srgb, var(--surface-3) 88%, var(--accent)), var(--surface-2));
  transition: opacity 0.48s ease, filter 0.48s ease;
}

.image-work-wash,
.image-work-wash::before,
.image-work-wash::after {
  position: absolute;
  content: "";
  inset: -35%;
  border-radius: 42% 58% 57% 43% / 43% 45% 55% 57%;
}

.image-work-wash {
  inset: -18%;
  background:
    radial-gradient(ellipse at 28% 32%, color-mix(in srgb, var(--accent) 28%, transparent), transparent 44%),
    radial-gradient(ellipse at 72% 68%, color-mix(in srgb, #4777a8 24%, transparent), transparent 46%);
  filter: blur(10px);
  animation: image-liquid-roll 9s linear infinite;
}

.image-work-wash::before {
  inset: 8% 30% 38% -8%;
  background: color-mix(in srgb, #4a6ca0 18%, transparent);
  transform: translate(18%, -8%);
  animation: image-liquid-drift 6.4s ease-in-out infinite alternate;
}

.image-work-wash::after {
  inset: 34% -12% -18% 28%;
  background: color-mix(in srgb, var(--surface) 34%, transparent);
  transform: translate(-17%, 18%) scale(0.88);
  animation: image-liquid-drift 7.6s ease-in-out -2s infinite alternate-reverse;
}

.image-work-mark {
  position: relative;
  z-index: 3;
  width: 64px;
  height: 64px;
  filter: drop-shadow(0 12px 28px color-mix(in srgb, var(--accent) 30%, transparent));
  animation: image-mark-breathe 2.2s ease-in-out infinite;
}

.image-work-mark i {
  position: absolute;
  display: block;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 88%, white);
  box-shadow: inset -4px -5px 10px rgba(4, 10, 20, 0.18);
}

.image-work-mark i:first-child {
  top: 7px;
  left: 7px;
  width: 29px;
  height: 29px;
}

.image-work-mark i:nth-child(2) {
  top: 28px;
  left: 29px;
  width: 21px;
  height: 21px;
}

.image-work-mark i:last-child {
  top: 42px;
  left: 14px;
  width: 12px;
  height: 12px;
}

.pic-work-layer,
.pic-work-final {
  position: absolute;
  z-index: 1;
  inset: 0;
  width: 100%;
  height: 100%;
  max-height: none;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.018);
  transition: opacity 0.42s ease, transform 0.52s ease, filter 0.42s ease;
}

.pic-work-layer.is-visible {
  z-index: 3;
  opacity: 0.78;
  transform: scale(1);
  filter: saturate(0.92) contrast(0.96);
}

.pic-work-layer.is-outgoing {
  opacity: 0;
  filter: blur(8px);
}

.pic-work-final {
  z-index: 5;
  object-fit: contain;
}

.pic-work-final.is-visible {
  opacity: 1;
  transform: scale(1);
}

.image-work-admitted .image-work-liquid {
  opacity: 0;
  filter: blur(10px);
}

/*
 * A finished picture owns its frame size. The in-flight card reserves a stable
 * aspect ratio so the conversation does not jump while pixels arrive. Once the
 * real image has decoded, keeping that reservation leaves a large empty panel
 * under a portrait capped by 60vh. The final image returns to normal flow and
 * sizes the frame. Expanded viewing still intentionally fills the window.
 */
.pic:not(.image-work):not(.is-image-expanded),
.image-work[data-phase="completed"]:not(.is-image-expanded) {
  width: fit-content;
  max-width: 100%;
}

.pic:not(.image-work):not(.is-image-expanded) .pic-frame,
.image-work[data-phase="completed"]:not(.is-image-expanded) .image-work-frame {
  width: fit-content;
  max-width: 100%;
  min-height: 0;
  aspect-ratio: auto !important;
}

.pic:not(.image-work):not(.is-image-expanded) .pic-img,
.image-work[data-phase="completed"]:not(.is-image-expanded) .pic-work-final {
  position: relative;
  inset: auto;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 60vh;
  object-fit: contain;
}

.image-work-receipt {
  display: flex;
  min-height: 72px;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 13px 15px 14px;
  border-top: 1px solid var(--line-2);
  background: color-mix(in srgb, var(--surface-2) 94%, transparent);
}

.image-work-copy {
  display: grid;
  min-width: 0;
  gap: 2px;
}

.image-work-copy strong {
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
}

.image-work-copy > span:not(.image-work-context) {
  color: var(--ink-2);
  font-size: 11.5px;
  line-height: 1.4;
}

.image-work-context {
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.045em;
  text-transform: uppercase;
}

.image-work-actions {
  display: flex;
  flex: none;
  gap: 7px;
}

.image-work-action {
  min-height: 34px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-2);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
}

.image-work-action:hover,
.image-work-action:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.image-work-action[hidden] {
  display: none;
}

/* A decoded image sets the card width, not its caption's unwrapped controls.
 * Inline-size containment excludes captions from intrinsic width calculation
 * while keeping their natural height. Loading and expanded frames are intact.
 */
.pic:not(.is-image-expanded):has(> .pic-frame.pic-ready) > :is(.image-work-receipt, .pic-actions) {
  contain: inline-size;
  min-inline-size: 0;
  max-inline-size: 100%;
  flex-wrap: wrap;
}

.pic:not(.is-image-expanded):has(> .pic-frame.pic-ready) .image-work-actions {
  flex: 0 1 auto;
  flex-wrap: wrap;
  min-inline-size: 0;
  max-inline-size: 100%;
  margin-inline-start: auto;
}

.pic:not(.is-image-expanded):has(> .pic-frame.pic-ready) :is(.image-work-copy, .pic-save, .pic-tool) {
  min-inline-size: 0;
  max-inline-size: 100%;
  overflow-wrap: anywhere;
}

.image-work[data-phase="cancelled"] .image-work-liquid,
.image-work[data-phase="refused"] .image-work-liquid,
.image-work[data-phase="rejected"] .image-work-liquid,
.image-work[data-phase="failed"] .image-work-liquid {
  animation: none;
  filter: saturate(0.25);
}

.image-work[data-phase="cancelling"] .image-work-liquid {
  filter: saturate(0.56);
}

.image-work[data-phase="cancelling"] .image-work-mark {
  opacity: 0.72;
  animation-duration: 3.2s;
}

.image-work[data-phase="cancelled"] .image-work-mark,
.image-work[data-phase="refused"] .image-work-mark,
.image-work[data-phase="rejected"] .image-work-mark,
.image-work[data-phase="failed"] .image-work-mark {
  animation: none;
  opacity: 0.46;
}

.image-work[data-phase="refused"] .image-work-receipt,
.image-work[data-phase="rejected"] .image-work-receipt,
.image-work[data-phase="failed"] .image-work-receipt {
  box-shadow: inset 3px 0 0 #d56f75;
}

.ic.on {
  color: var(--accent);
  border-color: var(--line-2);
  background: var(--surface-3);
  box-shadow: none;
}

.cmark {
  width: 19px;
  height: 19px;
}

.panel {
  width: 244px;
  padding: 12px 16px 14px;
  background: var(--grad-panel), var(--surface-2);
  border-color: var(--line);
}

.panel-h {
  margin: 0 8px 9px;
  color: var(--ink-3);
  font-size: 10.5px;
  font-weight: 760;
  letter-spacing: 0.09em;
}

.panel-tabs {
  gap: 4px;
  margin: 0 0 12px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: color-mix(in srgb, var(--surface) 38%, transparent);
}

.panel-tabs button {
  flex: 1;
  min-width: 0;
  padding: 6px 4px;
  border-radius: 8px;
  font-size: 10px;
}

.panel-tabs button[aria-pressed="true"] {
  border-color: transparent;
  background: var(--surface-3);
  color: var(--ink);
}

.panel-list {
  padding: 0;
}

.panel-item {
  margin-bottom: 6px;
}

.panel-row {
  padding: 9px 11px;
  border: 1px solid transparent;
  border-radius: 10px;
  color: var(--ink-2);
  font-size: 12.5px;
}

.thread-row {
  position: relative;
}

/*
 * SYN-01b. A conversation that is on the server but not on this machine.
 *
 * It has to read as REACHABLE-BUT-NOT-HERE. A dashed edge says "not yet
 * filled in" without inventing a new colour, and the row keeps full-strength
 * text because it is a real conversation the person owns — dimming the title
 * would say "less important" when the truth is "one click further away".
 */
/* SYN-02b. An attached file, as a chip inside the message it came with. It
 * reads as an object you can pick up, not as a picture: bordered rather than
 * filled, name first because that is what somebody scans for. */
.file-chip {
  -webkit-appearance: none;
  appearance: none;
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  max-width: 100%;
  padding: 6px 10px;
  margin: 4px 4px 0 0;
  border: 1px solid color-mix(in srgb, var(--ink-3) 32%, transparent);
  border-radius: var(--r-sm);
  background: none;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--ink-2);
  text-align: left;
}

.file-chip:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  color: var(--ink-1);
}

.file-chip-name {
  /* One line. A wrapped file name makes chips different heights, which turns a
   * row of them into a ragged block. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-chip-size {
  flex: none;
  font-size: 10.5px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.thread-remote {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--ink-3) 34%, transparent);
}

.thread-remote:hover:not(:disabled) {
  border-style: solid;
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}

.thread-remote .panel-when {
  color: color-mix(in srgb, var(--accent) 74%, var(--ink-3));
}

/*
 * SYN-10 — where a conversation was started. Owner-requested.
 *
 * INLINE, and after the time rather than beside the name: the rail is narrow and
 * the NAME is the thing that must never be squeezed. `max-width` with an ellipsis
 * keeps a long label from pushing the row wider on a small window.
 *
 * Colour is not the only carrier — `render.ts` puts the same words in the
 * button's accessible name — so this can stay quiet: a hairline outline and the
 * muted ink the timestamp already uses, rather than a filled badge competing with
 * the activity light for attention.
 */
.panel-origin {
  display: inline-block;
  margin-top: 2px;
  margin-inline-start: 6px;
  padding: 0 5px;
  max-width: 11ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: baseline;
  font-size: 9.5px;
  line-height: 15px;
  border-radius: 7px;
  border: 1px solid color-mix(in srgb, var(--ink-3) 34%, transparent);
  color: var(--ink-3);
}

/* On a remote row the chip picks up the same accent tint the time already has,
 * so the row reads as one thing rather than two. */
.thread-remote .panel-origin {
  border-color: color-mix(in srgb, var(--accent) 34%, transparent);
  color: color-mix(in srgb, var(--accent) 74%, var(--ink-3));
}

.thread-remote:disabled {
  cursor: progress;
  opacity: 0.72;
}

.thread-status {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--thread-status);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--thread-status) 14%, transparent);
}

.thread-status.status-selected { --thread-status: #54d79b; }
.thread-status.status-in-flight { --thread-status: #e9a84d; }
.thread-status.status-idle { --thread-status: var(--accent); }
.thread-status.status-error { --thread-status: #ef6b73; }

.panel-copy,
.panel-name {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.thread-row .panel-name {
  padding-right: 16px;
}

.panel-row:hover {
  border-color: var(--line);
  background: color-mix(in srgb, var(--surface-3) 58%, transparent);
}

.panel-row.on {
  border-color: var(--line-2);
  background: var(--surface-3);
  color: var(--ink);
}

.panel-when {
  margin-top: 2px;
  color: var(--ink-3);
  font-size: 10px;
}

.panel-actions {
  gap: 3px;
  padding: 3px 4px 0;
  opacity: 0;
  transition: opacity 0.14s ease;
}

.panel-actions button {
  padding: 4px 6px;
  border-radius: 7px;
  font-size: 9.5px;
}

.panel-empty {
  margin: 8px 10px;
  line-height: 1.5;
}

.permission-card {
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.permission-row {
  white-space: normal;
  overflow-wrap: anywhere;
}

.permission-connector {
  border-color: var(--line);
  background: var(--grad-card), color-mix(in srgb, var(--surface-3) 38%, transparent);
}

.permission-head {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}

.permission-state {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}

.permission-state.is-connected {
  background: #54d79b;
  box-shadow: 0 0 0 3px color-mix(in srgb, #54d79b 14%, transparent);
}

.permission-state.is-authorizing,
.permission-state.is-loading {
  background: #e9a84d;
  box-shadow: 0 0 0 3px color-mix(in srgb, #e9a84d 14%, transparent);
}

.permission-state.is-loading {
  animation: permission-pulse 1.15s ease-in-out infinite;
}

.permission-state.is-error {
  background: #ef6b73;
  box-shadow: 0 0 0 3px color-mix(in srgb, #ef6b73 14%, transparent);
}

.permission-state.is-unavailable {
  background: var(--ink-3);
  box-shadow: none;
}

.permission-account,
.permission-provider {
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.permission-actions {
  justify-content: flex-start;
  padding: 4px 5px 0;
  opacity: 1;
}

.permission-actions button:disabled {
  cursor: default;
  opacity: 0.64;
}

/* EXT-05. The extensions section sits under the standing-permission rows. */
.extensions-section {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.extensions-title {
  margin: 0 10px 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.extensions-status {
  margin: 0 10px 8px;
  font-size: 10.5px;
  line-height: 1.45;
  color: var(--ink-2);
}

.extensions-status:empty {
  display: none;
}

.extension-tools {
  margin: 4px 0 0;
  padding: 0 0 0 10px;
  list-style: none;
}

.extension-tool {
  margin-bottom: 4px;
}

.extension-tool-note {
  color: var(--ink-3);
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.permission-alert {
  margin: 8px 5px;
  padding: 8px 9px;
  border: 1px solid color-mix(in srgb, #ef6b73 42%, var(--line));
  border-radius: 9px;
  color: var(--ink-2);
  font-size: 10.5px;
  line-height: 1.45;
  list-style: none;
}

.calendar-event-form {
  margin: 8px 5px 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: color-mix(in srgb, var(--surface) 42%, transparent);
}

.calendar-event-form > strong {
  display: block;
  margin-bottom: 7px;
  color: var(--ink-2);
  font-size: 10.5px;
  font-weight: 680;
}

.calendar-event-fields {
  display: grid;
  gap: 6px;
}

.calendar-event-fields label,
.calendar-event-fields label > span {
  display: block;
}

.calendar-event-fields label > span {
  margin-bottom: 2px;
  color: var(--ink-3);
  font-size: 9.5px;
}

.calendar-event-fields input {
  width: 100%;
  min-width: 0;
  height: 30px;
  padding: 0 7px;
  border: 1px solid var(--line-2);
  border-radius: 7px;
  outline: none;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 10.5px;
}

.calendar-event-fields input:focus {
  border-color: var(--accent);
}

.calendar-event-review {
  width: 100%;
  margin-top: 8px;
  padding: 6px 8px;
  border: 1px solid var(--accent);
  border-radius: 7px;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 10.5px;
  cursor: pointer;
}

.calendar-action-card {
  border-color: color-mix(in srgb, var(--accent) 34%, var(--line));
}

.calendar-action-icon {
  color: var(--accent);
}

.calendar-action-body {
  display: grid;
  gap: 10px;
}

.calendar-action-facts,
.calendar-receipt-facts {
  display: grid;
  grid-template-columns: minmax(76px, auto) minmax(0, 1fr);
  gap: 5px 12px;
  margin: 0;
}

.calendar-action-facts dt,
.calendar-receipt-facts dt {
  color: var(--ink-3);
  font-size: 10.5px;
}

.calendar-action-facts dd,
.calendar-receipt-facts dd {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--ink-2);
  font-size: 11px;
}

.calendar-action-effect,
.calendar-action-warning {
  margin: 0 !important;
}

.calendar-action-warning {
  padding: 9px 10px;
  border: 1px solid color-mix(in srgb, #e9a84d 38%, var(--line));
  border-radius: 8px;
  background: color-mix(in srgb, #e9a84d 7%, transparent);
  color: var(--ink-2) !important;
}

.calendar-action-result {
  display: grid;
  gap: 5px;
}

.calendar-action-result > strong {
  color: var(--ink);
}

.calendar-receipt-facts {
  margin-top: 5px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

@keyframes permission-pulse {
  0%, 100% { opacity: 0.48; }
  50% { opacity: 1; }
}

.main {
  background: var(--bg);
  background-attachment: fixed;
}

:root[data-theme="light"] .main {
  background: var(--bg);
}

.topbar {
  min-height: 64px;
  padding: 0 28px;
  gap: 12px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  border-color: var(--line);
}

.crumb {
  color: var(--ink-3);
  font-size: 13px;
}

.crumb b {
  font-weight: 680;
}

:root[data-theme="light"] .crumb b {
  color: var(--accent);
}

.thread {
  padding: 42px 28px 24px;
}

.threadinner {
  max-width: 720px;
}

.bub {
  margin-bottom: 26px;
}

.bub-u {
  max-width: min(620px, 78%);
  padding: 11px 15px;
  border: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  border-radius: 15px 15px 4px 15px;
  background: var(--surface-3);
}

.bub-u p,
.bub-a p {
  font-size: 14px;
  line-height: 1.55;
}

.bub-a {
  position: relative;
  min-height: 30px;
  padding: 3px 0 0 42px;
}

.bub-a::before {
  content: "C";
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 18%, var(--surface-3));
  color: var(--accent);
  font-size: 13px;
  font-weight: 850;
}

.bub-a p {
  max-width: 620px;
  color: var(--ink-2);
}

.consent-host {
  margin: -7px 0 30px 42px;
}

.consent-card {
  overflow: hidden;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--accent) 44%, var(--line-2));
  border-radius: 16px;
  background: var(--surface-2);
  box-shadow: 0 16px 46px rgba(0, 0, 0, 0.22);
}

.consent-head {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 18px 19px 14px;
}

.consent-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 18%, var(--surface-3));
  color: var(--accent);
  font-size: 19px;
}

.consent-kicker {
  display: block;
  color: var(--ink-3);
  font-size: 10.5px;
  font-weight: 780;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.consent-card h3 {
  margin: 3px 0 0;
  color: var(--ink);
  font-size: 15px;
  font-weight: 730;
}

.consent-body {
  padding: 0 19px 17px 70px;
}

.consent-card p {
  margin: 0 0 7px;
  color: var(--ink-2);
  font-size: 12.5px;
  line-height: 1.5;
}

.consent-origin {
  display: inline-block;
  max-width: 100%;
  margin-top: 3px;
  overflow-wrap: anywhere;
  color: var(--accent);
  background: transparent;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
}

.consent-actions {
  gap: 9px;
  margin: 0;
  padding: 14px 19px;
  border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 42%, var(--surface-2));
}

.consent-actions .btn {
  min-height: 38px;
  padding: 0 15px;
  border-color: var(--line-2);
  border-radius: 10px;
  color: var(--ink-2);
  font-size: 12px;
  font-weight: 700;
}

.consent-actions .consent-primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--surface);
}

.consent-actions .btn:hover {
  transform: translateY(-1px);
  box-shadow: none;
}

.consent-result {
  padding: 14px 19px;
  border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 42%, var(--surface-2));
  color: var(--ok);
  font-size: 12px;
  font-weight: 760;
}

.consent-card[data-state="declined"] .consent-icon,
.consent-card[data-state="declined"] .consent-result {
  color: var(--ink-3);
}

.gallery {
  width: min(520px, calc(100% - 42px));
  margin: -7px 0 30px 42px;
}

.pic {
  width: 100%;
  border-radius: 17px;
  background: var(--surface-2);
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.28);
}

.pic-frame {
  position: relative;
  min-height: 240px;
  aspect-ratio: 16 / 10;
  background:
    radial-gradient(circle at 24% 32%, color-mix(in srgb, var(--accent) 28%, transparent), transparent 26%),
    radial-gradient(circle at 76% 68%, rgba(62, 92, 137, 0.34), transparent 30%),
    linear-gradient(135deg, var(--surface-3), var(--surface-2));
}

.pic-img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: 60vh;
  object-fit: contain;
  opacity: 1;
  transition: opacity 0.35s ease, transform 0.35s ease;
}

.pic-loading .pic-img {
  opacity: 0;
  transform: scale(1.025);
}

.pic-loader {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 9px;
  padding: 24px;
  overflow: hidden;
  color: var(--ink-2);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.pic-loader::after {
  content: "";
  position: absolute;
  inset: -55%;
  background: linear-gradient(100deg, transparent 38%, rgba(255, 255, 255, 0.16) 50%, transparent 62%);
  transform: translateX(-42%) rotate(8deg);
  animation: image-shimmer 1.8s ease-in-out infinite;
}

.pic-loading .pic-loader {
  opacity: 1;
}

.pic-loader > * {
  position: relative;
  z-index: 1;
}

.pic-loader strong {
  color: var(--ink);
  font-size: 14px;
  font-weight: 730;
}

.pic-loader > span:last-child {
  color: var(--ink-3);
  font-size: 12px;
}

.pic-loader-orbit {
  position: relative;
  width: 54px;
  height: 54px;
  margin-bottom: 3px;
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
  border-radius: 50%;
  animation: image-orbit 1.7s linear infinite;
}

.pic-loader-orbit::before {
  content: "";
  position: absolute;
  top: -5px;
  left: 22px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 18px var(--accent);
}

.pic-loader-orbit::after {
  content: "✦";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--accent);
  font-size: 18px;
  animation: image-counterspin 1.7s linear infinite;
}

.pic-gone {
  align-self: center;
  width: 100%;
}

/*
 * The label speaks for itself now. This block used to set `font-size: 0` and
 * paint a "⇩" through `::before`, which meant the accessible name said
 * "Download image" while the pixels said nothing a reader could name — and it
 * floated over the top-right corner of the picture. Deleted rather than
 * restyled: the base rule above is the whole button.
 */
.pic-save[data-status="saved"] {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-2));
  color: var(--accent);
}

.pic-save[data-status="failed"] {
  border-color: color-mix(in srgb, #e2564d 55%, var(--line-2));
  color: #e2564d;
}

.notice {
  max-width: 720px;
  padding: 0 28px;
}

.notice-in {
  border-left-width: 3px;
  border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-2));
}

.entry-q {
  font-size: clamp(26px, 3vw, 34px);
  font-weight: 520;
}

.composer-wrap {
  padding: 12px 28px 24px;
  background: linear-gradient(to top, var(--surface) 42%, transparent);
}

.composer {
  max-width: 720px;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--line-2);
  border-radius: 16px;
  background: var(--surface-2);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.18);
}

.pending-files,
.drop-hint {
  max-width: 720px;
}

.pending-files {
  margin-bottom: 9px;
}

.pending-file {
  padding: 7px 8px 7px 11px;
  border-radius: 10px;
  background: var(--surface-2);
}

/* A tile is its own ground — the chip padding would frame the picture. */
.pending-file.pending-thumb {
  padding: 0;
  background: transparent;
}

.drop-hint {
  padding: 14px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 7%, var(--surface-2));
}

.attach,
.image-options,
.voice-input,
.voice-replies,
.send-button,
#stop {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  min-width: 34px;
  min-height: 34px;
  padding: 0;
  border: 0;
  border-radius: 10px;
}

.attach {
  background: var(--surface-3);
  color: var(--ink-2);
  font-size: 17px;
}

.image-options,
.voice-input,
.voice-replies {
  border: 1px solid var(--line-2);
  background: transparent;
  color: var(--ink-2);
}

.image-options svg,
.voice-input svg,
.voice-replies svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.65;
}

.voice-replies[data-active="true"],
.image-options[data-active="true"],
.image-options[aria-expanded="true"] {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ── IMG2-07 image options popover ───────────────────────────────────────────
 * Anchored to the composer wrap and floated above it. The frame is the
 * affordance here too: chips are bordered, never filled. */
.composer-wrap {
  position: relative;
}

.image-options-popover {
  position: absolute;
  left: 50%;
  bottom: calc(100% - 6px);
  z-index: 20;
  width: min(720px, calc(100% - 56px));
  transform: translateX(-50%);
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line-2);
  border-radius: 14px;
  background: var(--surface-2);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.18);
}

.image-options-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.image-options-label {
  min-width: 150px;
  color: var(--ink-2);
  font-size: 11.5px;
}

.image-options-group {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--surface-2) 84%, transparent);
}

.image-options-group button {
  min-height: 28px;
  min-width: 28px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 11px;
}

.image-options-group button[aria-checked="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

.image-options-note {
  margin: 0;
  color: var(--ink-3);
  font-size: 11px;
  line-height: 1.45;
}

.voice-input[data-state="recording"] {
  border-color: #e2564d;
  color: #e2564d;
  box-shadow: 0 0 0 4px color-mix(in srgb, #e2564d 18%, transparent);
  animation: voice-recording 1.1s ease-in-out infinite;
}

.voice-input[data-state="transcribing"],
.voice-input[data-state="arming"] {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

@keyframes voice-recording {
  50% { box-shadow: 0 0 0 7px color-mix(in srgb, #e2564d 10%, transparent); }
}

.send-button {
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  font-size: 18px;
  font-weight: 760;
}

.send-button:hover {
  background: var(--accent-soft);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

#stop {
  width: auto;
  padding: 0 11px;
  border: 1px solid var(--line-2);
  color: var(--ink-2);
}

.cinput {
  min-height: 34px;
  max-height: 160px;
  padding: 7px 4px 6px;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  font-size: 13px;
}

.cinput:focus {
  border: 0;
  box-shadow: none;
}

.hint {
  max-width: 720px;
  margin-top: 7px;
  text-align: center;
}

.voice-status {
  display: block;
  max-width: 720px;
  min-height: 15px;
  margin: 7px auto 0;
  color: var(--ink-3);
  font-size: 10.5px;
  line-height: 1.4;
  text-align: center;
}

.voice-status:empty {
  display: none;
}

/* ── 0.7.0 approved-page sidecar ─────────────────────────────────────────── */

.browser-rail {
  position: absolute;
  z-index: 25;
  top: 78px;
  right: 18px;
  display: flex;
  flex-direction: column;
  width: min(390px, calc(100vw - 350px));
  min-width: 300px;
  max-width: calc(100vw - 96px);
  height: min(360px, calc(100vh - 176px));
  min-height: 220px;
  max-height: calc(100vh - 96px);
  flex: none;
  overflow: hidden;
  resize: both;
  background: var(--grad-panel), var(--surface-2);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  box-shadow: 0 18px 52px color-mix(in srgb, #000 32%, transparent), 0 0 0 1px color-mix(in srgb, var(--accent) 5%, transparent);
}

.browser-rail.is-expanded {
  top: 64px;
  right: 0;
  bottom: 0;
  width: min(720px, 55vw);
  min-width: min(520px, 55vw);
  max-width: calc(100vw - 58px);
  height: auto;
  max-height: none;
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
  border-radius: 0;
  resize: horizontal;
}

.browser-rail.is-collapsed {
  width: 44px;
  min-width: 44px;
  max-width: 44px;
  height: 44px;
  min-height: 44px;
  max-height: 44px;
  resize: none;
}

.browser-rail.is-collapsed .browser-head {
  min-height: 44px;
  flex: 1;
  align-items: flex-start;
  justify-content: center;
  padding: 9px;
  border-bottom: 0;
}

.browser-rail.is-collapsed .browser-title-wrap,
.browser-rail.is-collapsed .browser-address-row,
.browser-rail.is-collapsed .browser-guidance-row,
.browser-rail.is-collapsed .browser-view-controls,
.browser-rail.is-collapsed .browser-stage,
.browser-rail.is-collapsed .browser-action:not(.browser-collapse) {
  display: none;
}

.browser-rail.is-collapsed .browser-actions {
  display: block;
}

.browser-head {
  min-height: 64px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 78%, transparent);
}

.browser-title-wrap {
  min-width: 0;
  flex: 1;
}

.browser-kicker {
  display: block;
  margin-bottom: 1px;
  color: var(--accent);
  font-size: 9px;
  font-weight: 750;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.browser-title {
  display: block;
  overflow: hidden;
  color: var(--ink);
  font-size: 12px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.browser-context {
  display: block;
  overflow: hidden;
  margin-top: 2px;
  color: var(--ink-3);
  font-size: 9px;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.browser-actions {
  display: flex;
  flex: none;
  gap: 3px;
}

.browser-action {
  width: 26px;
  height: 26px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 15px;
  line-height: 1;
}

.browser-action:hover,
.browser-action:focus-visible {
  border-color: var(--line-2);
  background: var(--surface-3);
  color: var(--accent);
  outline: none;
}

.browser-action:disabled {
  cursor: default;
  opacity: 0.42;
}

.browser-action:disabled:hover {
  border-color: transparent;
  background: transparent;
  color: var(--ink-3);
}

.browser-open {
  width: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0 7px;
  font-size: 10px;
  white-space: nowrap;
}

.browser-address-row {
  flex: none;
  overflow: hidden;
  padding: 7px 14px 8px;
  border-bottom: 1px solid var(--line);
}

.browser-address-label {
  display: block;
  margin-bottom: 2px;
  color: var(--ink-3);
  font-size: 8px;
  font-weight: 720;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.browser-address {
  display: block;
  overflow: hidden;
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.45;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.browser-guidance-row {
  display: flex;
  flex: none;
  align-items: flex-start;
  gap: 7px;
  padding: 7px 14px 8px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, #e9a84d 7%, transparent);
  color: var(--ink-3);
  font-size: 9.5px;
  line-height: 1.4;
}

.browser-guidance-dot {
  width: 6px;
  height: 6px;
  flex: none;
  margin-top: 3px;
  border-radius: 50%;
  background: #e9a84d;
  box-shadow: 0 0 0 3px color-mix(in srgb, #e9a84d 13%, transparent);
}

.browser-view-controls {
  display: flex;
  flex: none;
  gap: 3px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

.browser-view-button {
  min-height: 25px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 9.5px;
}

.browser-view-button[aria-pressed="true"] {
  border-color: var(--line-2);
  background: var(--surface);
  color: var(--accent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--ink) 7%, transparent);
}

.browser-view-button:hover,
.browser-view-button:focus-visible {
  color: var(--accent);
  outline: none;
}

.browser-view-button:disabled {
  cursor: default;
  opacity: 0.42;
}

.browser-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  background: var(--surface);
}

.browser-frame {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--surface);
  pointer-events: none;
}

.browser-loading {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 8px;
  padding: 28px;
  background: var(--grad-panel), var(--surface);
  color: var(--ink-2);
  text-align: center;
}

.browser-loading strong {
  font-size: 12px;
  font-weight: 650;
}

.browser-loading small {
  color: var(--ink-3);
  font-size: 10px;
}

.browser-loading-orbit {
  width: 26px;
  height: 26px;
  border: 2px solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: browser-capture-spin 900ms linear infinite;
}

@keyframes browser-capture-spin {
  to { transform: rotate(360deg); }
}

.browser-reader {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: auto;
  padding: 18px;
  border: 0;
  outline: none;
  background: var(--surface);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 12.5px;
  line-height: 1.65;
  overflow-wrap: anywhere;
  tab-size: 2;
  white-space: pre-wrap;
  user-select: text;
}

.browser-reader:focus-visible {
  box-shadow: inset 0 0 0 1px var(--accent);
}

.browser-empty {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 8px;
  padding: 28px;
  text-align: center;
}

.browser-empty p,
.browser-empty small {
  max-width: 230px;
  margin: 0;
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1.5;
}

.browser-empty small {
  color: var(--ink-3);
  font-size: 10.5px;
}

.browser-empty-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #54d79b;
  box-shadow: 0 0 0 4px color-mix(in srgb, #54d79b 16%, transparent), 0 0 16px color-mix(in srgb, #54d79b 32%, transparent);
}

/* ── 0.7.1 task-bound live browser rail ──────────────────────────────────── */

.live-browser-rail {
  --live-browser-rail-width: 420px;
  --live-browser-viewport-height: 480px;
  position: absolute;
  z-index: 32;
  inset: 0 0 0 auto;
  display: flex;
  width: min(var(--live-browser-rail-width), calc(100vw - 58px));
  min-width: min(320px, calc(100vw - 58px));
  max-width: min(960px, calc(100vw - 58px));
  flex-direction: column;
  overflow: hidden;
  background: var(--grad-panel), var(--surface-2);
  border-left: 1px solid var(--line-2);
  box-shadow: -22px 0 52px color-mix(in srgb, #000 24%, transparent);
}

.live-browser-rail.is-expanded {
  width: min(960px, calc(100vw - 58px));
}

.live-browser-rail.is-collapsed {
  width: 48px;
  min-width: 48px;
  max-width: 48px;
}

.live-browser-rail.is-collapsed .live-browser-heading,
.live-browser-rail.is-collapsed .live-browser-status,
.live-browser-rail.is-collapsed .live-browser-content,
.live-browser-rail.is-collapsed .live-browser-rail-resize,
.live-browser-rail.is-collapsed .live-browser-action:not(.live-browser-collapse-action) {
  display: none;
}

.live-browser-rail.is-collapsed .live-browser-head {
  min-height: 48px;
  justify-content: center;
  padding: 10px;
  border-bottom: 0;
}

.live-browser-rail-resize {
  position: absolute;
  z-index: 4;
  top: 0;
  bottom: 0;
  left: -4px;
  width: 9px;
  cursor: ew-resize;
  touch-action: none;
}

.live-browser-rail-resize::after {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 4px;
  width: 1px;
  background: transparent;
  content: "";
}

.live-browser-rail-resize:hover::after,
.live-browser-rail-resize:focus-visible::after {
  background: var(--accent);
  box-shadow: 0 0 10px var(--halo);
}

.live-browser-rail-resize:focus-visible,
.live-browser-viewport-resize:focus-visible {
  outline: none;
}

.live-browser-head {
  min-height: 66px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 10px;
  padding: 0 12px 0 16px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 76%, transparent);
  -webkit-app-region: drag;
}

.live-browser-heading {
  min-width: 0;
  flex: 1;
}

.live-browser-kicker {
  display: block;
  color: var(--accent);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.live-browser-heading strong,
.live-browser-task {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-browser-heading strong {
  margin-top: 1px;
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
}

.live-browser-task {
  margin-top: 1px;
  color: var(--ink-3);
  font-size: 9px;
}

.live-browser-status {
  min-height: 24px;
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--ink-2);
  font-size: 9px;
  letter-spacing: 0.04em;
}

.live-browser-status-dot,
.live-browser-activity-dot {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: #e9a84d;
  box-shadow: 0 0 0 3px color-mix(in srgb, #e9a84d 13%, transparent);
}

.live-browser-rail[data-lifecycle="completed"] .live-browser-status-dot,
.live-browser-reopen[data-lifecycle="completed"] .live-browser-status-dot {
  background: #54d79b;
  box-shadow: 0 0 0 3px color-mix(in srgb, #54d79b 14%, transparent);
}

.live-browser-rail[data-lifecycle="error"] .live-browser-status-dot,
.live-browser-reopen[data-lifecycle="error"] .live-browser-status-dot {
  background: #e56f76;
  box-shadow: 0 0 0 3px color-mix(in srgb, #e56f76 14%, transparent);
}

.live-browser-actions {
  display: flex;
  flex: none;
  gap: 3px;
}

.live-browser-action,
.live-browser-new-tab,
.live-browser-nav,
.live-browser-go,
.live-browser-tab,
.live-browser-tab-close {
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  -webkit-app-region: no-drag;
}

.live-browser-action {
  width: 26px;
  height: 26px;
  padding: 0;
  border-radius: var(--r-md);
  font-size: 15px;
  line-height: 1;
}

.live-browser-action:hover,
.live-browser-action:focus-visible,
.live-browser-new-tab:hover,
.live-browser-new-tab:focus-visible,
.live-browser-nav:hover,
.live-browser-nav:focus-visible,
.live-browser-go:hover,
.live-browser-go:focus-visible,
.live-browser-tab:hover,
.live-browser-tab:focus-visible,
.live-browser-tab-close:hover,
.live-browser-tab-close:focus-visible {
  border-color: var(--line-2);
  background: var(--surface-3);
  color: var(--accent);
  outline: none;
}

.live-browser-content {
  min-height: 0;
  display: flex;
  flex: 1;
  flex-direction: column;
  overflow-y: auto;
}

.live-browser-tabs-row {
  min-height: 40px;
  display: flex;
  flex: none;
  align-items: end;
  gap: 5px;
  padding: 7px 10px 0;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
}

.live-browser-tabs {
  min-width: 0;
  display: flex;
  flex: 1;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}

.live-browser-tab-wrap {
  min-width: 82px;
  max-width: 168px;
  height: 32px;
  display: flex;
  flex: 1 1 118px;
  align-items: center;
  border: 1px solid transparent;
  border-radius: var(--r-md) var(--r-md) 0 0;
  background: color-mix(in srgb, var(--surface-3) 60%, transparent);
}

.live-browser-tab-wrap:has(.live-browser-tab[aria-selected="true"]) {
  border-color: var(--line-2);
  border-bottom-color: var(--surface);
  background: var(--surface);
}

.live-browser-tab {
  min-width: 0;
  height: 100%;
  flex: 1;
  overflow: hidden;
  padding: 0 2px 0 9px;
  color: var(--ink-2);
  font-size: 9.5px;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-browser-tab[aria-selected="true"] {
  color: var(--ink);
}

.live-browser-tab-close {
  width: 23px;
  height: 23px;
  flex: none;
  margin-right: 3px;
  padding: 0;
  border-radius: 6px;
  font-size: 13px;
}

.live-browser-new-tab,
.live-browser-nav {
  width: 27px;
  height: 27px;
  flex: none;
  padding: 0;
  border-radius: var(--r-md);
  font-size: 14px;
}

.live-browser-tabs-row button:disabled,
.live-browser-toolbar button:disabled,
.live-browser-address:disabled {
  cursor: default;
  opacity: 0.5;
}

.live-browser-toolbar {
  min-height: 45px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 5px;
  padding: 7px 10px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
}

.live-browser-address-wrap {
  min-width: 0;
  height: 30px;
  display: flex;
  flex: 1;
  align-items: center;
  gap: 6px;
  padding: 0 9px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--ink-3);
}

.live-browser-address-wrap:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.live-browser-address-lock {
  flex: none;
  color: var(--accent);
  font-size: 9px;
}

.live-browser-address {
  min-width: 0;
  height: 100%;
  flex: 1;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 10px;
}

.live-browser-address::placeholder {
  color: var(--ink-3);
}

.live-browser-go {
  min-width: 30px;
  height: 27px;
  padding: 0 7px;
  border-color: var(--line-2);
  border-radius: var(--r-md);
  font-size: 9px;
}

.live-browser-viewport-wrap {
  position: relative;
  height: min(var(--live-browser-viewport-height), calc(100vh - 210px));
  min-height: 240px;
  max-height: 960px;
  flex: none;
  padding-bottom: 10px;
  background: var(--surface);
}

.live-browser-viewport {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--surface);
}

.live-browser-canvas {
  width: 100%;
  height: 100%;
  display: block;
  background: var(--surface);
  cursor: default;
  touch-action: none;
}

.live-browser-canvas:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.live-browser-canvas.is-human-control {
  cursor: pointer;
  outline: 2px solid color-mix(in srgb, #f4b84a 74%, var(--accent));
  outline-offset: -2px;
}

.live-browser-waiting {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 8px;
  padding: 28px;
  background: var(--bg);
  color: var(--ink-2);
  text-align: center;
}

.live-browser-waiting strong {
  font-size: 12px;
  font-weight: 500;
}

.live-browser-waiting small {
  max-width: 250px;
  color: var(--ink-3);
  font-size: 10px;
  line-height: 1.5;
}

.live-browser-waiting-orbit {
  width: 28px;
  height: 28px;
  border: 2px solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: browser-capture-spin 900ms linear infinite;
}

.live-browser-viewport-resize {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 10px;
  cursor: ns-resize;
  touch-action: none;
}

.live-browser-viewport-resize::after {
  position: absolute;
  top: 4px;
  left: 50%;
  width: 38px;
  height: 1px;
  background: var(--line-2);
  content: "";
  transform: translateX(-50%);
}

.live-browser-viewport-resize:hover::after,
.live-browser-viewport-resize:focus-visible::after {
  background: var(--accent);
  box-shadow: 0 0 9px var(--halo);
}

.live-browser-activity {
  min-height: 38px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  padding: 8px 13px;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 9.5px;
}

.live-browser-activity-dot {
  width: 6px;
  height: 6px;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.live-browser-reopen {
  position: absolute;
  z-index: 31;
  top: 78px;
  right: 16px;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 11px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--grad-card), var(--surface-2);
  box-shadow: 0 8px 24px color-mix(in srgb, #000 22%, transparent), 0 0 0 3px var(--accent-soft);
  color: var(--ink-2);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
}

.live-browser-reopen:hover,
.live-browser-reopen:focus-visible {
  color: var(--accent);
}

.live-browser-reopen:disabled {
  border-color: var(--line-2);
  box-shadow: 0 8px 24px color-mix(in srgb, #000 18%, transparent);
  color: var(--ink-3);
  cursor: default;
}

/*
 * 0.7.1 approved live-browser composition.
 *
 * This later block intentionally owns the complete rail composition while the
 * preceding rules retain the individual control states. The approved browser
 * is a fourth flex column, not a floating document card. It therefore gives
 * the conversation its real remaining width, and collapse, hide, reopen, and
 * rail resizing change layout exactly as the clickable reference did.
 */
.app {
  position: relative;
}

.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.topbar .live-browser-reopen {
  position: static;
  z-index: auto;
  top: auto;
  right: auto;
  min-height: 30px;
  gap: 6px;
  padding: 0 9px;
  border-radius: var(--r-md);
  background: transparent;
  box-shadow: none;
  color: var(--accent);
  -webkit-app-region: no-drag;
}

.topbar .live-browser-reopen:hover,
.topbar .live-browser-reopen:focus-visible {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  outline: none;
}

.live-browser-rail {
  --live-browser-rail-width: 390px;
  --live-browser-viewport-height: 344px;
  position: relative;
  z-index: 32;
  inset: auto;
  width: min(var(--live-browser-rail-width), calc(100vw - 58px));
  min-width: min(320px, calc(100vw - 58px));
  max-width: min(960px, calc(100vw - 58px));
  flex: none;
  overflow: hidden;
  border-left: 1px solid var(--line-2);
  background: color-mix(in srgb, var(--surface-2) 94%, transparent);
  box-shadow: none;
  transition: width 180ms ease;
}

.live-browser-rail.is-expanded {
  width: min(960px, 52vw);
}

.live-browser-rail.is-collapsed {
  width: 48px;
  min-width: 48px;
  max-width: 48px;
}

.live-browser-rail-resize::after {
  top: 46%;
  bottom: auto;
  left: 3px;
  width: 2px;
  height: 42px;
  border-radius: 2px;
  background: var(--line-2);
}

.live-browser-head {
  min-height: 64px;
  height: 64px;
  gap: 9px;
  padding: 0 12px 0 15px;
  background: transparent;
}

.live-browser-heading strong {
  margin: 0;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.live-browser-task {
  margin-top: 2px;
  font-size: 9px;
}

.live-browser-status-dot {
  width: 7px;
  height: 7px;
  flex: none;
  background: #e9a84d;
  box-shadow: 0 0 0 4px color-mix(in srgb, #e9a84d 12%, transparent);
}

.live-browser-rail[data-lifecycle="working"] .live-browser-status-dot,
.live-browser-rail[data-lifecycle="completed"] .live-browser-status-dot,
.live-browser-reopen[data-lifecycle="completed"] .live-browser-status-dot {
  background: #54d79b;
  box-shadow: 0 0 0 4px color-mix(in srgb, #54d79b 12%, transparent),
    0 0 14px color-mix(in srgb, #54d79b 45%, transparent);
}

/* ── 0.8.15 background tasks, composed into the 0.8.18 activity stack ──── */

.work-rail {
  --work-rail-width: 390px;
  position: relative;
  z-index: 32;
  width: min(var(--work-rail-width), calc(100vw - 58px));
  min-width: min(320px, calc(100vw - 58px));
  max-width: min(720px, calc(100vw - 58px));
  flex: none;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--line-2);
  background: color-mix(in srgb, var(--surface-2) 94%, transparent);
  color: var(--ink);
  transition: width 180ms ease;
}

.work-rail.is-expanded {
  width: min(720px, 48vw);
}

.work-rail-resize {
  position: absolute;
  z-index: 4;
  inset: 0 auto 0 -4px;
  width: 9px;
  cursor: ew-resize;
  touch-action: none;
}

.work-rail-resize::after {
  position: absolute;
  top: 46%;
  left: 3px;
  width: 2px;
  height: 42px;
  border-radius: 2px;
  background: var(--line-2);
  content: "";
}

.work-rail-resize:hover::after,
.work-rail-resize:focus-visible::after {
  background: var(--accent);
  box-shadow: 0 0 10px var(--halo);
}

.work-rail-head {
  min-height: 64px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 9px;
  padding: 0 12px 0 15px;
  border-bottom: 1px solid var(--line);
  -webkit-app-region: drag;
}

.work-rail-heading {
  min-width: 0;
  flex: 1;
}

.work-rail-heading strong,
.work-rail-heading span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.work-rail-heading strong {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.work-rail-heading span {
  margin-top: 2px;
  color: var(--ink-3);
  font-size: 9px;
}

.work-rail-actions {
  display: flex;
  gap: 2px;
}

.work-rail-action {
  width: 27px;
  height: 27px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 15px;
  -webkit-app-region: no-drag;
}

.work-rail-action:hover,
.work-rail-action:focus-visible {
  border-color: var(--line-2);
  background: var(--surface-3);
  color: var(--accent);
  outline: none;
}

.work-status-dot {
  --work-dot: var(--accent);
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--work-dot);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--work-dot) 12%, transparent);
}

.work-rail[data-tone="done"] .work-rail-head > .work-status-dot,
.work-rail-reopen[data-tone="done"] > .work-status-dot,
.work-phase[data-tone="done"] .work-phase-head > .work-status-dot,
.work-task[data-tone="done"] > .work-status-dot { --work-dot: #54d79b; }
.work-rail[data-tone="working"] .work-rail-head > .work-status-dot,
.work-rail-reopen[data-tone="working"] > .work-status-dot,
.work-phase[data-tone="working"] .work-phase-head > .work-status-dot,
.work-task[data-tone="working"] > .work-status-dot { --work-dot: #e9a84d; }
.work-rail[data-tone="error"] .work-rail-head > .work-status-dot,
.work-rail-reopen[data-tone="error"] > .work-status-dot,
.work-phase[data-tone="error"] .work-phase-head > .work-status-dot,
.work-task[data-tone="error"] > .work-status-dot { --work-dot: #ef6b73; }

.work-rail-content {
  min-height: 0;
  flex: 1;
  overflow: auto;
  padding: 14px;
}

.automation-section {
  display: grid;
  gap: 10px;
}

.automation-section-rail {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.automation-section-head,
.mobile-task-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.automation-section-head > div,
.mobile-task-section-head > div { min-width: 0; }
.automation-section-head strong,
.mobile-task-section-head strong { display: block; color: var(--ink); font-size: 11px; font-weight: 680; }
.automation-section-head small,
.mobile-task-section-head small { display: block; margin-top: 2px; color: var(--ink-3); font-size: 9px; }

.automation-new {
  min-height: 30px;
  padding: 0 11px;
  border: 1px solid color-mix(in srgb, var(--accent) 58%, var(--line));
  border-radius: 10px;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
  font-weight: 650;
}
.automation-new:hover,
.automation-new:focus-visible { background: var(--surface-3); outline: none; }
/* AUT-06: the New button is the write gate on a dark or unprobed broker. */
.automation-new:disabled { cursor: default; opacity: .45; background: transparent; }

.automation-list { display: grid; gap: 8px; }
.automation-empty { margin: 0; padding: 18px 10px; color: var(--ink-3); font-size: 10px; text-align: center; }
/* AUT-06: "not set up on this server" reads like the Skills empty state, not like a missing list. */
.automation-empty[data-state="unconfigured"],
.automation-empty[data-state="probing"] {
  padding: 14px 12px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-md);
  color: var(--ink-2);
  line-height: 1.45;
}

.automation-card {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-card), var(--surface);
}
.automation-card[data-tone="working"] { border-color: color-mix(in srgb, #e9a84d 42%, var(--line)); }
.automation-card[data-tone="error"] { border-color: color-mix(in srgb, #ef6b73 42%, var(--line)); }
.automation-card[data-tone="done"] { border-color: color-mix(in srgb, #54d79b 34%, var(--line)); }

.automation-card-main {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr) auto;
  align-items: start;
  gap: 10px;
  padding: 11px;
}
.automation-dot {
  width: 7px;
  height: 7px;
  margin-top: 4px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 10%, transparent);
}
.automation-card[data-tone="working"] .automation-dot { background: #e9a84d; box-shadow: 0 0 0 4px color-mix(in srgb, #e9a84d 12%, transparent); }
.automation-card[data-tone="error"] .automation-dot { background: #ef6b73; box-shadow: 0 0 0 4px color-mix(in srgb, #ef6b73 12%, transparent); }
.automation-card[data-tone="done"] .automation-dot { background: #54d79b; box-shadow: 0 0 0 4px color-mix(in srgb, #54d79b 12%, transparent); }
.automation-copy { min-width: 0; }
.automation-copy strong { display: block; overflow: hidden; color: var(--ink); font-size: 11px; font-weight: 680; text-overflow: ellipsis; white-space: nowrap; }
.automation-copy small { display: block; margin-top: 3px; color: var(--ink-3); font-size: 9px; line-height: 1.4; }
.automation-unread {
  align-self: start;
  padding: 3px 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-size: 7.5px;
  font-weight: 750;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.automation-budget {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 11px 9px 30px;
  color: var(--ink-3);
  font-size: 8.5px;
}
.automation-budget-track { flex: 1; height: 3px; overflow: hidden; border-radius: 99px; background: var(--surface-3); }
.automation-budget-track i { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
.automation-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 9px 11px; border-top: 1px solid var(--line); }
.automation-actions button {
  min-height: 27px;
  padding: 0 8px;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 8.5px;
}
.automation-actions button:hover,
.automation-actions button:focus-visible { border-color: currentColor; background: var(--surface-3); outline: none; }
.automation-actions button.is-danger { margin-left: auto; color: #ef6b73; }
.automation-actions button:disabled { cursor: default; opacity: .55; }

.automation-history { display: grid; gap: 7px; padding: 0 11px 11px; }
.automation-run {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface-2);
}
.automation-run > i { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.automation-run[data-tone="working"] > i { background: #e9a84d; }
.automation-run[data-tone="error"] > i { background: #ef6b73; }
.automation-run[data-tone="done"] > i { background: #54d79b; }
.automation-run-copy { min-width: 0; }
.automation-run-copy strong { display: block; color: var(--ink); font-size: 9px; font-weight: 650; }
.automation-run-copy small { display: block; margin-top: 2px; overflow: hidden; color: var(--ink-3); font-size: 8px; text-overflow: ellipsis; white-space: nowrap; }
.automation-run-actions { display: flex; gap: 4px; }
.automation-run-actions button { min-height: 24px; padding: 0 6px; border: 1px solid var(--line); border-radius: 7px; background: transparent; color: var(--accent); cursor: pointer; font: inherit; font-size: 8px; }

.work-conversation-label { margin: 14px 0 8px; color: var(--ink-3); font-size: 9px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; }

.automation-dialog {
  width: min(620px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 0;
  overflow: auto;
  border: 1px solid var(--line-2);
  border-radius: 18px;
  background: var(--surface-2);
  color: var(--ink);
  box-shadow: 0 28px 90px rgb(0 0 0 / .38);
}
.automation-dialog::backdrop { background: rgb(4 8 16 / .62); backdrop-filter: blur(8px); }
.automation-form,
.automation-receipt-dialog article { display: grid; gap: 16px; padding: 20px; }
.automation-dialog header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.automation-dialog header span { color: var(--accent); font-size: 8px; font-weight: 750; letter-spacing: .14em; text-transform: uppercase; }
.automation-dialog h2 { margin: 4px 0 0; color: var(--ink); font-size: 22px; letter-spacing: -.025em; }
.automation-dialog-close { width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 10px; background: transparent; color: var(--ink-2); cursor: pointer; font-size: 20px; }
.automation-form-note { margin: -4px 0 0; color: var(--ink-3); font-size: 11px; line-height: 1.55; }
.automation-form > label,
.automation-form-grid > label { display: grid; gap: 7px; color: var(--ink-2); font-size: 10px; font-weight: 650; }
.automation-form input,
.automation-form textarea {
  width: 100%;
  min-height: 42px;
  padding: 10px 11px;
  border: 1px solid var(--line);
  border-radius: 10px;
  outline: none;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
}
.automation-form input:focus,
.automation-form textarea:focus { border-color: var(--accent); }
.automation-form textarea { min-height: 116px; resize: vertical; line-height: 1.5; }
.automation-form-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.automation-money,
.automation-number { display: flex; align-items: center; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.automation-choice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 5px; }
.automation-choice button {
  min-height: 42px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
}
.automation-choice button[aria-pressed="true"] { border-color: color-mix(in srgb, var(--accent) 62%, var(--line)); color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.automation-choice button:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.automation-choice button:disabled { cursor: default; opacity: .36; }
.automation-money:focus-within,
.automation-number:focus-within { border-color: var(--accent); }
.automation-money b { padding-left: 11px; color: var(--ink-3); font-size: 12px; font-weight: 500; }
.automation-money input,
.automation-number input { border: 0; background: transparent; }
.automation-number small { padding-right: 10px; color: var(--ink-3); font-size: 9px; }
.automation-weekdays { display: flex; flex-wrap: wrap; gap: 7px; margin: 0; padding: 0; border: 0; }
.automation-weekdays legend { width: 100%; margin-bottom: 1px; color: var(--ink-2); font-size: 10px; font-weight: 650; }
.automation-weekdays label { display: flex; align-items: center; gap: 4px; min-height: 32px; padding: 0 8px; border: 1px solid var(--line); border-radius: 9px; color: var(--ink-2); font-size: 9px; }
.automation-weekdays input { width: auto; min-height: auto; }
.automation-form-error { margin: 0; padding: 9px 11px; border: 1px solid color-mix(in srgb, #ef6b73 45%, var(--line)); border-radius: 9px; color: #ef6b73; font-size: 10px; }
.automation-form footer { display: flex; justify-content: flex-end; gap: 8px; }
.automation-receipt-meta { display: flex; flex-wrap: wrap; gap: 7px; }
.automation-receipt-meta span { padding: 5px 8px; border: 1px solid var(--line); border-radius: 999px; color: var(--ink-3); font-size: 9px; }
.automation-receipt-answer { max-height: 52vh; overflow: auto; white-space: pre-wrap; color: var(--ink-2); font-size: 12px; line-height: 1.65; }

.work-rail-empty {
  min-height: 240px;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  padding: 24px;
  text-align: center;
}

.work-rail-empty strong { font-size: 12px; font-weight: 500; }
.work-rail-empty small { max-width: 240px; color: var(--ink-3); font-size: 10px; line-height: 1.5; }

.work-phase-list {
  display: grid;
  gap: 10px;
}

.work-run { display: grid; gap: 10px; }
.work-run + .work-run { margin-top: 14px; }
.work-run-bar {
  min-height: 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.work-run-label {
  color: var(--ink-3);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.work-run-controls { display: flex; align-items: center; gap: 6px; }
.work-control {
  min-height: 24px;
  padding: 0 8px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 8.5px;
}
.work-control.is-danger { color: #ef6b73; }
.work-control:hover,
.work-control:focus-visible { border-color: currentColor; background: var(--surface-3); outline: none; }
.work-control:disabled { cursor: default; opacity: .55; }

.work-phase {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--grad-card), var(--surface);
}

.work-phase-head {
  width: 100%;
  min-height: 40px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 11px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  text-align: left;
}

.work-phase-head strong {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .08em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.work-phase-head small { color: var(--ink-3); font-size: 9px; }
.work-phase-chevron { color: var(--ink-3); font-size: 13px; transition: transform 140ms ease; }
.work-phase.is-collapsed .work-phase-chevron { transform: rotate(-90deg); }
.work-phase.is-collapsed .work-phase-tasks { display: none; }

.work-phase-tasks { display: grid; }

.work-task {
  display: grid;
  grid-template-columns: 7px minmax(0, 1fr) auto;
  align-items: start;
  gap: 9px;
  padding: 11px;
  border-bottom: 1px solid var(--line);
}

.work-task:last-child { border-bottom: 0; }
.work-task > .work-status-dot { margin-top: 4px; width: 6px; height: 6px; }
.work-task-copy { min-width: 0; }
.work-task-title { overflow: hidden; color: var(--ink); font-size: 11px; font-weight: 500; text-overflow: ellipsis; white-space: nowrap; }
.work-task-meta { margin-top: 3px; color: var(--ink-3); font-family: "IBM Plex Mono", monospace; font-size: 8.5px; line-height: 1.45; }
.work-task-state { color: var(--ink-3); font-size: 8.5px; letter-spacing: .05em; text-transform: uppercase; }
.work-task-tail { display: grid; justify-items: end; gap: 7px; }
.work-redirect { min-height: 21px; padding-inline: 6px; }

.work-rail-footer {
  flex: none;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 8.5px;
  line-height: 1.45;
}

.work-rail-reopen {
  min-height: 30px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 9px;
  border: 1px solid var(--accent);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
  -webkit-app-region: no-drag;
}

.work-rail-reopen:hover,
.work-rail-reopen:focus-visible {
  background: var(--accent-soft);
  outline: none;
}

@media (max-width: 720px) {
  .work-rail,
  .work-rail-reopen { display: none !important; }
}

.live-browser-actions {
  gap: 2px;
}

.live-browser-action {
  width: 27px;
  height: 27px;
  border-radius: var(--r-md);
}

.live-browser-content {
  background: color-mix(in srgb, var(--surface-2) 92%, transparent);
}

.live-browser-tabs-row {
  min-height: 41px;
  align-items: end;
  gap: 3px;
  padding: 9px 11px 0;
  background: color-mix(in srgb, var(--surface) 54%, transparent);
}

.live-browser-tabs {
  gap: 3px;
}

.live-browser-tab-wrap {
  min-width: 76px;
  max-width: 126px;
  height: 31px;
  flex: 1 1 105px;
  gap: 5px;
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
  background: transparent;
}

.live-browser-tab-wrap:has(.live-browser-tab[aria-selected="true"]) {
  border-color: var(--line-2);
  border-bottom-color: var(--surface-2);
  background: var(--surface-2);
}

.live-browser-tab {
  padding: 0 0 0 9px;
  font-size: 9px;
}

.live-browser-tab-close {
  width: 18px;
  height: 18px;
  margin-right: 5px;
  border-radius: 5px;
  font-size: 12px;
}

.live-browser-new-tab {
  width: 25px;
  height: 25px;
  margin-bottom: 3px;
  border-radius: var(--r-md);
}

.live-browser-body {
  min-height: 0;
  padding: 0 14px 14px;
}

.live-browser-viewport-wrap {
  position: relative;
  height: auto;
  min-height: 0;
  max-height: none;
  margin-top: 14px;
  padding-bottom: 10px;
  overflow: hidden;
  border: 1px solid var(--line-2);
  border-radius: 11px;
  background: var(--surface);
  box-shadow: 0 16px 34px color-mix(in srgb, #000 25%, transparent);
}

.live-browser-toolbar {
  min-height: 38px;
  height: 38px;
  gap: 8px;
  padding: 0 9px;
  border-bottom: 1px solid var(--line-2);
  background: var(--surface-3);
}

.live-browser-window-controls {
  display: flex;
  flex: none;
  gap: 4px;
}

.live-browser-nav {
  position: relative;
  width: 7px;
  height: 7px;
  padding: 0;
  overflow: visible;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink-3) 42%, transparent);
  color: var(--ink-2);
  opacity: 1;
}

.live-browser-nav span {
  position: absolute;
  inset: 50% auto auto 50%;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%);
}

.live-browser-nav:hover,
.live-browser-nav:focus-visible {
  border: 0;
  background: color-mix(in srgb, var(--accent) 62%, var(--surface-3));
  box-shadow: 0 0 0 3px var(--accent-soft);
  outline: none;
}

.live-browser-toolbar .live-browser-nav:disabled {
  cursor: default;
  opacity: 0.64;
}

.live-browser-address-wrap {
  height: 25px;
  gap: 0;
  padding: 0 9px;
  border-color: var(--line-2);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink-3);
}

.live-browser-address-wrap:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.live-browser-address {
  color: var(--ink-2);
  font-size: 9px;
}

.live-browser-address::placeholder {
  color: var(--ink-3);
}

.live-browser-stream-badge {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 5px;
  color: #328565;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.live-browser-stream-badge i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #45c78e;
  animation: live-browser-pulse 1.5s ease-in-out infinite;
}

.live-browser-viewport {
  height: min(var(--live-browser-viewport-height), calc(100vh - 250px));
  min-height: 225px;
  background: var(--surface);
}

.live-browser-canvas {
  image-rendering: auto;
}

.live-browser-waiting {
  background: var(--surface);
  color: var(--ink-2);
}

.live-browser-waiting small {
  color: var(--ink-3);
}

.live-browser-viewport-resize {
  background: var(--surface-3);
}

.live-browser-activity {
  min-height: 0;
  display: block;
  margin-top: 13px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
}

.live-browser-activity strong,
.live-browser-activity span {
  display: block;
}

.live-browser-authority,
.live-browser-approval,
.live-browser-takeover {
  display: grid;
  gap: 10px;
  margin-top: 10px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
}

.live-browser-authority-copy {
  display: grid;
  gap: 3px;
}

.live-browser-source {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.live-browser-source-copy {
  display: grid;
  gap: 3px;
}

.live-browser-source-copy strong {
  color: var(--ink);
  font-size: 10px;
  font-weight: 620;
}

.live-browser-source-copy span,
.live-browser-pairing span,
.live-browser-pairing small {
  color: var(--ink-3);
  font-size: 8.5px;
  line-height: 1.45;
}

.live-browser-source-modes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface);
}

.live-browser-source-modes button {
  min-height: 29px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  font-size: 8.5px;
  white-space: nowrap;
  cursor: pointer;
}

.live-browser-source-modes button[aria-pressed="true"] {
  border-color: var(--line-2);
  background: var(--surface-3);
  color: var(--accent);
}

.live-browser-source-modes button:disabled {
  cursor: not-allowed;
  opacity: .48;
}

.live-browser-pairing {
  display: grid;
  gap: 8px;
  padding: 10px;
  border: 1px solid color-mix(in srgb, var(--accent) 38%, var(--line));
  border-radius: 9px;
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}

.live-browser-pairing dl {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  margin: 0;
}

.live-browser-pairing dl > div {
  display: grid;
  gap: 2px;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
}

.live-browser-pairing dt {
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 7px;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.live-browser-pairing dd {
  margin: 0;
  color: var(--ink);
  font-family: "IBM Plex Mono", monospace;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .06em;
}

.live-browser-extension-setup {
  justify-self: start;
  min-height: 30px;
  padding: 0 10px;
  border: 1px solid var(--line-2);
  border-radius: 7px;
  background: var(--surface);
  color: var(--accent);
  font: inherit;
  font-size: 8.5px;
  cursor: pointer;
}

.live-browser-extension-path {
  overflow-wrap: anywhere;
  color: var(--ink-2) !important;
}

.live-browser-authority-copy strong,
.live-browser-approval header strong,
.live-browser-takeover header strong {
  color: var(--ink);
  font-size: 10px;
  font-weight: 620;
}

.live-browser-authority-copy span,
.live-browser-approval header span,
.live-browser-takeover header span,
.live-browser-takeover p {
  color: var(--ink-3);
  font-size: 8.5px;
  line-height: 1.45;
}

.live-browser-authority-modes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface);
}

.live-browser-authority-modes button,
.live-browser-approval-actions button,
.live-browser-takeover-actions button {
  min-width: 0;
  min-height: 29px;
  padding: 0 7px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  font-size: 8.5px;
  cursor: pointer;
}

.live-browser-authority-modes button[aria-pressed="true"] {
  border-color: var(--line-2);
  background: var(--surface-3);
  color: var(--accent);
}

.live-browser-authority-modes button:disabled {
  cursor: not-allowed;
  opacity: .48;
}

.live-browser-approval {
  border-color: color-mix(in srgb, #f4b84a 42%, var(--line));
}

.live-browser-takeover {
  border-color: color-mix(in srgb, #f4b84a 58%, var(--line));
  background: color-mix(in srgb, #f4b84a 5%, var(--surface-2));
}

.live-browser-approval header,
.live-browser-takeover header {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
}

.live-browser-approval header > div,
.live-browser-takeover header > div {
  display: grid;
  gap: 2px;
}

.live-browser-approval-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #f4b84a;
  box-shadow: 0 0 0 4px rgb(244 184 74 / .1);
}

.live-browser-takeover-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #f4b84a;
  box-shadow: 0 0 0 4px rgb(244 184 74 / .12);
  animation: live-browser-takeover-pulse 1.8s ease-in-out infinite;
}

@keyframes live-browser-takeover-pulse {
  50% { box-shadow: 0 0 0 7px rgb(244 184 74 / .04); }
}

.live-browser-takeover p {
  margin: 0;
}

.live-browser-approval dl,
.live-browser-takeover dl {
  display: grid;
  gap: 7px;
  margin: 0;
}

.live-browser-approval dl > div,
.live-browser-takeover dl > div {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr);
  gap: 8px;
}

.live-browser-approval dt,
.live-browser-takeover dt {
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 7.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
}

.live-browser-approval dd,
.live-browser-takeover dd {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--ink-2);
  font-size: 8.5px;
  line-height: 1.4;
}

.live-browser-approval-actions,
.live-browser-takeover-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}

.live-browser-approval-actions button,
.live-browser-takeover-actions button {
  border-color: var(--line-2);
}

.live-browser-approval-actions button:last-child,
.live-browser-takeover-actions button:last-child {
  border-color: var(--accent);
  color: var(--accent);
}

.live-browser-authority-modes button:focus-visible,
.live-browser-source-modes button:focus-visible,
.live-browser-approval-actions button:focus-visible,
.live-browser-takeover-actions button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .live-browser-takeover-dot { animation: none; }
}

.live-browser-activity strong {
  color: var(--ink);
  font-size: 10px;
  font-weight: 500;
}

.live-browser-activity span {
  margin-top: 4px;
  color: var(--ink-3);
  font-size: 9px;
  line-height: 1.45;
}

.live-browser-research {
  margin-top: 10px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
}

.live-browser-research > header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.live-browser-research > header strong {
  color: var(--ink);
  font-size: 10px;
  font-weight: 560;
}

.live-browser-research > header span {
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 8px;
  text-align: right;
}

.live-browser-research ol {
  display: grid;
  gap: 8px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.live-browser-research-event {
  min-width: 0;
  padding: 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}

.live-browser-research-event-head {
  min-width: 0;
  display: grid;
  grid-template-columns: 6px minmax(0, 1fr) auto;
  align-items: center;
  gap: 7px;
}

.live-browser-research-event-head > i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #54d79b;
  box-shadow: 0 0 0 3px rgb(84 215 155 / .09);
}

.live-browser-research-event[data-outcome="refused"] .live-browser-research-event-head > i,
.live-browser-research-event[data-outcome="failed"] .live-browser-research-event-head > i {
  background: #ef6b73;
  box-shadow: 0 0 0 3px rgb(239 107 115 / .09);
}

.live-browser-research-event-head > strong {
  min-width: 0;
  overflow: hidden;
  color: var(--ink-2);
  font-size: 9.5px;
  font-weight: 560;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-browser-evidence-link,
.live-browser-research-sources button {
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 8.5px;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 42%, transparent);
  text-underline-offset: 2px;
}

.live-browser-research-event > p {
  max-height: 76px;
  margin: 7px 0 0 13px;
  overflow: hidden;
  color: var(--ink-3);
  font-size: 8.5px;
  line-height: 1.5;
  white-space: pre-wrap;
}

.live-browser-research-sources {
  display: flex;
  flex-wrap: wrap;
  gap: 5px 9px;
  margin: 7px 0 0 13px;
}

.live-browser-research-sources button {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-browser-evidence-link:focus-visible,
.live-browser-research-sources button:focus-visible {
  border-radius: 3px;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── XFER-PRODUCER: owner-driven downloads, quarantined before they are saved ── */

.live-browser-files {
  margin-top: 10px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
}

.live-browser-files > header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.live-browser-files > header > div {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.live-browser-files > header strong {
  color: var(--ink);
  font-size: 10px;
  font-weight: 560;
}

.live-browser-files > header span {
  color: var(--ink-3);
  font-size: 9px;
  line-height: 1.45;
}

.live-browser-files > header button,
.live-browser-files-quarantine-actions button {
  flex: none;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink-2);
  font: inherit;
  font-size: 9px;
  cursor: pointer;
}

.live-browser-files > header button:disabled,
.live-browser-files-quarantine-actions button:disabled,
.live-browser-files-element button:disabled {
  opacity: .5;
  cursor: default;
}

.live-browser-files > header button:focus-visible,
.live-browser-files-quarantine-actions button:focus-visible,
.live-browser-files-element button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.live-browser-files-note {
  margin: 8px 0 0;
  color: var(--ink-3);
  font-size: 9px;
  line-height: 1.45;
}

.live-browser-files ol {
  display: grid;
  gap: 6px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.live-browser-files ol:empty {
  display: none;
}

.live-browser-files-element,
.live-browser-files-transfer {
  min-width: 0;
  display: grid;
  gap: 4px;
  padding: 8px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}

.live-browser-files-element {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
}

.live-browser-files-element span,
.live-browser-files-transfer strong {
  min-width: 0;
  overflow: hidden;
  color: var(--ink-2);
  font-size: 9.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.live-browser-files-element button {
  padding: 3px 7px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--ink-2);
  font: inherit;
  font-size: 9px;
  cursor: pointer;
}

.live-browser-files-transfer strong {
  font-weight: 560;
}

.live-browser-files-transfer small {
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 8px;
  line-height: 1.4;
  word-break: break-all;
}

.live-browser-files-transfer[data-state="blocked"] strong,
.live-browser-files-transfer[data-state="scan_failed"] strong {
  color: #ef6b73;
}

.live-browser-files-quarantine-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}

.live-browser-files-quarantine-actions em {
  color: var(--ink-3);
  font-size: 9px;
  font-style: normal;
}

.live-browser-rail.is-collapsed .live-browser-head {
  height: 100%;
  min-height: 100%;
  align-items: flex-start;
  justify-content: center;
  padding: 18px 0;
}

.live-browser-rail.is-collapsed .live-browser-head > .live-browser-status-dot {
  display: none;
}

@keyframes live-browser-pulse {
  50% {
    opacity: 0.32;
    transform: scale(0.82);
  }
}

@keyframes image-shimmer {
  from { transform: translateX(-42%) rotate(8deg); }
  to { transform: translateX(42%) rotate(8deg); }
}

@keyframes image-orbit {
  to { transform: rotate(360deg); }
}

@keyframes image-counterspin {
  to { transform: rotate(-360deg); }
}

@keyframes image-liquid-roll {
  to { transform: rotate(360deg); }
}

@keyframes image-liquid-drift {
  from { translate: -5% -4%; scale: 0.92; }
  to { translate: 7% 6%; scale: 1.08; }
}

@keyframes image-mark-breathe {
  50% { transform: translateY(-3px) scale(1.035); opacity: 0.88; }
}

/* WRK-05, exact replies. All controls are real buttons with focus states. */
.bub {
  position: relative;
}

.bub-reply-action,
.pic-reply {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 9px;
  background: color-mix(in srgb, var(--surface-2) 92%, transparent);
  color: var(--ink-3);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.14s ease, color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}

.bub-reply-action {
  position: absolute;
  top: 50%;
  right: -36px;
  transform: translateY(-50%);
}

.bub-u .bub-reply-action {
  right: auto;
  left: -36px;
}

.bub:hover .bub-reply-action,
.bub:focus-within .bub-reply-action,
.pic:hover .pic-reply,
.pic:focus-within .pic-reply,
.bub-reply-action:focus-visible,
.pic-reply:focus-visible {
  opacity: 1;
}

.bub-reply-action:hover,
.bub-reply-action:focus-visible,
.pic-reply:hover,
.pic-reply:focus-visible {
  border-color: var(--accent);
  background: var(--surface);
  color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.bub-reply-action[hidden],
.pic-reply[hidden] {
  display: none;
}

.pic-reply {
  position: absolute;
  z-index: 3;
  top: 10px;
  right: 10px;
}

.bub-reply-preview {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px 8px;
  margin: 0 0 8px;
  padding: 7px 9px;
  border-left: 2px solid var(--accent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  color: var(--ink-3);
  font-size: 11px;
  line-height: 1.35;
}

.bub-reply-preview strong {
  grid-row: 1 / 3;
  color: var(--accent);
  font-weight: 700;
}

.bub-reply-preview span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reply-preview {
  width: 100%;
  max-width: 720px;
  margin: 0 auto 8px;
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 28px;
  align-items: center;
  gap: 9px;
  min-height: 48px;
  padding: 7px 9px;
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--accent);
  border-radius: 12px;
  background: var(--surface-2);
}

.reply-preview-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent);
}

.reply-preview-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
}

.reply-preview-copy strong {
  color: var(--accent);
  font-size: 11.5px;
}

.reply-preview-copy span {
  overflow: hidden;
  color: var(--ink-3);
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reply-preview-clear {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  font: inherit;
  font-size: 17px;
  cursor: pointer;
}

.reply-preview-clear:hover,
.reply-preview-clear:focus-visible {
  background: var(--accent-soft);
  color: var(--accent);
  outline: none;
}

@media (hover: none) {
  .bub-reply-action,
  .pic-reply {
    opacity: 0.74;
  }
}

@media (max-width: 860px) {
  .panel {
    position: absolute;
    z-index: 20;
    top: 0;
    bottom: 0;
    left: 58px;
    box-shadow: 18px 0 46px rgba(0, 0, 0, 0.28);
  }

  .topbar {
    padding: 0 20px;
  }

  .thread {
    padding: 30px 20px 20px;
  }

  .composer-wrap {
    padding: 10px 20px 18px;
  }

  .browser-rail {
    top: 72px;
    right: 12px;
    width: min(380px, calc(100vw - 82px));
    min-width: min(300px, calc(100vw - 82px));
    max-width: calc(100vw - 82px);
    height: min(340px, calc(100vh - 158px));
  }

  .browser-rail.is-expanded {
    top: 64px;
    right: 0;
    bottom: 0;
    width: min(680px, calc(100vw - 58px));
    min-width: min(520px, calc(100vw - 58px));
    height: auto;
  }

  .live-browser-rail {
    width: min(var(--live-browser-rail-width), calc(100vw - 58px));
    min-width: min(320px, calc(100vw - 58px));
  }

  .live-browser-rail.is-expanded {
    width: calc(100vw - 58px);
  }
}

@media (max-width: 620px) {
  .rail {
    width: 50px;
  }

  .panel {
    left: 50px;
    width: min(244px, calc(100vw - 50px));
  }

  .topbar {
    min-height: 56px;
    padding: 0 14px;
  }

  .thread {
    padding: 24px 14px 16px;
  }

  .bub-u {
    max-width: 88%;
  }

  .consent-host,
  .gallery {
    width: 100%;
    margin-left: 0;
  }

  .artifact-card {
    grid-template-columns: 38px minmax(0, 1fr);
    width: 100%;
  }

  .artifact-actions {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 1fr 1fr;
  }

  .artifact-open {
    min-height: 44px;
    width: 100%;
  }

  .artifact-comments-toggle {
    min-height: 44px;
    width: 100%;
  }

  .artifact-comment-form {
    grid-template-columns: 1fr;
  }

  .artifact-comment-submit,
  .artifact-comment-actions button {
    min-height: 44px;
  }

  .consent-body {
    padding-left: 19px;
  }

  .consent-actions .btn {
    flex: 1 1 120px;
  }

  .pic-frame {
    min-height: 180px;
  }

  .image-work-frame {
    min-height: 210px;
  }

  .image-work-receipt {
    align-items: flex-start;
    flex-direction: column;
    gap: 9px;
    padding: 12px;
  }

  .image-work-actions,
  .image-work-action {
    width: 100%;
  }

  .composer-wrap {
    padding: 9px 12px 14px;
  }

  .hint {
    display: none;
  }

  .voice-status {
    margin-top: 6px;
    padding: 0 8px;
    font-size: 11px;
  }

  .browser-rail {
    right: 8px;
    width: calc(100vw - 66px);
    min-width: 0;
    max-width: calc(100vw - 66px);
    height: min(320px, calc(100vh - 144px));
  }

  .browser-rail.is-expanded {
    top: 56px;
    width: calc(100vw - 50px);
    min-width: calc(100vw - 50px);
    max-width: calc(100vw - 50px);
    height: auto;
  }

  .live-browser-rail,
  .live-browser-rail.is-expanded {
    position: absolute;
    z-index: 32;
    top: 56px;
    right: 0;
    bottom: 0;
    width: calc(100vw - 50px);
    min-width: calc(100vw - 50px);
    max-width: calc(100vw - 50px);
  }

  .live-browser-rail.is-collapsed {
    width: 48px;
    min-width: 48px;
    max-width: 48px;
  }

  .live-browser-status {
    display: none;
  }

  .live-browser-head {
    padding-left: 12px;
  }

  .live-browser-viewport-wrap {
    height: auto;
  }

  .live-browser-reopen {
    top: 68px;
    right: 10px;
  }
}

/* Responsive application shell. Desktop remains the default above 720px. */
.mobile-only {
  display: none;
}

@media (max-width: 720px) {
  :root {
    --mobile-safe-top: env(safe-area-inset-top, 0px);
    --mobile-safe-bottom: env(safe-area-inset-bottom, 0px);
    --mobile-header-height: calc(64px + var(--mobile-safe-top));
    --mobile-nav-height: calc(68px + var(--mobile-safe-bottom));
    /* The account strip on Permissions: one 44px touch target plus breathing room. */
    --mobile-account-height: 60px;
  }

  html,
  body,
  #root {
    width: 100%;
    height: 100%;
    min-height: 100dvh;
  }

  body {
    overscroll-behavior: none;
  }

  .mobile-only {
    display: flex;
  }

  .app {
    position: relative;
    width: 100%;
    min-width: 0;
    height: 100%;
    min-height: 0;
    overflow: hidden;
  }

  .rail {
    display: none;
  }

  .main {
    width: 100%;
    height: 100%;
    min-width: 0;
    min-height: 0;
  }

  .topbar {
    min-height: var(--mobile-header-height);
    height: var(--mobile-header-height);
    gap: 10px;
    padding: var(--mobile-safe-top) 14px 0;
    background: color-mix(in srgb, var(--surface) 94%, transparent);
    backdrop-filter: blur(18px);
  }

  .mobile-menu {
    display: grid;
    place-items: center;
    flex: 0 0 42px;
    width: 42px;
    height: 42px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 13px;
    background: var(--surface-2);
    color: var(--accent);
  }

  .mobile-menu svg {
    width: 19px;
    height: 19px;
  }

  .mobile-header-copy {
    display: flex;
    flex: 1;
    min-width: 0;
    flex-direction: column;
    justify-content: center;
    line-height: 1.2;
    -webkit-app-region: drag;
  }

  .crumb,
  .mobile-view-title {
    max-width: 100%;
    overflow: hidden;
    color: var(--accent);
    font-size: 14px;
    font-weight: 720;
    line-height: 1.25;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .crumb b,
  :root[data-theme="light"] .crumb b {
    color: var(--accent);
    font-weight: 720;
  }

  .mobile-view-title {
    display: none;
  }

  .app:not([data-mobile-screen="chat"]) .crumb {
    display: none;
  }

  .app:not([data-mobile-screen="chat"]) .mobile-view-title {
    display: block;
  }

  .mobile-subtitle {
    display: block;
    margin-top: 3px;
    overflow: hidden;
    color: var(--ink-3);
    font-size: 9px;
    letter-spacing: 0.04em;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .topbar .grow {
    display: none;
  }

  .topbar .chip {
    flex: none;
    min-height: 30px;
    padding: 0 9px;
    border-radius: 9px;
    font-size: 8px;
    letter-spacing: 0.11em;
  }

  .app #class-lock.hidden {
    display: inline-flex !important;
  }

  .topbar .chip .sw {
    width: 6px;
    height: 6px;
    background: #54d79b;
    box-shadow: 0 0 0 3px color-mix(in srgb, #54d79b 13%, transparent);
  }

  .topbar .tsw {
    flex: 0 0 42px;
    width: 42px;
    height: 42px;
  }

  .topbar .live-browser-reopen {
    position: absolute;
    z-index: 4;
    top: calc(var(--mobile-header-height) + 9px);
    right: 13px;
    min-height: 34px;
    border: 1px solid var(--line-2);
    background: color-mix(in srgb, var(--surface-2) 94%, transparent);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
    backdrop-filter: blur(14px);
  }

  .thread {
    padding: 22px 15px 14px;
  }

  .threadinner {
    max-width: none;
  }

  .bub {
    margin-bottom: 20px;
  }

  /* Keep Reply inside the touch viewport. Desktop places the action just
   * outside the bubble, but that puts assistant actions past the right edge on
   * a phone and makes a visible control impossible to tap. */
  .bub-reply-action,
  .bub-u .bub-reply-action {
    position: relative;
    top: auto;
    right: auto;
    left: auto;
    transform: none;
    margin-top: 7px;
  }

  .bub-u .bub-reply-action {
    margin-left: auto;
  }

  .bub-u {
    max-width: 88%;
  }

  .bub-a {
    padding-left: 38px;
  }

  .bub-a::before {
    width: 28px;
    height: 28px;
  }

  .consent-host,
  .gallery {
    width: 100%;
    margin-left: 0;
  }

  .gallery {
    margin-bottom: 22px;
  }

  .pic {
    border-radius: 15px;
  }

  .pic-frame {
    min-height: 180px;
  }

  /* Only the touch target differs now — the glass treatment is the base rule. */
  .pic-expand {
    top: 12px;
    left: 12px;
    width: 38px;
    height: 38px;
    border-radius: 11px;
    font-size: 17px;
  }

  /* Safe areas: the notch and the home indicator both eat into `100dvh`. */
  .pic.is-image-expanded {
    padding: calc(var(--mobile-safe-top) + 58px) 12px calc(var(--mobile-safe-bottom) + 18px);
  }

  .pic.is-image-expanded .pic-frame {
    min-height: min(68vh, 620px);
    max-height: calc(100dvh - var(--mobile-safe-top) - var(--mobile-safe-bottom) - 88px);
  }

  .pic.is-image-expanded .pic-img {
    max-height: calc(100dvh - var(--mobile-safe-top) - var(--mobile-safe-bottom) - 90px);
  }

  .pic.is-image-expanded .pic-expand {
    top: calc(var(--mobile-safe-top) + 10px);
    left: 12px;
  }

  .pic.is-image-expanded .pic-expand::before {
    content: "Close";
    position: absolute;
    left: 48px;
    color: var(--ink-2);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.03em;
  }

  .composer-wrap {
    padding: 8px 12px 11px;
    background: linear-gradient(to top, var(--surface) 55%, transparent);
  }

  .composer {
    gap: 8px;
    padding: 8px;
    border-radius: 17px;
  }

  .attach,
  .voice-input,
  .voice-replies,
  .send-button,
  #stop {
    width: 44px;
    height: 44px;
    min-width: 44px;
    min-height: 44px;
    border-radius: 12px;
  }

  /*
   * IMG2-07. DESKTOP-ONLY until it is folded into the attach sheet. Four
   * 44px buttons with 8px gaps already leave a 375px phone 125px of draft; a
   * fifth squeezed it to 73px and wrapped the placeholder inside a one-row
   * field. The setting itself still rides the wire from a phone (`Session.send`
   * reads the stored key), so nothing about pictures breaks — only the knob is
   * withheld here. The popover goes with its trigger so a resize cannot leave
   * it open with nothing to close it from.
   */
  .image-options,
  .image-options-popover {
    display: none;
  }

  .cinput {
    min-height: 44px;
    padding: 10px 3px 8px;
    font-size: 16px;
  }

  .hint {
    display: none;
  }

  .mobile-nav {
    position: relative;
    z-index: 30;
    display: grid;
    flex: 0 0 var(--mobile-nav-height);
    grid-template-columns: repeat(6, minmax(0, 1fr));
    min-height: var(--mobile-nav-height);
    margin-top: auto;
    padding: 5px 4px var(--mobile-safe-bottom);
    border-top: 1px solid var(--line);
    background: color-mix(in srgb, var(--surface-2) 96%, transparent);
    backdrop-filter: blur(18px);
  }

  .mobile-nav button {
    display: flex;
    min-width: 0;
    min-height: 56px;
    padding: 5px 2px 4px;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    border: 0;
    border-radius: 11px;
    background: transparent;
    color: var(--ink-3);
    font: inherit;
    font-size: 9px;
    cursor: pointer;
  }

  .mobile-nav button svg {
    width: 21px;
    height: 21px;
  }

  .mobile-nav button[aria-current="page"] {
    background: var(--accent-soft);
    color: var(--accent);
  }

  .mobile-nav button[aria-current="page"] span {
    font-weight: 750;
  }

  /*
   * `.notice` IS DELIBERATELY ABSENT FROM THIS LIST, ON ALL FOUR SCREENS.
   *
   * It used to be hidden here with `!important`, and it is the only surface
   * that tells a person something went wrong. Threads and Permissions both
   * raise failures, and both rendered them into a container this rule had
   * already hidden — so on a phone the action did nothing and the app
   * explained nothing. An error nobody can see is the same as no error
   * handling at all.
   *
   * Nothing else is needed to keep these screens clean: `#renderNotice`
   * (app/src/render.ts) toggles a `hidden` class and clears the body whenever
   * there is no notice, so the element is already absent unless it has
   * something to say.
   */
  .app[data-mobile-screen="tasks"] .thread,
  .app[data-mobile-screen="tasks"] .entry,
  .app[data-mobile-screen="tasks"] .composer-wrap,
  .app[data-mobile-screen="skills"] .thread,
  .app[data-mobile-screen="skills"] .entry,
  .app[data-mobile-screen="skills"] .composer-wrap,
  .app[data-mobile-screen="library"] .thread,
  .app[data-mobile-screen="library"] .entry,
  .app[data-mobile-screen="library"] .composer-wrap,
  .app[data-mobile-screen="threads"] .thread,
  .app[data-mobile-screen="threads"] .entry,
  .app[data-mobile-screen="threads"] .composer-wrap,
  .app[data-mobile-screen="permissions"] .thread,
  .app[data-mobile-screen="permissions"] .entry,
  .app[data-mobile-screen="permissions"] .composer-wrap {
    display: none !important;
  }

  .mobile-surface {
    display: none;
    flex: 1;
    min-height: 0;
    padding: 22px 15px;
    flex-direction: column;
    overflow-y: auto;
  }

  .depot-surface {
    display: none !important;
  }

  .memory-surface {
    display: none !important;
  }

  /*
   * Sign out, update and the version live in `.rail`, which this breakpoint
   * hides — so without this a phone has no way to sign out, no way to take an
   * update, and no way to read its own version.
   *
   * Pinned above the navigation rather than scrolled with the panel: these are
   * the controls a person goes looking for, and hunting for them at the bottom
   * of a scrolling list is how they end up believed to be missing.
   */
  .mobile-account {
    position: absolute;
    z-index: 23;
    inset: auto 0 var(--mobile-nav-height);
    display: none;
    align-items: center;
    gap: 12px;
    height: var(--mobile-account-height);
    padding: 0 15px calc(env(safe-area-inset-bottom, 0px) / 2);
    border-top: 1px solid var(--line);
    /*
     * The same treatment `.mobile-nav` uses directly below, and for the same
     * reason: this is a pinned bar with content scrolling behind it.
     *
     * NOT `var(--bg)`. That token is a radial-gradient sized to the PAGE, so on
     * a 60px strip it paints an arbitrary slice of it and leaves
     * `background-color` transparent — the panel showed through.
     */
    background: color-mix(in srgb, var(--surface-2) 96%, transparent);
    backdrop-filter: blur(18px);
  }

  .app[data-mobile-screen="permissions"] .mobile-account {
    display: flex;
  }

  .mobile-account-version {
    flex: 1;
    min-width: 0;
    color: var(--ink-3);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
  }

  .mobile-account-update,
  .mobile-account-out {
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
    color: var(--ink);
    font: inherit;
    font-size: 14px;
  }

  .mobile-account-update {
    border-color: color-mix(in srgb, var(--accent) 46%, var(--line));
  }

  .app[data-mobile-screen="tasks"] .mobile-tasks,
  .app[data-mobile-screen="skills"] .mobile-skills,
  .app[data-mobile-screen="library"] .mobile-depot {
    display: flex;
  }

  .mobile-depot .mobile-surface-head {
    margin-bottom: 10px;
  }

  .depot-mobile-toolbar {
    margin-top: 0;
  }

  .depot-mobile-toolbar .depot-filter,
  .depot-mobile-toolbar .depot-view {
    width: 100%;
    margin-left: 0;
  }

  .depot-mobile-toolbar .depot-filter button,
  .depot-mobile-toolbar .depot-view button {
    flex: 1;
    min-height: 44px;
    min-width: 0;
    padding-inline: 4px;
    font-size: 9px;
  }

  .mobile-depot .depot-items {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 9px;
  }

  .mobile-depot .depot-items[data-layout="list"] {
    grid-template-columns: minmax(0, 1fr);
  }

  .mobile-depot .depot-card-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .mobile-depot .depot-origin {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .mobile-depot .depot-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mobile-depot .depot-actions button {
    min-height: 44px;
  }

  .mobile-depot .depot-items[data-layout="list"] .depot-card {
    grid-template-columns: 82px minmax(0, 1fr);
    grid-template-rows: auto auto;
  }

  .mobile-depot .depot-items[data-layout="list"] .depot-thumb {
    grid-row: 1 / span 2;
  }

  .mobile-depot .depot-items[data-layout="list"] .depot-actions {
    justify-content: stretch;
    padding-top: 0;
  }

  .depot-preview {
    padding: calc(var(--mobile-safe-top) + 10px) 10px calc(var(--mobile-safe-bottom) + 10px);
  }

  .depot-preview-card {
    width: 100%;
    max-height: 100%;
  }

  .mobile-surface-head,
  .mobile-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }

  .mobile-surface-head {
    margin-bottom: 20px;
  }

  .mobile-surface-head h2,
  .mobile-section-head h2 {
    margin: 0;
    color: var(--ink);
    font-size: 24px;
    font-weight: 680;
    letter-spacing: -0.025em;
  }

  .mobile-surface-head p,
  .mobile-section-head span {
    margin: 3px 0 0;
    color: var(--ink-3);
    font-size: 11px;
  }

  .mobile-count {
    display: grid;
    place-items: center;
    min-width: 31px;
    height: 31px;
    padding: 0 8px;
    border: 1px solid var(--line-2);
    border-radius: 10px;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 11px;
  }

  .mobile-task-list {
    display: grid;
    gap: 10px;
  }

  .mobile-tasks { gap: 18px; }
  .mobile-tasks .mobile-surface-head { margin-bottom: 0; }
  .mobile-tasks .automation-new { min-height: 40px; padding-inline: 16px; font-size: 12px; }
  .mobile-tasks .automation-section { padding: 14px; border: 1px solid var(--line); border-radius: 16px; background: color-mix(in srgb, var(--surface-2) 72%, transparent); }
  .mobile-tasks .automation-section-head strong,
  .mobile-task-section-head strong { font-size: 12px; }
  .mobile-tasks .automation-section-head small,
  .mobile-task-section-head small { font-size: 10px; }
  .mobile-tasks .automation-card-main { min-height: 72px; align-items: center; padding: 13px; }
  .mobile-tasks .automation-copy strong { font-size: 13px; }
  .mobile-tasks .automation-copy small { font-size: 10px; }
  .mobile-tasks .automation-actions button { min-height: 36px; padding-inline: 11px; font-size: 10px; }
  .mobile-tasks .automation-run { min-height: 54px; }
  .mobile-tasks .automation-run-copy strong { font-size: 10px; }
  .mobile-tasks .automation-run-copy small { font-size: 9px; }
  .mobile-tasks .automation-run-actions button { min-height: 34px; font-size: 9px; }

  .mobile-task-card {
    position: relative;
    display: grid;
    width: 100%;
    min-height: 92px;
    grid-template-columns: 10px minmax(0, 1fr) 28px;
    align-items: center;
    gap: 12px;
    padding: 15px;
    border: 1px solid var(--line);
    border-radius: 15px;
    background: var(--grad-card), var(--surface-2);
    color: var(--ink);
    text-align: left;
  }

  .mobile-task-card:hover,
  .mobile-task-card:focus-visible {
    border-color: var(--line-2);
    background: var(--surface-3);
  }

  .mobile-task-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
  }

  .mobile-task-dot.status-in-flight {
    background: #e9a84d;
    box-shadow: 0 0 0 4px color-mix(in srgb, #e9a84d 12%, transparent);
  }

  .mobile-task-dot.status-done {
    background: #54d79b;
    box-shadow: 0 0 0 4px color-mix(in srgb, #54d79b 12%, transparent);
  }

  .mobile-task-dot.status-error {
    background: #ef6b73;
    box-shadow: 0 0 0 4px color-mix(in srgb, #ef6b73 12%, transparent);
  }

  .mobile-task-copy {
    display: block;
    min-width: 0;
  }

  .mobile-task-eyebrow,
  .mobile-task-copy strong,
  .mobile-task-copy small {
    display: block;
  }

  .mobile-task-eyebrow {
    margin-bottom: 3px;
    color: var(--ink-3);
    font-size: 8px;
    font-weight: 750;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }

  .mobile-task-copy strong {
    overflow: hidden;
    font-size: 13px;
    font-weight: 680;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .mobile-task-copy small {
    margin-top: 3px;
    color: var(--ink-3);
    font-size: 10px;
  }

  .mobile-task-affordance {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--line);
    border-radius: 9px;
    color: var(--accent);
  }

  .mobile-empty {
    margin: auto 0;
    padding: 28px 22px;
    color: var(--ink-3);
    font-size: 12px;
    text-align: center;
  }

  .automation-dialog {
    width: calc(100vw - 20px);
    max-height: calc(100dvh - 20px);
    border-radius: 16px;
  }
  .automation-form,
  .automation-receipt-dialog article { padding: 16px; }
  .automation-form-grid { grid-template-columns: minmax(0, 1fr); }
  .automation-form input,
  .automation-choice button { min-height: 46px; }
  .automation-form footer { position: sticky; bottom: -16px; margin: 0 -16px -16px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); background: var(--surface-2); }
  .automation-form footer .btn { min-height: 44px; }

  /* ── SKL-P9: the list the tab never had ──────────────────────────────── */

  .mobile-skill-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .mobile-skill-list:empty {
    display: none;
  }

  .mobile-skill-row {
    display: flex;
    flex-direction: column;
    gap: 3px;
    width: 100%;
    padding: 13px 15px;
    border: 1px solid var(--line-2);
    border-radius: 14px;
    background: var(--surface-2);
    color: inherit;
    font: inherit;
    text-align: left;
    /* A tap target, not a link: 44px is the floor a thumb needs. */
    min-height: 44px;
    cursor: pointer;
  }

  .mobile-skill-row:active {
    background: color-mix(in srgb, var(--surface-2) 82%, var(--ink) 18%);
  }

  .mobile-skill-name {
    font-weight: 600;
    font-variant-ligatures: none;
  }

  .mobile-skill-detail {
    color: var(--ink-2);
    font-size: 13px;
    /* One line: the description is a hint here, and a wrapping paragraph turns
       a scannable list into a wall. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .mobile-skills-empty {
    display: grid;
    place-items: center;
    min-height: 270px;
    margin: auto 0;
    padding: 34px 24px;
    border: 1px dashed var(--line-2);
    border-radius: 18px;
    background: color-mix(in srgb, var(--surface-2) 70%, transparent);
    text-align: center;
  }

  .mobile-skills-empty svg {
    width: 40px;
    height: 40px;
    margin-bottom: 15px;
    color: var(--accent);
  }

  .mobile-skills-empty h3 {
    margin: 0;
    font-size: 17px;
    font-weight: 680;
  }

  .mobile-skills-empty p {
    margin: 6px 0 0;
    color: var(--ink-3);
    font-size: 12px;
  }

  .panel,
  .panel.hidden {
    display: none !important;
  }

  .app[data-mobile-screen="threads"] .panel,
  .app[data-mobile-screen="permissions"] .panel {
    position: absolute;
    z-index: 22;
    inset: var(--mobile-header-height) 0 var(--mobile-nav-height);
    display: flex !important;
    width: 100%;
    min-width: 0;
    padding: 22px 15px 14px;
    border: 0;
    background: var(--bg);
    box-shadow: none;
  }

  /*
   * Permissions is the only destination that also carries the account strip, so
   * the panel stops short of it. Threads keeps the full height.
   */
  .app[data-mobile-screen="permissions"] .panel {
    inset: var(--mobile-header-height) 0 calc(var(--mobile-nav-height) + var(--mobile-account-height));
    display: flex !important;
    width: 100%;
    min-width: 0;
    padding: 22px 15px 14px;
    border: 0;
    background: var(--bg);
    box-shadow: none;
  }

  .panel-h {
    display: none;
  }

  .mobile-section-head {
    flex: none;
    margin-bottom: 17px;
  }

  .mobile-thread-tabs {
    display: flex;
    flex: none;
    gap: 4px;
    width: 100%;
    margin: 0 0 12px;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: 13px;
    background: color-mix(in srgb, var(--surface) 38%, transparent);
  }

  .mobile-thread-tabs button {
    flex: 1;
    min-height: 40px;
    font-size: 11px;
  }

  .app[data-mobile-screen="permissions"] .mobile-thread-tabs {
    display: none;
  }

  .panel[data-thread-subview="memory"] .panel-tabs,
  .panel[data-thread-subview="memory"] .panel-list,
  .panel[data-thread-subview="memory"] .panel-empty {
    display: none !important;
  }

  .panel[data-thread-subview="memory"] .mobile-memory {
    display: flex !important;
  }

  .mobile-memory {
    flex: 1;
    min-height: 0;
    flex-direction: column;
    gap: 10px;
    overflow-y: auto;
  }

  .mobile-memory .memory-filter {
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .mobile-memory .memory-filter button {
    flex: 1;
    min-width: max-content;
    min-height: 44px;
  }

  .mobile-memory .memory-settings button,
  .mobile-memory .memory-settings input {
    min-height: 44px;
  }

  .mobile-memory .memory-list {
    margin-top: 2px;
  }

  .mobile-memory .memory-card {
    min-height: 82px;
    padding: 14px;
    border-radius: 14px;
  }

  .mobile-memory .memory-deleted-heading {
    margin-top: 18px;
  }

  .mobile-memory .memory-detail {
    padding: 14px;
    border-radius: 14px;
  }

  .mobile-memory .memory-detail-copy input,
  .mobile-memory .memory-detail-copy textarea,
  .mobile-memory .btn {
    min-height: 44px;
    font-size: 13px;
  }

  .memory-mode {
    margin-top: 15px;
    padding-top: 12px;
  }

  .memory-mode-options button {
    flex: 1;
    min-height: 44px;
  }

  .mobile-new {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    padding: 0;
    border: 1px solid var(--accent);
    border-radius: 13px;
    background: transparent;
    color: var(--accent);
    font-size: 21px;
  }

  .panel-tabs {
    flex: none;
    width: 100%;
    margin: 0 0 15px;
    padding: 4px;
    border-radius: 13px;
  }

  .app[data-mobile-screen="threads"] #panel-permissions {
    display: none;
  }

  .app[data-mobile-screen="permissions"] .panel-tabs {
    display: none;
  }

  .panel-tabs button {
    min-height: 38px;
    font-size: 11px;
  }

  .panel-list {
    flex: 1;
    padding: 0;
  }

  .panel-item {
    margin-bottom: 9px;
  }

  .panel-row {
    min-height: 66px;
    padding: 13px 14px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--surface-2) 82%, transparent);
    font-size: 13px;
  }

  .panel-row.on {
    border-color: var(--line-2);
    background: var(--surface-3);
  }

  .thread-status {
    top: 13px;
    right: 13px;
    width: 8px;
    height: 8px;
  }

  .panel-when {
    margin-top: 4px;
    font-size: 10px;
  }

  .panel-actions {
    min-height: 38px;
    padding-top: 5px;
    opacity: 1;
  }

  .panel-actions button {
    min-height: 34px;
    padding: 7px 9px;
    font-size: 10px;
  }

  .permission-card {
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: color-mix(in srgb, var(--surface-2) 82%, transparent);
  }

  .permission-card .panel-row {
    background: transparent;
  }

  .permission-actions {
    padding: 0 10px 11px;
  }

  .browser-rail,
  .browser-rail.is-expanded,
  .live-browser-rail,
  .live-browser-rail.is-expanded {
    position: absolute;
    z-index: 80;
    inset: 0;
    width: 100%;
    min-width: 100%;
    max-width: 100%;
    height: 100%;
    min-height: 100%;
    max-height: 100%;
    border: 0;
    border-radius: 0;
    resize: none;
  }

  .browser-head,
  .live-browser-head {
    min-height: calc(62px + var(--mobile-safe-top));
    height: calc(62px + var(--mobile-safe-top));
    padding-top: var(--mobile-safe-top);
  }

  .browser-rail.is-collapsed,
  .live-browser-rail.is-collapsed {
    inset: calc(var(--mobile-safe-top) + 8px) 9px auto auto;
    width: 48px;
    min-width: 48px;
    max-width: 48px;
    height: 48px;
    min-height: 48px;
    max-height: 48px;
    border: 1px solid var(--line-2);
    border-radius: 14px;
  }

  .live-browser-body {
    padding: 0 10px 10px;
  }

  .live-browser-tabs-row {
    padding-inline: 8px;
  }

  .live-browser-viewport-wrap {
    margin-top: 10px;
  }

  .live-browser-viewport {
    height: min(var(--live-browser-viewport-height), calc(100dvh - var(--mobile-safe-top) - 250px));
    min-height: 210px;
  }

  .live-browser-rail-resize,
  .live-browser-viewport-resize {
    display: none;
  }
}

@media (max-width: 380px) {
  .topbar {
    gap: 7px;
    padding-inline: 10px;
  }

  .mobile-menu,
  .topbar .tsw {
    flex-basis: 40px;
    width: 40px;
    height: 40px;
  }

  .topbar .chip {
    width: 30px;
    min-width: 30px;
    padding: 0;
    justify-content: center;
  }

  .topbar .chip span {
    display: none;
  }

  .mobile-nav button {
    font-size: 8px;
  }

  .thread,
  .mobile-surface,
  .app[data-mobile-screen="threads"] .panel,
  .app[data-mobile-screen="permissions"] .panel {
    padding-inline: 11px;
  }
}

@media (max-width: 340px) {
  .mobile-subtitle {
    display: none;
  }

  .mobile-nav button span {
    max-width: 54px;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .mobile-task-card {
    padding-inline: 12px;
    gap: 9px;
  }
}

/* 0.8.18 composable activity rail. Browser and work cards remain independent. */
.right-rail-stack {
  --right-rail-width: 420px;
  position: relative;
  z-index: 32;
  width: min(var(--right-rail-width), calc(100vw - 58px));
  min-width: min(320px, calc(100vw - 58px));
  max-width: min(var(--right-rail-limit, 960px), calc(100vw - 58px));
  min-height: 0;
  display: flex;
  flex: none;
  flex-direction: column;
  gap: 10px;
  overflow-x: hidden;
  overflow-y: auto;
  padding: 0 9px 9px;
  border-left: 1px solid var(--line-2);
  background:
    radial-gradient(circle at 78% 8%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 31%),
    color-mix(in srgb, var(--surface-2) 97%, transparent);
  scrollbar-width: thin;
  transition: width 180ms ease;
}

.right-rail-stack:not(:has(> aside:not(.hidden), > .activity-hidden-card:not(.hidden))) { display: none; }
.right-rail-stack.is-expanded { width: min(720px, 52vw); }
.right-rail-stack:has(> .browser-rail.is-expanded),
.right-rail-stack:has(> .live-browser-rail.is-expanded) { width: min(960px, 56vw); }
.right-rail-stack.is-manually-sized,
.right-rail-stack.is-manually-sized:has(> .browser-rail.is-expanded, > .live-browser-rail.is-expanded) {
  width: var(--right-rail-width);
  transition: none;
}

.activity-rail-head {
  position: sticky;
  z-index: 48;
  top: 0;
  min-height: 58px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 10px;
  margin: 0 -9px;
  padding: 0 11px 0 18px;
  border-bottom: 1px solid var(--line-2);
  background: color-mix(in srgb, var(--surface-2) 91%, transparent);
  backdrop-filter: blur(16px);
}

.activity-rail-head > strong {
  min-width: 0;
  flex: 1;
  color: var(--ink);
  font-size: 13px;
  font-weight: 560;
  letter-spacing: -.01em;
}

.activity-rail-count {
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  letter-spacing: .03em;
}

.activity-rail-action {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 15px;
  -webkit-app-region: no-drag;
}

.activity-rail-action:hover,
.activity-rail-action:focus-visible {
  border-color: var(--line-2);
  outline: none;
  background: var(--surface-3);
  color: var(--accent);
}

.activity-hidden-card {
  min-height: 46px;
  display: flex;
  flex: none;
  align-items: center;
  gap: 9px;
  padding: 10px 12px;
  border: 1px dashed color-mix(in srgb, var(--accent) 36%, var(--line-2));
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-2));
  color: var(--ink-3);
  font-size: 10px;
}

.activity-hidden-card > span:not(.work-status-dot):not(.live-browser-status-dot) {
  min-width: 0;
  flex: 1;
}

.activity-hidden-card > button {
  padding: 4px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
}

.activity-hidden-card > button:hover,
.activity-hidden-card > button:focus-visible {
  outline: none;
  background: var(--accent-soft);
}

.activity-hidden-card[data-tone="done"] > .work-status-dot { --work-dot: #54d79b; }
.activity-hidden-card[data-tone="working"] > .work-status-dot { --work-dot: #e9a84d; }
.activity-hidden-card[data-tone="error"] > .work-status-dot { --work-dot: #ef6b73; }

.right-rail-stack-resize {
  position: absolute;
  z-index: 50;
  inset: 0 auto 0 -5px;
  width: 10px;
  cursor: ew-resize;
  touch-action: none;
}

.right-rail-stack-resize::after {
  position: absolute;
  top: 46%;
  left: 4px;
  width: 2px;
  height: 44px;
  border-radius: 2px;
  background: var(--line-2);
  content: "";
}

.right-rail-stack-resize:hover::after,
.right-rail-stack-resize:focus-visible::after {
  background: var(--accent);
  box-shadow: 0 0 10px var(--halo);
}

.app[data-right-rail-panel] .right-rail-stack > .browser-rail:not(.hidden),
.app[data-right-rail-panel] .right-rail-stack > .live-browser-rail:not(.hidden),
.app[data-right-rail-panel] .right-rail-stack > .work-rail:not(.hidden),
.right-rail-stack > .browser-rail:not(.hidden),
.right-rail-stack > .live-browser-rail:not(.hidden),
.right-rail-stack > .work-rail:not(.hidden) {
  position: relative;
  inset: auto;
  width: 100%;
  min-width: 0;
  max-width: none;
  display: flex;
  flex: 0 0 auto;
  overflow: hidden;
  border: 1px solid var(--line-2);
  border-radius: 14px;
  background: var(--grad-panel), var(--surface-2);
  box-shadow: inset 0 1px rgb(255 255 255 / .025);
  resize: none;
}

.right-rail-stack .browser-head,
.right-rail-stack .live-browser-head,
.right-rail-stack .work-rail-head {
  min-height: 52px;
  height: 52px;
  gap: 9px;
  padding: 8px 9px 8px 13px;
  border-bottom: 1px solid var(--line-2);
  background: color-mix(in srgb, var(--surface-3) 62%, transparent);
}

.right-rail-stack .browser-kicker,
.right-rail-stack .live-browser-heading strong,
.right-rail-stack .work-rail-heading strong {
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 8px;
  font-weight: 540;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.right-rail-stack .browser-title,
.right-rail-stack .live-browser-task,
.right-rail-stack .work-rail-heading span {
  margin-top: 2px;
  color: var(--ink);
  font-size: 11px;
  font-weight: 520;
  letter-spacing: 0;
  text-transform: none;
}

.right-rail-stack .browser-context { display: none; }

.right-rail-stack > .browser-rail:not(.hidden) {
  height: min(390px, calc(100vh - 120px));
  min-height: 230px;
  max-height: 72vh;
}

.right-rail-stack > .browser-rail.is-expanded:not(.hidden) {
  top: auto;
  right: auto;
  bottom: auto;
  width: 100%;
  min-width: 0;
  height: min(680px, calc(100vh - 32px));
  max-height: none;
  border: 1px solid var(--line-2);
  border-radius: 14px;
}

.right-rail-stack > .browser-rail.is-collapsed:not(.hidden),
.right-rail-stack > .live-browser-rail.is-collapsed:not(.hidden),
.right-rail-stack > .work-rail.is-collapsed:not(.hidden) {
  width: 100%;
  min-width: 0;
  max-width: none;
  height: 52px;
  min-height: 52px;
  max-height: 52px;
}

.right-rail-stack > .work-rail.is-collapsed .work-rail-content,
.right-rail-stack > .work-rail.is-collapsed .work-rail-footer { display: none; }
.right-rail-stack > .work-rail.is-collapsed .work-rail-head { border-bottom-color: transparent; }

.right-rail-stack > .live-browser-rail:not(.hidden) { --live-browser-viewport-height: 344px; }
.right-rail-stack > .live-browser-rail .live-browser-content { flex: 0 0 auto; }
.right-rail-stack > .work-rail .work-rail-content { max-height: 70vh; flex: 0 1 auto; padding: 15px; }
.right-rail-stack > .work-rail.is-expanded:not(.hidden) { width: 100%; }
.right-rail-stack .live-browser-rail-resize,
.right-rail-stack .work-rail-resize { display: none; }

.right-rail-stack .live-browser-tabs-row { padding: 7px 7px 0; background: color-mix(in srgb, var(--surface) 76%, transparent); }
.right-rail-stack .live-browser-tab-wrap {
  border-radius: 8px 8px 0 0;
  background: var(--surface);
}
.right-rail-stack .live-browser-tab[aria-selected="true"] { background: var(--surface-3); color: var(--ink); }
.right-rail-stack .live-browser-toolbar { border-top-color: var(--line-2); background: var(--surface-3); }
.right-rail-stack .live-browser-address { border-color: var(--line-2); border-radius: 8px; background: var(--surface); }
.right-rail-stack .live-browser-viewport { background: var(--surface); }

.right-rail-stack .work-conversation-label {
  margin: 0 0 9px 2px;
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .1em;
}

.right-rail-stack .work-run {
  gap: 0;
  padding: 15px;
  border: 1px solid var(--line-2);
  border-radius: 13px;
  background: var(--grad-card), var(--surface);
}

.right-rail-stack .work-run + .work-run { margin-top: 10px; }
.right-rail-stack .work-run-bar { min-height: 34px; }
.right-rail-stack .work-run-label {
  min-width: 0;
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  overflow: hidden;
  color: var(--ink);
  font-size: 11px;
  font-weight: 560;
  letter-spacing: 0;
  text-overflow: ellipsis;
  text-transform: none;
  white-space: nowrap;
}

.right-rail-stack .work-run-label::before {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 9%, transparent);
  content: "";
}
.right-rail-stack .work-run[data-tone="working"] .work-run-label::before { background: #e9a84d; box-shadow: 0 0 0 4px rgb(233 168 77 / .09); }
.right-rail-stack .work-run[data-tone="done"] .work-run-label::before { background: #54d79b; box-shadow: 0 0 0 4px rgb(84 215 155 / .09); }
.right-rail-stack .work-run[data-tone="error"] .work-run-label::before { background: #ef6b73; box-shadow: 0 0 0 4px rgb(239 107 115 / .09); }

.right-rail-stack .work-run-controls { gap: 5px; }
.right-rail-stack .work-control { min-height: 28px; border-radius: 8px; font-size: 8px; }
.right-rail-stack .work-run-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 8px 0 0 18px;
  color: var(--ink-3);
  font-family: "IBM Plex Mono", monospace;
  font-size: 8.5px;
}

.right-rail-stack .work-run-goal {
  margin: 14px 0 17px 18px;
  padding: 12px 13px;
  border: 1px solid color-mix(in srgb, var(--accent) 24%, var(--line));
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-2));
  color: var(--ink-2);
  font-size: 10px;
  line-height: 1.5;
}

.right-rail-stack .work-phases-title {
  margin: 0 0 9px 18px;
  color: var(--ink);
  font-size: 11px;
  font-weight: 560;
}

.right-rail-stack .work-phase {
  margin: 0 0 8px 18px;
  border-color: var(--line-2);
  border-radius: 10px;
  background: var(--surface-2);
}

.right-rail-stack .work-phase:last-child { margin-bottom: 0; }
.right-rail-stack .work-phase-head {
  min-height: 49px;
  padding: 9px 11px;
  border-bottom-color: var(--line-2);
  background: var(--surface-3);
}
.right-rail-stack .work-phase-head strong {
  font-size: 10px;
  font-weight: 560;
  letter-spacing: 0;
  text-transform: none;
}

.right-rail-stack .work-phase-progress { display: flex; gap: 4px; }
.right-rail-stack .work-phase-progress i {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 42%, var(--surface-3));
}
.right-rail-stack .work-phase-progress i[data-tone="done"] { background: #54d79b; }
.right-rail-stack .work-phase-progress i[data-tone="working"] { background: #e9a84d; }
.right-rail-stack .work-phase-progress i[data-tone="error"] { background: #ef6b73; }

.right-rail-stack .work-phase-tasks { padding: 11px 10px 7px; }
.right-rail-stack .work-task-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) .65fr .45fr .7fr;
  align-items: baseline;
  gap: 7px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 8px;
}
.right-rail-stack .work-task-grid.is-head { margin-bottom: 6px; color: var(--ink-3); }
.right-rail-stack .work-task-grid.is-row { color: var(--ink-2); }
.right-rail-stack .work-task-grid > span:nth-child(n+2) { text-align: right; }
.right-rail-stack .work-task-worker {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
}
.right-rail-stack .work-task-worker b { overflow: hidden; font-weight: 500; text-overflow: ellipsis; white-space: nowrap; }
.right-rail-stack .work-task-worker .work-status-dot { width: 6px; height: 6px; }
.right-rail-stack .work-task[data-tone="done"] .work-task-worker .work-status-dot { --work-dot: #54d79b; }
.right-rail-stack .work-task[data-tone="working"] .work-task-worker .work-status-dot { --work-dot: #e9a84d; }
.right-rail-stack .work-task[data-tone="error"] .work-task-worker .work-status-dot { --work-dot: #ef6b73; }

.right-rail-stack .work-task {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 5px 9px;
  padding: 8px 0;
  border-bottom-color: var(--line);
}
.right-rail-stack .work-task-grid { grid-column: 1 / -1; }
.right-rail-stack .work-task-meta { grid-column: 1; margin: 0; }
.right-rail-stack .work-task-tail { grid-column: 2; grid-row: 2; display: flex; align-items: center; gap: 6px; }
.right-rail-stack .automation-section-rail { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); border-bottom: 0; }

@media (max-width: 900px) {
  .right-rail-stack { --right-rail-width: 390px; }
  .right-rail-stack .work-run { padding-inline: 10px; }
  .right-rail-stack .work-run-goal,
  .right-rail-stack .work-phases-title,
  .right-rail-stack .work-phase,
  .right-rail-stack .work-run-stats { margin-left: 0; }
  .right-rail-stack .work-task-grid { grid-template-columns: minmax(0, 1.35fr) .65fr .45fr .7fr; gap: 5px; }
}

@media (max-width: 720px) {
  .right-rail-stack { display: none !important; }
}

/* Activity can make chat compact even on a wide display. Keep the established
   mobile layout separate and adapt to the actual desktop chat column. */
@media (min-width: 721px) {
  .main { container: chat-column / inline-size; }
  .topbar .mobile-header-copy { min-width: 0; }
  .topbar .crumb { display: block; }

  @container chat-column (max-width: 480px) {
    .topbar { flex-wrap: wrap; gap: 8px; padding: 12px; }
    .topbar .mobile-header-copy { flex: 1 0 100%; }
    .topbar .grow { display: none; }
    .topbar .tsw { margin-left: auto; flex: none; }
    .topbar .work-rail-reopen,
    .topbar .live-browser-reopen { min-width: 0; max-width: 100%; }
    .topbar .work-rail-reopen > span,
    .topbar .live-browser-reopen > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .composer-wrap { padding-inline: 12px; }
    .composer {
      display: grid;
      grid-template-columns: 34px 34px minmax(0, 1fr) 34px 34px;
      gap: 8px 6px;
      padding: 8px;
    }
    .composer .attach { grid-column: 1; grid-row: 1; }
    .composer .image-options { grid-column: 2; grid-row: 1; }
    .composer .cinput { grid-column: 3 / -1; grid-row: 1; width: 100%; }
    .composer .voice-replies { grid-column: 3; grid-row: 2; justify-self: end; }
    .composer .voice-input { grid-column: 4; grid-row: 2; }
    .composer .send-button,
    .composer #stop { grid-column: 5; grid-row: 2; min-width: 0; width: 34px; padding: 0; }
    .hint { overflow-wrap: anywhere; }
  }
}
