/* ---------- theme ----------
   Two palettes, one set of names: the dark one on :root, the light one once
   index.html has put data-theme="light" on <html> (this browser's choice,
   else the OS's — themeToggle in app.js). Every rule below speaks in these
   names; a rule that names a colour is a bug in one theme or the other. The
   tints are mixed from the base colours, so a theme is only its bases. */
/* hidden means hidden, whatever display the element's own rule gives it */
[hidden] { display: none !important; }

:root {
  color-scheme: dark;
  --bg: #0f0f12;
  --bg-sunken: #0a0a0c;
  --bg-raised: #17171b;
  --bg-hover: #1f1f24;
  --bg-code: #0a0a0c;
  --bg-overlay: rgba(23, 23, 27, 0.88);
  --input-bg: #0f0f12;
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.15);
  --text: #ececef;
  --text-dim: #9b9ba4;
  --text-faint: #6c6c76;
  --accent: #8b7cf6;
  --accent-strong: #6e5ce6;
  --green: #4ade80;
  --green-strong: #238636;
  --red: #f87171;
  --yellow: #fbbf24;
  --blue: #60a5fa;
  --backdrop: rgba(0, 0, 0, 0.6);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.5);
  --checker-a: #1c1c21;
  --checker-b: #141418;
  /* the checkerboard transparent sprites read against */
  --checker: repeating-conic-gradient(var(--checker-a) 0% 25%, var(--checker-b) 0% 50%) 0 0 / 18px 18px;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --radius: 10px;
}
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f8f8f9;
  --bg-sunken: #f0f0f2;
  --bg-raised: #ffffff;
  --bg-hover: #ececee;
  --bg-code: #f3f3f5;
  --bg-overlay: rgba(255, 255, 255, 0.9);
  --input-bg: #ffffff;
  --border: rgba(0, 0, 0, 0.08);
  --border-strong: rgba(0, 0, 0, 0.14);
  --text: #18181b;
  --text-dim: #60606a;
  --text-faint: #8d8d97;
  --accent: #5b4fe0;
  --accent-strong: #5b4fe0;
  --green: #15803d;
  --green-strong: #1f883d;
  --red: #dc2626;
  --yellow: #b45309;
  --blue: #2563eb;
  --backdrop: rgba(24, 24, 27, 0.4);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.08);
  --shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.18);
  --checker-a: #e6e6ea;
  --checker-b: #f6f6f8;
  /* The status text is dark enough to read on white; its tints come from
     the brighter shade of the same hue, or they would be mud. */
  --accent-soft: rgba(91, 79, 224, 0.1);
  --green-soft: rgba(34, 197, 94, 0.14);
  --red-soft: rgba(239, 68, 68, 0.12);
  --yellow-soft: rgba(245, 158, 11, 0.16);
  --blue-soft: rgba(59, 130, 246, 0.12);
}
/* the tints: a wash behind text of that colour, a line around it, a breath of it */
:root {
  --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 35%, transparent);
  --green-soft: color-mix(in srgb, var(--green) 12%, transparent);
  --green-line: color-mix(in srgb, var(--green) 35%, transparent);
  --green-faint: color-mix(in srgb, var(--green) 7%, transparent);
  --red-soft: color-mix(in srgb, var(--red) 12%, transparent);
  --red-line: color-mix(in srgb, var(--red) 35%, transparent);
  --red-faint: color-mix(in srgb, var(--red) 7%, transparent);
  --yellow-soft: color-mix(in srgb, var(--yellow) 12%, transparent);
  --yellow-line: color-mix(in srgb, var(--yellow) 35%, transparent);
  --yellow-faint: color-mix(in srgb, var(--yellow) 6%, transparent);
  --blue-soft: color-mix(in srgb, var(--blue) 12%, transparent);
  --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

#app { height: 100%; display: flex; flex-direction: column; }

/* Four buttons: the plain one, the accent one for the screen's action, the
   green one for a merge, the red-lettered one for what cannot be undone.
   All 32px tall, so a row of them lines up. */
button {
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  border: 1px solid var(--border-strong);
  background: var(--bg-raised);
  color: var(--text);
  padding: 6px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  white-space: nowrap;
}
button:hover { background: var(--bg-hover); }
button:disabled { opacity: 0.45; cursor: default; }
button.primary { background: var(--accent-strong); border-color: transparent; color: #fff; font-weight: 600; }
button.primary:hover:not(:disabled) { filter: brightness(1.08); }
button.good { background: var(--green-strong); border-color: transparent; color: #fff; font-weight: 600; }
button.good:hover:not(:disabled) { filter: brightness(1.08); }
button.danger { background: transparent; border-color: var(--border-strong); color: var(--red); }
button.danger:hover { background: var(--red-soft); border-color: var(--red-line); }
button.ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
/* where "Update from main" stands once there is nothing to bring: a button's
   size and place, none of its look */
.up-to-date { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; font-size: 13px; line-height: 18px; color: var(--text-faint); white-space: nowrap; }
.up-to-date .ico { color: var(--green); }
button.ghost:hover { color: var(--text); background: var(--bg-hover); }
/* a button that is only its icon (the theme switch) */
button.icon-btn { width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center; }
button.icon-btn svg { width: 16px; height: 16px; display: block; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
button.ghost.danger { color: var(--text-dim); border-color: transparent; }
button.ghost.danger:hover { background: var(--red-soft); color: var(--red); }

/* ---------- model picker + usage ---------- */
.field-row { display: flex; gap: 12px; margin-top: 4px; }
.field-row > div { flex: 1; min-width: 0; }
.field-row select { width: 100%; }
.plan-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-dim); background: var(--bg-raised);
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px; text-decoration: none; white-space: nowrap; }
.plan-chip:hover { color: var(--text); border-color: var(--border-strong); }
.plan-chip.warm { color: var(--yellow); border-color: var(--yellow); }
.plan-chip.hot { color: var(--red); border-color: var(--red); }
/* The Admin chip while the box's Health card has a problem (lib/health.js). */
.admin-chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--red); flex-shrink: 0; }
/* Something new to read: an answer on a feedback note (lib/feedback.js) —
   on the Feedback chip, the Admin chip, the admin page's tab, the note. */
.dot.new, .admin-chip .dot.new { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
/* The Health card on the admin dashboard: one row per check. */
.health-rows { display: flex; flex-direction: column; }
.health-row { display: flex; align-items: baseline; gap: 10px; padding: 7px 0; border-top: 1px solid var(--border); font-size: 13px; }
.health-row:first-child { border-top: 0; }
.health-row .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; position: relative; top: -1px; background: var(--text-faint); }
.health-row .dot.ok { background: var(--green); }
.health-row .dot.bad { background: var(--red); }
.health-row .dot.warn { background: var(--yellow); }
.health-row .h-label { min-width: 96px; color: var(--text-dim); font-size: 12px; flex-shrink: 0; }
.health-row .h-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.health-failing { margin: 6px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-dim); }
.health-failing li { margin: 2px 0; overflow-wrap: anywhere; }
/* The usage chip: the dial, then a segment per plan — its name, how much of
   its tightest window is used — each coloured by its own windows; the edge
   by the louder of them (paintUsageChip). A button: it opens the panel. */
.usage-chip { font-weight: 400; line-height: inherit; gap: 6px; }
.usage-chip:hover { background: var(--bg-raised); }
.usage-chip.open { color: var(--text); border-color: var(--border-strong); }
.plan-chip.usage-chip.warm, .plan-chip.usage-chip.hot { color: var(--text-dim); }
.plan-chip.usage-chip.warm { border-color: var(--yellow-line); }
.plan-chip.usage-chip.hot { border-color: var(--red-line); }
.usage-chip > .ico { display: inline-flex; width: 14px; height: 14px; }
.usage-chip > .ico svg { width: 14px; height: 14px; }
.usage-chip.warm > .ico { color: var(--yellow); }
.usage-chip.hot > .ico { color: var(--red); }
.uc-plan { display: inline-flex; align-items: baseline; gap: 4px; }
.uc-plan + .uc-plan { padding-left: 7px; border-left: 1px solid var(--border-strong); }
.uc-pct { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.uc-plan.warm .uc-pct { color: var(--yellow); }
.uc-plan.hot .uc-pct { color: var(--red); }
/* The panel under the chip: each plan's windows as meters, then Refresh and
   the way to the Usage page. */
.usage-pop {
  position: fixed; inset: auto; margin: 0; overflow: auto;
  max-height: calc(100vh - 64px); padding: 4px 16px 10px;
  background: var(--bg-raised); color: var(--text); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg);
}
.usage-pop .plan-sec { padding: 12px 0 10px; }
.usage-pop .plan-sec + .plan-sec { border-top: 1px solid var(--border); }
.usage-pop .plan-row { padding: 7px 0; border-top: 0; }
.usage-pop .plan-row-pct { font-size: 14px; }
.usage-pop .plan-row .meter { margin: 5px 0 0; }
.up-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-top: 10px; border-top: 1px solid var(--border); }
.up-foot button { display: inline-flex; align-items: center; gap: 6px; padding: 5px 8px; margin-left: -8px; }
.up-foot button .ico, .plan-refresh .ico { display: inline-flex; width: 14px; height: 14px; }
.up-more { font-size: 12.5px; }
/* One plan: its name and plan type, how old its newest report is, then its
   windows — or why there are none. The panel's, the Usage page's cards'. */
.plan-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.plan-title { font-weight: 600; font-size: 14px; }
.plan-type { font-size: 11.5px; color: var(--text-dim); padding: 1px 7px; border: 1px solid var(--border-strong); border-radius: 999px; }
.plan-age { margin-left: auto; font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.plan-empty { display: flex; align-items: center; gap: 10px; color: var(--text-dim); font-size: 12.5px; padding: 6px 0 2px; }
.plan-empty .plan-connect { padding: 3px 9px; font-size: 12.5px; color: var(--accent); }
/* The Usage page's plan cards: one per plan, side by side where they fit. */
.plan-limits { margin-top: 4px; }
.home .plan-limits:not(:first-child) { margin-top: 28px; }
.plan-limits > .card-head .plan-refresh { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px; }
.plan-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; }
.plan-card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 14px 18px 12px; box-shadow: var(--shadow-sm); min-width: 0; }
.no-dollars { color: var(--text-faint); }
.plan-rows { display: flex; flex-direction: column; gap: 4px; container-type: inline-size; }
.plan-row { padding: 10px 0; border-top: 1px solid var(--border); }
.plan-row:first-child { border-top: 0; padding-top: 2px; }
.plan-row-head { display: flex; align-items: baseline; gap: 12px; }
.plan-row-name { font-weight: 600; font-size: 13.5px; min-width: 0; }
.plan-row-reset { color: var(--text-dim); font-size: 12px; flex: 1; }
.plan-row-pct { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.plan-row.warm .plan-row-pct { color: var(--yellow); }
.plan-row.hot .plan-row-pct { color: var(--red); }
.plan-row .meter { margin: 6px 0 4px; }
.plan-row-sub { font-size: 12px; color: var(--text-dim); }
.plan-row-reset { white-space: nowrap; }
/* Too narrow for the name, the reset and the number on one line (a phone,
   the chip's panel on one): the reset takes a line of its own under them. */
@container (max-width: 340px) {
  .plan-row-head { flex-wrap: wrap; row-gap: 0; }
  .plan-row-name { flex: 1; }
  .plan-row-reset { order: 3; flex-basis: 100%; }
}
.api-equiv-note { color: var(--text-dim); font-size: 12px; margin: 4px 0 12px; }
/* The person, as their initials: the account menu's button. */
button.avatar {
  width: 28px; height: 28px; padding: 0; margin-left: 2px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--accent-line); background: var(--accent-soft); color: var(--accent);
  font-size: 11px; font-weight: 700; letter-spacing: 0.03em; line-height: 1;
}
button.avatar:hover, button.avatar.open { background: color-mix(in srgb, var(--accent) 24%, transparent); border-color: var(--accent); }
button.avatar .ico { width: 15px; height: 15px; }
.usage-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin: 16px 0 8px; }
.stat { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; box-shadow: var(--shadow-sm); }
.stat .s-label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
.stat .s-value { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; margin-top: 4px; }
.stat .s-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.meter { height: 6px; border-radius: 999px; background: var(--bg-hover); overflow: hidden; margin: 8px 0 6px; }
.meter-fill { height: 100%; background: var(--green); border-radius: 999px; }
.meter-fill.warm { background: var(--yellow); }
.meter-fill.hot { background: var(--red); }
.utable { width: 100%; border-collapse: collapse; margin-bottom: 8px; font-size: 13px; }
.utable th { text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); padding: 6px 10px; border-bottom: 1px solid var(--border); }
.utable td { padding: 7px 10px; border-bottom: 1px solid var(--border); color: var(--text-dim); }
.utable td:first-child { color: var(--text); }
.utable a { color: var(--accent); text-decoration: none; }
.utable a:hover { text-decoration: underline; }

input, select, textarea {
  font: inherit;
  background: var(--input-bg);
  border: 1px solid var(--border-strong);
  color: var(--text);
  border-radius: 8px;
  padding: 7px 10px;
  width: 100%;
  transition: border-color 0.12s, box-shadow 0.12s;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
input::placeholder, textarea::placeholder { color: var(--text-faint); }
input[type="checkbox"], input[type="radio"] { width: auto; accent-color: var(--accent); }
textarea { resize: vertical; min-height: 90px; font-family: inherit; }

/* ---------- top bar ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  flex-shrink: 0;
  height: 52px;
}
.topbar .logo {
  color: var(--text);
  text-decoration: none;
  display: flex;
  align-items: center;
  border-radius: 8px;
}
.logo .logo-mark {
  width: 24px; height: 24px; border-radius: 7px;
  background: linear-gradient(135deg, var(--accent), #4f8df0);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; color: #fff;
}
.topbar .spacer { flex: 1; }
/* Only the title gives way: one line, cut short before it wraps into the
   chips beside it. */
.topbar > * { flex-shrink: 0; }
.topbar h1 { font-size: 14px; margin: 0; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 64px; }
/* A project's name: the way to its board, and the one thing in the bar that
   gives way when the bar is short of room. */
.topbar .tb-project {
  font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 48px; max-width: 280px;
  padding: 4px 8px; margin: 0 -4px; border-radius: 6px;
}
.topbar .tb-project:hover { background: var(--bg-hover); }
/* …and its screens, the tabs drawn on the bar's own bottom line */
.topbar .proj-tabs { margin-left: 12px; }
/* …and who it is shared with: Share for its owner, how many are on it for
   anyone else, and View only for whoever may only look (shareControl). */
.tb-share { display: inline-flex; align-items: center; gap: 6px; margin-left: 6px; }
.share-btn { height: 30px; padding: 0 10px; display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-dim); }
.share-btn:hover { color: var(--text); }
.share-btn .ico, .view-only .ico { display: inline-flex; }
.share-btn .ico svg { width: 15px; height: 15px; }
.chip.view-only { height: 24px; }
.chip.view-only .ico svg { width: 13px; height: 13px; }

/* The Share dialog: the people on the project, a field to add one, and
   who may find it. */
dialog.share-dlg { width: 480px; max-width: 94vw; }
dialog.fork-dlg { width: 440px; max-width: 94vw; }
dialog.fork-dlg input { width: 100%; }
dialog.takeover-dlg { width: 480px; max-width: 94vw; }
dialog.decline-dlg { width: 440px; max-width: 94vw; }
dialog.decline-dlg textarea { width: 100%; resize: vertical; }
.share-people { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 10px; }
.share-row { display: flex; align-items: center; gap: 10px; padding: 6px 4px; border-radius: 8px; min-height: 40px; }
.share-row:hover { background: var(--bg-hover); }
.share-who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; }
.share-role { color: var(--text-faint); font-size: 12px; }
.share-add { display: flex; gap: 8px; }
.share-add input { flex: 1; min-width: 0; }
.share-seen { display: flex; }
.share-seen .seg-btn { flex: 1; }
.share-seen .seg-btn[disabled] { cursor: default; }
.share-dlg .dlg-actions .spacer { flex: 1; }
button.danger-text { color: var(--red); }
/* A person as their initials, outside the account button: the Share list
   and a task card's starter. */
.avatar.small, .avatar.tiny {
  display: inline-flex; align-items: center; justify-content: center; flex: none; border-radius: 50%;
  border: 1px solid var(--accent-line); background: var(--accent-soft); color: var(--accent);
  font-weight: 700; letter-spacing: 0.03em; line-height: 1;
}
.avatar.small { width: 28px; height: 28px; font-size: 11px; }
.avatar.tiny { width: 18px; height: 18px; font-size: 8.5px; }

.claude-status { display: flex; align-items: center; gap: 6px; color: var(--text-faint); font-size: 12px; white-space: nowrap; }
.tb-sep { color: var(--text-faint); }
.claude-status .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green); }
.claude-status .dot.bad { background: var(--red); }
.claude-status .dot.warn { background: var(--yellow); }

.setup-card {
  background: var(--bg-raised); border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent); border-radius: 12px;
  padding: 18px 22px; margin-top: 20px;
}
.setup-card h3 { margin: 0 0 10px; font-size: 15px; }
.setup-card p { color: var(--text-dim); font-size: 13.5px; }
.setup-card code { font-family: var(--mono); background: var(--bg-hover); padding: 1px 6px; border-radius: 5px; color: var(--text); font-size: 12.5px; }
.setup-row { display: flex; gap: 10px; margin-top: 12px; max-width: 560px; }
/* The plans card: one row per plan — on the home screen while a plan this
   Gamma offers is missing, and in the Plans… dialog from the account menu. */
.plans-card .card-head { margin-bottom: 4px; }
.plans-card .card-head .pc-later { margin-left: auto; padding: 4px 8px; font-size: 12.5px; }
.pc-lead { margin: 2px 0 4px; color: var(--text-dim); font-size: 13.5px; }
.pc-row { display: flex; align-items: flex-start; gap: 10px; padding: 12px 0; border-top: 1px solid var(--border); }
.pc-lead + .pc-row { border-top: 0; }
.pc-name { width: 72px; flex: none; font-weight: 600; line-height: 32px; }
.pc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.pc-body > .setup-row { margin-top: 0; width: 100%; max-width: 560px; }
.pc-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-height: 32px; }
.pc-gives { color: var(--text); font-size: 13px; line-height: 1.45; padding-top: 7px; }
.pc-state { display: inline-flex; align-items: center; gap: 6px; color: var(--text-dim); font-size: 13px; }
.pc-state.ok { color: var(--text); }
.pc-state.ok .ico { display: inline-flex; width: 15px; height: 15px; color: var(--green); }
.pc-hint { color: var(--text-faint); font-size: 12px; }
.pc-err { color: var(--red); font-size: 12.5px; }
/* What a row keeps folded until asked: a token to paste instead of
   signing in, the ways to replace a connected plan. */
.pc-more { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; width: 100%; }
.pc-more[hidden] { display: none; }
.pc-more > .setup-row { margin-top: 0; width: 100%; }
.pc-code { flex: 1; min-width: 0; font-family: var(--mono); font-size: 12.5px; }
/* A home card with a plan connected: each row on one line. */
.plans-card.home .pc-row { padding: 8px 0; }
/* A phone: the plan's name over its row, so the token box has the width. */
@media (max-width: 600px) {
  .pc-row { flex-direction: column; gap: 4px; }
  .pc-name { width: auto; line-height: 1.4; }
  .pc-gives { padding-top: 0; }
}
.device-code { font-family: var(--mono); font-size: 18px; letter-spacing: 2px; padding: 4px 10px; background: var(--bg-hover); border-radius: 6px; cursor: pointer; user-select: all; }
dialog.plans-dlg { width: 640px; max-width: 94vw; }
dialog.plans-dlg .setup-card { margin-top: 0; border: none; padding: 0; background: none; }

/* ---------- main layouts ---------- */
.page { flex: 1; overflow: auto; padding: 28px 32px 40px; }
.page-split { flex: 1; display: flex; overflow: hidden; }

/* ---------- home ---------- */
.home { max-width: 1100px; margin: 0 auto; }
.home h2 { font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); margin: 28px 0 12px; }
.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; }
.project-card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: border-color 0.12s, box-shadow 0.12s;
}
.project-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.project-card .pc-head { display: flex; gap: 12px; align-items: center; }
.project-card .pc-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 20px; }
.project-card .pc-line .meta { margin-right: 2px; }
.project-card .pc-title { min-width: 0; flex: 1; }
/* The card's picture (projectThumb): the icon, a capture, or the initial. */
.pc-thumb { flex: none; width: 64px; height: 64px; border-radius: 9px; object-fit: cover; background: var(--bg-sunken); border: 1px solid var(--border); }
.pc-initial { display: inline-flex; align-items: center; justify-content: center; font-weight: 600; font-size: 24px; color: hsl(var(--h) 70% 78%); background: hsl(var(--h) 30% 20%); border-color: hsl(var(--h) 25% 28%); }
:root[data-theme="light"] .pc-initial { color: hsl(var(--h) 55% 40%); background: hsl(var(--h) 60% 92%); border-color: hsl(var(--h) 40% 84%); }
.project-card .owner-chip.link { cursor: pointer; }
.project-card .owner-chip.link:hover { color: var(--accent); border-color: var(--accent-line); }
.home-back { margin-left: -6px; }
.project-card .name { font-weight: 600; font-size: 15px; letter-spacing: -0.01em; margin-bottom: 4px; }
.project-card .meta { color: var(--text-faint); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.project-card.new {
  display: flex; align-items: center; justify-content: center;
  background: transparent; box-shadow: none;
  border-style: dashed; border-color: var(--border-strong); color: var(--text-dim); font-weight: 500;
  min-height: 86px; gap: 8px;
}
.project-card.new:hover { color: var(--accent); border-color: var(--accent-line); box-shadow: none; }
.home-head { display: flex; align-items: center; gap: 8px; min-height: 22px; margin: 28px 0 12px; }
.home .home-head h2 { margin: 0; }
.home-sub { color: var(--text-faint); font-size: 12px; }
/* The studio's projects: looked at, not worked on — a quieter card. */
.project-card.studio { background: transparent; box-shadow: none; }
.project-card .card-lock { display: inline-flex; vertical-align: -2px; margin-right: 6px; color: var(--text-faint); }
.project-card .card-lock svg { width: 14px; height: 14px; }
.project-card .pc-line .chip .ico { display: inline-flex; }
.project-card .pc-line .chip .ico svg { width: 12px; height: 12px; }
/* A project's ⋯ (projectCard): in the card's corner, shown on a hover — always
   on a screen without one — and while its menu is open. */
.project-card-wrap { position: relative; }
.project-card-wrap > .project-card { height: 100%; }
.project-card-wrap .name { padding-right: 26px; }
.card-more { position: absolute; top: 10px; right: 10px; opacity: 0; transition: opacity 0.12s; }
.project-card-wrap:hover .card-more, .card-more:focus-visible, .card-more.open { opacity: 1; }
@media (hover: none) { .card-more { opacity: 1; } }

.empty-hint { color: var(--text-faint); padding: 30px 0; text-align: center; }

/* ---------- admin ---------- */
.admin-tabs { display: flex; gap: 22px; margin-top: 4px; border-bottom: 1px solid var(--border); }
.admin-tab {
  color: var(--text-dim); text-decoration: none; font-weight: 500; font-size: 13px;
  padding: 8px 2px 10px; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color 0.12s;
}
.admin-tab:hover { color: var(--text); }
.admin-tab.active { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }
.admin-tab .dot.new { margin-left: 6px; position: relative; top: -1px; }

/* ---------- feedback ---------- */
/* the top bar's chip: a word on a wide screen, its icon on a phone */
.feedback-chip .ico { display: none; }
.plan-chip[aria-current="page"] { color: var(--text); border-color: var(--border-strong); }
.fb-page { max-width: 760px; }
.fb-back { display: inline-block; margin-bottom: 12px; color: var(--text-dim); font-size: 13px; text-decoration: none; }
.fb-back:hover { color: var(--text); }
.fb-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.fb-form textarea { min-height: 150px; }
.fb-form .attach-tray:not(:empty) { margin-top: 10px; }
.fb-form.drop-over { outline: 2px dashed var(--accent); outline-offset: -4px; background: var(--accent-soft); }
.fb-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.fb-actions .spacer { flex: 1; }
.fb-filters { display: flex; flex-wrap: wrap; gap: 6px; margin: 16px 0 12px; }
.fb-count { color: var(--text-faint); font-variant-numeric: tabular-nums; }
.fb-list { display: flex; flex-direction: column; gap: 10px; }
.fb-card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; box-shadow: var(--shadow-sm); }
.fb-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 12px; color: var(--text-dim); }
.fb-who { color: var(--text); font-weight: 600; margin-left: 4px; overflow-wrap: anywhere; }
.fb-when { margin-left: auto; color: var(--text-faint); white-space: nowrap; }
.fb-body { margin-top: 8px; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.55; }
.fb-shots { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.fb-shots img { display: block; height: 96px; max-width: 220px; object-fit: cover; border-radius: 8px; border: 1px solid var(--border); background: var(--checker); }
.fb-shots a:hover img { border-color: var(--border-strong); }
.fb-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.fb-files .attach-chip { padding-right: 11px; text-decoration: none; }
.fb-files .attach-chip:hover { color: var(--text); border-color: var(--accent); }
.fb-meta { margin-top: 10px; font-size: 12px; color: var(--text-faint); }
.fb-new { display: inline-flex; align-items: center; gap: 5px; margin-left: 4px; color: var(--accent); font-weight: 600; }
/* the thread under a note, and the box to answer in */
.fb-conv { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.fb-thread { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.fb-reply-item { font-size: 13px; padding-left: 10px; border-left: 2px solid var(--border); }
.fb-reply-item.new { border-left-color: var(--accent); }
.fb-reply-head { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: var(--text-dim); }
.fb-reply-who { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }
.fb-reply-head .fb-when { margin-left: 0; }
.fb-reply-text { margin-top: 2px; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.5; }
.fb-reply { display: flex; align-items: flex-end; gap: 8px; }
.fb-reply textarea { flex: 1; min-height: 34px; resize: none; font-size: 13px; line-height: 1.4; padding: 6px 10px; }
.fb-reply button { flex-shrink: 0; }
.chip.fb-tag { background: var(--accent-soft); color: var(--accent); }
.chip.fb-tag.bug { background: var(--red-soft); color: var(--red); }
.chip.fb-tag.feature { background: var(--blue-soft); color: var(--blue); }

.chart-card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; margin-bottom: 8px; box-shadow: var(--shadow-sm); }
.chart-card .c-head { display: flex; justify-content: space-between; align-items: baseline; }
.chart-card .c-title { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); }
.chart-card .c-max { font-size: 11px; color: var(--text-faint); }
.chart-card .c-value { font-size: 12px; color: var(--text-dim); min-height: 18px; margin-top: 6px; }
.bars { display: flex; align-items: flex-end; gap: 3px; height: 110px; padding-top: 10px; }
.bars .bar { flex: 1; background: var(--accent); border-radius: 3px 3px 0 0; opacity: .85; transition: opacity .1s; }
.bars .bar:hover { opacity: 1; }
.bars .bar.empty { background: var(--bg-hover); height: 2px; }
.bars-x { display: flex; justify-content: space-between; color: var(--text-faint); font-size: 11px; padding-top: 4px; }

.brain-doc { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 20px 24px; margin-bottom: 24px; box-shadow: var(--shadow-sm); }
.brain-doc p { margin: 0 0 8px; }
.brain-doc h2, .brain-doc h3, .brain-doc h4 { font-size: 14px; margin: 14px 0 6px; text-transform: none; letter-spacing: 0; color: var(--text); }
.brain-doc ul, .brain-doc ol { margin: 4px 0 8px; padding-left: 22px; }
.brain-doc li { margin-bottom: 4px; }
.brain-doc pre { background: var(--bg-code); border: 1px solid var(--border); padding: 10px; border-radius: 8px; overflow-x: auto; font-family: var(--mono); font-size: 12px; }
.brain-doc code { font-family: var(--mono); font-size: 12.5px; background: var(--bg-hover); padding: 1px 5px; border-radius: 4px; }
.brain-doc pre code { background: none; padding: 0; }

/* ---------- board ---------- */
.board-wrap { flex: 1; overflow: auto; padding: 20px 24px 32px; }
.board { display: grid; grid-template-columns: repeat(3, minmax(260px, 1fr)); gap: 12px; align-items: start; max-width: 1400px; margin: 0 auto; }
.board.with-todos { grid-template-columns: minmax(220px, 0.8fr) repeat(3, minmax(260px, 1fr)); }
/* Beside the project's game the board has about two thirds of the width:
   narrower tracks, so its four columns fit a small laptop's screen
   unscrolled — even ones, or the To do lines break inside their words. */
.board-split .board-wrap { padding: 16px 16px 28px; }
.board-split .board.with-todos { grid-template-columns: repeat(4, minmax(145px, 1fr)); gap: 10px; }
/* Columns are tracks, not boxes: a shade below the page, no border, the
   cards raised on them. */
.col { background: var(--bg-sunken); border-radius: 12px; padding: 10px; min-height: 140px; }
.col-head { display: flex; align-items: center; gap: 8px; padding: 4px 6px 10px; color: var(--text-dim); font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.col-head .count { background: var(--bg-hover); color: var(--text-faint); border-radius: 999px; padding: 0 7px; font-size: 11px; font-variant-numeric: tabular-nums; }
/* Done's way to its archived tasks, and back: a quiet button at the head's
   end, in the head's own small type. The home screen's archive switch is the
   same button beside its heading. */
.col-head .col-switch, .home-head .col-switch {
  display: inline-flex; align-items: center;
  padding: 1px 6px; font-size: 11.5px; line-height: 18px; font-weight: 500;
  text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.col-head .col-switch { margin-left: auto; }
.col-head .col-switch .ico, .home-head .col-switch .ico { width: 13px; height: 13px; }
.col-head .col-switch.on, .home-head .col-switch.on { background: var(--accent-soft); color: var(--accent); }
/* In progress's first slot: where a new task starts, drawn as the home
   screen's New project card is — dashed, empty, lit on a hover. */
.new-task-card {
  display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; margin-bottom: 8px; padding: 8px 10px;
  background: transparent; border: 1px dashed var(--border-strong); border-radius: 10px; color: var(--text-dim); font-weight: 500;
}
.new-task-card:hover { background: transparent; color: var(--accent); border-color: var(--accent-line); }
.new-task-card .ico { width: 14px; height: 14px; }
/* A column too narrow for both drops the button under its name. */
.col-head.with-switch { flex-wrap: wrap; row-gap: 4px; }
.task-card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 8px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: border-color 0.12s, box-shadow 0.12s;
}
.task-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.task-card .t-title { font-weight: 600; font-size: 13.5px; line-height: 1.35; margin-bottom: 8px; }
.task-card .t-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-faint); flex-wrap: wrap; }
.task-card .diffstat { font-family: var(--mono); font-size: 11px; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* In progress holds working and halted tasks alike: a dot and a word say
   which, in the status's colour, with no pill (taskCard). */
.task-card .t-state { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; white-space: nowrap; }
.task-card .t-state .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.t-state.running, .t-state.preparing { color: var(--blue); }
.t-state.resolving { color: var(--accent); }
.t-state.failed, .t-state.stopped, .t-state.prep_failed { color: var(--red); }
.t-state.interrupted, .t-state.submitted { color: var(--yellow); }
.t-state.asking { color: var(--accent); }
/* An archived card's Restore, at the end of its meta line. */
.task-card .card-restore { margin-left: auto; padding: 2px 8px; font-size: 12px; display: inline-flex; align-items: center; }
.task-card .card-restore .ico { width: 13px; height: 13px; }
.task-card .t-error {
  margin-top: 6px; font-size: 11.5px; color: var(--red);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; line-height: 1.35;
}

/* To do cards are a list first: one line each, no chrome until hovered — and
   then a button, the whole line: a click on it opens the new-task dialog. */
.todo-card {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 4px 5px 8px; margin-bottom: 2px;
  border: 1px solid transparent; border-radius: 6px;
  font-size: 13.5px; line-height: 1.35; cursor: pointer;
}
.todo-card:hover { background: var(--bg-raised); border-color: var(--border); }
.todo-card:focus-visible { outline-offset: -2px; }
.todo-card .todo-body { flex: 1; min-width: 0; overflow-wrap: anywhere; }
/* The prompt a line carries (a dialog left without starting the task): a faint
   glimpse under the line, the whole of it in the tooltip and back in the dialog. */
.todo-card .todo-prompt {
  color: var(--text-faint); font-size: 12px; line-height: 1.3; margin-top: 1px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* The line's one button of its own, shown with the line's hover (always,
   where nothing hovers: a tap on the line opens it). */
.todo-card .todo-x {
  flex: none; background: none; border: 0; padding: 2px 6px; border-radius: 5px;
  color: var(--text-faint); font-size: 14px; line-height: 1; cursor: pointer; opacity: 0;
}
.todo-card:hover .todo-x, .todo-card:focus-visible .todo-x, .todo-card .todo-x:focus-visible { opacity: 1; }
.todo-card .todo-x:hover { background: var(--bg-hover); color: var(--text); }
@media (hover: none) { .todo-card .todo-x { opacity: 1; padding: 9px 10px; margin: -7px -4px; } }
/* The ▶ says a line can become a task, in its hover text too. The line is
   what is pressed, so the ▶ lights with the line and never apart from it:
   one that answered the pointer alone read as "start it now". */
.todo-card .todo-go { flex: none; padding: 2px 6px; color: var(--text-faint); font-size: 11px; line-height: 1; }
.todo-card .todo-go.ready { color: var(--text-dim); }
.todo-card:hover .todo-go { color: var(--text); }
/* A draft on its way: the faint pulse a line carries until the dialog has something to open with. */
.todo-drafting, .nt-suggest-pulse {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--text-faint); animation: todo-pulse 1.4s ease-in-out infinite;
}
.nt-suggest-pulse { margin-right: 2px; vertical-align: middle; }
@keyframes todo-pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 0.9; } }
.nt-suggest { min-height: 16px; margin: -4px 0 8px; }
.nt-suggest:empty { display: none; }
.nt-suggest-cost { color: var(--text-faint); }
.todo-input {
  width: 100%; box-sizing: border-box; margin-top: 4px;
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  padding: 5px 8px; font: inherit; font-size: 13.5px; color: var(--text);
}
.todo-input::placeholder { color: var(--text-faint); }
.todo-input:focus { outline: none; border-color: var(--border); background: var(--bg-raised); box-shadow: none; }

.chip {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; line-height: 1.5;
  font-size: 11px; font-weight: 600; border-radius: 999px; padding: 2px 9px;
}
.chip.running, .chip.preparing { background: var(--blue-soft); color: var(--blue); }
.chip.review, .chip.submitted, .chip.interrupted { background: var(--yellow-soft); color: var(--yellow); }
/* A contribution's badge (lib/access.js): quiet, with the fork mark. */
.chip.contrib .ico { display: inline-flex; }
.chip.contrib .ico svg { width: 11px; height: 11px; }
.chip.failed, .chip.stopped, .chip.prep_failed { background: var(--red-soft); color: var(--red); }
.chip.resolving { background: var(--accent-soft); color: var(--accent); }
/* The agent asked something and waits on its person (askingOf). */
.chip.asking { background: var(--accent-soft); color: var(--accent); }
.chip.accepted { background: var(--green-soft); color: var(--green); }
.chip.archived, .chip.quiet { background: var(--bg-hover); color: var(--text-faint); }

.pulse { width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: pulse 1.2s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

.banner {
  display: flex; align-items: center; gap: 12px;
  background: var(--yellow-soft); border: 1px solid var(--yellow-line);
  color: var(--yellow); border-radius: 8px; padding: 10px 14px; margin: 0 20px;
  margin-top: 16px; max-width: 1360px;
}
.banner .msg { flex: 1; }
/* Saying a project is someone else's, to look at: not a warning. */
.banner.view-only-banner { background: var(--bg-hover); border-color: var(--border); color: var(--text-dim); gap: 10px; }
.banner.view-only-banner > .ico { display: inline-flex; }
.banner.view-only-banner > .ico svg { width: 15px; height: 15px; }

/* ---------- task view ---------- */
/* The two panes share the width by a dragged handle (splitHandle in app.js)
   — the transcript's or the board's share is a variable, the preview takes
   the rest. */
.split-left { flex: 0 0 var(--split-left, 54%); display: flex; flex-direction: column; min-width: 0; }
.split-right { flex: 1 1 0; display: flex; flex-direction: column; min-width: 0; background: var(--bg-sunken); }

.transcript-wrap { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* The thread is a centred column, as wide as reading is comfortable: on a
   wide pane the sides take the rest. */
.transcript { flex: 1; overflow-y: auto; padding: 22px max(24px, calc((100% - 820px) / 2)) 28px; scroll-behavior: smooth; }
.transcript .ev { margin-bottom: 16px; max-width: 100%; }
/* the human's words: a plain bubble on the right — the Claude app's, no
   outline, no tint — with what came with them above it */
.ev-user { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.ev-user .bubble-wrap { position: relative; max-width: 80%; }
.ev-user .bubble { background: var(--bg-hover); padding: 10px 16px; border-radius: 18px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 14.5px; line-height: 1.6; }
.user-files { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: flex-end; gap: 6px; max-width: 80%; }
.user-pic { padding: 0; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--bg-code); line-height: 0; cursor: zoom-in; }
.user-pic:hover { border-color: var(--border-strong); background: var(--bg-code); }
/* a fixed height, so a picture landing after the thread has scrolled to its
   end never pushes the end out of view */
.user-pic img { display: block; height: 120px; width: auto; min-width: 48px; max-width: 220px; object-fit: cover; }
.user-files .attach-chip .ico svg { width: 13px; height: 13px; }
/* the agent's words: prose, no bubble, a size made for reading */
.ev-say { position: relative; }
.ev-text { color: var(--text); overflow-wrap: break-word; font-size: 14.5px; line-height: 1.65; }
.ev-text p { margin: 0 0 10px; }
.ev-text p:last-child { margin-bottom: 0; }
.ev-text pre { background: var(--bg-code); border: 1px solid var(--border); padding: 10px 12px; border-radius: 8px; overflow-x: auto; font-family: var(--mono); font-size: 12.5px; line-height: 1.5; }
.ev-text code { font-family: var(--mono); font-size: 0.88em; background: var(--bg-hover); padding: 1px 5px; border-radius: 4px; }
/* A file the agent named: click to open it (openFileRef). */
.ev-text code.file-ref { cursor: pointer; text-decoration: underline dotted var(--text-faint); text-underline-offset: 3px; }
.ev-text code.file-ref:hover, .ev-text code.file-ref:focus-visible { color: var(--accent); text-decoration-color: var(--accent); outline: none; }
.ev-text pre code { background: none; padding: 0; font-size: inherit; }
.ev-text ul, .ev-text ol { margin: 4px 0 10px; padding-left: 24px; }
.ev-text li { margin: 3px 0; }
.ev-text h1, .ev-text h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 20px 0 8px; }
.ev-text h3 { font-size: 15.5px; font-weight: 600; margin: 18px 0 6px; }
.ev-text h4, .ev-text h5 { font-size: 14.5px; font-weight: 600; margin: 14px 0 6px; }
.ev-text > :first-child { margin-top: 0; }
.ev-text blockquote { margin: 6px 0 10px; padding: 2px 0 2px 14px; border-left: 3px solid var(--border-strong); color: var(--text-dim); }
.ev-text blockquote p { margin: 0 0 6px; }
.ev-text hr { border: 0; border-top: 1px solid var(--border); margin: 18px 0; }
.ev-text .md-table { overflow-x: auto; margin: 6px 0 12px; }
.ev-text table { border-collapse: collapse; font-size: 13.5px; line-height: 1.5; }
.ev-text th, .ev-text td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; vertical-align: top; }
.ev-text th { background: var(--bg-sunken); font-weight: 600; }
/* A copy button and a time, on a hover, as the Claude app has them: one per
   human message, just under its bubble on the right with how a busy agent
   heard it (always shown) — in the gap below, made tall enough to hold it,
   so a hover never moves a line or covers one; and one per agent run, on its
   "Worked for" line, shown too while the run's closing words are hovered. */
.transcript .ev-user { margin-bottom: 28px; }
.msg-actions { position: absolute; top: 100%; display: flex; align-items: center; gap: 8px; height: 24px; margin-top: 1px; font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.ev-user .msg-actions { right: 0; flex-direction: row-reverse; }
.ev-user .msg-tools { flex-direction: row-reverse; }
.ev-done > .msg-actions { position: static; height: auto; margin: 0 0 0 4px; }
.msg-tools { display: inline-flex; align-items: center; gap: 2px; opacity: 0; pointer-events: none; transition: opacity 0.12s; }
.ev-user:hover .msg-tools, .ev-done:hover .msg-tools, .ev-say:hover + .ev-done .msg-tools, .msg-actions:focus-within .msg-tools { opacity: 1; pointer-events: auto; }
.msg-note { font-size: 11px; }
.msg-time { padding: 0 4px; }
.msg-copy { width: 24px; height: 24px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--text-faint); border-radius: 6px; }
.msg-copy:hover { background: var(--bg-hover); color: var(--text); }
.msg-copy svg { width: 14px; height: 14px; }
.msg-copy.done { color: var(--green); }
@media (hover: none) { .msg-tools { display: none; } }
/* "Jump to latest", over the thread's foot while the reader is up the page */
.jump-latest { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 3; width: 34px; height: 34px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--bg-raised); border: 1px solid var(--border-strong); color: var(--text-dim); box-shadow: var(--shadow-md); }
.jump-latest:hover { background: var(--bg-hover); color: var(--text); }
.jump-latest svg { width: 17px; height: 17px; }

/* tool runs: one quiet row per run of similar calls, opened on click — the
   Claude Code app's "Ran 2 commands ›". A run of one names its call in the
   row; a run of many lists them, each with its own chevron. */
.transcript .ev-tools { margin: 0 0 2px -6px; }
.transcript .ev-tools + .ev:not(.ev-tools) { margin-top: 14px; }
.tg-head, .ti-head {
  display: flex; align-items: center; gap: 8px; width: 100%; max-width: 100%;
  background: none; border: none; padding: 4px 8px; border-radius: 6px;
  color: var(--text-dim); font-size: 13px; font-weight: 400; text-align: left; cursor: pointer; white-space: nowrap;
}
.tg-head:hover, .ti-head:hover { background: var(--bg-hover); color: var(--text); }
.chev { flex-shrink: 0; width: 10px; color: var(--text-faint); font-size: 15px; line-height: 1; transition: transform 0.12s; }
.chev::before { content: '›'; }
.ev-tools.open > .tg-head .chev, .tg-item.open > .ti-head .chev { transform: rotate(90deg); }
/* The row's line keeps its length while there is room and ends in "…" when
   there is not (a long web query, a stretch of many kinds) — before the
   counts and the state give way; a lone command's text takes what is left. */
.tg-label { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tg-sum { flex: 1 1 0; }
.ti-verb { flex-shrink: 0; color: var(--text-dim); }
/* (rules about a row's own calls go through > : an Agent call's subagent
   steps nest inside it, and keep their verbs, lines and folds) */
.ev-tools:not(.mixed) > .tg-body > .tg-item > .ti-head > .ti-verb { display: none; }
.tg-sum, .ti-sum { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ev-tools:not([data-count="1"]) .tg-sum { display: none; }
.tg-state, .ti-state { margin-left: auto; flex-shrink: 0; display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-faint); }
.tg-err { color: var(--red); }
/* a call its run ended without answering (app.js settleToolCalls): said
   quietly, not in red — nothing failed, the record just stops there */
.tg-none, .ti-none { color: var(--text-faint); }
.tg-body { display: none; margin: 2px 0 6px 12px; padding-left: 10px; border-left: 1px solid var(--border); }
.ev-tools.open > .tg-body { display: block; }
.ti-body { display: none; margin: 2px 0 8px 26px; }
.tg-item.open > .ti-body { display: block; }
.ev-tools[data-count="1"] > .tg-body > .tg-item > .ti-head { display: none; }
.ev-tools[data-count="1"] > .tg-body > .tg-item > .ti-body { display: block; margin-left: 0; }
.tg-item.err > .ti-head > .ti-sum, .tg-item.err > .ti-head > .ti-state { color: var(--red); }
.ti-meta, .tg-count { flex-shrink: 0; display: inline-flex; gap: 6px; font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.tg-count:empty { display: none; }
.cnt-add { color: var(--green); }
.cnt-del { color: var(--red); }
.ti-state .ico svg { width: 13px; height: 13px; }
.ti-desc { color: var(--text-faint); font-size: 12px; margin: 2px 0 4px; overflow-wrap: break-word; }
.ti-cmd, .ti-out {
  background: var(--bg-code); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; margin: 4px 0;
  font-family: var(--mono); font-size: 12px; color: var(--text-dim); white-space: pre-wrap; overflow-wrap: break-word;
  max-height: 260px; overflow-y: auto;
}
/* a failed call's words: red text in the box every output has, no red box */
.tg-item.err > .ti-body > .ti-out { color: var(--red); }
/* What a subagent did, inside its Agent call: its steps, folded like the
   agent's own, and its words — the last of them its answer, in full colour. */
.ti-steps { margin: 4px 0 6px; padding-left: 10px; border-left: 1px solid var(--border); }
.ti-steps .ti-head { font-size: 12.5px; padding: 3px 8px; }
.sub-say { font-size: 13px; line-height: 1.55; color: var(--text-dim); margin: 6px 8px; }
.sub-say:last-child { color: var(--text); }
.ti-images { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 4px; }
.ti-image { padding: 0; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-code); overflow: hidden; cursor: zoom-in; line-height: 0; }
.ti-image:hover { border-color: var(--text-faint); background: var(--bg-code); }
.ti-image img { display: block; max-width: min(320px, 100%); max-height: 240px; }
.ti-image-full { display: block; max-width: 100%; max-height: 78vh; margin: 0 auto; border-radius: 8px; }
.ti-diff { font-family: var(--mono); font-size: 12px; margin: 4px 0; border: 1px solid var(--border); border-radius: 8px; max-height: 320px; overflow-y: auto; }
.ti-diff .dl { padding: 0 10px; white-space: pre-wrap; overflow-wrap: break-word; }
.ti-diff .dl.del { background: var(--red-soft); color: var(--red); }
.ti-diff .dl.add { background: var(--green-soft); color: var(--green); }
.ev-earlier { justify-content: center; margin: 0 0 14px; }
/* the quiet lines: a notice, "Worked for", an interruption — faint, with an
   icon where one says something */
.ev-meta { color: var(--text-faint); font-size: 12.5px; display: flex; align-items: center; gap: 6px; }
.ev-meta > .ico { display: inline-flex; flex-shrink: 0; }
.ev-meta > .ico svg { width: 14px; height: 14px; }
.ev-done { min-height: 24px; }
/* The agent's question to the person, said in the thread: its words, and
   under them what it offered. The answer is the bubble that follows. */
.ev-ask { display: flex; align-items: flex-start; gap: 8px; }
.ev-ask > .ico { display: inline-flex; flex-shrink: 0; margin-top: 3px; color: var(--accent); }
.ev-ask > .ico svg { width: 16px; height: 16px; }
.ask-said { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ask-words { font-size: 14.5px; line-height: 1.6; color: var(--text); overflow-wrap: break-word; }
.ask-offered { font-size: 12.5px; color: var(--text-faint); overflow-wrap: break-word; }
.ev-stopped { color: var(--text-dim); }

/* An error, the Claude app's way: a red mark and a plain sentence, the raw
   words behind Details, Try again under it (placeRetry). */
.ev-err { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; line-height: 1.55; }
.err-mark { flex-shrink: 0; display: inline-flex; color: var(--red); margin-top: 2px; }
.err-mark svg { width: 17px; height: 17px; }
.err-body { flex: 1; min-width: 0; }
.err-msg { color: var(--text); }
.err-hint { color: var(--text-dim); font-size: 13px; margin-top: 4px; }
.err-detail { margin-top: 4px; font-size: 12px; color: var(--text-faint); }
.err-detail > summary { display: inline-flex; align-items: center; gap: 4px; width: fit-content; cursor: pointer; list-style: none; }
.err-detail > summary::-webkit-details-marker { display: none; }
.err-detail > summary::after { content: '›'; display: inline-block; font-size: 14px; line-height: 1; transition: transform 0.12s; }
.err-detail[open] > summary::after { transform: rotate(90deg); }
.err-detail > summary:hover { color: var(--text-dim); }
.err-detail pre { margin: 6px 0 0; padding: 8px 10px; background: var(--bg-code); border: 1px solid var(--border); border-radius: 8px; font-family: var(--mono); font-size: 11.5px; color: var(--text-dim); white-space: pre-wrap; overflow-wrap: break-word; max-height: 220px; overflow-y: auto; }
.ev-retry { margin-top: 10px; }
.ev-retry button { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; font-size: 12.5px; }
.ev-retry .ico svg { width: 14px; height: 14px; }

/* The conflict resolver's run — a second agent in a session of its own,
   settling a merge git could not: a band apart from the task agent's thread
   (renderInto), opened by its kickoff row (resolverHead), the kickoff itself
   folded under the label with the error row's own fold. */
.rs-band { margin: 4px 0 24px; padding: 14px 0 2px 16px; border-left: 2px solid color-mix(in srgb, var(--accent) 55%, transparent); }
.rs-band > .ev:last-child { margin-bottom: 8px; }
.ev-rs-head { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; }
.ev-rs-head > .ico { flex-shrink: 0; display: inline-flex; color: var(--accent); margin-top: 2px; }
.ev-rs-head > .ico svg { width: 17px; height: 17px; }
.rs-body { flex: 1; min-width: 0; }
.rs-title { color: var(--text); }
.rs-title b { font-weight: 600; }
.rs-sub { color: var(--text-dim); }
.rs-sub::before { content: ' · '; color: var(--text-faint); }
.rs-brief pre { max-height: 360px; }

/* The agent's plan: one list, pinned over the composer (renderPlan), and in
   the thread a row per version that opens to it (planRow). */
.plan-list { display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.plan-item { display: flex; align-items: flex-start; gap: 8px; color: var(--text-dim); line-height: 1.45; }
.plan-item .ico { display: inline-flex; flex-shrink: 0; margin-top: 2px; color: var(--text-faint); }
.plan-item .ico svg { width: 14px; height: 14px; }
.plan-item.completed { color: var(--text-faint); text-decoration: line-through; }
.plan-item.completed .ico { color: var(--green); }
.plan-item.in_progress { color: var(--text); font-weight: 500; }
.plan-item.in_progress .ico { color: var(--accent); }
.ev-plan .tg-body .plan-list { padding: 4px 0 6px; }
.task-plan { flex-shrink: 0; margin: 0 max(16px, calc((100% - 836px) / 2)) 8px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-raised); max-height: 32vh; overflow-y: auto; }
.plan-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 2px 0; border: 0; background: none; color: var(--text-dim); font-size: 12.5px; font-weight: 400; text-align: left; cursor: pointer; }
.plan-head:hover { background: none; color: var(--text); }
.plan-head .ico { display: inline-flex; }
.plan-head .ico svg { width: 15px; height: 15px; }
.plan-title { color: var(--text); font-weight: 600; }
.plan-count { font-variant-numeric: tabular-nums; }
.plan-now { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-head .chev { margin-left: auto; }
.task-plan:not(.folded) .plan-head { margin-bottom: 6px; }
.task-plan:not(.folded) .plan-head .chev { transform: rotate(90deg); }

/* The composer, the Claude app's: one rounded card on the page — what is
   attached, the words, then the tools and a round send. */
.composer { flex-shrink: 0; display: flex; flex-direction: column; gap: 6px; padding: 6px max(16px, calc((100% - 836px) / 2)) 14px; background: var(--bg); }
/* Where the composer would be, for someone not driving the task. */
.watch-card { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border: 1px dashed var(--border-strong); border-radius: 18px; color: var(--text-dim); font-size: 13px; line-height: 1.45; }
.watch-card > .ico { display: inline-flex; flex: none; color: var(--text-faint); }
.watch-card > .ico svg { width: 16px; height: 16px; }
.wiki-ask.watch-note .watch-card { border-radius: 12px; padding: 10px 12px; font-size: 12.5px; }
.composer-card { display: flex; flex-direction: column; gap: 4px; padding: 10px 10px 8px 14px; border: 1px solid var(--border-strong); border-radius: 18px; background: var(--bg-raised); box-shadow: var(--shadow-sm); transition: border-color 0.12s; }
.composer-card:focus-within { border-color: color-mix(in srgb, var(--text) 28%, transparent); }
.composer.drop-over .composer-card { outline: 2px dashed var(--accent); outline-offset: 2px; background: var(--accent-soft); }
.composer-card textarea { min-height: 26px; max-height: 220px; padding: 3px 2px; border: 0; border-radius: 0; background: transparent; box-shadow: none; resize: none; overflow-y: hidden; font-size: 14.5px; line-height: 1.5; color: var(--text); }
.composer-card textarea:focus { border: 0; box-shadow: none; }
.composer-tools { display: flex; align-items: center; gap: 2px; margin-left: -6px; }
.composer-tools .spacer { flex: 1; }
.composer-tools .attach-btn { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border-radius: 8px; color: var(--text-dim); }
.composer-tools .attach-btn:hover { background: var(--bg-hover); color: var(--text); }
.composer-tools .attach-btn svg { width: 17px; height: 17px; }
.composer-tools .run-choice { margin: 0 6px 0 0; }
/* the working row: the last line of a busy transcript */
.ev-working { display: flex; align-items: center; gap: 10px; color: var(--text-dim); font-size: 13px; padding: 6px 8px; }
.ev-working .w-time { color: var(--text-faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.spin {
  flex-shrink: 0; width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- preview pane ---------- */
.pane-tabs { display: flex; gap: 18px; align-items: center; height: 42px; padding: 0 14px; border-bottom: 1px solid var(--border); background: var(--bg); flex-shrink: 0; container-type: inline-size; }
.pane-tabs > button { border: 0; border-bottom: 2px solid transparent; background: none; color: var(--text-dim); border-radius: 0; padding: 0 2px; height: 42px; margin-bottom: -1px; }
.pane-tabs > button:hover { color: var(--text); background: none; }
.pane-tabs > button.active { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }
.pane-tabs .spacer { flex: 1; }
.pane-tabs .pane-name { color: var(--text); font-weight: 600; white-space: nowrap; }
.board-split .pane-tabs { gap: 10px; }
/* One row of controls, evenly spaced: the device and its rotate, the tuner,
   then what is done to the game — reload, the phone share, a new tab — and
   last the pane's own fold. */
.pane-tabs .pane-actions { display: flex; gap: 2px; align-items: center; flex-wrap: nowrap; flex-shrink: 0; margin: 0; }
/* A narrow pane sheds words before its buttons crowd: the device's size
   first, then the pane's name, and at last the device's own name — its
   icon and chevron stay, so the picker still reads as one. */
@container (max-width: 600px) { .pane-tabs .device-controls .dim { display: none; } }
@container (max-width: 480px) { .pane-tabs .pane-name { display: none; } }
@container (max-width: 420px) { .pane-tabs .dp-name { display: none; } }
.pane-tabs .pane-actions button { padding: 4px 8px; border-radius: 6px; }
/* The way back to the left pane on a phone; a wide screen has both panes. */
.pane-tabs .pane-back { display: none; }

.pane-body { flex: 1; overflow: hidden; position: relative; }
.phone-stage { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
/* content-box: width/height ARE the device's screen, so the game gets exactly
   the size the picker names; the 10px bezel sits outside them. */
.phone {
  position: relative; width: 390px; height: 844px; flex-shrink: 0; box-sizing: content-box;
  /* The bezel's radius is the screen's (--screen-corner, from the device:
     app.js applyDevice) plus its own width, so the clip the game's corners
     get is exactly the real screen's. */
  border-radius: calc(var(--screen-corner, 24px) + 10px); border: 10px solid #000; background: #000;
  box-shadow: var(--shadow-lg), 0 0 0 1px var(--border-strong);
  overflow: hidden; transform-origin: center center;
}
/* The game's frame fills the screen, or sits inside the safe area when
   the page did not ask for the whole screen, the page's own background on
   the phone behind it (app.js syncFrame sets the four --frame-* and the
   background). Sized
   outright, not by its edges: a replaced element given top and bottom and
   no height keeps its intrinsic 150px. */
.phone { --frame-top: 0px; --frame-right: 0px; --frame-bottom: 0px; --frame-left: 0px; }
.phone iframe {
  position: absolute; top: var(--frame-top); left: var(--frame-left);
  width: calc(100% - var(--frame-left) - var(--frame-right)); height: calc(100% - var(--frame-top) - var(--frame-bottom));
  border: none; background: #000; display: block;
}
/* The phone's hardware over the game (PREVIEW_DEVICES): the camera's cutout
   at the top — a notch, a Dynamic Island, a punch hole — and the home
   indicator over the bottom; turned with the device, the cutout to the left
   edge, the bar along the bottom still. Sized in the device's own pixels,
   scaled with it. Never in the game's way: no pointer events. */
.phone .cutout, .phone .home-bar { position: absolute; z-index: 2; pointer-events: none; display: none; }
.phone .cutout { background: #000; left: 50%; top: 0; transform: translateX(-50%); }
.phone[data-cutout="notch"] .cutout { display: block; width: 160px; height: 32px; border-radius: 0 0 20px 20px; }
.phone[data-cutout="island"] .cutout { display: block; top: 11px; width: 124px; height: 36px; border-radius: 999px; }
.phone[data-cutout="hole"] .cutout { display: block; top: 10px; width: 22px; height: 22px; border-radius: 50%; }
.phone.landscape .cutout { left: 0; top: 50%; transform: translateY(-50%); }
.phone.landscape[data-cutout="notch"] .cutout { width: 32px; height: 160px; border-radius: 0 20px 20px 0; }
.phone.landscape[data-cutout="island"] .cutout { left: 11px; width: 36px; height: 124px; }
.phone.landscape[data-cutout="hole"] .cutout { left: 10px; }
.phone.home .home-bar { display: block; left: 50%; bottom: 8px; width: 134px; height: 5px; border-radius: 3px; transform: translateX(-50%); background: rgba(255, 255, 255, 0.78); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.22); }
.phone.home.landscape .home-bar, .phone.home.tablet .home-bar { width: 208px; }
/* A preview's call on window.gamma.native (lib/nativeapi.js): a chip in
   the phone's corner for a moment. */
.native-chips { position: absolute; left: 12px; top: 12px; z-index: 3; display: flex; flex-direction: column; gap: 6px; pointer-events: none; max-width: 80%; }
.native-chip { background: rgba(21, 24, 31, 0.88); color: #fff; font-size: 12px; font-weight: 600; line-height: 1.3; padding: 6px 10px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35); animation: native-chip 0.2s ease-out; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@keyframes native-chip { from { opacity: 0; transform: translateY(-4px); } }
/* Device controls (dropdown, size, rotate): in the task pane they sit in the
   tab bar between the tabs and the pane actions; a preview dialog, which has
   no tab bar, puts them in a row above the frame. */
.device-controls { display: flex; align-items: center; gap: 2px; font-size: 12px; color: var(--text-dim); white-space: nowrap; min-width: 0; }
/* The picker: a phone (or tablet), the device's name, a chevron — one
   button-shaped thing — with the real select laid invisibly over it, so the
   menu, the keyboard and the screen reader are the browser's own. */
.device-pick { position: relative; display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 5px 0 7px; border-radius: 6px; color: var(--text); font-size: 12.5px; cursor: pointer; }
.device-pick:hover { background: var(--bg-hover); }
.device-pick:focus-within { outline: 2px solid var(--accent); outline-offset: -2px; }
.device-pick .dp-kind { display: inline-flex; color: var(--text-dim); }
.device-pick .dp-name { max-width: 150px; overflow: hidden; text-overflow: ellipsis; }
.device-pick > .ico:last-of-type { color: var(--text-dim); }
.device-pick select { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer; min-width: 0; }
.device-controls .dim { color: var(--text-faint); font-variant-numeric: tabular-nums; margin: 0 4px; }
.preview-dialog[open] { display: flex; flex-direction: column; gap: 8px; width: fit-content; max-width: none; background: transparent; border: none; padding: 0; box-shadow: none; }
.device-bar { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 3px 8px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg-overlay); box-shadow: var(--shadow-md); }
.device-bar .spacer { flex: 1; }
.device-bar .history-preview-tag { position: static; transform: none; border: none; background: none; padding: 0 6px; }
.preview-msg { color: var(--text-faint); text-align: center; padding: 40px; }
.preview-msg.error { color: var(--red); white-space: pre-wrap; font-family: var(--mono); font-size: 12px; text-align: left; overflow: auto; max-height: 100%; }

/* ---------- parked previews ---------- */
/* The task pane's game frames live here, over the page, each placed on the
   pane that shows it (app.js, parked previews): a frame that left the DOM
   would reload, so leaving a task hides its frame instead of removing it.
   The layer sits below the pane's own overlays — the server strip and the
   build tag (z 5), the tuner (6), every menu — and above the flow under it.
   An unshown frame is invisible where it stands and keeps its box, so the
   game in it sees no resize while it is frozen. */
#parked { position: fixed; inset: 0; z-index: 4; pointer-events: none; }
#parked > .parked { position: fixed; pointer-events: auto; }
#parked > .parked.off { visibility: hidden; }
/* The task screen after a merge, lifted out of #app whole and shrinking onto
   its card on the board (app.js shrinkTaskToBoard): laid out as #app is, under
   the parked layer so the task's held frame stays on top of it, over nothing
   else of the board's. */
body.shrinking #parked > .parked:not(.held) { visibility: hidden; }
.shrink-sheet { position: fixed; top: 0; left: 0; z-index: 3; display: flex; flex-direction: column; overflow: hidden; background: var(--bg); transform-origin: 0 0; pointer-events: none; will-change: transform, opacity; box-shadow: var(--shadow-lg); }

/* ---------- tuner pane ---------- */
/* A panel down the preview's right edge, flush with it, no margin wasted:
   app.js (tunerPane) sets its width and narrows the stage by as much, and
   the stage's ResizeObserver refits the handset. */
.tuner {
  position: absolute; top: 0; right: 0; bottom: 0; width: 280px; z-index: 6;
  display: flex; flex-direction: column; min-height: 0;
  border-left: 1px solid var(--border); background: var(--bg);
  font-size: 12.5px; color: var(--text-dim);
}
.tuner-head { display: flex; align-items: center; gap: 4px; height: 40px; padding: 0 6px 0 12px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.tuner-head .tuner-title { font-weight: 600; color: var(--text); }
.tuner-head .spacer { flex: 1; }
.tuner-head .t-hidden { font-size: 11.5px; padding: 2px 8px; border-radius: 999px; }
.tuner-head .t-hidden.active { color: var(--text); background: var(--bg-hover); }
.tuner-head .t-phones { font-size: 11px; color: var(--text-dim); border: 1px solid var(--border); border-radius: 999px; padding: 0 7px; margin-left: 6px; white-space: nowrap; }
.tuner-list { flex: 1; overflow: auto; padding: 6px 8px; min-height: 0; }
.tuner-empty { color: var(--text-faint); text-align: center; padding: 22px 12px; line-height: 1.5; }
.tuner-row { padding: 5px 6px 8px; border-radius: 8px; }
.tuner-row:hover { background: var(--bg-hover); }
.tuner-row.is-hidden { opacity: 0.55; }
.t-top { display: flex; align-items: center; gap: 4px; min-height: 26px; }
.t-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.t-mini { padding: 0 5px; line-height: 20px; font-size: 13px; border-radius: 6px; }
.tuner-row input.t-num { width: 66px; padding: 2px 6px; font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.tuner-row input.t-num::-webkit-inner-spin-button, .tuner-row input.t-num::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.tuner-row input.t-range { display: block; width: 100%; margin: 6px 0 0; padding: 0; border: none; background: none; accent-color: var(--accent); }
.tuner-row input.t-toggle { width: auto; margin: 0 6px 0 4px; accent-color: var(--accent); }
.tuner-row select.t-choice { margin-top: 6px; padding: 4px 8px; font-size: 12px; }
.tuner-foot { border-top: 1px solid var(--border); padding: 8px; display: flex; flex-direction: column; gap: 6px; flex-shrink: 0; }
.tuner-foot .tuner-send { width: 100%; font-size: 12.5px; padding: 6px 10px; white-space: normal; }
.tuner-foot input.tuner-add { font-size: 12.5px; padding: 6px 9px; }
.tuner-toggle.active { color: var(--accent); background: var(--accent-soft); }
.tuner-title .ico { vertical-align: -2px; margin-right: 2px; }
/* Under the device (app.js tunerBelow: a landscape device, or a phone): a
   panel along the bottom edge, app.js setting its height. The head and the
   foot share a column at the left; the rows fill the rest in as many columns
   as the width holds, so a short panel still shows most of the knobs. */
.tuner.below {
  top: auto; left: 0; right: 0; bottom: 0; width: auto; height: 240px;
  display: grid; grid-template-columns: 220px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr);
  border-left: 0; border-top: 1px solid var(--border);
}
.tuner.below .tuner-head { grid-area: 1 / 1 / 2 / 2; height: auto; min-height: 40px; flex-wrap: wrap; row-gap: 2px; padding: 6px 6px 4px 12px; border-bottom: 0; }
.tuner.below .tuner-foot { grid-area: 2 / 1 / 3 / 2; border-top: 0; justify-content: flex-end; }
.tuner.below .tuner-list { grid-area: 1 / 2 / 3 / 3; display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 0 8px; align-content: start; border-left: 1px solid var(--border); }
.tuner.below .tuner-empty { grid-column: 1 / -1; }

/* ---------- diff ---------- */
.diff-view { position: absolute; inset: 0; overflow: auto; padding: 14px 18px; font-family: var(--mono); font-size: 12px; }
.diff-view .stat { color: var(--text-dim); white-space: pre; margin-bottom: 14px; border-bottom: 1px solid var(--border); padding-bottom: 12px; }

/* ---------- dialogs ---------- */
dialog {
  background: var(--bg-raised); color: var(--text);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 22px 24px; width: 440px; max-width: 92vw;
  box-shadow: var(--shadow-lg);
}
dialog::backdrop { background: var(--backdrop); }
dialog h3 { margin: 0 0 16px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
dialog label { display: block; font-size: 12px; color: var(--text-dim); margin: 12px 0 5px; font-weight: 600; }
dialog .dlg-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
/* An asset's actions can be many (a task's review beside the library's own): they wrap. */
dialog.asset-dlg .dlg-actions { flex-wrap: wrap; row-gap: 8px; }
dialog .hint { color: var(--text-faint); font-size: 12px; line-height: 1.5; margin-top: 8px; }

/* ---------- phone sharing ---------- */
.qr-wrap { background: #fff; border-radius: 12px; padding: 14px; width: 236px; margin: 6px auto 0; }
.qr-wrap svg { display: block; width: 100%; height: auto; }
.phone-url {
  font-family: var(--mono); font-size: 12.5px; text-align: center; color: var(--text);
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; margin: 12px auto 2px; user-select: all; overflow-wrap: anywhere; cursor: pointer;
}
.phone-url:hover { border-color: var(--border-strong); }

/* ---------- toasts ---------- */
/* A popover, so it is in the top layer and no dialog's backdrop dims it: the
   UA's box is undone, it spans the window and takes no clicks, the toasts
   do. Three places in it: the stack under the bars across the top, the
   newest on top, and the bar — the top bar's empty middle, after its tabs —
   both set by app.js raiseToasts(); and the bottom-right corner, for good
   news the bar has no room for. */
#toasts { position: fixed; inset: 0; width: auto; height: auto; margin: 0; padding: 0; border: 0; background: none; color: inherit; overflow: visible; pointer-events: none; }
#toasts:popover-open { display: block; }
.toast-stack { position: absolute; top: 62px; left: 12px; right: 12px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.toast-bar { position: absolute; top: 26px; transform: translateY(-50%); display: flex; align-items: center; gap: 8px; height: 36px; overflow: hidden; }
.toast-corner { position: absolute; right: 18px; bottom: 18px; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
/* an error: red, a wash of it behind the words, until its × or 20 s */
.toast {
  pointer-events: auto; display: flex; align-items: flex-start; gap: 8px;
  max-width: min(520px, 100%); padding: 8px 14px;
  background: color-mix(in srgb, var(--red) 7%, var(--bg-raised));
  border: 1px solid var(--red-line); border-left: 3px solid var(--red); border-radius: 10px;
  box-shadow: var(--shadow-lg); font-size: 13px;
  white-space: pre-wrap; overflow-wrap: anywhere;
  animation: toast-in 0.18s ease-out;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } }
.toast > span { flex: 1 1 auto; min-width: 0; padding: 2px 0; }
/* good news: a green pill in the bar, gone in a moment — a card with a green
   edge in the corner, where the bar has no room for it */
.toast.ok { background: var(--bg-raised); border-color: var(--border); border-left-color: var(--green); }
.toast-bar .toast { flex: none; padding: 2px 12px; border: 1px solid var(--green-line); border-radius: 999px; background: var(--green-soft); box-shadow: none; font-size: 12.5px; white-space: nowrap; }
/* its buttons, on the first line of the words: Undo, and the × an error carries */
.toast > button { flex: none; height: 24px; padding: 0 8px; line-height: 22px; border-radius: 6px; }
.toast > button:last-child { margin-right: -6px; }
.toast .toast-act { color: var(--accent); font-weight: 600; }
.toast .toast-x { width: 24px; padding: 0; font-size: 16px; }

/* --- game-server preview: the failure card's logs --------------------------- */
.server-logs {
  text-align: left; /* .preview-msg centres its children; a log must not be */
  overflow-wrap: anywhere;
  background: var(--bg-code);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  margin: 0;
  max-height: 50vh;
  overflow: auto;
  white-space: pre-wrap;
  font: 12px/1.5 var(--mono);
}
.preview-card {
  text-align: left;
  min-width: 0;
  max-width: 560px;
  margin: 0 auto;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px 22px;
  box-shadow: var(--shadow-lg);
}

/* ---------- a project's screens, and a task's, as tabs ---------- */
/* Text on the bar's bottom line, the one lit underlined: in the top bar
   (projectNav) and in a task's bar (taskTabs), stretched to the bar's height. */
.proj-tabs { display: flex; align-self: stretch; gap: 20px; flex-shrink: 0; }
.proj-tab {
  display: inline-flex; align-items: center;
  color: var(--text-dim); text-decoration: none; font-weight: 500; font-size: 13px;
  padding: 0 2px; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color 0.12s;
}
.proj-tab:hover { color: var(--text); }
.proj-tab.active { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }

.home.wide { max-width: 1250px; }

/* ---------- art screen ---------- */
/* A section of the Art tab: a real title over a sunken track, so the groups
   inside (a flow of screens, a group of the cast) read as its children. */
.art-sec-head { display: flex; align-items: center; gap: 10px; margin-top: 28px; flex-wrap: wrap; row-gap: 8px; }
.art-sec-head h2 { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -0.01em; text-transform: none; color: var(--text); }
.art-sec-head h2 a { color: inherit; text-decoration: none; }
.art-sec-head h2 a:hover { text-decoration: underline; }
.art-sec-head .info-text { flex-basis: 100%; margin: 0; }
.sec-body { margin-top: 10px; padding: 12px; border-radius: var(--radius); background: var(--bg-sunken); }
.sec-body > .asset-grid, .sec-body > .screen-map, .sec-body > .cast-groups, .sec-body > .look-card { margin-top: 0; }
.sec-body > .job-row:not(:empty) { margin-bottom: 12px; }
.sec-body > .empty-hint { padding: 18px 8px; }
.sec-body .flow-row:first-child { margin-top: 0; }
@media (max-width: 720px) { .sec-body { padding: 10px; } .sec-body > .asset-grid { grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); gap: 10px; } }
.art-sec-head .more-btn { width: 32px; padding: 0; justify-content: center; }
.art-sec-head .more-btn.open { background: var(--bg-hover); color: var(--text); }
.pane-link { color: inherit; text-decoration: none; }
.pane-link:hover { color: var(--text); text-decoration: underline; }
/* a screen nobody captured yet: a short dashed box, the capture one click away */
.a-thumb.shot-empty { flex-direction: column; gap: 8px; border: 1px dashed var(--border-strong); background: var(--bg); color: var(--text-faint); font-size: 12px; }
.a-thumb.shot-empty button { height: 28px; padding: 0 10px; font-size: 12px; }
.sec-count { background: var(--bg-hover); border-radius: 10px; padding: 0 8px; font-size: 12px; font-weight: 600; color: var(--text-dim); white-space: nowrap; }
.sec-count.pending { background: var(--yellow-soft); color: var(--yellow); }
.art-jobs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.art-jobs .chip { padding: 5px 12px; }
.asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; margin-top: 12px; }
.asset-grid.screens { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.asset-grid.mini { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
.asset-card {
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 8px; cursor: pointer; box-shadow: var(--shadow-sm); transition: border-color 0.12s, box-shadow 0.12s;
}
.asset-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.a-thumb {
  height: 120px; border-radius: 7px; overflow: hidden; display: flex; align-items: center; justify-content: center;
  /* checkerboard so transparent sprites read as transparent */
  background: var(--checker);
}
.asset-grid.mini .a-thumb { height: 80px; }
.asset-grid.screens .a-thumb { height: 190px; }
.a-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.a-fallback { font-size: 40px; opacity: .8; color: var(--text-faint); }
.a-fallback .ico { width: 30px; height: 30px; }
.a-fallback-big .ico { width: 72px; height: 72px; color: var(--text-faint); }
.a-name { font-weight: 600; font-size: 12.5px; margin-top: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.a-meta { color: var(--text-faint); font-size: 12px; margin-top: 2px; }
.a-meta a { color: var(--accent); text-decoration: none; }
.a-meta a:hover { text-decoration: underline; }
dialog.asset-dlg { width: 620px; max-width: 94vw; max-height: 92vh; overflow-y: auto; }
.a-full {
  border-radius: 10px; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: var(--checker);
  max-height: 55vh;
}
.a-full img { max-width: 100%; max-height: 55vh; object-fit: contain; display: block; }
.a-fallback-big { font-size: 84px; padding: 40px; }
.anim-row { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 4px; }
.a-sub-head { margin: 16px 0 6px; font-size: 13px; }
.asset-card.pickable { cursor: pointer; }
.a-fallback.pending { opacity: .35; animation: fadepulse 1.4s ease-in-out infinite; }
@keyframes fadepulse { 0%, 100% { opacity: .25; } 50% { opacity: .6; } }

/* the recorded API request, name/value */
.param-table { display: flex; flex-direction: column; gap: 1px; font-size: 12px; }
.param-row { display: flex; gap: 12px; padding: 5px 10px; border: 1px solid var(--border); border-radius: 7px; }
.param-row code { font-family: var(--mono); color: var(--text-dim); flex: 0 0 42%; overflow: hidden; text-overflow: ellipsis; }
.param-row span { color: var(--text); word-break: break-word; }

/* ---------- 3D viewer ---------- */
.glb-stage {
  position: relative; height: 46vh; min-height: 260px; border-radius: 10px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(120% 90% at 50% 0%, var(--bg-hover) 0%, var(--bg-sunken) 70%);
  border: 1px solid var(--border);
}
.glb-canvas { width: 100%; height: 100%; display: block; cursor: grab; }
.glb-canvas:active { cursor: grabbing; }
.glb-still { max-width: 100%; max-height: 100%; object-fit: contain; }
.glb-note {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 8px 12px;
  background: rgba(0, 0, 0, .55); color: var(--text-dim); font-size: 11.5px;
}
.glb-status { color: var(--text-faint); font-size: 11.5px; margin-top: 6px; min-height: 16px; }
.clip-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 10px; }
.clip-row .spacer { flex: 1; }
.clip-btn {
  padding: 5px 12px; font-size: 12px; text-transform: capitalize;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: 999px; color: var(--text-dim); cursor: pointer;
}
.clip-btn:hover { border-color: var(--border-strong); color: var(--text); }
.clip-btn.on { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }

/* ---------- generation dialogs ---------- */
dialog.gen-dlg { width: 680px; max-width: 94vw; max-height: 92vh; overflow-y: auto; }
dialog.asset-dlg.wide-dlg { width: 860px; }
.picker { border: 1px solid var(--border); border-radius: 10px; padding: 8px; background: var(--bg); }
.picker input[type=search] { width: 100%; margin-bottom: 8px; }
.pick-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px; max-height: 190px; overflow-y: auto;
}
.pick-strip { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin; }
.pick-strip > .pick-card { flex: 0 0 88px; }
.pick-strip > .opt-hint { flex: 1 1 auto; align-self: center; }
.picker .pick-status { margin-top: 6px; }
.picker input[type=search][hidden] { display: none; }
.pick-card {
  position: relative; border: 1px solid var(--border); border-radius: 8px; padding: 4px; cursor: pointer;
  background: var(--bg-raised); transition: border-color .12s;
}
.pick-card:hover { border-color: var(--border-strong); }
.pick-card.on { border-color: var(--accent); background: var(--accent-soft); }
.pick-thumb {
  height: 60px; border-radius: 5px; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: repeating-conic-gradient(var(--checker-a) 0% 25%, var(--checker-b) 0% 50%) 0 0 / 12px 12px;
}
.pick-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.pick-name { font-size: 12px; margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-dim); }
.pick-group { font-size: 12px; color: var(--text-faint); }
.pick-badge {
  position: absolute; top: 3px; right: 3px; min-width: 17px; height: 17px; border-radius: 999px;
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; padding: 0 4px;
}

/* optional API parameters */
.opt-fold { border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; margin-top: 14px; }
.opt-fold > summary { cursor: pointer; font-size: 12px; font-weight: 600; color: var(--text-dim); }
.opt-fold[open] > summary { margin-bottom: 6px; }
.opt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.opt-field label { margin-top: 6px !important; font-family: var(--mono); font-size: 12px !important; }
.opt-field select, .opt-field input { width: 100%; }
.opt-hint { color: var(--text-faint); font-size: 12px; line-height: 1.45; margin-top: 4px; }
.opt-error { color: var(--red); font-size: 12px; margin-top: 4px; }
.opt-json { margin-top: 12px; }
.opt-json textarea.mono { font-family: var(--mono); font-size: 12px; }
.chip-pick {
  padding: 4px 11px; font-size: 11.5px; border-radius: 999px; cursor: pointer;
  background: var(--bg); border: 1px solid var(--border); color: var(--text-dim);
}
.chip-pick:hover { border-color: var(--border-strong); color: var(--text); }
.chip-pick.on { background: var(--accent-soft); border-color: var(--accent); color: var(--text); }

/* a placeholder card while art is being generated */
.asset-card.job-card { border-style: dashed; }
.asset-card.trashed { opacity: .72; }
.asset-card.trashed:hover { opacity: 1; }
.asset-card.trashed .a-meta { color: var(--text-faint); }
.asset-card.job-card.failed { border-color: var(--red); background: var(--red-soft); }
.asset-card.job-card .a-meta { color: var(--text-dim); }
.asset-card.job-card.failed .a-meta { color: var(--red); white-space: normal; }
.job-spinner {
  width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: spin 0.9s linear infinite;
}

.job-actions { display: flex; gap: 4px; margin-top: 6px; }
.job-dismiss {
  flex: 1; padding: 3px 8px; font-size: 12px;
  background: transparent; border: 1px solid var(--border-strong); color: var(--text-dim);
}

/* is this asset actually used by the game? */
.use-dot {
  display: inline-block; margin-top: 5px; padding: 1px 7px; border-radius: 999px;
  font-size: 12px;
  background: var(--bg-hover); color: var(--text-faint); border: 1px solid var(--border);
}
.use-dot.on { background: var(--green-soft); color: var(--green); border-color: transparent; }
.use-list { display: flex; flex-direction: column; gap: 2px; font-size: 12px; }
.use-row {
  display: flex; gap: 10px; align-items: baseline; padding: 5px 10px;
  border: 1px solid var(--border); border-radius: 7px;
}
.use-row code { font-family: var(--mono); color: var(--accent); flex: 0 0 auto; }
.use-kind { color: var(--text-faint); font-size: 12px; flex: 0 0 auto; }
.use-text { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
dialog.img-dlg { width: 760px; }

/* ---------- upload (art screen) ---------- */
.up-drop {
  border: 1px dashed var(--border-strong); border-radius: 10px;
  padding: 12px; cursor: pointer; transition: border-color .12s, background .12s;
}
.up-drop:hover, .up-drop.over { border-color: var(--accent); background: var(--accent-soft); }
.up-preview {
  height: 190px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  background: var(--checker);
  overflow: hidden;
}
.up-preview img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.up-empty { color: var(--text-faint); font-size: 12.5px; }
.up-hint { text-align: center; color: var(--text-faint); font-size: 11.5px; margin-top: 8px; }

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

.attach-tray { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.attach-tray:empty { display: none; }
.composer-card .attach-tray { padding: 2px 0 6px; }
.attach-chip .ico { display: inline-flex; flex-shrink: 0; }
.attach-chip .ico svg { width: 13px; height: 13px; }
/* a picture in the tray is a small tile of itself */
.tray-pic { position: relative; width: 56px; height: 56px; flex-shrink: 0; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--bg-code); }
.tray-pic img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tray-pic .x { position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; padding: 0; display: flex; align-items: center; justify-content: center; border: 0; border-radius: 50%; background: var(--backdrop); color: #fff; font-size: 13px; line-height: 1; }
.tray-pic .x:hover { background: var(--red); color: #fff; }
.attach-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 260px;
  background: var(--bg); border: 1px solid var(--border-strong); border-radius: 999px;
  padding: 3px 6px 3px 11px; font-size: 12px; color: var(--text-dim);
}
.attach-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-chip .x {
  background: none; border: none; color: var(--text-faint); cursor: pointer;
  padding: 0 4px; font-size: 14px; line-height: 1; flex-shrink: 0;
}
.attach-chip .x:hover { color: var(--red); background: none; }
.attach-chip.mini { padding: 2px 9px; background: var(--bg-sunken); }
.bubble-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* ---------- wiki screen ---------- */
.wiki-split { display: flex; gap: 18px; margin-top: 16px; align-items: flex-start; }
.wiki-side {
  /* Stuck under the top bar and the project tabs; a list longer than what
     is left of the window scrolls inside its own box. */
  flex: 0 0 220px; position: sticky; top: 12px; max-height: calc(100vh - 144px); overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px;
}
.wiki-item { display: flex; align-items: center; gap: 6px; flex-shrink: 0; color: var(--text-dim); text-decoration: none; font-size: 13px; padding: 7px 10px; border-radius: 7px; white-space: nowrap; }
.wiki-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* A page a layer down sits indented under the page above it. */
.wiki-item.sub { padding-left: calc(10px + var(--depth) * 14px); }
.wiki-item .chev.open { transform: rotate(90deg); }
.wiki-item:hover { color: var(--text); background: var(--bg-hover); }
.wiki-item.active { color: var(--text); background: var(--accent-soft); font-weight: 600; }
.wiki-main { flex: 1; min-width: 0; }
.wiki-doc img { max-width: 100%; max-height: 340px; object-fit: contain; border-radius: 8px; margin: 6px 0; display: block; }
.wiki-doc a { color: var(--accent); text-decoration: none; cursor: pointer; }
.wiki-doc a:hover { text-decoration: underline; }

/* ---------- git history screen ---------- */
.commit-list { margin-top: 4px; }
.commit-row {
  display: flex; align-items: center; gap: 12px; padding: 9px 12px 9px 4px;
  cursor: pointer; border-radius: 8px;
}
.commit-row:hover { background: var(--bg-hover); }
.c-graph { position: relative; width: 26px; align-self: stretch; flex-shrink: 0; }
.c-graph::before {
  content: ''; position: absolute; left: 12px; top: -10px; bottom: -10px;
  width: 2px; background: var(--border-strong);
}
.c-graph.last::before { bottom: 50%; }
.commit-row:first-child .c-graph::before { top: 50%; }
.c-dot {
  position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--bg-raised); border: 2px solid var(--text-faint);
}
.c-dot.head { background: var(--accent); border-color: var(--accent); }
.c-main { flex: 1; min-width: 0; }
.c-subject { font-weight: 600; font-size: 13.5px; display: flex; align-items: center; gap: 8px; overflow: hidden; }
.c-subject .chip { flex-shrink: 0; text-decoration: none; }
.c-meta { color: var(--text-faint); font-size: 11.5px; font-family: var(--mono); margin-top: 2px; }
.c-actions { display: flex; gap: 4px; flex-shrink: 0; }
.diff-view.static { position: static; padding: 14px 0; overflow-x: auto; }
.history-preview-tag {
  position: absolute; top: 10px; left: 50%; transform: translateX(-50%);
  pointer-events: none;
  background: var(--bg-overlay); border: 1px solid var(--border-strong); box-shadow: var(--shadow-md);
  border-radius: 999px; padding: 5px 14px; font-size: 12px; color: var(--text);
  white-space: nowrap; z-index: 5;
}
/* In the task pane the tag sits at the left, clear of the tuner at the right. */
.pane-body .history-preview-tag { left: 12px; transform: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; }

/* ---------- task art: what the task adds or changes, reviewed on its Art tab ---------- */
/* On a card of the task's library: what was decided about the asset, and
   the decision's two buttons. */
.a-review { display: flex; align-items: center; gap: 4px; margin-top: 6px; }
.a-review .spacer { flex: 1; }
.a-review button { padding: 1px 8px; font-size: 12px; line-height: 1.5; min-height: 0; height: 24px; }
.ta-badge { display: inline-block; padding: 0 6px; border-radius: 999px; font-size: 10px; font-weight: 600; letter-spacing: .02em; flex-shrink: 0; }
.ta-badge.pending { background: var(--yellow-soft); color: var(--yellow); }
.ta-badge.approved { background: var(--green-soft); color: var(--green); }
.ta-badge.discarded, .ta-badge.rejected { background: var(--red-soft); color: var(--red); }

/* an art path in the transcript, as a chip with its picture */
.art-ref {
  display: inline-flex; align-items: center; gap: 5px; vertical-align: middle; max-width: 100%;
  padding: 1px 6px 1px 2px; border: 1px solid var(--border); border-radius: 6px; background: var(--bg-raised);
  font-family: var(--mono); font-size: 12px; color: var(--text); cursor: pointer; transition: border-color .12s;
}
.art-ref:hover { border-color: var(--accent); }
.art-ref-thumb {
  height: 22px; width: auto; max-width: 44px; border-radius: 4px; display: block; object-fit: contain;
  background: repeating-conic-gradient(var(--checker-a) 0% 25%, var(--checker-b) 0% 50%) 0 0 / 8px 8px;
}
.art-ref-thumb.failed { display: none; }
.art-ref-glyph { font-size: 14px; line-height: 1; }
.art-ref-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Inside `code` the chip IS the code: no second box around it. */
.ev-text code:has(> .art-ref:only-child) { background: none; padding: 0; }
.tsum .art-ref { font-size: 11px; padding: 0 5px 0 1px; }
.tsum .art-ref-thumb { height: 16px; }

/* the decision line in a task-mode detail dialog */
.ta-review { margin-top: 10px; padding: 8px 12px; border-radius: 8px; font-size: 12.5px; border: 1px solid var(--border); }
.ta-review.pending { background: var(--yellow-soft); color: var(--yellow); border-color: var(--yellow-line); }
.ta-review.approved { background: var(--green-soft); color: var(--green); border-color: var(--green-line); }
.ta-review.discarded, .ta-review.rejected { background: var(--red-soft); color: var(--red); border-color: var(--red-line); }

/* the reject menu, the discard message, and the merge gate */
dialog.reject-dlg { width: 460px; }
.reject-choice {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%;
  text-align: left; white-space: normal; padding: 10px 14px; margin-top: 8px;
}
.reject-choice .rc-label { font-weight: 600; }
.reject-choice .rc-sub { font-size: 12px; color: var(--text-dim); font-weight: 400; }
dialog.discard-dlg { width: 560px; }
.discard-dlg textarea { min-height: 130px; }
dialog.pending-dlg { width: 640px; max-width: 94vw; max-height: 90vh; overflow-y: auto; }

/* A task's own bar, under the project's tabs (taskChrome): its title and
   chips, its tabs — the same underline, a step quieter — and its actions. */
.task-bar { display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 16px 0 20px; border-bottom: 1px solid var(--border); background: var(--bg-sunken); flex-shrink: 0; }
.task-bar > * { flex-shrink: 0; }
.task-bar .task-title { font-size: 14px; margin: 0; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 80px; max-width: min(520px, 40%); }
.task-bar .spacer { flex: 1; }
.task-bar #task-tabs-host { align-self: stretch; display: flex; margin-left: 14px; padding-left: 18px; border-left: 1px solid var(--border); }
.task-bar #task-tabs-host:empty { display: none; }
.task-bar .task-tabs { gap: 18px; }
.task-tabs .proj-tab { font-size: 12.5px; gap: 6px; }
.task-bar #task-actions { display: flex; align-items: center; gap: 8px; }
.task-bar .tb-more:has(#task-actions:empty) { display: none; }
.tab-count { background: var(--yellow-soft); color: var(--yellow); border-radius: 10px; padding: 0 7px; font-size: 11px; font-weight: 600; line-height: 17px; }
.task-tabs .spin { width: 11px; height: 11px; }

/* a task's Wiki tab: the proposal's line over the wiki, then the pages —
   and the same line over the library on its Art tab */
.wiki-head { display: flex; align-items: center; gap: 10px; min-height: 32px; font-size: 12.5px; color: var(--text-dim); }
.art-head { margin-bottom: 4px; }
/* the proposal's one line, under the head, whole */
.wiki-summary { font-size: 12.5px; color: var(--text-dim); margin: 2px 0 6px; line-height: 1.5; }
/* the three counts: to decide, accepted, rejected */
.tally { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.tally-label { font-size: 11.5px; color: var(--text-faint); margin-right: 2px; }
.sec-count.ok { background: var(--green-soft); color: var(--green); }
.sec-count.no { background: var(--red-soft); color: var(--red); }
.sec-count.zero { opacity: 0.45; }
/* a decision over many changes at once: one shape for the head's pair and the page's */
.wiki-act { background: var(--bg-raised); border: 1px solid var(--border-strong); color: var(--text); padding: 3px 10px; font-size: 12px; font-weight: 500; }
.wiki-act:hover { background: var(--bg-hover); }
.wiki-act .glyph { font-weight: 700; }
.wiki-act .glyph.ok { color: var(--green); }
.wiki-act .glyph.no { color: var(--red); }
.wiki-head .spacer, .wiki-page-bar .spacer { flex: 1; }
.wiki-head .spin { width: 12px; height: 12px; flex-shrink: 0; }
.wiki-head button { flex-shrink: 0; }
.task-wiki-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 0 1 auto; color: var(--text-faint); }
.task-wiki-note.error { color: var(--red); }
/* Two strips of tabs and the proposal's line stand over this list. */
.wiki-split.in-task .wiki-side { max-height: calc(100vh - 220px); }
.wiki-item.gone .wiki-item-name { text-decoration: line-through; }
.wiki-mark { flex-shrink: 0; min-width: 16px; text-align: center; font-size: 11px; font-weight: 600; color: var(--text-faint); }
.wiki-mark.open { background: var(--yellow-soft); color: var(--yellow); border-radius: 10px; padding: 0 6px; line-height: 17px; }
.wiki-page-bar { display: flex; align-items: center; gap: 6px; min-height: 30px; margin-bottom: 8px; font-size: 12.5px; min-width: 0; }
.wiki-page-bar code { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wiki-page-bar .dim { white-space: nowrap; }
.wiki-page-bar button { padding: 3px 10px; font-size: 12px; flex-shrink: 0; }

/* ---------- 3D in four steps ---------- */
dialog.gen-dlg.steps-dlg { width: 760px; }
.gen-steps { display: grid; gap: 10px; margin-top: 12px; }
.gen-step { border: 1px solid var(--border); border-radius: 10px; background: var(--bg-raised); padding: 10px 14px 12px; }
.gen-step.off { opacity: .6; }
.gen-step-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.gen-step-head .gen-k { font-weight: 700; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; }
.gen-step-head .gen-k small { color: var(--text-faint); margin-right: 5px; font-weight: 600; }
.gen-price { margin-left: auto; font-family: var(--mono); font-size: 12px; color: var(--yellow); white-space: nowrap; font-variant-numeric: tabular-nums; }
.gen-price.free { color: var(--green); }
.gen-price.muted { color: var(--text-faint); }
.gen-when { display: inline-flex; border: 1px solid var(--border-strong); border-radius: 999px; overflow: hidden; }
.gen-when button { background: transparent; color: var(--text-dim); border: 0; font: inherit; font-size: 11.5px; padding: 2px 10px; cursor: pointer; }
.gen-when button.on { background: var(--accent-soft); color: var(--text); }
.gen-when button:disabled { opacity: .5; cursor: default; }
.gen-modes { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 2px; }
.gen-mode { background: var(--bg); color: var(--text-dim); border: 1px solid var(--border); border-radius: 8px; font: inherit; font-size: 12.5px; padding: 5px 10px; cursor: pointer; }
.gen-mode.on { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.gen-api { font-family: var(--mono); font-size: 12px; color: var(--text-faint); margin-top: 8px; word-break: break-word; }
.gen-api b { color: var(--text-dim); font-weight: 500; }
.gen-total { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.gen-total .gen-sum { font-family: var(--mono); font-size: 12px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.gen-total .gen-sum b { color: var(--yellow); font-weight: 500; }
.gen-total .gen-checked { font-size: 12px; color: var(--text-faint); }

/* a job's steps, on its card */
.job-steps { display: grid; gap: 3px; margin-top: 6px; text-align: left; }
.job-step { display: grid; grid-template-columns: 10px 72px minmax(0, 1fr); gap: 6px; align-items: baseline; font-size: 12px; color: var(--text-dim); }
.job-step .js-dot { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--text-faint); align-self: center; }
.job-step.done .js-dot { background: var(--green); border-color: var(--green); }
.job-step.running .js-dot { border-color: var(--blue); border-top-color: transparent; animation: spin 0.9s linear infinite; }
.job-step.failed .js-dot { background: var(--red); border-color: var(--red); }
.job-step.skipped .js-dot { border-style: dashed; }
.job-step .js-k { font-weight: 600; font-size: 12px; color: var(--text); }
.job-step.skipped .js-k, .job-step.queued .js-k { color: var(--text-faint); }
.job-step .js-s { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-step.failed .js-s { color: var(--red); white-space: normal; }
.job-step .js-s .js-usd { color: var(--yellow); font-family: var(--mono); }
.asset-card.job-card .job-steps .js-s { color: var(--text-dim); }

.clip-row.clips { margin-top: 4px; }
.clip-row .clip-label { font-size: 12px; color: var(--text-faint); align-self: center; margin-right: 2px; }

/* ---------- screens: capture + concept ---------- */
/* Named by a screen, a sidecar or a document — not loaded by the game, so
   never the green of "in use". */
.use-dot.ref { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
/* What a screen card is showing, over its picture: a concept is not the game. */
.asset-card .a-thumb { position: relative; }
.a-chip {
  position: absolute; left: 6px; top: 6px; max-width: calc(100% - 12px);
  padding: 2px 8px; border-radius: 999px; font-size: 12px;
  background: var(--bg-overlay); color: var(--text-dim); border: 1px solid var(--border-strong);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.a-chip.pending { color: var(--yellow); border-color: var(--yellow-line); }
dialog.asset-dlg.screen-dlg { width: 860px; }
.screen-panes { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 8px; }
.screen-panes.single { grid-template-columns: 1fr; }
.screen-panes.single .shot-frame { margin: 0 auto; }
@media (max-width: 720px) { .screen-panes { grid-template-columns: 1fr; } }
.screen-pane { min-width: 0; }
.pane-title { font-size: 12px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); font-weight: 600; margin-bottom: 6px; }
.pane-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
/* A phone-shaped frame for a capture or a concept; the checkerboard reads as
   "no pixels here" exactly as it does on every other thumbnail. */
.shot-frame {
  border-radius: 10px; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: var(--checker);
  max-height: 55vh;
}
.shot-frame img { max-width: 100%; max-height: 55vh; object-fit: contain; display: block; }
.shot-frame.empty { aspect-ratio: 9 / 19.5; max-width: 260px; margin: 0 auto; border: 1px dashed var(--border-strong); background: var(--bg); }
.shot-frame.small { max-height: 240px; width: 140px; flex: 0 0 140px; }
.shot-frame.small img { max-height: 240px; }
/* the picture a restyle task is about, above its words (the new-task dialog) */
dialog.nt-dlg, dialog.np-dlg { width: 560px; }
dialog h3.dlg-head { display: flex; align-items: center; gap: 8px; }
dialog .info-text { margin: -6px 0 14px; }
dialog .np-warn { color: var(--yellow); }
/* Where a new project starts (openNewProjectDialog): the source switch, and
   the row each import source opens under it. */
dialog .np-seg { margin: -4px 0 12px; }
dialog .np-src-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 12px; }
dialog .np-src-row[hidden] { display: none; }
dialog .np-src-row .ghost { display: inline-flex; align-items: center; gap: 6px; }
dialog .np-chosen { font-size: 12px; color: var(--text-dim); min-width: 0; }
dialog .np-git { flex-direction: column; align-items: stretch; }
dialog .np-git input { width: 100%; }
dialog .np-token-row { display: flex; align-items: center; gap: 8px; }
dialog .np-token-row input { flex: 1; min-width: 0; }
dialog .np-token-help { margin-top: 0; }
dialog .np-token-help p { margin: 0 0 6px; }
dialog .np-token-help a { color: var(--accent); }
dialog.nt-wide { width: 640px; max-height: 92vh; overflow-y: auto; }
.nt-concept { margin-bottom: 14px; }
/* A dialog's card (dialogComposer) is the task composer's (.composer-card),
   with a title line over the words — New task, New project. */
.dlg-card .dc-title { padding: 3px 2px 6px; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; background: transparent; box-shadow: none; font-size: 15px; font-weight: 600; color: var(--text); }
.dlg-card .dc-title:focus { border-color: var(--border); box-shadow: none; }
.dlg-card .attach-tray { padding: 6px 0 0; }
.dlg-card textarea { min-height: 96px; max-height: 320px; padding-top: 6px; }
.composer-card.drop-over { outline: 2px dashed var(--accent); outline-offset: 2px; background: var(--accent-soft); }
.run-choice .model-other { width: 150px; padding: 2px 8px; font-size: 12px; }
.run-choice.fallback select:first-child { color: var(--yellow); }
dialog.nt-dlg .nt-suggest { margin: 8px 0 0; }
/* TEMPORARY — the model comparison: six drafts as tabs under the prompt box. */
dialog.nt-compare { width: 900px; max-width: calc(100vw - 32px); }
.cmp-head { font-size: 12px; margin: 4px 0 6px; }
.cmp-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--border); padding-bottom: 6px; }
.cmp-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: var(--text-dim); font-size: 12.5px; }
.cmp-tab.active { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.cmp-grid-btn { margin-left: auto; }
.cmp-name { font-weight: 600; color: var(--text); }
.cmp-time { font-variant-numeric: tabular-nums; }
.cmp-place { min-width: 18px; height: 18px; border-radius: 9px; padding: 0 5px; box-sizing: border-box; background: var(--green); color: var(--bg); font-size: 12px; font-weight: 700; line-height: 18px; text-align: center; }
.cmp-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.cmp-dot.pending { border: 1.5px solid var(--text-faint); box-sizing: border-box; animation: todo-pulse 1.4s ease-in-out infinite; }
.cmp-dot.ready { background: var(--green); }
.cmp-dot.failed { background: var(--red); }
.cmp-answer { padding: 8px 2px 0; }
.cmp-meta { font-size: 12px; color: var(--text-faint); margin-bottom: 6px; }
.cmp-text { white-space: pre-wrap; font-size: 13.5px; line-height: 1.5; color: var(--text); max-height: 260px; overflow-y: auto; }
.cmp-error { color: var(--red); }
.cmp-actions { display: flex; justify-content: flex-end; margin-top: 8px; }
.cmp-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding-top: 8px; }
.cmp-cell { border: 1px solid var(--border); border-radius: 8px; padding: 8px; min-width: 0; }
.cmp-cell-head { display: flex; align-items: center; gap: 6px; }
.cmp-cell .cmp-text { font-size: 12.5px; max-height: 220px; }
@media (max-width: 720px) { .cmp-grid { grid-template-columns: minmax(0, 1fr); } }
.nt-frames { display: flex; gap: 14px; justify-content: center; }
.nt-frame { flex: 1 1 0; min-width: 0; max-width: 260px; }
.nt-frame a { display: block; }
.nt-frame .shot-frame { max-height: 300px; }
.nt-frame .shot-frame img { max-height: 300px; }
.nt-frame.new .shot-frame { outline: 2px solid var(--accent); outline-offset: -2px; }
/* a thing, at the size the game draws it, with room around it */
.nt-frame .shot-frame.thing-frame { padding: 14px; min-height: 140px; }
.shot-frame.thing-frame img { image-rendering: auto; }
.shot-placeholder { color: var(--text-faint); font-size: 12.5px; text-align: center; padding: 20px; }
.screen-pane > .s-sub, .pending-text > .s-sub { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; margin-top: 6px; font-size: 12px; color: var(--text-dim); }
.changed-mark { font-size: 12px; padding: 1px 7px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); white-space: nowrap; }
.opt-hint.warn { color: var(--yellow); }
.pending-block { margin-top: 16px; padding: 12px 14px; border: 1px solid var(--yellow-line); border-radius: 10px; background: var(--yellow-faint); }
.pending-body { display: flex; gap: 14px; align-items: flex-start; }
.pending-text { min-width: 0; flex: 1; }
.pending-text a { color: var(--accent); text-decoration: none; }
.pending-text a:hover { text-decoration: underline; }

/* --- the Look card: the art direction at the top of the Art tab --- */
.look-card {
  display: flex; gap: 18px; align-items: stretch; margin-top: 0; padding: 14px 16px;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.look-main { flex: 1; min-width: 0; }
.look-card .dim { color: var(--text-faint); font-size: 12.5px; }
.look-swatches { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.look-swatch { width: 22px; height: 22px; border-radius: 6px; border: 1px solid var(--border-strong); }
.look-line { font-size: 13px; line-height: 1.5; color: var(--text); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; max-width: 760px; }
.look-actions { display: flex; gap: 6px; align-items: center; margin-top: 10px; }
.look-target { flex: 0 0 120px; display: flex; flex-direction: column; gap: 6px; }
.look-target-shot {
  height: 150px; border-radius: 8px; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: var(--checker); cursor: pointer;
}
.look-target-shot img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.look-target-shot.empty { cursor: default; background: var(--bg-sunken); color: var(--text-faint); font-size: 12px; border: 1px dashed var(--border-strong); }
.look-target-pick { width: 100%; font-size: 12px; }
@media (max-width: 720px) { .look-card { flex-direction: column; } .look-target { flex-basis: auto; flex-direction: row; align-items: center; } .look-target-shot { width: 90px; height: 120px; flex: 0 0 90px; } }

/* --- the screen map: flows as rows, a screen card per step --- */
.job-row:empty { display: none; }
.screen-map { margin-top: 4px; }
.flow-row { margin-top: 14px; }
.flow-name { font-size: 12.5px; color: var(--text-dim); font-weight: 600; margin-bottom: 8px; }
.flow-name.dim { color: var(--text-faint); }
.flow-row > .asset-grid { margin-top: 0; }
.flow-cards { display: flex; align-items: flex-start; gap: 8px; overflow-x: auto; padding-bottom: 6px; }
.flow-cards > .asset-card { flex: 0 0 150px; }
.flow-cards > .asset-card .a-thumb { height: 190px; }
/* level with the middle of the thumbnails, whatever each card carries below */
.flow-arrow { flex: 0 0 auto; color: var(--text-faint); font-size: 18px; margin-top: 92px; }
.flow-slugs { margin-top: 8px; font-size: 12px; color: var(--text-dim); line-height: 1.8; }
.a-states { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.st-pill {
  padding: 1px 8px; height: auto; border-radius: 999px; font-size: 12px; font-weight: 500;
  background: var(--bg-sunken); border: 1px solid var(--border); color: var(--text-dim); cursor: pointer;
}
.st-pill:hover { color: var(--text); border-color: var(--border-strong); }
.st-pill.missing { opacity: .55; border-style: dashed; }

/* --- the mood board: the look's references, a strip under its words --- */
.look-mood { margin-top: 14px; }
.mood-strip.asset-grid { display: flex; flex-wrap: nowrap; gap: 8px; margin-top: 0; overflow-x: auto; padding-bottom: 4px; scrollbar-width: thin; }
.mood-item, .mood-add { flex: none; }
.look-target .pane-title { margin: 0; }
.mood-item {
  width: 72px; height: 72px; border-radius: 8px; overflow: hidden; cursor: pointer;
  background: var(--checker); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center;
}
.mood-item:hover { border-color: var(--border-strong); }
.mood-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mood-add {
  width: 72px; height: 72px; padding: 0; border-radius: 8px; border: 1px dashed var(--border-strong);
  background: transparent; color: var(--text-faint); font-size: 22px; display: inline-flex; align-items: center; justify-content: center;
}
.mood-add:hover:not([disabled]) { color: var(--text); border-color: var(--text-faint); }
.mood-strip > .asset-card { flex: 0 0 140px; }
.mood-strip > .asset-card .a-thumb { height: 72px; }

/* --- the cast: every thing the game draws, alone, at its own size --- */
.cast-groups { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px 28px; margin-top: 14px; }
.cast-group { min-width: 0; max-width: 100%; }
.cast-row { display: flex; flex-wrap: wrap; gap: 12px; }
.cast-row > .asset-card { width: 150px; }
/* A filtered Files list may be made taller than its cards (app.js, setFilter)
   so its head holds its place on screen: the cards stay at the top of it. */
#grid-files.filtered { align-content: start; }
@media (max-width: 560px) { .cast-row > .asset-card { width: calc(50vw - 30px); } }
.thing-thumb { height: 120px; }
/* the picture keeps its size; only a thing too big for the card shrinks */
.thing-thumb img { max-width: 100%; max-height: 100%; height: auto; object-fit: contain; }
/* What a thing is shown on: the transparent checkerboard, the game's own
   background (set inline from the look's first colour), black or white. */
.thing-stage {
  display: flex; align-items: center; justify-content: center; min-height: 180px; max-height: 60vh; overflow: auto;
  padding: 16px; border-radius: 10px; border: 1px solid var(--border);
}
.thing-stage.bg-checker { background: var(--checker); }
.thing-stage.bg-dark { background: #000; }
.thing-stage.bg-light { background: #fff; }
.thing-stage .pin-box img { display: block; max-width: none; height: auto; }
.thing-stage.cmp-mode { flex-direction: column; gap: 8px; }
.thing-stage .shot-placeholder { color: var(--text-faint); }
.thing-stage.bg-dark .shot-placeholder { color: #8a8a8a; }
.thing-stage.bg-light .shot-placeholder { color: #6b6b6b; }
img.pixelated { image-rendering: pixelated; }
/* Compared, a small thing is sized by its own width rather than a phone's
   height: the comparison box then wraps it exactly. */
.thing-stage .cmp { background: transparent; }
.thing-stage .cmp-a[style], .thing-stage canvas.cmp-diff[style] { max-width: none; }
.thing-stage + .cmp-legend, .cmp-stage > .thing-stage { margin-top: 0; }
dialog.asset-dlg.thing-dlg { width: 820px; }

/* "New thing…": how to make it is a choice of four, two by two */
.make-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.make-choices .reject-choice { margin-top: 0; }
.reject-choice.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
@media (max-width: 560px) { .make-choices { grid-template-columns: 1fr; } }
/* the picture dialog: the words first and large, the look as one line, the
   references as a row, the settings that rarely change on one line */
.gen-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.gen-head h3 { margin: 0; flex: 1 1 auto; }
.gen-desc { min-height: 96px; font-size: 14px; line-height: 1.45; }
.look-chip {
  display: flex; align-items: center; gap: 8px; margin: 8px 0 0; padding: 4px 10px; max-width: 100%;
  border: 1px solid var(--border); border-radius: 999px; font-size: 12px; color: var(--text-dim); font-weight: 400;
}
.look-chip input { margin: 0; flex: none; }
.look-chip .lc-k { font-weight: 600; color: var(--text); flex: none; }
.look-chip .lc-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.save-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: center; margin-top: 14px; }
.save-row > label { margin: 0; }
.save-row select { width: auto; }
.gen-settings { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: center; margin-top: 14px; }
.gen-settings .gs { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.gen-settings .gs > label { margin: 0; font-size: 12px; }
.gen-settings select { height: 30px; font-size: 12.5px; width: auto; }
.gen-cost { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--text-faint); align-self: center; }
dialog .dlg-actions.with-cost { align-items: center; }
.plan-note { margin-top: 10px; }
/* the words of a picture and, under them, the composer's tray and tools */
.gen-words { display: flex; flex-direction: column; gap: 6px; }
.gen-words .attach-tray { padding: 0; }
.gen-words .composer-tools .tools-note { font-size: 12px; color: var(--text-faint); margin-left: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-bar { height: 4px; border-radius: 999px; background: var(--bg-hover); margin-top: 8px; overflow: hidden; }
.job-fill { height: 100%; background: var(--accent); border-radius: 999px; transition: width .4s; }

/* --- the screen popup: states, compare modes, a note pinned to a spot --- */
.cmp-bars { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 4px; }
.cmp-bars .dim { color: var(--text-faint); font-size: 12px; }
.seg { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px; border-radius: 8px; background: var(--bg-sunken); align-items: center; }
.seg-btn { height: 26px; padding: 0 10px; border: 0; border-radius: 6px; background: transparent; color: var(--text-dim); font-size: 12px; font-weight: 500; }
.seg-btn:hover { color: var(--text); }
.seg-btn.on { background: var(--bg-raised); color: var(--text); box-shadow: var(--shadow-sm); }
.seg-btn.missing { opacity: .55; }
.seg-extra { height: 26px; padding: 0 10px; font-size: 12px; }
.cmp-against { height: 30px; font-size: 12.5px; max-width: 180px; }
.cmp-stage { margin-top: 10px; text-align: center; overflow-x: auto; }
.cmp-stage > .screen-panes { text-align: left; }
/* The game's picture sets the box (as tall as the side-by-side frames may
   be); the other is laid over it at the same width, top-aligned, the way a
   mockup is laid over a build. */
.cmp { position: relative; display: inline-block; vertical-align: top; line-height: 0; border-radius: 10px; overflow: hidden; background: var(--checker); text-align: left; }
/* Sized by height (a phone screen is tall): the box then wraps the picture
   exactly, which a percentage width inside a shrink-to-fit box cannot. */
.cmp-a { display: block; height: min(55vh, 620px); width: auto; max-width: none; }
.cmp-b { position: absolute; left: 0; top: 0; width: 100%; height: auto; }
.cmp-handle { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--accent-strong); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25); pointer-events: none; }
/* the canvas only: the box around it is .cmp.cmp-diff too, and wraps it */
canvas.cmp-diff { display: block; height: min(55vh, 620px); width: auto; max-width: none; }
.cmp-legend { display: flex; gap: 10px; align-items: center; justify-content: center; margin-top: 8px; font-size: 12px; }
.cmp-legend .dim { color: var(--text-faint); }
.cmp-slider { width: 200px; }
.pin-target { cursor: crosshair; }
.pin-box { position: relative; display: inline-block; line-height: 0; max-width: 100%; }
.pin-dot {
  position: absolute; width: 16px; height: 16px; margin: -8px 0 0 -8px; border-radius: 50%;
  border: 2px solid #fff; background: var(--accent-strong); box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.35); pointer-events: none;
}
.pin-composer { margin-top: 10px; padding: 10px 12px; border-radius: 10px; background: var(--bg-sunken); }
.pin-composer textarea { margin-top: 6px; }
.info-row { margin-top: 2px; }
.art-sec-head.sub { margin-top: 18px; }
.art-sec-head.sub .a-sub-head { margin: 0; }
.asset-grid.variants .a-thumb { height: 150px; }
.asset-grid.variants .pane-actions { margin-top: 6px; gap: 6px; }

/* --- a sprite sheet, playing --- */
.sheet-anim { height: 100%; max-width: 100%; aspect-ratio: 1; background-repeat: no-repeat; }
.sheet-anim.big { height: min(260px, 40vh); }
.a-full.sheet-full { padding: 16px; }
.a-full.sheet-grid { margin-top: 10px; max-height: 30vh; }
.a-full.sheet-grid img { max-height: 30vh; }
.sheet-edit { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 10px; font-size: 12.5px; }
.sheet-edit .dim { color: var(--text-faint); }
.sheet-num { width: 64px; height: 30px; }
/* The capture bar under the preview, in the device bar's own shape. */
.capture-bar {
  display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap;
  padding: 6px 12px; border: 1px solid var(--border); border-radius: 18px; background: var(--bg-overlay); box-shadow: var(--shadow-md);
  color: var(--text-dim); font-size: 12.5px;
}
.capture-bar .dim { color: var(--text-faint); }
.capture-error { flex-basis: 100%; color: var(--yellow); font-size: 12px; text-align: center; }
.screen-pick { display: flex; gap: 12px; align-items: flex-start; width: 100%; max-width: 520px; text-align: left; }
.screen-pick-thumb { width: 72px; max-height: 150px; object-fit: contain; border-radius: 8px; background: var(--checker); flex: 0 0 72px; }
.screen-pick-fields { flex: 1; min-width: 0; }
.screen-pick-fields label { display: block; margin: 0 0 4px; font-size: 12px; color: var(--text-dim); }
.screen-pick-fields select, .screen-pick-fields input { width: 100%; margin-bottom: 6px; }
dialog.shot-dlg { width: 560px; max-width: 94vw; }

/* ---------- speaking to a busy agent ---------- */
/* The composer's keys while the agent works are the Claude Code app's; the
   only furniture is a hint line when a queue exists, and the queue itself:
   dim lines above the composer, where that app keeps them. */
.composer-hint { font-size: 11.5px; color: var(--text-faint); padding: 0 6px; }
/* In the composer's tools: the task's model and effort, as the Claude app
   has them (runChoice). */
.run-choice { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-dim); white-space: nowrap; }
.run-choice .rc-sep { color: var(--text-faint); }
/* The model's plan close to its limit, or not connected (paintLimitSlot):
   quiet otherwise. */
.rc-limit .rc-connect { padding: 1px 7px; margin-left: 2px; font-size: 12px; border-radius: 6px; border: 1px solid var(--red-line); background: transparent; color: var(--red); }
.rc-limit .rc-connect:hover { background: var(--red-soft); }
.rc-limit { display: inline-flex; align-items: center; gap: 4px; margin-left: 6px; font-variant-numeric: tabular-nums; }
.rc-limit .ico, .rc-limit .ico svg { width: 13px; height: 13px; display: inline-flex; }
.rc-limit.warm { color: var(--yellow); }
.rc-limit.hot { color: var(--red); }
.run-choice select { width: auto; field-sizing: content; padding: 2px 6px; font-size: 12px; border-radius: 6px; border-color: transparent; background: transparent; color: var(--text-dim); cursor: pointer; }
.run-choice select:hover:not(:disabled) { background: var(--bg-hover); color: var(--text); }
.run-choice select:disabled { cursor: default; opacity: 1; }
.ev-stopped { color: var(--text-dim); }
/* The button beside the composer: Send, or Stop while the agent works and
   there is nothing to send — the desktop app's button. Its keys show on a
   hover, in a small card above it. */
.send-wrap { position: relative; flex-shrink: 0; }
#composer-send { width: 32px; height: 32px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; }
#composer-send .ico { display: inline-flex; }
#composer-send .ico svg { width: 17px; height: 17px; stroke-width: 2.2; }
#composer-send.idle { opacity: 0.4; }
#composer-send.stop { background: var(--bg-hover); border-color: var(--border-strong); color: var(--text); }
#composer-send.stop .ico svg { width: 18px; height: 18px; }
#composer-send.stop:hover:not(:disabled) { background: var(--red-soft); border-color: var(--red-line); color: var(--red); }
.send-tip {
  display: none; position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 5;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px;
  font-size: 12px; color: var(--text-dim); white-space: nowrap; box-shadow: var(--shadow-md);
}
.send-wrap:hover .send-tip:not(:empty), .send-wrap:focus-within .send-tip:not(:empty) { display: block; }
.send-tip .tip-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 2px 0; }
.send-tip kbd { font-family: inherit; color: var(--text-faint); border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; font-size: 11px; }
/* the working row's "esc to interrupt", and its idle state after Esc */
.ev-working .w-esc { color: var(--text-faint); font-size: 11.5px; }
.ev-working .w-esc::before { content: '·'; margin-right: 10px; }
.ev-working.waiting .spin { display: none; }
.ev-working.waiting .w-label { color: var(--text); }
/* A secret the agent asked for: one card per request, above the composer. */
.task-secrets { flex-shrink: 0; display: flex; flex-direction: column; gap: 8px; padding: 6px max(16px, calc((100% - 836px) / 2)); }
.tsr-card { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border: 1px solid var(--yellow); border-radius: 10px; background: var(--bg); }
.task-secrets.merged .tsr-card { border-color: var(--border); }
.tsr-head { font-size: 13px; font-weight: 600; }
.tsr-head code { font-size: 13px; }
.tsr-why { font-weight: 400; color: var(--text-dim); }
.tsr-row { display: flex; gap: 8px; align-items: center; }
.tsr-row input { flex: 1; min-width: 0; }
.tsr-foot { display: flex; gap: 6px; align-items: center; font-size: 12px; }
.tsr-foot select { width: auto; padding: 2px 6px; font-size: 12px; }
.tsr-foot .spacer { flex: 1; }
.tsr-foot button { padding: 3px 10px; font-size: 12px; }
.tsr-card .hint { margin: 0; color: var(--text-faint); font-size: 11.5px; line-height: 1.5; }

/* A question the agent asked (renderTaskQuestion), over the composer: its
   words, an option a button — the label and a line about it — the person's
   own words under them, and Skip and Send at its foot. As wide as the
   composer, and never taller than leaves the thread readable. */
.task-question { flex-shrink: 0; padding: 6px max(16px, calc((100% - 836px) / 2)) 2px; }
.ask-card { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; border: 1px solid var(--accent-line); border-radius: 14px; background: var(--bg-raised); box-shadow: var(--shadow-sm); max-height: 52vh; }
.ask-body { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; overflow-y: auto; }
.ask-card.sending { opacity: 0.7; }
@media (max-width: 900px) { .ask-card { max-height: 44vh; } }
.ask-head { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--accent); }
.ask-head .ico { display: inline-flex; }
.ask-head .ico svg { width: 15px; height: 15px; }
.ask-q { display: flex; flex-direction: column; gap: 8px; }
.ask-q + .ask-q { padding-top: 12px; border-top: 1px solid var(--border); }
.ask-q-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ask-tag { font-size: 11px; font-weight: 600; color: var(--text-dim); padding: 1px 7px; border: 1px solid var(--border-strong); border-radius: 999px; white-space: nowrap; }
.ask-q-words { font-size: 14.5px; font-weight: 600; line-height: 1.45; color: var(--text); overflow-wrap: anywhere; }
.ask-many { font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.ask-opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px; }
.ask-opt { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-height: 44px; padding: 9px 12px; text-align: left; white-space: normal; border-radius: 10px; background: var(--bg); }
.ask-opt:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.ask-opt[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.ask-opt-label { font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.ask-opt-desc { font-size: 12.5px; font-weight: 400; line-height: 1.45; color: var(--text-dim); overflow-wrap: anywhere; }
.ask-opt-preview { align-self: stretch; margin: 4px 0 0; padding: 6px 8px; max-height: 160px; overflow: auto; border-radius: 6px; background: var(--bg-code); font-family: var(--mono); font-size: 11.5px; font-weight: 400; line-height: 1.35; color: var(--text-dim); white-space: pre; }
.ask-foot { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.ask-foot .spacer { flex: 1; }
.ask-hint { font-size: 11.5px; line-height: 1.4; color: var(--text-faint); }
.task-queue { flex-shrink: 0; padding: 4px max(22px, calc((100% - 824px) / 2)) 0; }
.tq-row { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 2px 0; font-size: 13px; color: var(--text-dim); cursor: text; }
.tq-row:hover { color: var(--text); }
.tq-row .tq-mark { flex-shrink: 0; width: 12px; display: inline-flex; justify-content: center; color: var(--text-faint); }
.tq-row .tq-mark svg { width: 11px; height: 11px; }
.tq-row .tq-files { flex-shrink: 0; display: inline-flex; align-items: center; gap: 2px; font-size: 11.5px; color: var(--text-faint); }
.tq-row .tq-files svg { width: 12px; height: 12px; }
.tq-row.interrupting .tq-mark { color: var(--red); animation: pulse 1.2s ease-in-out infinite; }
.tq-row .tq-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tq-row .x { flex-shrink: 0; padding: 0 6px; font-size: 13px; line-height: 1; visibility: hidden; }
.tq-row:hover .x { visibility: visible; }

/* ---------- publish tab ---------- */
.pub-card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 18px 20px; margin: 14px 0; box-shadow: var(--shadow-sm); }
.pub-url { display: inline-block; font-family: var(--mono); font-size: 13.5px; color: var(--text); background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; text-decoration: none; overflow-wrap: anywhere; }
.pub-url:hover { border-color: var(--accent); }
.pub-label { display: block; font-size: 12px; color: var(--text-dim); margin: 12px 0 5px; font-weight: 600; }
.pub-slug { display: flex; align-items: center; gap: 8px; max-width: 560px; }
.pub-slug input { flex: 1; font-family: var(--mono); }
.pub-suffix { color: var(--text-dim); font-family: var(--mono); font-size: 13px; white-space: nowrap; }
.pub-build-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.rel-list { margin-top: 10px; border-top: 1px solid var(--border); }
.rel-item { border-bottom: 1px solid var(--border); }
.rel-row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; font-size: 13px; flex-wrap: wrap; }
.rel-row.live { background: var(--green-soft); border-radius: 8px; }
.rel-row.failed { opacity: 0.8; }
.rel-toggle { padding: 0 8px; font-size: 16px; line-height: 22px; }
.rel-n { font-weight: 700; min-width: 34px; }
.rel-sha.mono { font-family: var(--mono); font-size: 12px; color: var(--text-dim); }
.rel-chip { font-size: 11px; border-radius: 999px; padding: 1px 8px; border: 1px solid var(--border); color: var(--text-dim); display: inline-flex; align-items: center; gap: 4px; }
.rel-chip.ok { color: var(--green); border-color: var(--green-line); }
.rel-chip.warn { color: var(--yellow); border-color: var(--yellow-line); }
.rel-chip.bad { color: var(--red); border-color: var(--red-line); }
.rel-row .spacer { flex: 1; }
.btn-link { display: inline-block; text-decoration: none; padding: 5px 10px; border-radius: 8px; color: var(--text-dim); font-size: 13px; }
.btn-link:hover { color: var(--text); background: var(--bg-hover); }
.rel-details { padding: 4px 8px 12px 44px; font-size: 12.5px; color: var(--text-dim); }
.rel-details details summary { cursor: pointer; }
.rel-findings { margin: 4px 0 8px; padding-left: 18px; color: var(--yellow); }

/* ---------- settings: secrets ---------- */
.secret-list { display: flex; flex-direction: column; gap: 6px; }
.secret-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg); }
.secret-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.secret-name { display: flex; align-items: center; gap: 10px; }
.secret-name code { font-size: 13px; color: var(--text); }
.secret-how { font-size: 12px; overflow-wrap: anywhere; }
.secret-how code { font-size: 11.5px; }
.secret-meta { font-size: 11.5px; }
.secret-actions { display: flex; gap: 4px; flex-shrink: 0; }
/* A secret's value: a text box masked by CSS (see secretValueInput), the eye shows it. */
.secret-value-wrap { display: flex; align-items: center; gap: 4px; flex: 1; min-width: 0; }
.secret-value-wrap input { flex: 1; min-width: 0; }
.secret-value.masked { -webkit-text-security: disc; }
.secret-eye { flex-shrink: 0; padding: 4px 7px; font-size: 13px; opacity: 0.6; }
.secret-eye:hover, .secret-eye.on { opacity: 1; }
.secret-fields { display: flex; flex-direction: column; gap: 8px; }
.secret-fields .field-row { gap: 10px; }
.secret-check { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); }
.secret-check input { width: auto; accent-color: var(--accent); }
.secret-proxy { padding: 10px 12px; border: 1px dashed var(--border-strong); border-radius: 10px; }
.secret-form { margin-top: 4px; }
dialog.secret-dlg { width: 640px; max-width: 94vw; }

/* ---------- settings: the cards ---------- */
/* The Settings tab: its sections down the side, the open one's cards beside
   them (renderSettings). */
.settings-layout { display: flex; align-items: flex-start; gap: 32px; }
.settings-nav { flex: 0 0 168px; display: flex; flex-direction: column; gap: 2px; position: sticky; top: 0; padding-top: 14px; }
.settings-link { padding: 7px 10px; border-radius: 8px; color: var(--text-dim); text-decoration: none; font-size: 13.5px; font-weight: 500; }
.settings-link:hover { color: var(--text); background: var(--bg-hover); }
.settings-link.active { color: var(--text); background: var(--accent-soft); font-weight: 600; }
.settings-main { flex: 1; min-width: 0; }
/* A card is its controls; what it is for folds behind the ⓘ by its title.
   Hints here are hints (small, faint) — outside a dialog they had no style
   of their own and read as a second paragraph of body text. */
.card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.card-head .pane-title { margin: 0; }
.info-btn {
  width: 18px; height: 18px; padding: 0; border-radius: 999px; flex-shrink: 0;
  border: 1px solid var(--border-strong); background: transparent; color: var(--text-faint);
  font: italic 700 11px/1 Georgia, "Times New Roman", serif;
  display: inline-flex; align-items: center; justify-content: center;
}
.info-btn:hover, .info-btn[aria-expanded="true"] { color: var(--text); border-color: var(--text-dim); background: var(--bg-hover); }
.info-text { margin: 0 0 12px; max-width: 760px; color: var(--text-dim); font-size: 12.5px; line-height: 1.5; }
.settings-card .hint { color: var(--text-faint); font-size: 11.5px; line-height: 1.5; }
.settings-card .dim { color: var(--text-faint); }
.settings-card .secret-check { padding: 2px 0; }
.secret-check .dim { color: var(--text-faint); font-size: 12.5px; }
.settings-pickers { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.settings-pickers button.ghost { padding: 4px 10px; font-size: 12.5px; }
/* The compact picker: label and select on one line, the selects at their
   own width, the note as the select's tooltip. */
.field-row.compact { align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 0; }
.field-row.compact > .pick-inline { flex: 0 1 auto; display: flex; align-items: center; gap: 8px; }
.pick-inline label { margin: 0; font-size: 12px; font-weight: 600; color: var(--text-dim); white-space: nowrap; }
.field-row.compact select { width: auto; max-width: 260px; padding: 5px 10px; font-size: 13px; }
.pick-inline .model-other { width: 220px; padding: 5px 10px; font-size: 13px; }

/* ---------- publish: targets + testers ---------- */
.pub-icon-row { display: flex; align-items: flex-start; gap: 16px; }
.pub-icon { width: 72px; height: 72px; border-radius: 16px; background: var(--bg); border: 1px solid var(--border); flex-shrink: 0; }
.native-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 0; font-size: 13px; }
.native-name { font-weight: 600; min-width: 92px; }
.native-row .spacer { flex: 1; }
.native-log { flex-basis: 100%; font-size: 12.5px; color: var(--text-dim); }
.native-log summary { cursor: pointer; }
.pub-dest { border-top: 1px solid var(--border); padding: 12px 0; }
.pub-dest:first-of-type { border-top: 0; padding-top: 4px; }
.pub-dest-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pub-dest-name { font-weight: 600; font-size: 14px; min-width: 130px; }
.pub-dest-head .spacer { flex: 1; }
.pub-soon { font-size: 11px; border-radius: 999px; padding: 2px 10px; border: 1px solid var(--border-strong); color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; }
.rel-fold { font-size: 12.5px; margin-top: 4px; }
.pub-pick-wrap { display: inline-flex; align-items: center; gap: 6px; }
.pub-pick { width: auto; min-width: 110px; font-family: var(--mono); font-size: 12.5px; padding: 6px 8px; }
.pub-addr { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin-top: 8px; }
.pub-addr .pub-qr { width: 88px; padding: 5px; }
.pub-addr-main { flex: 1; min-width: 260px; display: flex; flex-direction: column; gap: 8px; }
.pub-addr-main .pane-actions { margin: 0; align-items: center; }
.native-details { margin-top: 10px; }
/* The name the native apps hold while the web app is off: shown, not editable. */
.pub-fixed { font-family: var(--mono); font-size: 13px; color: var(--text-dim); padding: 8px 0; }
dialog.notes-dlg { width: 560px; max-width: 94vw; }
dialog.notes-dlg textarea { width: 100%; font: inherit; font-size: 13.5px; min-height: 140px; }

/* asking for a change on the Wiki screen */
.wiki-ask { margin-top: 18px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-raised); padding: 10px 14px 12px; display: flex; flex-direction: column; gap: 8px; }
.wiki-ask-row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--text-dim); min-width: 0; }
.wiki-ask-row .spacer { flex: 1; }
.wiki-ask-row button { padding: 3px 10px; font-size: 12px; }
.wiki-ask-row.compose { align-items: flex-end; }
.wiki-ask-row.compose textarea { flex: 1; min-height: 44px; resize: vertical; }
/* what the composer's words are about */
.wiki-ask-ctx { display: flex; flex-wrap: wrap; gap: 6px; min-height: 18px; }
.wiki-ask-ctx:empty { display: none; }
.wt-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; font-size: 11.5px; line-height: 18px; padding: 0 8px; border-radius: 10px; border: 1px solid var(--border); background: var(--bg-sunken); color: var(--text-dim); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wt-chip.on { border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: var(--accent-soft); color: var(--text); }
.wt-chip.whole { opacity: 0.75; }
a.wt-chip:hover { color: var(--text); border-color: var(--border-strong); }
.wt-chip-x { border: 0; background: none; color: var(--text-faint); font-size: 14px; line-height: 1; padding: 0 0 0 2px; margin-right: -3px; cursor: pointer; }
.wt-chip-x:hover { color: var(--red); background: none; }

/* a task's Wiki tab: the thread with the wiki editor, left of the pages */
.wiki-thread {
  flex: 0 0 320px; position: sticky; top: 12px; max-height: calc(100vh - 220px);
  display: flex; flex-direction: column; min-width: 0;
}
.wiki-thread .wiki-ask { margin-top: 10px; flex-shrink: 0; }
/* A window too narrow for three columns reads the page first: the thread
   goes under it, its list scrolling in its own box. */
@media (max-width: 1100px) {
  .wiki-split.in-task { flex-wrap: wrap; }
  .wiki-split.in-task .wiki-side { position: static; max-height: none; }
  .wiki-thread { position: static; flex: 1 1 100%; max-height: none; order: 3; }
  .wiki-thread-list { max-height: 40vh; }
}
.wiki-thread-list { flex: 1; min-height: 120px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; padding: 2px 6px 2px 2px; font-size: 12.5px; line-height: 1.5; color: var(--text); }
.wt-empty { color: var(--text-faint); font-size: 12px; line-height: 1.5; padding: 8px 4px; }
.wt-entry { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.wt-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 11.5px; color: var(--text-faint); min-width: 0; }
.wt-meta > .ico { display: inline-flex; }
.wt-meta > .ico svg { width: 13px; height: 13px; }
.wt-you { color: var(--text-dim); font-weight: 600; }
.wt-time { white-space: nowrap; }
.wt-unfold { border: 0; background: none; padding: 0; font: inherit; font-size: 11.5px; color: var(--accent); cursor: pointer; }
.wt-unfold:hover { text-decoration: underline; background: none; }
.wt-page { color: var(--accent); text-decoration: none; }
.wt-page:hover { text-decoration: underline; }
.wt-bubble { align-self: flex-start; max-width: 100%; background: var(--bg-hover); padding: 7px 12px; border-radius: 14px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 13px; line-height: 1.5; }
.wt-answer { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-left: 8px; padding-left: 9px; border-left: 2px solid var(--border); border-radius: 0; color: var(--text-dim); font-size: 12.5px; min-width: 0; }
.wt-answer .spin { width: 11px; height: 11px; }
.wt-answer button.ghost { padding: 1px 8px; font-size: 11.5px; }
.wt-answer .dim { color: var(--text-faint); }
.wt-summary { flex-basis: 100%; color: var(--text-faint); font-size: 12px; line-height: 1.45; }
.wt-cost { flex-basis: 100%; color: var(--text-faint); font-size: 11px; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.wt-quote { color: var(--text); font-style: italic; }
.wt-err { color: var(--red); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.wt-body { max-height: 260px; overflow: auto; margin: 0; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-sunken); font-size: 11px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text-dim); }
/* the page column holds the selection's Comment button and the editor */
.wiki-page { position: relative; }
.wiki-sel-btn { position: absolute; z-index: 3; display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; font-size: 12px; border-radius: 8px; border: 1px solid var(--border-strong); background: var(--bg-raised); color: var(--text); box-shadow: var(--shadow-sm); }
.wiki-sel-btn[hidden] { display: none; }
.wiki-sel-btn .ico svg { width: 13px; height: 13px; }
.wiki-editor { width: 100%; min-height: 60vh; resize: vertical; font-family: var(--mono); font-size: 13px; line-height: 1.55; padding: 14px 16px; border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--bg-raised); color: var(--text); }
.rl-btn.note { background: var(--bg); color: var(--text-dim); border-color: var(--border-strong); padding: 4px 6px; box-shadow: none; display: inline-flex; align-items: center; }
.rl-btn.note .ico svg { width: 13px; height: 13px; }
.rl-btn.note:hover { color: var(--text); background: var(--bg-hover); }

/* the wiki renderer's design-document extras */
.wiki-doc h5, .wiki-doc h6 { font-size: 13px; margin: 12px 0 4px; text-transform: none; letter-spacing: 0; color: var(--text); }
.wiki-doc blockquote { margin: 8px 0; padding: 4px 14px; border-left: 3px solid var(--border-strong); color: var(--text-dim); }
.wiki-doc blockquote p { margin: 0 0 4px; }
.wiki-doc .img-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-start; margin: 8px 0; }
.wiki-doc .img-row figure { margin: 0; flex: 1 1 160px; max-width: 320px; min-width: 0; }
.wiki-doc .img-row.one figure { flex-basis: auto; max-width: 100%; }
.wiki-doc .img-row img { width: 100%; max-height: 340px; object-fit: contain; border-radius: 8px; display: block; margin: 0; }
.wiki-doc figcaption { font-size: 11.5px; color: var(--text-faint); margin-top: 4px; text-align: center; }
.wiki-doc hr { border: 0; border-top: 1px solid var(--border); margin: 14px 0; }
.wiki-doc ol { list-style: decimal; }
.wiki-doc li > ul, .wiki-doc li > ol { margin: 2px 0 2px; }
.wiki-doc li.task { list-style: none; margin-left: -18px; }
.wiki-doc li.task .box { font-family: var(--mono); color: var(--text-dim); }
.wiki-doc li.task.done { color: var(--text-dim); }
.wiki-doc code.swatch i { display: inline-block; width: 11px; height: 11px; border-radius: 3px; border: 1px solid var(--border-strong); margin-right: 5px; vertical-align: -1px; }
.wiki-doc kbd { font-family: var(--mono); font-size: 11.5px; border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: 5px; padding: 0 5px; background: var(--bg); }
.wiki-doc mark { background: var(--yellow-soft); color: var(--text); padding: 0 3px; border-radius: 3px; }
.wiki-doc del { color: var(--text-faint); }
.wiki-doc details { margin: 6px 0; border: 1px solid var(--border); border-radius: 8px; padding: 6px 12px; }
.wiki-doc summary { cursor: pointer; font-weight: 600; }
.wiki-doc th, .wiki-doc td { vertical-align: top; }

/* the wiki reads as a document, not as the admin's code view */
.wiki-doc { padding: 34px 44px 38px; max-width: 860px; font-size: 15px; line-height: 1.65; color: var(--text); }
.wiki-doc > h2:first-child { margin-top: 0; }
.wiki-doc h2 { font-size: 26px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; margin: 0 0 14px; }
.wiki-doc h3 { font-size: 18px; font-weight: 700; margin: 30px 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.wiki-doc h4 { font-size: 15.5px; font-weight: 700; margin: 22px 0 8px; }
.wiki-doc h5, .wiki-doc h6 { font-size: 14px; font-weight: 700; margin: 16px 0 6px; }
/* a heading a link scrolls to stops short of the edge */
.wiki-doc [data-slug] { scroll-margin-top: 12px; }
.wiki-doc p { margin: 0 0 12px; }
.wiki-doc p:empty { display: none; }
.wiki-doc ul, .wiki-doc ol { margin: 6px 0 14px; padding-left: 26px; }
.wiki-doc li { margin-bottom: 6px; }
.wiki-doc li > ul, .wiki-doc li > ol { margin: 6px 0 2px; }
.wiki-doc li > p { margin: 6px 0 0; }
.wiki-doc strong { font-weight: 700; }
.wiki-doc code { font-size: 13px; }
.wiki-doc pre { font-size: 12.5px; padding: 12px 14px; margin: 10px 0 16px; }
.wiki-doc .utable { font-size: 14px; margin: 10px 0 18px; }
.wiki-doc .utable th { font-size: 11.5px; padding: 8px 12px; }
.wiki-doc .utable td { padding: 9px 12px; color: var(--text); }
.wiki-doc img { max-height: 420px; border: 1px solid var(--border); }
.wiki-doc .img-row { margin: 12px 0 18px; }
.wiki-doc .img-row figure { max-width: 380px; }
.wiki-doc figcaption { font-size: 12.5px; margin-top: 6px; }
.wiki-doc blockquote { margin: 12px 0 16px; padding: 6px 18px; border-left: 3px solid var(--accent); color: var(--text-dim); font-style: italic; }
.wiki-doc hr { margin: 24px 0; }
.wiki-doc details { padding: 8px 16px; margin: 10px 0 16px; }

/* the redline: the page rendered with its changes in place, decided from the margin */
.rl-count { font-weight: 400; font-size: 12px; margin-left: 6px; }
.rl-outer { position: relative; }
/* On a task's Wiki tab the redline is the page itself: it scrolls with the
   screen, and the bar over it steps between its changes. */
.rl-outer.inline .rl-wrap { max-height: none; overflow: visible; }
.rl-outer.inline .rl-nav { display: none; }
/* …and its cards carry a third button, the comment, so the margin is wider. */
.rl-outer.inline .rl-gutter { width: 112px; }
.rl-outer.inline .rl-doc.wiki-doc { padding-right: 124px; }
.rl-wrap { position: relative; max-height: 62vh; overflow: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-raised); }
.rl-doc.wiki-doc { border: 0; border-radius: 0; margin: 0; padding: 26px 96px 30px 30px; max-width: none; background: transparent; }
.rl-gutter { position: absolute; top: 0; right: 0; width: 84px; }
.rl-card { position: absolute; right: 8px; display: flex; gap: 4px; align-items: center; transition: top 0.15s ease-out; }
.rl-btn { font: inherit; font-weight: 700; font-size: 13px; line-height: 1; padding: 6px 9px; border-radius: 8px; border: 1px solid transparent; cursor: pointer; color: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); }
.rl-btn.ok { background: var(--green); }
.rl-btn.no { background: var(--red); }
.rl-btn.ok:hover, .rl-btn.no:hover { filter: brightness(1.12); }
.rl-btn.undo { background: var(--bg); color: var(--text-dim); border-color: var(--border-strong); font-weight: 600; font-size: 11.5px; padding: 4px 7px; box-shadow: none; }
.rl-state { font-size: 11px; color: var(--text-faint); }
.rl-card.rl-focus .rl-btn { outline: 2px solid var(--accent); outline-offset: 1px; }
.rl-nav { position: absolute; right: 2px; width: 22px; height: 22px; padding: 0; font-size: 9px; line-height: 22px; text-align: center; border-radius: 6px; border: 1px solid var(--border-strong); background: var(--bg); color: var(--text-dim); cursor: pointer; z-index: 2; }
.rl-nav.up { top: 2px; }
.rl-nav.down { bottom: 2px; }
.rl-nav:hover { color: var(--text); }
.rl-del { color: var(--red); background: var(--red-soft); text-decoration: line-through; text-decoration-thickness: 1.5px; border-radius: 3px; }
.rl-ins { color: var(--green); background: var(--green-soft); text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 2px; border-radius: 3px; }
.rl-change.accepted { background: var(--green-soft); border-radius: 3px; }
.rl-change.rejected { background: var(--red-soft); border-radius: 3px; }
.rl-change.rl-focus, .rl-block.rl-focus { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.rl-block { margin: 6px 0; padding: 4px 12px; border-left: 3px solid var(--border-strong); border-radius: 4px; }
.rl-block.del { border-left-color: var(--red); background: var(--red-soft); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--red) 60%, transparent); }
.rl-block.ins { border-left-color: var(--green); background: var(--green-soft); }
.rl-block.accepted, .rl-block.rejected { text-decoration: none; background: transparent; }
.rl-block.accepted { border-left-color: var(--green); }
.rl-block.rejected { border-left-color: var(--red); }
.rl-doc .rl-change, .rl-doc .rl-block { cursor: pointer; }
/* a change inside a code block: its lines, marked in place */
span.rl-block { display: block; margin: 0; padding: 0 8px; }
/* where a decided change's dropped side was: its card's place on the page */
.rl-anchor { display: block; height: 0; }

/* ---------- icons ---------- */
.ico { display: inline-flex; width: 14px; height: 14px; vertical-align: -2px; flex-shrink: 0; }
.ico svg { width: 100%; height: 100%; display: block; }
button > .ico:first-child:not(:only-child) { margin-right: 4px; }
/* cards that are links look exactly as they did as divs */
a.project-card, a.task-card, a.commit-row { color: inherit; text-decoration: none; }
a.project-card, a.task-card { display: block; }

/* ---------- hover texts ---------- */
/* Every title= in the app, shown at once (app.js, "hover texts"). A popover,
   so the UA's centring is undone: app.js places it by left/top. */
.hover-tip {
  position: fixed; inset: auto; margin: 0; overflow: visible; pointer-events: none;
  max-width: min(360px, calc(100vw - 16px)); padding: 5px 9px;
  background: var(--bg-raised); color: var(--text); border: 1px solid var(--border-strong); border-radius: 6px; box-shadow: var(--shadow-md);
  font-size: 12px; line-height: 1.45; white-space: pre-line; overflow-wrap: anywhere;
}

/* ---------- menus ---------- */
/* A menu under its button (popMenu): a popover, so the UA's centring is
   undone and app.js places it by top/right. */
.pop-menu {
  position: fixed; inset: auto; margin: 0; overflow: visible;
  min-width: 210px; max-width: min(320px, calc(100vw - 16px)); padding: 5px;
  background: var(--bg-raised); color: var(--text); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg);
}
.pop-menu:popover-open { display: flex; flex-direction: column; gap: 1px; }
.pm-head { padding: 6px 10px 9px; margin-bottom: 4px; border-bottom: 1px solid var(--border); font-size: 12px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm-sep { height: 1px; margin: 4px 0; background: var(--border); }
.pm-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px; border: 0; border-radius: 7px; background: none; color: var(--text); font-weight: 400; text-align: left; }
.pm-item:hover, .pm-item:focus-visible { background: var(--bg-hover); outline: none; }
.pm-item > .ico { width: 15px; height: 15px; color: var(--text-dim); }
.pm-label { flex: 1; }
/* What an item still offers, beside its name (Plans…: "Add ChatGPT"). */
.pm-note { font-size: 11.5px; color: var(--accent); white-space: nowrap; }
.pm-check .ico { width: 15px; height: 15px; color: var(--accent); }
.pm-item.danger, .pm-item.danger > .ico { color: var(--red); }
.pm-item.danger:hover, .pm-item.danger:focus-visible { background: var(--red-soft); }
/* A select's list (selectMenu): placed by top/left, its whole list unless
   the window is shorter than it; an <optgroup> is a quiet heading. */
.sel-menu { min-width: 150px; overflow-y: auto; font-size: 13px; }
.sel-menu .pm-item { padding: 6px 10px; }
.pm-group { padding: 7px 10px 3px; font-size: 11.5px; font-weight: 600; color: var(--text-faint); }

/* ---------- a bar's overflow ---------- */
/* A task's buttons live in a <details>: held open on its bar on a wide
   screen (its summary hidden), a ⋯ with a menu under it on a phone. */
.tb-more { display: flex; align-items: center; }
.tb-more > summary { display: none; list-style: none; }
.tb-more > summary::-webkit-details-marker { display: none; }
.tb-menu { display: flex; align-items: center; gap: 8px; }

/* ---------- reconnecting ---------- */
#offline { position: fixed; top: 10px; left: 50%; transform: translateX(-50%); z-index: 200; display: flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; background: var(--bg-raised); border: 1px solid var(--yellow-line); color: var(--yellow); font-size: 12.5px; box-shadow: var(--shadow-md); }
#offline .spin { border-top-color: var(--yellow); }

/* ---------- loading ---------- */
.skeleton { display: grid; gap: 10px; padding: 6px 0; max-width: 720px; }
.sk-row { height: 14px; border-radius: 6px; background: var(--bg-hover); animation: sk-pulse 1.4s ease-in-out infinite; }
.sk-row:nth-child(2) { width: 82%; }
.sk-row:nth-child(3) { width: 64%; }
.sk-row:nth-child(4) { width: 90%; }
.sk-row:nth-child(5) { width: 48%; }
.sk-row:nth-child(6) { width: 72%; }
@keyframes sk-pulse { 50% { opacity: 0.45; } }

/* ---------- the palette ---------- */
dialog.palette { width: 580px; max-width: 94vw; padding: 0; margin-top: 12vh; overflow: hidden; }
.pal-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border); color: var(--text-faint); }
.pal-head .ico { width: 16px; height: 16px; }
.pal-head input, .pal-head input:focus { flex: 1; border: 0; background: none; padding: 4px 0; font-size: 15px; box-shadow: none; color: var(--text); }
.pal-head kbd, .pal-item kbd { font: 11px/1 inherit; color: var(--text-faint); border: 1px solid var(--border); border-radius: 4px; padding: 3px 5px; }
.pal-list { max-height: 50vh; overflow-y: auto; padding: 6px; }
.pal-group { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); padding: 8px 10px 4px; }
.pal-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 13.5px; }
.pal-item.active { background: var(--accent-soft); }
.pal-item:focus-visible { outline: none; background: var(--accent-soft); }
.pal-label { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pal-sub { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-faint); font-size: 12px; }
.pal-empty { color: var(--text-faint); padding: 18px 10px; text-align: center; }

/* ---------- the split ---------- */
.split-handle { flex: 0 0 9px; position: relative; cursor: col-resize; z-index: 3; touch-action: none; }
.split-handle::before { content: ''; position: absolute; top: 0; bottom: 0; left: 4px; width: 1px; background: var(--border); transition: background 0.12s, width 0.12s, left 0.12s; }
.split-handle:hover::before, .page-split.dragging .split-handle::before { left: 3px; width: 3px; background: var(--accent-line); }
.split-handle:focus-visible { outline: none; }
.split-handle:focus-visible::before { left: 3px; width: 3px; background: var(--accent); }
.page-split.dragging { user-select: none; cursor: col-resize; }
.page-split.dragging iframe { pointer-events: none; }
body:has(.page-split.dragging) #parked > .parked { pointer-events: none; } /* the parked frame is not under .page-split */
.sh-glyph { display: none; }
.page-split.folded .split-right { display: none; }
.page-split.folded .split-left { flex: 1 1 auto; }
.page-split.folded .split-handle { flex-basis: 22px; cursor: pointer; background: var(--bg-sunken); border-left: 1px solid var(--border); }
.page-split.folded .split-handle::before { display: none; }
.page-split.folded .sh-glyph { display: block; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 14px; height: 14px; color: var(--text-faint); }
.page-split.folded .sh-glyph svg { display: block; width: 100%; height: 100%; }
.page-split.folded .split-handle:hover { background: var(--bg-hover); }
.page-split.folded .split-handle:hover .sh-glyph { color: var(--text); }
.mobile-switch { display: none; }

/* ---------- the diff, file by file ---------- */
.diff-files-view { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif; font-size: 13px; }
.df-summary { color: var(--text-dim); font-size: 12.5px; margin: 0 0 10px; }
.df-add { color: var(--green); }
.df-del { color: var(--red); }
.df-counts { display: inline-flex; gap: 6px; font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.df-files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.df-file-link { font-family: var(--mono); font-size: 11.5px; font-weight: 400; padding: 3px 8px; border-radius: 6px; background: var(--bg-raised); border: 1px solid var(--border); color: var(--text-dim); line-height: 1.4; }
.df-file-link .df-counts { margin-left: 6px; }
.df { border: 1px solid var(--border); border-radius: 10px; background: var(--bg-raised); margin-bottom: 12px; overflow: hidden; }
.df > summary { display: flex; align-items: center; gap: 10px; padding: 8px 12px; cursor: pointer; list-style: none; font-family: var(--mono); font-size: 12.5px; font-weight: 600; }
.df > summary::-webkit-details-marker { display: none; }
.df > summary::before { content: '›'; color: var(--text-faint); width: 8px; transition: transform 0.12s; }
.df[open] > summary::before { transform: rotate(90deg); }
.df[open] > summary { border-bottom: 1px solid var(--border); }
.df > summary .df-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-from { color: var(--text-faint); font-weight: 400; }
.df-note { font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-faint); border: 1px solid var(--border); border-radius: 999px; padding: 0 7px; }
/* A workspace file, read-only (fileViewer): the diff's table, one line-number column. */
dialog.file-dlg { width: 860px; max-width: 94vw; height: 86vh; padding: 0; display: flex; flex-direction: column; overflow: hidden; }
dialog.file-dlg:not([open]) { display: none; }
.file-dlg-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px 10px 16px; border-bottom: 1px solid var(--border); }
.file-dlg-name { flex: 1; min-width: 0; font-family: var(--mono); font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-dlg-body { flex: 1; overflow: auto; padding: 6px 0; }
.file-dlg .hint { padding: 0 16px 10px; }
.file-dlg .df-table td.ln { border-right: 1px solid var(--border); }
.file-dlg .df-table tr.hit td { background: var(--accent-soft); }
.df-table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 12px; line-height: 1.5; table-layout: fixed; }
.df-table td { padding: 0 10px 0 6px; vertical-align: top; white-space: pre-wrap; overflow-wrap: anywhere; }
.df-table td.ln { width: 44px; text-align: right; color: var(--text-faint); user-select: none; padding: 0 6px; font-variant-numeric: tabular-nums; }
.df-table td.ln + td.ln { border-right: 1px solid var(--border); }
.df-table tr.add td { background: var(--green-faint); }
.df-table tr.add td.code { color: var(--green); }
.df-table tr.del td { background: var(--red-faint); }
.df-table tr.del td.code { color: var(--red); }
.df-table tr.hunk td { background: var(--bg-sunken); color: var(--blue); padding-top: 3px; padding-bottom: 3px; }
.df-table tr.meta td { color: var(--text-faint); }
.df-binary { padding: 10px 14px; color: var(--text-faint); font-size: 12.5px; }

/* ---------- a copyable code block ---------- */
.codeblock { position: relative; }
.copy-btn { position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; background: var(--bg-raised); border: 1px solid var(--border); color: var(--text-faint); opacity: 0; transition: opacity 0.12s, color 0.12s; }
.codeblock:hover .copy-btn, .copy-btn:focus-visible { opacity: 1; }
.copy-btn svg { width: 14px; height: 14px; }
.copy-btn:hover { color: var(--text); }
.copy-btn.done { color: var(--green); opacity: 1; }

/* ---------- motion, when asked for less ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  .spin, .job-spinner, .job-step.running .js-dot { animation: none !important; opacity: 0.8; }
}

/* ---------- phones and narrow windows ---------- */
@supports (height: 100dvh) { #app { height: 100dvh; } }
@media (max-width: 900px) {
  .page { padding: 16px 16px 32px; }
  .topbar { padding: 0 10px; gap: 6px; }
  .topbar .plan-chip, .topbar .claude-status { display: none; }
  /* the usage chip folds into its dial, coloured by the louder plan; the
     panel it opens has both */
  .topbar .plan-chip.usage-chip { display: inline-flex; justify-content: center; width: 34px; height: 34px; padding: 0; border-color: transparent; background: none; border-radius: 8px; }
  .topbar .usage-chip > .ico, .topbar .usage-chip > .ico svg { width: 17px; height: 17px; }
  .topbar .usage-chip .uc-plan { display: none; }
  .topbar .feedback-chip { display: inline-flex; justify-content: center; width: 34px; height: 34px; padding: 0; border-color: transparent; background: none; border-radius: 8px; }
  .topbar .feedback-chip .ico { display: inline-flex; width: 16px; height: 16px; }
  .topbar .feedback-chip .fb-chip-label { display: none; }
  .topbar .feedback-chip { position: relative; }
  .topbar .feedback-chip .dot.new { position: absolute; top: 6px; right: 6px; }
  /* Share keeps its icon (and a count); View only is said by the board's
     banner and the task's note — the bar has no room for it */
  .topbar .share-btn { height: 34px; padding: 0 8px; }
  .topbar .chip.view-only { display: none; }
  .fb-actions button, .fb-reply button { min-height: 40px; }
  .fb-reply textarea { min-height: 40px; }
  /* the title is what a phone has room for */
  .topbar .tb-sep { display: none; }
  .topbar button.icon-btn { width: 34px; height: 34px; }
  /* the ⋯ and its menu */
  .tb-more { position: relative; }
  .tb-more > summary { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 8px; color: var(--text-dim); cursor: pointer; }
  .tb-more > summary:hover, .tb-more[open] > summary { background: var(--bg-hover); color: var(--text); }
  .tb-more > summary svg { width: 18px; height: 18px; }
  .tb-menu { display: none; }
  .tb-more[open] > .tb-menu { display: flex; flex-direction: column; align-items: stretch; gap: 4px; position: absolute; right: 0; top: calc(100% + 6px); min-width: 220px; padding: 6px; background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-lg); z-index: 60; }
  .tb-menu button { min-height: 40px; justify-content: flex-start; text-align: left; }
  .tb-menu #task-actions { display: flex; flex-direction: column; align-items: stretch; gap: 4px; margin: 0 !important; }
  /* a project's tabs drop to a line of their own, scrolled sideways */
  .topbar:has(> .proj-tabs) { flex-wrap: wrap; height: auto; padding-top: 9px; row-gap: 9px; }
  .topbar > .proj-tabs { order: 10; flex-basis: calc(100% + 20px); height: 40px; margin: 0 -10px; padding: 0 16px; gap: 18px; overflow-x: auto; scrollbar-width: none; border-top: 1px solid var(--border); }
  .topbar > .proj-tabs::-webkit-scrollbar { display: none; }
  .proj-tab { flex-shrink: 0; }
  .settings-layout { flex-direction: column; gap: 4px; }
  .settings-nav { flex: none; flex-direction: row; position: static; padding-top: 0; overflow-x: auto; }
  /* the board: one column at a time, a flick to the next */
  .board-wrap { padding: 12px 16px 24px; }
  .board, .board.with-todos { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 6px; }
  .col { flex: 0 0 84vw; scroll-snap-align: start; }
  /* the task and the board: one pane at a time, chosen from the strip */
  .mobile-switch { display: flex; border-bottom: 1px solid var(--border); background: var(--bg); flex-shrink: 0; }
  .mobile-switch button { flex: 1; min-height: 42px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: none; color: var(--text-dim); font-weight: 500; }
  .mobile-switch button.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }
  .page-split { flex-direction: column; }
  .split-left, .split-right { flex: 1 1 auto !important; width: 100%; min-width: 0; min-height: 0; }
  .split-handle, .fold-btn { display: none; }
  .page-split.folded .split-right { display: flex; }
  .page-split[data-pane="left"] .split-right { display: none; }
  .page-split[data-pane="right"] .split-left { display: none; }
  /* The right pane is the whole screen while it shows: the app's bars and
     the strip go, and the pane's own bar — the way back at its left, then
     Preview / Changes — is the one bar left. The game fills the pane edge to
     edge: the phone it runs on IS the device, so no frame, no picker, no
     cutout drawn over it, and the game gets every pixel. */
  body:has(.page-split[data-pane="right"]) .topbar,
  body:has(.page-split[data-pane="right"]) .task-bar,
  body:has(.page-split[data-pane="right"]) .mobile-switch { display: none; }
  .pane-tabs { padding: 0 6px 0 4px; gap: 8px; overflow: hidden; }
  .pane-tabs .pane-back { display: inline-flex; padding: 4px 6px; }
  .pane-tabs .device-controls { display: none; }
  .phone-stage { padding: 0; }
  .phone { width: 100% !important; height: 100% !important; transform: none !important; border: 0; border-radius: 0; box-shadow: none; }
  .phone .cutout, .phone .home-bar { display: none !important; }
  .phone { --frame-top: 0px !important; --frame-right: 0px !important; --frame-bottom: 0px !important; --frame-left: 0px !important; }
  /* The tuner is a sheet over the game's lower part (app.js tunerBelow),
     stacked: its head, its rows, its box. */
  .tuner.below { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; }
  .tuner.below .tuner-head { grid-area: 1 / 1 / 2 / 2; }
  .tuner.below .tuner-list { grid-area: 2 / 1 / 3 / 2; grid-template-columns: minmax(0, 1fr); border-left: 0; border-top: 1px solid var(--border); }
  .tuner.below .tuner-foot { grid-area: 3 / 1 / 4 / 2; border-top: 1px solid var(--border); }
  .transcript { padding: 14px; }
  .ev-user .bubble-wrap, .user-files { max-width: 92%; }
  .composer { padding: 6px 10px calc(10px + env(safe-area-inset-bottom)); }
  .dlg-actions button { min-height: 40px; }
  .composer-tools .attach-btn, #composer-send { width: 38px; height: 38px; }
  /* dialogs are sheets */
  dialog[open]:not(.preview-dialog):not(.palette) { width: 100% !important; max-width: 100% !important; margin: auto 0 0; max-height: 92dvh; border-radius: 16px 16px 0 0; border-bottom: 0; padding: 18px 16px calc(18px + env(safe-area-inset-bottom)); overflow-y: auto; }
  dialog.palette { margin: 8px auto 0; width: calc(100% - 16px); max-width: none; }
  .pal-list { max-height: 60vh; }
  /* wide things scroll on their own */
  .utable { display: block; overflow-x: auto; white-space: nowrap; }
  .wiki-split { flex-direction: column; }
  .wiki-side { position: static; flex: none; width: 100%; max-height: none; flex-direction: row; overflow-x: auto; gap: 4px; }
  .wiki-item.sub { padding-left: 10px; font-size: 12px; }
  .wiki-head, .wiki-page-bar { flex-wrap: wrap; }
  .wiki-split.in-task .wiki-side { max-height: none; }
  /* the thread goes under the page on a phone */
  .wiki-thread { position: static; flex: none; width: 100%; max-height: none; order: 3; }
  .wiki-thread-list { max-height: 50vh; }
  .task-tabs { padding: 0 16px; }
  /* the task's bar: its title and ⋯ on one line, its tabs on the next */
  .task-bar { flex-wrap: wrap; height: auto; padding: 4px 10px 0 16px; row-gap: 0; }
  .task-bar .task-title { flex: 1 1 0; max-width: none; min-height: 38px; line-height: 38px; }
  .task-bar .spacer { display: none; }
  .task-bar #task-tabs-host { order: 10; flex-basis: 100%; height: 36px; margin: 0; padding: 0; border: 0; }
  .wiki-item .chev.open { transform: none; }
  .wiki-doc { padding: 20px 18px; }
  .usage-grid { grid-template-columns: repeat(2, 1fr); }
  .toast-corner { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); align-items: stretch; }
  .toast-corner .toast { max-width: none; }
}

.pub-req-mod { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; white-space: nowrap; }
