/* @layer shell — maude DS studio chrome (Plan B), ported from `.design/ui/Studio.css`.
 *
 * The `.st-*` classes are lifted near-verbatim from the approved Studio.css
 * mockup (every value a maude `var(--*)` token). They live inside the
 * `.maude[data-theme]` root the App renders, so the maude ladder
 * (1-tokens-maude.css) drives them. Grown slice-by-slice:
 *   Task 3 — shell scaffold · menubar · dropdowns · status bar · atoms.
 *   Task 4 — sidebar · tree · rail.            (appended later)
 *   Task 5 — stage · world chrome.             (appended later)
 *   Task 6 — right panel · palette · toast.    (appended later)
 *
 * Per CLAUDE.md "Lift, don't reinvent"; DDR-014 @layer order preserved.
 */

@layer shell {

/* ─── Shell scaffold ───────────────────────────────────────────────────────
 * The real app fills the viewport (NOT an artboard body), so this overrides the
 * mockup's rounded-border `.st-shell` frame: full-bleed flex column, the
 * existing `.app` grid flexes as the middle body row between the bars. */
.maude { position: relative; }
.st-shell {
  width: 100vw; height: 100vh; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--bg-0); color: var(--fg-0);
  font-family: var(--font-body); font-size: var(--type-base); line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
}
/* The legacy grid body (sidebar | main | rsidebar) now flexes between the
 * full-width menubar + status bar instead of owning the whole viewport. */
.st-shell > .app { width: 100%; height: auto; flex: 1 1 auto; min-height: 0; }
.st-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ─── Menubar (top) ───────────────────────────────────────────────────────── */
.st-menubar {
  height: 40px; flex: 0 0 40px;
  display: flex; align-items: center; gap: var(--space-3);
  padding: 0 var(--space-3) 0 var(--space-4);
  background: var(--bg-1); border-bottom: 1px solid var(--border-default);
  position: relative; z-index: 40;
}
.st-brand { display: inline-flex; align-items: center; gap: var(--space-3); padding-right: var(--space-3); }
.st-brand-mark {
  width: 18px; height: 18px;
  /* message-bubble corner — bottom-right squared, the other three rounded */
  border-radius: var(--radius-sm) var(--radius-sm) 0 var(--radius-sm);
  background: var(--accent); display: grid; place-items: center; color: var(--accent-fg);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
/* the spark star fills the bubble (32-grid path, identical to the logo specimen) */
.st-brand-mark svg { width: 100%; height: 100%; display: block; }
.st-brand-name { font-family: var(--font-display); font-weight: 600; font-size: var(--type-md); letter-spacing: var(--tracking-tight); }
.st-menus { display: flex; align-items: center; gap: var(--space-1); }
.st-menu {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-1);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs);
  transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out);
}
.st-menu:hover { background: var(--bg-3); color: var(--fg-0); }
.st-menu[aria-expanded="true"] { background: var(--bg-3); color: var(--fg-0); }
.st-menu[aria-disabled="true"] { color: var(--fg-3); cursor: default; }
/* keyboard ring: the shared `.maude :is(button…):focus-visible` recipe */

.st-mb-right { margin-left: auto; display: flex; align-items: center; gap: var(--space-3); }
.st-stamp {
  font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--accent);
  padding: var(--space-1) var(--space-3); border: 1px solid var(--accent-muted);
  border-radius: var(--radius-pill); background: var(--accent-tint);
}
/* Cloud Phase 25 C2 — the viewer-role stamp. Warning hue so "why is editing
   missing" has a visible, hoverable answer in the chrome. */
.st-stamp--viewonly {
  color: var(--status-warning, var(--accent));
  border-color: color-mix(in oklab, var(--status-warning, var(--accent)) 40%, transparent);
  background: color-mix(in oklab, var(--status-warning, var(--accent)) 12%, transparent);
}
.st-mb-file { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; }
.st-mb-file b { color: var(--fg-0); font-weight: 600; }
.st-mb-sep { width: 1px; height: 16px; background: var(--border-default); }
.st-mb-count { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-1); }
.st-mb-proj { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--status-success); }
.st-reportbug {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 26px; height: 26px; display: grid; place-items: center; border-radius: var(--radius-sm);
  color: var(--fg-1);
}
.st-reportbug:hover { background: var(--bg-3); color: var(--fg-0); }

.st-whatsnew {
  position: relative; appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 26px; height: 26px; display: grid; place-items: center; border-radius: var(--radius-sm);
  color: var(--fg-1);
}
.st-whatsnew:hover { background: var(--bg-3); color: var(--fg-0); }
.st-whatsnew[data-unseen="true"] { color: var(--accent); }
.st-whatsnew[data-unseen="true"]::after {
  content: ""; position: absolute; top: 3px; right: 3px; width: 7px; height: 7px;
  border-radius: var(--radius-pill); background: var(--accent); border: 1.5px solid var(--bg-1);
}

/* feature-background-export-notification-center — menubar Exports button.
   Mirrors .st-whatsnew's attribute-driven state (data-busy instead of
   data-unseen — running/queued exports, not an unread count). */
.st-exports {
  position: relative; appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 26px; height: 26px; display: grid; place-items: center; border-radius: var(--radius-sm);
  color: var(--fg-1); font-size: 13px;
}
.st-exports:hover { background: var(--bg-3); color: var(--fg-0); }
.st-exports[data-busy="true"] { color: var(--accent); }
.st-exports__count {
  position: absolute; top: -2px; right: -2px; min-width: 14px; height: 14px; padding: 0 3px;
  display: grid; place-items: center; border-radius: var(--radius-pill);
  background: var(--accent); color: var(--accent-fg); font-family: var(--font-mono);
  font-size: 9px; font-weight: 700; line-height: 1; border: 1.5px solid var(--bg-1);
}

/* ─── Menubar dropdown ────────────────────────────────────────────────────── */
.st-dropdown {
  position: absolute; top: 38px; min-width: 230px;
  background: var(--bg-2); border: 1px solid var(--border-default);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  /* above the floating st-banner (9100) — an open menu must never sit under
     a transient notice */
  padding: var(--space-2); z-index: 9150;
  animation: st-pop var(--dur-panel) var(--ease-out);
  transform-origin: top left;
}
@keyframes st-pop { from { opacity: 0; transform: translateY(-4px) scale(0.985); } to { opacity: 1; transform: none; } }
.st-dd-hd {
  font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--fg-3); padding: var(--space-2) var(--space-3) var(--space-1);
}
.st-dd-item {
  display: flex; align-items: center; gap: var(--space-3); justify-content: space-between;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs);
  font-size: var(--type-sm); color: var(--fg-1); cursor: pointer;
  appearance: none; border: 0; background: transparent; width: 100%; text-align: left;
  font-family: var(--font-body);
}
.st-dd-item:hover, .st-dd-item.is-hover { background: var(--bg-4); color: var(--fg-0); }
.st-dd-item[aria-disabled="true"] { color: var(--fg-3); cursor: default; }
.st-dd-item[aria-disabled="true"]:hover { background: transparent; color: var(--fg-3); }
.st-dd-item .st-dd-lead { display: inline-flex; align-items: center; gap: var(--space-3); }
.st-dd-check { width: 14px; color: var(--accent); display: inline-flex; }
.st-dd-sep { height: 1px; background: var(--border-subtle); margin: var(--space-2) var(--space-2); }
.st-dd-phase { font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); letter-spacing: var(--tracking-wide); text-transform: uppercase; }

/* ─── Icon button (shared chrome control) ─────────────────────────────────── */
.st-iconbtn {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: var(--radius-sm); color: var(--fg-2);
  transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out);
}
.st-iconbtn:hover { background: var(--bg-3); color: var(--fg-0); }
/* Refresh-files button: spin the reload glyph while the tree re-reads so the
 * action visibly registers even when /_index-data returns instantly. Disabled
 * state stays full-opacity (it's a "busy" beat, not an unavailable control). */
.st-refresh:disabled { cursor: default; opacity: 1; }
.st-refresh.is-spinning svg { animation: st-refresh-spin 0.6s linear infinite; transform-origin: 50% 50%; }
@keyframes st-refresh-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .st-refresh.is-spinning svg { animation: none; }
}

/* ─── Presence avatars (menubar) ──────────────────────────────────────────── */
.st-presence { display: flex; align-items: center; }
/* DS avatar recipe (ui_kits showcase `.sc-avatar`): hue-TINTED surface + hue
 * border + fg-0 text. A solid hue fill with white text broke the accent-fg
 * contrast rule on dark and washed out entirely in light theme. */
.st-avatar {
  --av-hue: var(--accent);
  width: 22px; height: 22px; border-radius: var(--radius-pill);
  display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 10px; line-height: 1;
  letter-spacing: 0.02em; text-transform: uppercase; font-weight: 600;
  background: color-mix(in oklab, var(--av-hue) 22%, var(--bg-3));
  border: 1px solid var(--av-hue);
  color: var(--fg-0);
}
.st-presence .st-avatar { margin-left: -6px; box-shadow: 0 0 0 1.5px var(--bg-1); }
.st-presence .st-avatar:first-child { margin-left: 0; }

/* ─── Status bar (bottom — context) ───────────────────────────────────────── */
.st-statusbar {
  height: 30px; flex: 0 0 30px; display: flex; align-items: center; gap: var(--space-4);
  padding: 0 var(--space-4); background: var(--bg-2);
  border-top: 1px solid var(--border-strong);
  box-shadow: inset 0 1px 0 color-mix(in oklab, var(--fg-0) 6%, transparent);
  font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-1); z-index: 30;
}
.st-sb-slot { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }
.st-sb-slot .lbl { color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tracking-wide); font-size: 10px; flex: none; }
.st-sb-slot .val { color: var(--fg-0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-sb-slot + .st-sb-slot { padding-left: var(--space-4); border-left: 1px solid var(--border-subtle); }
.st-sb-active { font-weight: 500; }
.st-sb-active .lead { width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); flex: none; }
.st-sb-sel .val { color: var(--accent); }
.st-sb-sel-clear { appearance: none; border: 0; background: transparent; color: var(--fg-3); cursor: pointer; font-size: 13px; line-height: 1; padding: 0 2px; }
.st-sb-sel-clear:hover { color: var(--fg-0); }
.st-sb-spacer { flex: 1; }
.st-sb-theme { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; appearance: none; color: var(--fg-0); font-family: var(--font-mono); font-size: var(--type-xs); padding: 3px var(--space-3); border-radius: var(--radius-sm); border: 1px solid var(--border-default); background: var(--bg-3); }
.st-sb-theme:hover { background: var(--bg-4); border-color: var(--border-strong); }
.st-dot { width: 7px; height: 7px; border-radius: var(--radius-pill); display: inline-block; flex: none; }
.st-live-dot { width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--presence-offline); flex: none; }
.st-live-dot.is-connected { background: var(--presence-online); }
.st-sb-sync-dot { width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--status-warn); flex: none; }
.st-sb-sync-dot.is-online { background: var(--presence-online); }
/* feature-sync-progress-modal — the chip doubles as the Sync-panel toggle. */
.st-sb-sync--btn { appearance: none; border: 0; padding: 0; border-radius: 0; background: transparent; font: inherit; cursor: pointer; }
.st-sb-sync--btn:hover .val, .st-sb-sync--btn.is-open .val { color: var(--accent); }
.st-sb-sync--btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Phase 28 — clickable "changes" slot (opens the Changes panel). Button reset; the
   .st-sb-slot + .st-sb-slot rule still supplies the divider + left padding. */
.st-sb-changes { appearance: none; border: 0; padding: 0; border-radius: 0; background: transparent; font: inherit; cursor: pointer; }
.st-sb-changes:hover .val, .st-sb-changes.is-open .val { color: var(--accent); }
.st-sb-changes:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.st-sb-changes-dot { width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--border-strong); flex: none; }
.st-sb-changes.has-changes .st-sb-changes-dot { background: var(--status-warn); }
.st-sb-changes.has-unpushed .st-sb-changes-dot { background: var(--accent); }

/* The running release. Ambient, not a state to act on — so it sits at the same
   weight as a slot label rather than at .val's foreground. No new tokens. */
.st-sb-version .val { color: var(--fg-3); }

/* ═══ Task 4 — body row · sidebar · tree · rail ═══════════════════════════════ */

/* The body flex row replaces the legacy `.app` grid: rail | sidebar | main | rpanel. */
.st-body { flex: 1; display: flex; min-height: 0; min-width: 0; }
.st-body > .main { flex: 1; min-width: 0; }
.st-body > .st-rpanel { flex: 0 0 304px; }

/* ─── Dock slot (feature-configurable-panel-docking) ──────────────────────────
 * A left/right slot: an optional tab strip over the active panel, which fills the
 * remaining height. The wrapper owns the resizable width; the inner panel fills
 * it (width:100% wins over the panel's own inline width, which we no longer set). */
.st-dockslot { display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden; flex: none; }
.st-dockslot.is-collapsed { width: 0 !important; flex-basis: 0 !important; }
.st-dockslot > .st-rpanel,
.st-dockslot > .st-sidebar { flex: 1 1 auto; width: 100%; min-height: 0; }
.st-docktabs { display: flex; gap: 2px; padding: var(--space-2) var(--space-2) 0; border-bottom: 1px solid var(--border-subtle); background: var(--bg-1); flex: none; }
.st-docktab { appearance: none; border: 0; background: transparent; cursor: pointer; padding: var(--space-1) var(--space-3); border-radius: var(--radius-sm) var(--radius-sm) 0 0; color: var(--fg-3); font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); transition: color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
.st-docktab:hover { color: var(--fg-1); background: var(--bg-2); }
.st-docktab.is-active { color: var(--fg-0); background: var(--bg-2); box-shadow: inset 0 -2px 0 var(--accent); }
.st-docktab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ─── Left sidebar — file tree ────────────────────────────────────────────── */
.st-sidebar {
  width: 252px; flex: 0 0 252px;
  background: var(--bg-1); border-right: 1px solid var(--border-default);
  display: flex; flex-direction: column; min-height: 0;
  transition: width var(--dur-panel) var(--ease-in-out), flex-basis var(--dur-panel) var(--ease-in-out);
  overflow: hidden;
}
.st-sidebar.is-collapsed { width: 0; flex-basis: 0; border-right-color: transparent; }
.st-sb-hd {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-subtle);
}
.st-sb-title { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); }
.st-sb-hd-actions { display: flex; align-items: center; gap: var(--space-2); }
.st-live { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); white-space: nowrap; }

.st-search { padding: var(--space-3) var(--space-3) var(--space-2); }
.st-search-box {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); color: var(--fg-3);
}
.st-search-box svg { flex: none; }
.st-search-box input {
  appearance: none; border: 0; background: transparent; color: var(--fg-0);
  font-family: var(--font-body); font-size: var(--type-sm); width: 100%; min-width: 0;
}
.st-search-box input::placeholder { color: var(--fg-3); }
.st-search-box .kbd { margin-left: auto; }
.st-search-clear { appearance: none; border: 0; background: transparent; color: var(--fg-3); cursor: pointer; margin-left: auto; font-size: 14px; line-height: 1; padding: 0 2px; }
.st-search-clear:hover { color: var(--fg-0); }

/* New-board composer (Phase 22) — opens inline below the header on the + click. */
.st-newboard { display: flex; gap: var(--space-2); padding: var(--space-2) var(--space-3); }
.st-newboard input {
  flex: 1; min-width: 0; appearance: none; background: var(--bg-3); border: 1px solid var(--accent-muted);
  border-radius: var(--radius-sm); color: var(--fg-0); font-family: var(--font-body); font-size: var(--type-sm);
  padding: var(--space-2) var(--space-3);
}
.st-newboard-go {
  appearance: none; border: 1px solid var(--accent); background: var(--accent); color: var(--accent-fg);
  border-radius: var(--radius-sm); cursor: pointer; padding: 0 var(--space-3); font-family: var(--font-mono); font-size: var(--type-sm);
}
.st-newboard-go:disabled { opacity: 0.5; cursor: not-allowed; }
.st-newboard-err { padding: var(--space-1) var(--space-4) var(--space-2); color: var(--status-error); font-size: var(--type-xs); }

.st-tree { flex: 1; overflow-y: auto; padding: var(--space-2) var(--space-2) var(--space-4); }
.st-tree-section { margin-bottom: var(--space-2); }
.st-tree-sec-hd {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-3); cursor: pointer; color: var(--fg-2);
  appearance: none; border: 0; background: transparent; text-align: left;
}
.st-tree-sec-hd:hover { color: var(--fg-0); }
/* feature-file-tree-drag-drop-folders (dogfood follow-up) — the section
   header is the drop target for "move back to this group's root". Same
   accent language as .st-row.is-drop-target. */
.st-tree-sec-hd.is-drop-target { background: var(--accent-tint); color: var(--fg-0); box-shadow: inset 2px 0 0 var(--accent); }
.st-tree-sec-hd .st-sec-name { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.st-tree-sec-hd .st-pill {
  margin-left: auto; font-family: var(--font-mono); font-size: 10px; color: var(--fg-3);
  padding: 0 6px; border: 1px solid var(--border-subtle); border-radius: var(--radius-pill);
}
.st-tree-empty { padding: var(--space-2) var(--space-5); color: var(--fg-3); font-size: var(--type-xs); font-style: italic; }

.st-row {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs);
  font-size: var(--type-sm); color: var(--fg-1); cursor: default; position: relative;
  appearance: none; border: 0; background: transparent; text-align: left; font-family: var(--font-body);
}
.st-row:hover { background: var(--bg-2); }
.st-row.is-sel { background: var(--accent-tint); color: var(--fg-0); box-shadow: inset 2px 0 0 var(--accent); }
.st-row.is-muted { color: var(--fg-3); }
.st-row[aria-disabled="true"] { cursor: default; }
/* feature-file-tree-drag-drop-folders (Task 8) — a valid drop target reuses
   the exact .st-row.is-sel treatment (same accent language: "this is where
   it lands"), the dragged source dims, and a busy row (server round-trip
   in flight) dims further + suspends pointer events so it can't be re-dragged
   mid-move. */
.st-row.is-drop-target { background: var(--accent-tint); color: var(--fg-0); box-shadow: inset 2px 0 0 var(--accent); }
.st-row.is-dragging { opacity: 0.45; transition: opacity var(--dur-soft) var(--ease-out); }
.st-row.is-busy { opacity: 0.6; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .st-row.is-dragging { transition-duration: 1ms; } }
.st-row-glyph { width: 14px; display: inline-flex; justify-content: center; color: var(--fg-3); flex: 0 0 14px; }
.st-row.is-sel .st-row-glyph { color: var(--accent); }
.st-row-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.st-row-badge {
  margin-left: auto; font-family: var(--font-mono); font-size: 10px; line-height: 1;
  min-width: 16px; height: 16px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill); background: var(--accent); color: var(--accent-fg); flex: none;
}
/* DDR-174 (T15) — "reconstructed from an image, experimental" marker. Sits left
   of the git/open-count badges (which already claim margin-left:auto), so this
   one gets an explicit left margin instead of fighting for the auto slot.
   `--status-warn` stays on the border only (a UI-component outline needs just
   3:1, which it clears) — a11y-auditor caught it also being used as 9px TEXT
   color failing WCAG AA in light theme (~3.46:1 vs the required 4.5:1); the
   sibling `.st-git-badge[data-kind="M"]` avoids this by using the warn token
   as a fill with a fixed dark foreground instead. Text uses `--fg-2` (the
   DS's own documented AA-clearing muted-text token) so both themes pass. */
.st-row-exp-badge {
  margin-left: 6px; font-family: var(--font-mono); font-size: 9px; font-weight: 700; letter-spacing: 0.02em;
  line-height: 1; padding: 2px 4px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-xs); border: 1px dashed var(--status-warn); color: var(--fg-2); flex: none;
}
/* delete affordance — sibling of the row button (can't nest buttons). */
.st-row-wrap { position: relative; display: flex; align-items: center; }
.st-row-wrap .st-row { flex: 1; }
.st-row-del {
  position: absolute; right: var(--space-2); top: 50%; transform: translateY(-50%);
  appearance: none; border: 0; background: transparent; color: var(--fg-3); cursor: pointer;
  width: 22px; height: 22px; display: grid; place-items: center; border-radius: var(--radius-xs);
  opacity: 0; transition: opacity var(--dur-soft) var(--ease-out);
}
/* Kept in the a11y tree (opacity, not display:none) so keyboard users reach it. */
.st-row-wrap:hover .st-row-del, .st-row-del:focus-visible { opacity: 1; }
/* Shift the open-comments badge AND the M/A/D/U git badge left of the delete
   button on hover/focus so they don't overlap (the delete is absolute at the
   row's right edge). */
.st-row-wrap:hover .st-row-badge,
.st-row-wrap:focus-within .st-row-badge,
.st-row-wrap:hover .st-git-badge,
.st-row-wrap:focus-within .st-git-badge { margin-right: 24px; }
.st-row-del:hover { color: var(--status-error); background: color-mix(in oklab, var(--status-error) 14%, transparent); }
/* feature-file-tree-drag-drop-folders (Task 9) — the keyboard-reachable
   "⋯" trigger (Move to… / New folder here). Same treatment as .st-row-del;
   sits to ITS left when both share a row (a canvas row has delete too). */
.st-row-menu-btn {
  position: absolute; right: var(--space-2); top: 50%; transform: translateY(-50%);
  appearance: none; border: 0; background: transparent; color: var(--fg-3); cursor: pointer;
  width: 22px; height: 22px; display: grid; place-items: center; border-radius: var(--radius-xs);
  opacity: 0; transition: opacity var(--dur-soft) var(--ease-out);
}
.st-row-wrap:hover .st-row-menu-btn, .st-row-menu-btn:focus-visible { opacity: 1; }
.st-row-menu-btn:hover { background: var(--bg-3); color: var(--fg-0); }
.st-row-menu-btn.has-delete-sibling { right: calc(var(--space-2) + 24px); }
@media (prefers-reduced-motion: reduce) { .st-row-menu-btn, .st-row-del { transition-duration: 1ms; } }

/* DS-folder row — chevron toggles disclosure, name opens the system view. */
.st-ds-folder { display: flex; align-items: center; gap: 0; padding: 0; }
.st-ds-folder.is-sel { background: var(--accent-tint); border-radius: var(--radius-xs); box-shadow: inset 2px 0 0 var(--accent); }
.st-ds-chev { appearance: none; border: 0; background: transparent; cursor: pointer; color: var(--fg-3); display: inline-flex; padding: var(--space-2) 0 var(--space-2) var(--space-2); }
.st-ds-open { appearance: none; border: 0; background: transparent; cursor: pointer; color: var(--fg-1); flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-2); text-align: left; padding: var(--space-2) var(--space-3) var(--space-2) 0; font-family: var(--font-body); font-size: var(--type-sm); }
.st-ds-folder.is-sel .st-ds-open { color: var(--fg-0); }

/* collapsed rail — thin strip with a re-open affordance */
.st-rail {
  width: 0; flex: 0 0 0; overflow: hidden; background: var(--bg-1);
  border-right: 1px solid transparent;
  transition: width var(--dur-panel) var(--ease-in-out), flex-basis var(--dur-panel) var(--ease-in-out), border-color var(--dur-panel) var(--ease-in-out);
}
.st-rail.is-shown { width: 44px; flex-basis: 44px; border-right-color: var(--border-default); }
.st-rail-inner { width: 44px; display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: var(--space-3) 0; }

/* ═══ Task 5 — stage (iframe viewport frame) + empty state ════════════════════
 * The canvas iframe (canvas-shell.tsx) renders its OWN dotted world + floating
 * toolbar + minimap + zoom HUD (DDR-054, reskinned to maude in Task 7). The
 * shell stage only frames it; the maude dot-grid shows in the empty/system
 * state behind the iframe. NO shell-side floating chrome — that would duplicate
 * the in-iframe controls. Keeps the legacy `.viewport > iframe` fill rules. */
.st-stage {
  background: var(--canvas-bg);
  background-image: radial-gradient(var(--canvas-dot) 1.1px, transparent 1.2px);
  background-size: var(--canvas-grid) var(--canvas-grid);
}
.st-empty {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--space-4);
  text-align: center; padding: var(--space-8); pointer-events: none;
}
.st-empty code, .st-empty .kbd, .st-empty strong { pointer-events: auto; }
.st-empty-brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.st-empty-wm { font-family: var(--font-display); font-size: var(--type-2xl); font-weight: 600; letter-spacing: var(--tracking-tight); color: var(--fg-0); }
.st-empty-sub { font-size: var(--type-xs); color: var(--fg-3); letter-spacing: var(--tracking-wide); }
.st-empty-title { font-family: var(--font-display); font-size: var(--type-xl); font-weight: 600; color: var(--fg-1); }
.st-empty-body { max-width: 540px; font-size: var(--type-sm); line-height: 1.7; color: var(--fg-2); }
.st-empty-body code { font-family: var(--font-mono); font-size: var(--type-xs); background: var(--bg-2); color: var(--accent); padding: 1px 5px; border-radius: var(--radius-xs); }
.st-empty-body strong { color: var(--fg-0); font-weight: 600; }
/* DDR-166 plan, Phase 2 (T7) — persistent "Setup" affordance, shown only while
   the project's own setup (design system / first canvas / brand assets) is
   incomplete; auto-hides once probeSetupReadiness() reports ready. */
.st-empty-quick-setup { pointer-events: auto; margin-top: var(--space-2); }

/* ═══ feature-studio-file-preview — non-canvas file preview overlay ════════
 * Layered above the (still-mounted) canvas iframe / empty state so switching
 * back to a canvas is instant. Shell-token only, no hardcoded colors. */
.st-file-preview-overlay {
  position: absolute; inset: 0; z-index: 5; display: flex; flex-direction: column;
  background: var(--bg-1); overflow: auto;
}
.st-file-preview-overlay:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.st-file-preview { display: flex; flex-direction: column; min-height: 100%; }
.st-file-preview-header {
  flex: none; margin: 0; padding: var(--space-3) var(--space-4); font-family: var(--font-mono);
  font-size: var(--type-xs); font-weight: 400; color: var(--fg-2); border-bottom: 1px solid var(--border-subtle);
  background: var(--bg-0);
}
.st-file-preview-body { flex: 1; padding: var(--space-6); }
.st-file-preview-status { color: var(--fg-3); font-size: var(--type-sm); }
.st-file-preview-error { color: var(--status-error); }
.st-file-preview-text {
  font-family: var(--font-mono); font-size: var(--type-xs); line-height: 1.6; color: var(--fg-1);
  white-space: pre-wrap; word-break: break-word; background: var(--bg-0);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: var(--space-4);
}
.st-file-preview-markdown { max-width: 720px; color: var(--fg-1); }
.st-file-preview-image-wrap {
  display: flex; align-items: center; justify-content: center; min-height: 200px;
  background-image: linear-gradient(45deg, var(--bg-2) 25%, transparent 25%),
    linear-gradient(-45deg, var(--bg-2) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--bg-2) 75%),
    linear-gradient(-45deg, transparent 75%, var(--bg-2) 75%);
  background-size: 16px 16px; background-position: 0 0, 0 8px, 8px -8px, -8px 0;
  border: 1px solid var(--border-subtle); border-radius: var(--radius-sm);
}
.st-file-preview-image { max-width: 100%; max-height: 70vh; object-fit: contain; }
.st-file-preview-media { max-width: 100%; max-height: 70vh; display: block; }
.st-file-preview-audio { width: 100%; }
.st-file-preview-font { display: flex; flex-direction: column; gap: var(--space-4); }
.st-file-preview-font-specimen { color: var(--fg-0); }
.st-file-preview-font-lg { font-size: 40px; line-height: 1.3; }
.st-file-preview-font-md { font-size: 24px; line-height: 1.4; }
.st-file-preview-font-sm { font-size: 14px; line-height: 1.6; color: var(--fg-2); word-break: break-all; }

/* ═══ Task 6 — right panel (Inspector / Comments) + palette + toast ═══════════ */
.st-rpanel {
  background: var(--bg-1); border-left: 1px solid var(--border-default);
  display: flex; flex-direction: column; min-height: 0;
}
.st-rp-tabs { display: flex; gap: var(--space-1); padding: var(--space-2) var(--space-3) 0; border-bottom: 1px solid var(--border-subtle); flex: none; }
.st-rp-tabs--filters { border-bottom: none; padding-bottom: var(--space-3); }
.st-rp-tab {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font-size: var(--type-sm); color: var(--fg-2); font-family: var(--font-body);
  padding: var(--space-3) var(--space-3); border-bottom: 2px solid transparent;
  display: inline-flex; align-items: center; gap: var(--space-2);
}
.st-rp-tab.is-active { color: var(--fg-0); border-bottom-color: var(--accent); }
.st-rp-tab .st-rp-tabct { font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); }
.st-rp-body { flex: 1; overflow-y: auto; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); }
.st-rp-hd { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); }
/* Stage H (INV-3) edit-scope strip — local (this element) vs shared (edits N places). */
.st-scope { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); font-size: var(--type-xs); border-bottom: 1px solid var(--border-subtle); flex: none; animation: st-pop var(--dur-soft) var(--ease-out); }
/* feature-4 detach-component — inline action on the Shared badge. */
.st-scope-detach { margin-left: auto; padding: 1px 8px; border-radius: var(--radius-xs); font-size: var(--type-xs); background: var(--bg-2); color: var(--fg-1); border: 1px solid var(--border-subtle); cursor: pointer; }
.st-scope-detach:hover { background: var(--bg-3); color: var(--fg-0); }
.st-scope-detach:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.st-scope-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.st-scope--local { color: var(--fg-2); }
.st-scope--local .st-scope-dot { background: var(--fg-3); }
.st-scope--shared { color: var(--accent); }
.st-scope--shared .st-scope-dot { background: var(--accent); }
.st-rp-empty { color: var(--fg-2); font-size: var(--type-sm); line-height: 1.6; display: flex; flex-direction: column; gap: var(--space-4); }

/* comment pin (inline badge in the panel) */
.st-pin--inline {
  position: static; width: 18px; height: 18px; border-radius: 4px;
  background: var(--accent); color: var(--accent-fg); display: grid; place-items: center;
  font-family: var(--font-mono); font-size: var(--type-xs); font-weight: 600; flex: none;
}

/* comments panel */
.st-cm-filters { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.st-cm-filter { appearance: none; border: 1px solid var(--border-default); background: var(--bg-2); cursor: pointer; font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); }
.st-cm-filter.is-active { background: var(--accent-tint); color: var(--accent); border-color: var(--accent-muted); }
.st-cm-group-hd { display: flex; align-items: center; justify-content: space-between; width: 100%; font-size: var(--type-xs); color: var(--fg-2); padding: var(--space-1) 0; appearance: none; border: 0; background: transparent; cursor: pointer; font-family: var(--font-body); }
.st-cm-group-hd:hover { color: var(--fg-0); }
.st-comment { border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: var(--space-3); background: var(--bg-2); display: flex; flex-direction: column; gap: var(--space-2); cursor: pointer; }
.st-comment:hover { border-color: var(--border-default); }
.st-comment.is-active { border-color: var(--accent-muted); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-comment.is-resolved { opacity: 0.6; }
.st-comment-hd { display: flex; align-items: center; gap: var(--space-2); }
.st-comment-time { margin-left: auto; font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); }
.st-comment-txt { font-size: var(--type-sm); color: var(--fg-1); line-height: 1.5; word-break: break-word; }
.st-comment-foot { display: flex; align-items: center; gap: var(--space-2); }
.st-comment-sel { font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); background: var(--bg-3); padding: 1px 5px; border-radius: var(--radius-xs); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
.st-mini-act { margin-left: auto; display: flex; gap: var(--space-1); flex: none; }
.st-mini-act .st-iconbtn { width: 22px; height: 22px; }

/* inspector panel rows */
.st-rp-tabct { font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); }
.st-insp-row { display: grid; grid-template-columns: 56px 1fr; align-items: center; gap: var(--space-3); }
.st-insp-label { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.st-insp-val { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-0); word-break: break-word; }
.st-insp-empty { color: var(--fg-3); font-size: var(--type-sm); line-height: 1.6; }
.st-insp-chips { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.st-insp-chip { font-family: var(--font-mono); font-size: 10px; color: var(--fg-1); background: var(--bg-3); border: 1px solid var(--border-subtle); padding: 1px 5px; border-radius: var(--radius-xs); }

/* ─── Floating status banners (sync / git-lifecycle) ──────────────────────── */
.st-banner {
  /* below the 40px menubar — at top:12px the banner covered the menus + file slot */
  position: fixed; top: 48px; left: 50%; transform: translateX(-50%); z-index: 9100;
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-pill);
  border: 1px solid var(--border-default); background: var(--bg-2); color: var(--fg-0);
  box-shadow: var(--shadow-md); font-family: var(--font-body); font-size: var(--type-sm);
  font-weight: 500; max-width: 80vw; line-height: 1.3;
  animation: st-slide-down var(--dur-route) var(--ease-out);
}
@keyframes st-slide-down { from { opacity: 0; transform: translate(-50%, -6px); } to { opacity: 1; transform: translate(-50%, 0); } }
.st-banner--warn    { border-color: var(--status-warn);    background: color-mix(in oklab, var(--status-warn) 14%, var(--bg-1)); }
.st-banner--error   { border-color: var(--status-error);   background: color-mix(in oklab, var(--status-error) 14%, var(--bg-1)); }
.st-banner--success { border-color: var(--status-success); background: color-mix(in oklab, var(--status-success) 14%, var(--bg-1)); }
.st-banner--info    { border-color: var(--status-info);    background: color-mix(in oklab, var(--status-info) 14%, var(--bg-1)); }
.st-banner-dot { width: 7px; height: 7px; border-radius: var(--radius-pill); flex: none; }
.st-banner--warn .st-banner-dot { background: var(--status-warn); }
.st-banner--error .st-banner-dot { background: var(--status-error); }
.st-banner--success .st-banner-dot { background: var(--status-success); }
.st-banner--info .st-banner-dot { background: var(--status-info); }
.st-banner .btn--sm { margin-left: var(--space-2); }
.st-banner-close { appearance: none; border: 0; background: transparent; color: var(--fg-2); cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px; margin-left: var(--space-1); border-radius: var(--radius-xs); flex: none; }
.st-banner-close:hover { background: color-mix(in oklab, var(--fg-0) 12%, transparent); color: var(--fg-0); }

/* ─── Command palette (⌘K) ───────────────────────────────────────────────── */
.st-scrim { position: fixed; inset: 0; background: color-mix(in oklab, var(--bg-0) 62%, transparent); z-index: 9000; display: grid; place-items: start center; padding-top: 12vh; }
.st-palette {
  width: 560px; max-width: 92vw; background: var(--bg-2); border: 1px solid var(--border-default);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden;
  animation: st-pop var(--dur-route) var(--ease-out);
}
.st-pal-search { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-subtle); color: var(--fg-3); }
.st-pal-search input { flex: 1; min-width: 0; appearance: none; border: 0; background: transparent; color: var(--fg-0); font-size: var(--type-lg); font-family: var(--font-body); }
.st-pal-search input::placeholder { color: var(--fg-3); }
.st-pal-search .kbd { margin-left: auto; }
.st-pal-list { max-height: 340px; overflow-y: auto; padding: var(--space-2); }
.st-pal-group { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-3); padding: var(--space-3) var(--space-3) var(--space-1); }
.st-pal-empty { padding: var(--space-5); text-align: center; color: var(--fg-3); font-size: var(--type-sm); }
.st-pal-item { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-3); border-radius: var(--radius-sm); color: var(--fg-1); appearance: none; border: 0; background: transparent; cursor: pointer; text-align: left; font-family: var(--font-body); font-size: var(--type-sm); }
.st-pal-item.is-active { background: var(--accent-tint); color: var(--fg-0); }
.st-pal-label { flex: 1; }
.st-pal-item .st-pal-kbd { margin-left: auto; flex: none; }
.st-pal-icon { width: 26px; height: 26px; border-radius: var(--radius-sm); background: var(--bg-4); display: grid; place-items: center; color: var(--fg-1); flex: none; }
.st-pal-item.is-active .st-pal-icon { background: var(--accent); color: var(--accent-fg); }

.st-toast-actions { display: flex; gap: var(--space-2); margin-top: var(--space-1); }

/* ─── Export & handoff dialog (Plan C P9/P10) ──────────────────────────────
 * Lifted from Studio.css `.st-dialog*` / `.st-fmt*`. Rendered inside `.st-scrim`. */
.st-dialog { width: 540px; max-width: 92vw; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden; animation: st-pop var(--dur-route) var(--ease-out); }
.st-dialog-hd { display: flex; align-items: center; justify-content: space-between; padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-subtle); }
.st-dialog-title { font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); }
.st-dialog-bd { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }
.st-fmt-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
.st-fmt { display: flex; flex-direction: column; gap: var(--space-2); align-items: flex-start; padding: var(--space-3) var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-2); cursor: pointer; color: var(--fg-1); appearance: none; text-align: left; }
.st-fmt:hover { border-color: var(--border-strong); }
.st-fmt.is-on { border-color: var(--accent); background: var(--accent-tint); color: var(--fg-0); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-fmt:disabled { opacity: 0.45; cursor: not-allowed; }
.st-fmt:disabled:hover { border-color: var(--border-default); }
/* feature-cloud-export-render-workers — the "why is this disabled" line under the format grid. */
.st-dialog-note { margin-top: var(--space-3); font-size: var(--type-xs); line-height: 1.5; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); }
.st-fmt-name { font-family: var(--font-mono); font-size: var(--type-sm); font-weight: 600; }
.st-fmt-sub { font-size: var(--type-xs); color: var(--fg-2); }
.st-dialog-row { display: flex; align-items: center; gap: var(--space-3); }
.st-dialog-lbl { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.st-select { flex: 1; appearance: none; background: var(--bg-2); color: var(--fg-0); border: 1px solid var(--border-default); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); font-family: var(--font-body); font-size: var(--type-sm); cursor: pointer; }
.st-dialog-ft { display: flex; align-items: center; gap: var(--space-3); justify-content: flex-end; padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-subtle); }

/* ── Unified Settings modal (feature-unified-settings-modal) ────────────────
 * One modal for every Maude preference: a vertical tab rail + an internally
 * scrolling pane, so no category can push the dialog off-screen. Extends the
 * shared .st-dialog shell (which already clips + pops). */
.st-dialog.is-settings { width: 760px; }
.st-settings-tabs { display: grid; grid-template-columns: 184px 1fr; min-height: 0; }
.st-settings-rail { display: flex; flex-direction: column; gap: 2px; padding: var(--space-4); border-right: 1px solid var(--border-subtle); background: var(--bg-0); }
.st-settings-tab { appearance: none; border: 0; background: transparent; text-align: left; cursor: pointer; padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); color: var(--fg-2); font-family: var(--font-body); font-size: var(--type-sm); transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
.st-settings-tab:hover { background: var(--bg-3); color: var(--fg-0); }
.st-settings-tab.is-active { background: var(--accent-tint); color: var(--fg-0); font-weight: 600; }
.st-settings-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* The scrolling pane — this is the fix for the AI-generation section overflowing
 * the viewport; the pane scrolls, the page never does. */
.st-settings-pane { max-height: min(72vh, 620px); overflow-y: auto; padding: var(--space-5); }
.st-settings-pane .st-rp-hd { margin-bottom: var(--space-3); }
.st-pref-row { display: flex; align-items: flex-start; gap: var(--space-4); justify-content: space-between; padding: var(--space-3) 0; border-bottom: 1px solid var(--border-subtle); cursor: pointer; }
.st-pref-row:last-child { border-bottom: 0; }
.st-pref-row.is-disabled { cursor: default; opacity: 0.6; }
.st-pref-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.st-pref-label { font-size: var(--type-sm); color: var(--fg-0); font-weight: 500; }
.st-pref-note { font-size: var(--type-xs); color: var(--fg-3); line-height: 1.45; }
/* Switch — styled checkbox; compositor-only transition (transform/background). */
.st-switch { appearance: none; flex: none; position: relative; width: 34px; height: 20px; border-radius: 999px; background: var(--bg-4); border: 1px solid var(--border-default); cursor: pointer; transition: background var(--dur-soft) var(--ease-out); margin-top: 2px; }
.st-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--fg-2); transition: transform var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
.st-switch:checked { background: var(--accent); border-color: var(--accent); }
.st-switch:checked::after { transform: translateX(14px); background: var(--accent-fg); }
.st-switch:disabled { cursor: default; }
.st-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .st-switch, .st-switch::after, .st-settings-tab { transition-duration: 1ms; } }
/* Layout tab — left/right segmented control per panel. */
.st-sidetoggle { display: inline-flex; flex: none; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; }
.st-sidebtn { appearance: none; border: 0; background: var(--bg-2); color: var(--fg-2); cursor: pointer; font-family: var(--font-mono); font-size: var(--type-xs); padding: var(--space-1) var(--space-3); min-width: 46px; transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
.st-sidebtn + .st-sidebtn { border-left: 1px solid var(--border-default); }
.st-sidebtn:hover:not(:disabled) { background: var(--bg-3); color: var(--fg-0); }
.st-sidebtn.is-active { background: var(--accent); color: var(--accent-fg); }
.st-sidebtn:disabled { opacity: 0.5; cursor: default; }
.st-sidebtn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.st-export-recent { display: flex; flex-direction: column; gap: 2px; max-height: 132px; overflow-y: auto; }
.st-export-recent-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); font-size: var(--type-xs); color: var(--fg-2); }
.st-export-recent-row:hover { background: var(--bg-2); }
.st-export-recent-row .st-mono { color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 50%; }

/* ─── AssetPicker (feature-element-editing-robustness Stage F1) ───────────── */
.st-btn { appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; min-height: 28px; border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); color: var(--fg-1); font-family: var(--font-mono); font-size: var(--type-xs); padding: 0 12px; transition: background var(--dur-soft) var(--ease-out), border-color var(--dur-soft) var(--ease-out); }
.st-btn:hover { background: var(--bg-3); border-color: var(--border-strong, var(--border-default)); }
.st-btn:disabled { opacity: 0.55; cursor: default; }
.st-asset-picker { width: 620px; }
.st-ap-toolbar { display: flex; align-items: center; gap: var(--space-3); }
.st-ap-err { color: var(--danger, #e5484d); font-family: var(--font-mono); font-size: var(--type-xs); }
.st-ap-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: var(--space-3); max-height: 52vh; overflow-y: auto; padding: 2px; }
.st-ap-empty { grid-column: 1 / -1; color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); padding: var(--space-6) 0; text-align: center; }
.st-ap-cell { position: relative; appearance: none; cursor: pointer; display: flex; flex-direction: column; gap: 4px; padding: 6px; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); background: var(--bg-2); text-align: left; transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
.st-ap-cell:hover { border-color: var(--accent, var(--border-strong, var(--border-default))); background: var(--bg-3); }
.st-ap-thumb { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-xs); background: var(--bg-4, var(--bg-3)); display: block; }
.st-ap-name { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* feature-bulk-media-insert — multi-select grid state + destination toggle + confirm bar */
.st-ap-cell[data-selected="true"] { border-color: var(--accent); background: var(--bg-3); }
.st-ap-check { position: absolute; top: 6px; right: 6px; width: 18px; height: 18px; border-radius: var(--radius-pill); border: 1px solid var(--border-default); background: var(--bg-1); color: var(--accent-fg, #fff); display: grid; place-items: center; }
.st-ap-cell[data-selected="true"] .st-ap-check { background: var(--accent); border-color: var(--accent); }
.st-ap-confirm { flex-wrap: wrap; }
.st-ap-count { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
.st-ap-seg { display: inline-flex; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-2); }
.st-ap-seg-btn { appearance: none; border: 0; background: transparent; color: var(--fg-2); font-size: var(--type-xs); font-family: var(--font-mono); padding: var(--space-2) var(--space-3); cursor: pointer; }
.st-ap-seg-btn[aria-pressed="true"] { background: var(--bg-4); color: var(--fg-0); }
.st-ap-seg-btn:disabled { opacity: 0.45; cursor: default; }
.st-ap-seg-btn + .st-ap-seg-btn { border-left: 1px solid var(--border-subtle); }
.st-ap-dest-note { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
.st-ap-confirm-spacer { flex: 1; }

/* ─── StickerPicker (feature-whiteboard-annotation-improvements Phase 4) ──── */
.st-sticker-picker { width: 640px; }
.st-sticker-picker .input {
  font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-0);
  background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4); width: 100%;
  transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out);
}
.st-sticker-picker .input::placeholder { color: var(--fg-3); }
.st-sticker-picker .input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-sp-body { max-height: 56vh; overflow-y: auto; padding: 2px; display: flex; flex-direction: column; gap: var(--space-5); }
.st-sp-pack-hd { display: flex; align-items: baseline; gap: var(--space-2); padding: 0 2px; }
.st-sp-pack-name { font-family: var(--font-mono); font-size: var(--type-xs); font-weight: 600; color: var(--fg-1); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.st-sp-pack-author { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-3); }
.st-sp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: var(--space-2); }
.st-sp-cell { appearance: none; cursor: pointer; display: flex; flex-direction: column; align-items: center; padding: 6px; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); background: var(--bg-2); transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
.st-sp-cell:hover { border-color: var(--accent, var(--border-strong, var(--border-default))); background: var(--bg-3); }
.st-sp-thumb { width: 100%; aspect-ratio: 1; object-fit: contain; display: block; }
.st-sp-empty { color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); padding: var(--space-6) 0; text-align: center; }
.st-sp-ft { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding: var(--space-3) var(--space-5); border-top: 1px solid var(--border-subtle); font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); }
.st-sp-ft a { color: var(--fg-2); }
.st-cp-replace { width: 100%; justify-content: center; }
/* Media "Replace…" — a full-width button, NOT inside the 3-col .st-cp-row grid
   (which would drop it into the 10px provenance-dot column and clip it). */
.st-cp-mediabtn { padding: var(--space-1) 0 var(--space-2); }

/* ─── Inspector panel fields / layers / css (Plan C P11–P13) ───────────────
 * Lifted from Studio.css; complements the already-present `.st-insp-row`,
 * `.st-insp-label`, `.st-rp-*`. */
.st-insp-fields { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.st-field { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); color: var(--fg-0); background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: var(--space-1) var(--space-2); width: 58px; text-align: right; }
.st-field-lead { display: inline-flex; align-items: center; gap: var(--space-1); }
.st-field-lead .k { font-family: var(--font-mono); font-size: 9px; color: var(--fg-3); }
/* Phase 12.3 — maude DS coordinate cell (components-inputs `.fld-mini`): a mono
 * axis tag glued to the tabular field, the tag a left segment of one bordered
 * group. focus-within rings the whole cell (border-accent + 3px tint halo). */
.st-fmini { display: inline-flex; align-items: stretch; min-width: 0; flex: 1 1 0; border: 1px solid var(--border-default); border-radius: var(--radius-xs); overflow: hidden; background: var(--bg-3); transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out); }
.st-fmini .st-mtag { flex: none; display: flex; align-items: center; justify-content: center; width: 20px; font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); background: var(--bg-2); border-right: 1px solid var(--border-default); }
.st-fmini input, .st-fmini .st-fminival { flex: 1 1 auto; min-width: 0; width: 100%; box-sizing: border-box; appearance: none; border: 0; border-radius: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); text-align: right; padding: 3px var(--space-2); }
.st-fmini input:focus { outline: none; }
.st-fmini:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-insp-unit { align-self: center; font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); letter-spacing: var(--tracking-wide); }
/* design-critic 1.2 — the Inspect FILL/TEXT chip was collapsing to a thin sliver
 * (read as a text caret) because its container `.st-swatch-row` had no flex rule,
 * so the inline swatch span ignored its width/height. Define the row + make the
 * chip a block so the resolved colour reads as a real swatch. */
.st-swatch-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.st-insp-swatch { display: block; width: 18px; height: 18px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); flex: none; }
.st-layer { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); border-radius: var(--radius-xs); font-size: var(--type-sm); color: var(--fg-1); font-family: var(--font-mono); }
.st-layer:hover { background: var(--bg-2); }
/* maude signature — selection is an accent-tint wash + an inset 2px accent bar,
 * never a solid fill (DS hard rule). */
.st-layer.is-sel { background: var(--accent-tint); color: var(--fg-0); box-shadow: inset 2px 0 0 var(--accent); }
/* Phase 12 Task 4 — browsable layers tree rows */
.st-layer--row { cursor: pointer; padding: 3px var(--space-2); gap: 4px; white-space: nowrap; }
.st-layer--row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.st-layer-caret { flex: none; width: 14px; height: 14px; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--fg-3); font-size: 9px; line-height: 1; cursor: pointer; padding: 0; }
.st-layer-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
.st-layer-type { flex: none; font-size: 9px; color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
/* Phase 12.3 (W3.1) — type icon tint + per-row visibility (eye) toggle. */
.st-layer-ticon { flex: none; color: var(--fg-3); }
.st-layer.is-sel .st-layer-ticon { color: var(--accent); }
.st-layer-eye { flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--fg-3); cursor: pointer; padding: 0; border-radius: var(--radius-xs); opacity: 0; }
.st-layer--row:hover .st-layer-eye, .st-layer--row:focus-within .st-layer-eye { opacity: 1; }
.st-layer-eye:hover { color: var(--fg-0); background: var(--bg-3); }
.st-layer-eye:focus-visible { outline: none; color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
/* feature-4 T7 — synthetic group row (unstamped wrapper): a muted, italic
   structural stand-in. Not selectable, not draggable, no eye — it exists only
   to restore real nesting in the tree. The folder icon reads as "container". */
.st-layer.is-group { cursor: default; color: var(--fg-3); }
.st-layer.is-group .st-layer-label { font-style: italic; }
.st-layer.is-group .st-layer-type { opacity: 0.7; }
.st-layer.is-group:hover { background: var(--bg-2); }
/* feature-4 T7a — component-instance rows (Figma purple). ◆ = the component's
   own frame root, ◇ = an inner member. The purple is deliberately Figma-adjacent
   so the vocabulary transfers. */
.st-layer.is-instance { color: var(--layer-instance, #a78bfa); }
.st-layer.is-instance .st-layer-label { color: var(--layer-instance, #a78bfa); }
.st-layer.is-instance .st-layer-type { color: var(--layer-instance, #a78bfa); opacity: 0.75; }
.st-layer-inst-glyph { flex: none; width: 14px; text-align: center; font-size: 10px; color: var(--layer-instance, #a78bfa); }
.st-layer.is-sel.is-instance { box-shadow: inset 2px 0 0 var(--layer-instance, #a78bfa); }
/* feature-4 T7b — locked rows: padlock stays visible when locked; dimmed label. */
.st-layer-lock { flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--fg-3); cursor: pointer; padding: 0; border-radius: var(--radius-xs); opacity: 0; }
.st-layer--row:hover .st-layer-lock, .st-layer--row:focus-within .st-layer-lock { opacity: 1; }
.st-layer-lock:hover { color: var(--fg-0); background: var(--bg-3); }
.st-layer-lock:focus-visible { outline: none; color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-layer.is-locked .st-layer-lock { opacity: 1; color: var(--fg-1); }
.st-layer.is-locked .st-layer-label { opacity: 0.6; }
/* feature-4 T7c — inline rename input matches the row's mono type. */
.st-layer-rename { flex: 1 1 auto; min-width: 40px; font: inherit; color: var(--fg-0); background: var(--bg-1); border: 1px solid var(--accent); border-radius: var(--radius-xs); padding: 0 4px; outline: none; }
/* a hidden layer stays dim + keeps its eye visible (so it can be re-shown) */
.st-layer.is-hidden { opacity: 0.45; }
.st-layer.is-hidden .st-layer-eye { opacity: 1; color: var(--fg-2); }
/* Phase 12.1 (DDR-138) — drag-to-reorder affordances (same model as the in-canvas
   drag): the dragged row floats with the cursor via an inline transform (its slot
   stays reserved). A fixed blue DIVIDER marks the drop — INDENTED (left offset) to
   the depth it will nest at (dnd-kit-tree / Figma style). */
.st-layer-divider {
  position: fixed;
  z-index: 60;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
  pointer-events: none;
  box-shadow: 0 0 0 1px var(--bg-0);
}
.st-rp-hint { font-family: var(--font-mono); font-size: 10px; color: var(--fg-3); padding: 4px var(--space-2) 6px; letter-spacing: var(--tracking-wide); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.st-css { font-family: var(--font-mono); font-size: var(--type-xs); background: var(--bg-0); border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: var(--space-3); line-height: 1.7; color: var(--fg-1); }
.st-css .comment { color: var(--fg-3); }

/* Phase 12.2 — in-canvas CSS editor knobs. Full-width value fields (NOT the 58px
   read-only inspect fields), grouped sections, color swatch, per-field feedback. */
.st-css-panel { display: flex; flex-direction: column; gap: var(--space-2); }
.st-css-title { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-1); word-break: break-word; }
.st-css-group { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-3); margin-top: var(--space-3); }
.st-css-row { display: grid; grid-template-columns: 72px 1fr; align-items: center; gap: var(--space-2); }
.st-css-label { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
.st-css-control { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.st-css-input { flex: 1 1 auto; min-width: 0; width: 100%; box-sizing: border-box; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); color: var(--fg-0); background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: var(--space-1) var(--space-2); text-align: left; }
.st-css-input::placeholder { color: var(--fg-3); }
.st-css-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-css-swatch { position: relative; flex: none; width: 22px; height: 22px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); padding: 0; cursor: pointer; overflow: hidden; background-image: linear-gradient(45deg, var(--bg-2) 25%, transparent 25%), linear-gradient(-45deg, var(--bg-2) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--bg-2) 75%), linear-gradient(-45deg, transparent 75%, var(--bg-2) 75%); background-size: 8px 8px; background-position: 0 0, 0 4px, 4px -4px, -4px 0; }
.st-css-swatch > span { position: absolute; inset: 0; }
.st-css-swatch input[type="color"] { position: absolute; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px); opacity: 0; cursor: pointer; border: 0; padding: 0; }
.st-css-status { font-family: var(--font-mono); font-size: 10px; min-height: 12px; }
.st-css-status.is-error { color: oklch(0.62 0.2 25); }
.st-css-status.is-saved { color: var(--fg-3); }
.st-css-help { font-size: var(--type-xs); color: var(--fg-3); line-height: 1.5; margin-top: var(--space-2); }
.st-css-help code { font-family: var(--font-mono); color: var(--fg-2); background: var(--bg-3); padding: 0 3px; border-radius: 3px; }
.st-css-disabled { color: var(--fg-2); font-size: var(--type-sm); line-height: 1.6; }
.st-css-disabled code { font-family: var(--font-mono); color: var(--accent); background: var(--bg-2); padding: 1px 5px; border-radius: var(--radius-xs); }


/* Phase 12.2 port — interactive CSS panel knobs (DDR-104). Ported from the
   critic-approved + user-iterated Studio.css spec. Tokens resolve from the
   shell .maude[data-theme] root (1-tokens-maude.css). */
/* ─── CSS panel · Phase 12.2 spec (DDR-104) ──────────────────────────────────
 * Hybrid vocabulary (friendly section headers + CSS-named rows), per-field
 * token dropdowns, nested box-model widget, per-row provenance, two-hatch
 * Advanced section. Scoped `.st-cp-*` (never reuses the cramped `.st-field`).
 * Critic iter-1 fixes: live text off the disabled --fg-3 token → --fg-2 (WCAG
 * AA ≥4.5:1); SHAPE-coded provenance (circle/square/ring, not colour alone);
 * colour swatch lives INSIDE the token field so every control shares one left
 * rail; 24px+ targets (bind / seg / box-model inputs); legible box-model. */
.st-cp { display: flex; flex-direction: column; gap: var(--space-4); }

/* element identity — Phase 12.3 (W2.3) hairline under the header for structure
 * (Figma-ish). DDR-171 critic pass — this is the panel's own top-level
 * boundary (vs. a section's internal divider below), so it gets the stronger
 * of the two border tokens; otherwise the id-row rule and the first section's
 * `.st-cp-sechd` rule read as identical weight stacked ~40px apart. */
.st-cp-id { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-strong); }
.st-cp-idtag { font-family: var(--font-mono); font-size: var(--type-sm); color: var(--fg-0); }
.st-cp-idcls { color: var(--accent); }
/* DDR-171 — the Advanced/Designer vocabulary toggle lives in the `.st-cp-id`
 * row's corner slot as a plain `IconButtonGroup` (`.st-cp-iconseg`, styled
 * below) — no extra wrapper class needed, `.st-cp-id`'s own flex/space-between
 * places it. Deliberately NOT a full-width `Segmented` row (too heavy for a
 * mode switch this minor — every other toggle in this panel is icon-sized).
 * The active glyph gets the stronger accent-tint treatment (normally reserved
 * for `aria-pressed` toggles) rather than the neutral `.is-active` fill every
 * OTHER icon-seg in this panel uses — this one is a mode switch, not a value
 * picker, so "which mode am I in" needs to read at a glance, not just on
 * close inspection. Scoped to `.st-cp-idmode` so it doesn't touch direction /
 * align / overflow etc. */
.st-cp-idmode .st-cp-iconseg button.is-active { background: var(--accent-tint); color: var(--accent); }

/* ── DDR-171 Designer-mode layout refinement ─────────────────────────────────
 * Why Figma's panel reads cleaner than our raw-CSS panel, and what we borrow
 * for Designer mode ONLY (Advanced mode stays byte-identical — it's the
 * DDR-104-critic-gated developer surface where mono labels + provenance dots
 * ARE the point). Three root causes, three scoped fixes:
 *
 *  1. Figma has NO per-row status dot — our provenance dot on every row builds
 *     a "punch-card" rail down the left edge. In Designer mode we hide the dot
 *     for INHERITED/unset rows (the common case) and keep it only where a value
 *     is genuinely token-bound or overridden — that's a useful "this is
 *     customized" marker even for a designer, and rare enough not to form a
 *     rail. The 14px grid column stays reserved so labels never shift.
 *  2. Figma section headers are quiet title-case ("Auto layout"), not code
 *     labels ("AUTO LAYOUT"). We drop the mono/uppercase/tracking for the body
 *     font, sentence case, one step brighter — reads as a group heading, not a
 *     token name.
 *  3. Figma row labels are soft sans, not monospace — we switch the label font
 *     to the body face so the column reads as prose, not a code editor. */
.st-cp--designer .st-cp-prov--inherit { visibility: hidden; }
.st-cp--designer .st-cp-sechd {
  font-family: var(--font-body);
  font-size: var(--type-sm);
  font-weight: 600;
  text-transform: none;
  letter-spacing: normal;
  color: var(--fg-1);
  padding-bottom: var(--space-2);
}
.st-cp--designer .st-cp-sechd:hover, .st-cp--designer .st-cp-sechd:hover svg { color: var(--fg-0); }
.st-cp--designer .st-cp-label { font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-1); }
.st-cp--designer .st-cp-modelabel { font-family: var(--font-body); font-size: var(--type-sm); }
/* a touch more air between clusters — Figma's sections breathe. */
.st-cp--designer .st-cp-sec { gap: var(--space-3); }

/* a Designer cluster's "···" overflow disclosure — same visual weight as the
 * section reset glyph (`.st-cp-secreset`), right-aligned under the cluster's
 * common rows. */
.st-cp-clustermore-row { display: flex; justify-content: flex-end; }
.st-cp-clustermore { appearance: none; cursor: pointer; background: transparent; border: 0; color: var(--fg-3); font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs); }
.st-cp-clustermore:hover { color: var(--accent); background: var(--accent-tint); }
.st-cp-clustermore:focus-visible { outline: none; color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }

/* sections */
.st-cp-sec { display: flex; flex-direction: column; gap: var(--space-2); }
/* section header — collapsible disclosure button */
.st-cp-sechd { width: 100%; appearance: none; cursor: pointer; display: flex; align-items: center; gap: var(--space-2); background: transparent; border: 0; border-bottom: 1px solid var(--border-subtle); text-align: left; font-family: var(--font-mono); font-size: var(--type-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--fg-2); padding: 0 0 var(--space-1); }
.st-cp-sechd svg { color: var(--fg-2); }
.st-cp-sechd:hover, .st-cp-sechd:hover svg { color: var(--fg-0); }
/* Phase 12.3 — section header row carries the shared underline so the toggle
 * button + the per-section reset sit on one baseline. */
.st-cp-sechd-row { display: flex; align-items: stretch; gap: var(--space-1); border-bottom: 1px solid var(--border-subtle); }
.st-cp-sechd-row .st-cp-sechd { border-bottom: 0; flex: 1 1 auto; }
/* reset affordances — a subtle revert glyph (⟲). Muted by default, brightens on
 * hover/focus. The per-row variant lives in .st-cp-ctl / .st-cp-kv; the
 * per-section variant sits at the end of the header row. */
.st-cp-reset, .st-cp-secreset { flex: none; appearance: none; cursor: pointer; background: transparent; border: 0; color: var(--fg-3); font-size: 12px; line-height: 1; padding: 2px; border-radius: var(--radius-xs); }
.st-cp-reset { width: 16px; height: 16px; }
.st-cp-reset:hover, .st-cp-secreset:hover { color: var(--accent); background: var(--accent-tint); }
.st-cp-reset:focus-visible, .st-cp-secreset:focus-visible { outline: none; color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-cp-secreset { align-self: center; display: inline-grid; place-items: center; }
.st-cp-secreset.is-quiet { color: var(--fg-3); opacity: 0.4; cursor: default; }
.st-cp-secreset.is-quiet:hover { color: var(--fg-3); background: transparent; }
/* read-only name field for an existing custom CSS prop / HTML attr row */
.st-cp-fin--ro { flex: 0 0 38%; background: var(--bg-2); color: var(--fg-2); cursor: default; }
.st-cp-fin--ro:focus { outline: none; border-color: var(--border-strong); box-shadow: none; }

/* a labelled row: [provenance] [css property] [control]. DDR-171 critic pass —
 * the dot column widened 10px→14px (was) so the provenance dot reads as a
 * detached status signal instead of looking glued to the label when several
 * rows stack (dot's own size is unchanged — this only adds breathing room,
 * doesn't shrink an already-small interactive/focusable target). */
.st-cp-row { display: grid; grid-template-columns: 14px 92px 1fr; align-items: center; column-gap: var(--space-3); min-height: 32px; padding: 3px 0; }
/* #1 bigger-bet — unset rows recede so the overridden ones pop; full opacity on
 * hover/focus so they're still editable. The panel reads as a diff of overrides. */
.st-cp-row.is-unset { opacity: 0.5; transition: opacity var(--dur-soft) var(--ease-out); }
.st-cp-row.is-unset:hover, .st-cp-row.is-unset:focus-within { opacity: 1; }
/* one-line labels keep the row rhythm uniform; the full property name is in the
 * row's title tooltip (design-critic 4.1 — uneven wrap was the top craft nit). */
.st-cp-label { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-1); line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-cp-ctl { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }

/* provenance — SHAPE-coded so token/override/inherited survive small size +
 * colour-blindness: token = filled accent circle · override = filled neutral
 * square · inherited = hollow ring. Each carries role=img + aria-label. */
.st-cp-prov { width: 9px; height: 9px; display: inline-block; flex: none; padding: 0; }
/* Phase 12.3 (#4) — the row's leading dot is a button: provenance + save status
 * (glow) + double-click reset. No appearance chrome; the variant fills it. */
/* reset native button chrome; the variants own the FILL (a transparent bg here
 * would out-specify them and hollow the dot — that was the bug). */
button.st-cp-prov { appearance: none; border: 0; cursor: default; }
.st-cp-prov.is-resettable { cursor: pointer; }
.st-cp-prov.is-resettable:hover { box-shadow: 0 0 0 3px var(--bg-4); }
.st-cp-prov:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-tint); }
/* save-status glows (replaces the trailing ✓/! markers) */
.st-cp-prov.is-saved { box-shadow: 0 0 0 3px color-mix(in oklab, var(--status-success) 45%, transparent); }
.st-cp-prov.is-saving { box-shadow: 0 0 0 3px color-mix(in oklab, var(--fg-2) 35%, transparent); }
.st-cp-prov.is-err { background: var(--status-error); border-color: var(--status-error); box-shadow: 0 0 0 3px color-mix(in oklab, var(--status-error) 40%, transparent); }
/* handoff — provenance dots match the design specimen (supersedes the older
 * shape-coded/neutral scheme): token-bound = accent · raw override = fg-1 ·
 * inherited = hollow ring. All circles. */
.st-cp-prov--bound { background: var(--accent); border-radius: 50%; }
.st-cp-prov--raw { background: var(--fg-1); border-radius: 50%; }
.st-cp-prov--inherit { background: transparent; box-shadow: inset 0 0 0 1.5px var(--border-strong); border-radius: 50%; }

/* colour swatch — standalone (border cluster) + inline (inside the token field) */
.st-cp-swatch { flex: none; width: 22px; height: 22px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); }
.st-cp-swatch--mini { width: 18px; height: 18px; }
.st-cp-tokswatch { flex: none; width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--border-default); }

/* token field (per-field DS-token dropdown) */
.st-cp-token { flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: var(--space-2); appearance: none; cursor: pointer; font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-0); background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 4px var(--space-2); }
.st-cp-token:hover { border-color: var(--accent); }
.st-cp-tokdot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.st-cp-tokname { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-cp-token svg { flex: none; color: var(--fg-2); }

/* number field: input + steppers + unit-select + bind-to-token */
.st-cp-num { flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: stretch; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); overflow: hidden; min-height: 26px; }
/* #2 — Figma-style property prefix segment inside the numeric field. */
.st-cp-numlead { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 20px; color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); border-right: 1px solid var(--border-subtle); background: var(--bg-2); }
.st-cp-num:focus-within .st-cp-numlead { color: var(--fg-1); }
.st-cp-num:hover { border-color: var(--border-strong); }
.st-cp-num:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-numin { flex: 1 1 auto; min-width: 0; width: 100%; appearance: none; border: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); padding: 3px var(--space-2); }
.st-cp-numin::placeholder { color: var(--fg-2); }
.st-cp-numin:focus { outline: none; }
/* Phase 12.3 (W2.2) — scrub affordance: a number field signals it's draggable
 * (ew-resize), reverts to a text caret when focused for typing. While a scrub is
 * active the whole document holds the resize cursor + suppresses selection. */
.st-cp-scrub { cursor: ew-resize; }
.st-cp-scrub:focus { cursor: text; }
body.st-scrubbing, body.st-scrubbing * { cursor: ew-resize !important; user-select: none !important; }
.st-cp-step { flex: none; display: flex; flex-direction: column; border-left: 1px solid var(--border-subtle); }
.st-cp-stepb { flex: 1; appearance: none; cursor: pointer; border: 0; background: var(--bg-2); color: var(--fg-2); font-size: 7px; line-height: 1; padding: 0 5px; }
.st-cp-stepb:first-child { border-bottom: 1px solid var(--border-subtle); }
.st-cp-stepb:hover { color: var(--accent); }
.st-cp-unit { flex: none; appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 2px; border: 0; border-left: 1px solid var(--border-subtle); background: var(--bg-2); color: var(--fg-2); font-family: var(--font-mono); font-size: 10px; padding: 0 var(--space-2); }
.st-cp-unit svg { color: var(--fg-2); }
.st-cp-bind { flex: none; width: 24px; appearance: none; cursor: pointer; border: 0; border-left: 1px solid var(--border-subtle); background: var(--bg-2); position: relative; }
.st-cp-bind::before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid var(--fg-2); }
.st-cp-bind:hover::before { border-color: var(--accent); }
.st-cp-numin--mini { flex: none; width: 38px; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); }

/* feature-inspector-controls-redesign — shared control library (inspector-controls.jsx).
 * The drag-to-scrub affordance now lives on the LEADING handle, not the input,
 * so click-to-type + select-all work; the input keeps a plain text caret. */
.st-cp-handle { cursor: ew-resize; touch-action: none; }
.st-cp-handle:hover { color: var(--fg-1); background: var(--bg-3); }
.st-cp-grip { display: inline-block; width: 7px; height: 12px; color: var(--fg-2); background-image: radial-gradient(currentColor 0.8px, transparent 0.8px); background-size: 3px 4px; background-position: center; opacity: 0.7; }
.st-cp-handle:hover .st-cp-grip { opacity: 1; }
/* static unit suffix inside a number field (e.g. a SliderField's compact numeric) */
.st-cp-numsuffix { flex: none; display: inline-flex; align-items: center; padding: 0 6px; color: var(--fg-2); font-family: var(--font-mono); font-size: 10px; border-left: 1px solid var(--border-subtle); background: var(--bg-2); }
/* compact numeric — the exact-value box paired with a Slider */
.st-cp-num--compact { flex: 0 0 auto; width: 64px; }
.st-cp-num--compact .st-cp-numin { text-align: right; }
/* SliderField row: real slider (flex) + compact numeric (fixed) */
.st-cp-sfield { flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
/* Toggle (immediate-effect boolean) */
.st-cp-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; cursor: pointer; color: var(--fg-1); }
.st-cp-toggle-lbl { color: var(--fg-1); }
/* handoff — Toggle is a real switch (not a checkbox), matching the DS .switch. */
.st-cp-switch { appearance: none; -webkit-appearance: none; position: relative; flex: none; width: 34px; height: 18px; border-radius: var(--radius-pill); background: var(--bg-4); border: 1px solid var(--border-default); cursor: pointer; transition: background var(--dur-flip) var(--ease-out), border-color var(--dur-flip) var(--ease-out); }
.st-cp-switch::after { content: ""; position: absolute; top: 1px; left: 1px; width: 14px; height: 14px; border-radius: var(--radius-pill); background: var(--fg-1); transition: transform var(--dur-flip) var(--ease-out), background var(--dur-flip) var(--ease-out); }
.st-cp-switch:checked { background: var(--accent); border-color: var(--accent); }
.st-cp-switch:checked::after { transform: translateX(16px); background: var(--accent-fg); }
.st-cp-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* inline help text under a Field control; wrapping a wide row keeps 3 controls fitting */
.st-cp-help { flex-basis: 100%; font-size: 10px; color: var(--fg-2); margin-top: 2px; }
.st-cp-row--wide { flex-wrap: wrap; }

/* ════ feature-inspector-controls-redesign — ported design controls ══════════
 * The design-specimen control set promoted into the shared library
 * (inspector-controls.jsx). lucide icons; `.st-cp-*` to match the shell. */

/* bipolar slider zero-tick */
.st-cp-zero { position: absolute; top: -3px; bottom: -3px; width: 1px; background: var(--border-strong); }
.st-cp-dial--scrub, body.st-scrubbing--dial, body.st-scrubbing--dial * { cursor: grabbing !important; }

/* icon button group (flex-direction / justify / align / text-align / overflow) */
.st-cp-iconseg { display: inline-flex; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-2); }
.st-cp-iconseg button { appearance: none; border: 0; background: transparent; color: var(--fg-2); min-width: 30px; height: 26px; display: grid; place-items: center; cursor: pointer; transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
.st-cp-iconseg button + button { border-left: 1px solid var(--border-subtle); }
.st-cp-iconseg button:hover:not(.is-active) { color: var(--fg-0); background: var(--bg-3); }
.st-cp-iconseg button.is-active { background: var(--bg-4); color: var(--fg-0); }
.st-cp-iconseg button[aria-pressed="true"] { background: var(--accent-tint); color: var(--accent); }

/* DS checkbox */
.st-cp-check { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 11px; color: var(--fg-1); cursor: pointer; }
.st-cp-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.st-cp-check-box { flex: none; width: 15px; height: 15px; border-radius: var(--radius-xs); border: 1px solid var(--border-strong); background: var(--bg-3); display: grid; place-items: center; color: transparent; transition: background var(--dur-soft) var(--ease-out), border-color var(--dur-soft) var(--ease-out); }
.st-cp-check input:checked + .st-cp-check-box { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.st-cp-check input:focus-visible + .st-cp-check-box { box-shadow: 0 0 0 3px var(--accent-tint); }

/* 9-point alignment pad */
.st-cp-alignpad { width: 68px; height: 68px; display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); flex: none; }
.st-cp-alignpad button { appearance: none; border: 0; background: transparent; display: grid; place-items: center; cursor: pointer; }
.st-cp-alignpad button::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--fg-3); transition: background var(--dur-soft) var(--ease-out); }
.st-cp-alignpad button:hover::before { background: var(--fg-1); }
.st-cp-alignpad button.is-active::before { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }

/* angle dial */
.st-cp-dial { flex: none; width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--border-default); background: var(--bg-3); position: relative; cursor: grab; touch-action: none; padding: 0; }
.st-cp-dial:active { cursor: grabbing; }
.st-cp-dial:hover { border-color: var(--border-strong); }
.st-cp-dial:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-dial-needle { position: absolute; top: 50%; left: 50%; width: 11px; height: 1.5px; background: var(--accent); border-radius: 1px; transform-origin: left center; transform: rotate(var(--angle, 0deg)); }
.st-cp-dial::after { content: ""; position: absolute; top: 50%; left: 50%; width: 4px; height: 4px; border-radius: 50%; background: var(--fg-1); transform: translate(-50%, -50%); }

/* collapsable section — height animation + caret rotation (on top of .st-cp-sec) */
.st-cp-sechd[aria-expanded="false"] .st-cp-caret { transform: rotate(-90deg); }
.st-cp-caret { transition: transform var(--dur-flip) var(--ease-out); display: inline-grid; place-items: center; }
.st-cp-sec-anim { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-panel) var(--ease-in-out); }
.st-cp-sec-anim.is-open { grid-template-rows: 1fr; }
.st-cp-sec-inner { overflow: hidden; min-height: 0; }
.st-cp-sec-anim.is-open .st-cp-sec-inner { padding-top: var(--space-1); }

/* compact composite colour field — swatch flush prefix + divider, value [+alpha+eye] */
.st-cp-cf { display: flex; align-items: stretch; min-height: 26px; min-width: 0; flex: 1 1 auto; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out); }
.st-cp-cf:hover { border-color: var(--border-strong); }
/* handoff — accent frame ONLY when editing the value input, not when the swatch
 * (popover trigger) has focus — clicking the swatch left a persistent blue frame. */
.st-cp-cf:has(.st-cp-cf-in:focus) { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-cf .st-cp-tokwrap { display: flex; align-items: stretch; }
.st-cp-cf > *:last-child { border-top-right-radius: 2px; border-bottom-right-radius: 2px; }
.st-cp-cf-sw { flex: none; width: 26px; border: 0; border-right: 1px solid var(--border-default); border-radius: 2px 0 0 2px; padding: 0; cursor: pointer; position: relative; overflow: hidden; }
.st-cp-cf-in { flex: 1 1 auto; min-width: 0; width: 100%; border: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); text-transform: uppercase; padding: 0 var(--space-2); }
.st-cp-cf-in.is-bound { color: var(--accent); text-transform: none; }
.st-cp-cf-in:focus { outline: none; }
.st-cp-cf-alpha { flex: none; width: 42px; border: 0; border-left: 1px solid var(--border-default); background: transparent; color: var(--fg-1); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); text-align: right; padding: 0 6px; }
.st-cp-cf-alpha:focus { outline: none; }
.st-cp-cf-eye { flex: none; width: 26px; border: 0; border-left: 1px solid var(--border-default); background: transparent; color: var(--fg-2); cursor: pointer; display: grid; place-items: center; }
.st-cp-cf-eye:hover { color: var(--fg-0); background: var(--bg-2); }
.st-cp-cf-eye.is-off { color: var(--fg-3); }

/* value-token binding (◇ + bound chip) */
.st-cp-tokfield { display: flex; align-items: center; gap: var(--space-2); flex: 1 1 auto; min-width: 0; }
.st-cp-tokfield > .st-cp-num, .st-cp-tokfield > .st-cp-boundchip { flex: 1 1 auto; min-width: 0; }
.st-cp-tokbtn { flex: none; width: 24px; height: 24px; display: grid; place-items: center; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-2); color: var(--fg-2); cursor: pointer; position: relative; }
.st-cp-tokbtn:hover { border-color: var(--border-strong); color: var(--fg-0); }
.st-cp-tokbtn.is-bound { border-color: var(--accent); color: var(--accent); background: var(--accent-tint); }
.st-cp-boundchip { display: flex; align-items: center; gap: var(--space-2); min-height: 26px; border: 1px solid var(--accent-muted); border-radius: var(--radius-xs); background: var(--accent-tint); padding: 0 var(--space-2); }
.st-cp-boundchip-lead { display: inline-grid; place-items: center; color: var(--accent); }
.st-cp-boundchip-name { flex: 1 1 auto; min-width: 0; font-family: var(--font-mono); font-size: var(--type-xs); color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-cp-boundchip-x { flex: none; appearance: none; border: 0; background: transparent; color: var(--accent); cursor: pointer; display: grid; place-items: center; padding: 0 2px; }
.st-cp-boundchip-x:hover { color: var(--fg-0); }

/* corner-radius control — uniform field + detach quad with per-corner glyphs */
.st-cp-radius { display: grid; gap: var(--space-2); flex: 1 1 auto; min-width: 0; }
.st-cp-radius-main { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.st-cp-radius-main > .st-cp-num { flex: 1 1 auto; min-width: 0; }
.st-cp-splitbtn { flex: none; width: 24px; height: 24px; display: grid; place-items: center; border: 1px solid transparent; border-radius: var(--radius-xs); background: transparent; color: var(--fg-2); cursor: pointer; }
.st-cp-splitbtn:hover { color: var(--fg-0); background: var(--bg-3); }
.st-cp-splitbtn.is-on { color: var(--accent); border-color: var(--accent-muted); background: var(--accent-tint); }
.st-cp-corners { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.st-cp-corner { display: flex; align-items: center; gap: 6px; min-height: 26px; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 0 8px; }
.st-cp-corner:hover { border-color: var(--border-strong); }
.st-cp-corner:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-corner input { flex: 1; min-width: 0; width: 100%; appearance: none; border: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; padding: 0; }
.st-cp-corner input:focus { outline: none; }
.st-cp-cnr { flex: none; width: 11px; height: 11px; border: 1.5px solid var(--fg-2); box-sizing: border-box; }
.st-cp-cnr--tl { border-right: 0; border-bottom: 0; border-top-left-radius: 4px; }
.st-cp-cnr--tr { border-left: 0; border-bottom: 0; border-top-right-radius: 4px; }
.st-cp-cnr--bl { border-right: 0; border-top: 0; border-bottom-left-radius: 4px; }
.st-cp-cnr--br { border-left: 0; border-top: 0; border-bottom-right-radius: 4px; }

/* select (font-weight, border-style) */
.st-cp-select { flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; justify-content: space-between; gap: var(--space-2); appearance: none; cursor: pointer; font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-0); background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 4px var(--space-2); min-height: 26px; }
.st-cp-select span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-cp-select svg { flex: none; color: var(--fg-2); }
.st-cp-select--mini { flex: 0 1 auto; }

/* segmented control (text-align) with drawn align glyphs — 26px tall targets */
.st-cp-seg { display: inline-flex; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); overflow: hidden; }
.st-cp-segbtn { appearance: none; cursor: pointer; border: 0; background: transparent; min-width: 26px; min-height: 26px; padding: 0 7px; display: inline-flex; align-items: center; justify-content: center; border-right: 1px solid var(--border-subtle); }
.st-cp-segbtn:last-child { border-right: 0; }
.st-cp-segbtn.is-active { background: var(--accent-tint); }
.st-cp-segbtn:hover:not(.is-active) { background: var(--bg-4); }
.st-cp-bars { display: flex; flex-direction: column; gap: 2px; width: 13px; color: var(--fg-1); }
.st-cp-segbtn.is-active .st-cp-bars { color: var(--accent); }
.st-cp-bars i { height: 2px; border-radius: 1px; background: currentColor; }
.st-cp-bars--left i:nth-child(1) { width: 100%; }
.st-cp-bars--left i:nth-child(2) { width: 60%; }
.st-cp-bars--left i:nth-child(3) { width: 80%; }
.st-cp-bars--center i { margin: 0 auto; }
.st-cp-bars--center i:nth-child(1) { width: 100%; }
.st-cp-bars--center i:nth-child(2) { width: 55%; }
.st-cp-bars--center i:nth-child(3) { width: 75%; }
.st-cp-bars--right i { margin-left: auto; }
.st-cp-bars--right i:nth-child(1) { width: 100%; }
.st-cp-bars--right i:nth-child(2) { width: 60%; }
.st-cp-bars--right i:nth-child(3) { width: 80%; }
.st-cp-bars--just i { width: 100%; }

/* nested box-model widget (Webflow-style): margin outer · padding inner */
.st-cp-box { position: relative; margin-top: var(--space-2); padding: 34px 30px; border: 1px dashed var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); display: grid; place-items: center; }
.st-cp-boxpad { position: relative; width: 100%; padding: 30px 26px; border: 1px dashed var(--border-subtle); border-radius: var(--radius-xs); background: var(--bg-1); display: grid; place-items: center; }
/* handoff — spacing size core is PLAIN mono text (no box/border), 1:1 with the
 * design's .icp-box-core. Only the position core (--pos, below) is an accent bar. */
.st-cp-boxcore { min-width: 72px; padding: 10px 16px; background: transparent; border: 0; color: var(--fg-2); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 10px; text-align: center; }
.st-cp-boxcore--pos { padding: 7px 12px; border-radius: var(--radius-xs); font-size: 11px; }
.st-cp-boxtag { position: absolute; top: 4px; left: 6px; display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); pointer-events: none; }
.st-cp-boxtag .st-cp-prov { width: 6px; height: 6px; }
.st-cp-boxv { position: absolute; width: 36px; height: 24px; border: 1px solid transparent; border-radius: var(--radius-xs); background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; text-align: center; padding: 0; }
.st-cp-boxv.is-zero { color: var(--fg-2); }
.st-cp-boxv:hover, .st-cp-boxv:focus { border-color: var(--border-strong); background: var(--bg-1); outline: none; color: var(--fg-0); }
.st-cp-boxv--mt, .st-cp-boxv--pt { top: 1px; left: 50%; transform: translateX(-50%); }
.st-cp-boxv--mb, .st-cp-boxv--pb { bottom: 1px; left: 50%; transform: translateX(-50%); }
.st-cp-boxv--ml, .st-cp-boxv--pl { left: 0; top: 50%; transform: translateY(-50%); }
.st-cp-boxv--mr, .st-cp-boxv--pr { right: 0; top: 50%; transform: translateY(-50%); }
/* feature-element-editing-robustness Stage B — Position inset widget. One ring
   (no nested padding box): the 4 inset inputs sit on the outer box edges around
   a centered core showing the current `position` keyword (Figma constraints box). */
.st-cp-boxv--it { top: 1px; left: 50%; transform: translateX(-50%); }
.st-cp-boxv--ib { bottom: 1px; left: 50%; transform: translateX(-50%); }
.st-cp-boxv--il { left: 0; top: 50%; transform: translateY(-50%); }
.st-cp-boxv--ir { right: 0; top: 50%; transform: translateY(-50%); }
.st-cp-boxtag--i { color: var(--accent); }
/* handoff — position core IS an accent bar (design); spacing core is plain text */
.st-cp-boxcore--pos { text-transform: none; letter-spacing: 0; background: var(--accent-tint); border: 1px solid var(--accent); color: var(--accent); }
.st-cp-boxhint { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.st-cp-boxhint + .st-cp-row { margin-top: var(--space-1); }
.st-cp-chip { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 1px 6px; }

/* opacity slider — role=slider, focusable */
.st-cp-slider { flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.st-cp-track { position: relative; flex: 1 1 auto; height: 6px; border-radius: 3px; background: var(--bg-2); border: 1px solid var(--border-default); cursor: pointer; }
.st-cp-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.st-cp-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; background: var(--accent); }
.st-cp-thumb { position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%; background: var(--fg-0); border: 2px solid var(--accent); transform: translate(-50%, -50%); }
.st-cp-slval { flex: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); color: var(--fg-1); width: 34px; text-align: right; }

/* border cluster — fills to the right control rail */
.st-cp-border { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; }
.st-cp-border .st-cp-swatch--mini { margin-left: 0; }
/* design-critic 1.1 — the border row was cramming width+style+swatch; the
 * width field was eating the flex and clipping the style select to "styl▾".
 * Fix the width field, let the style select take the rest. Task 5 (feature-
 * inspector-controls-redesign) — border-width now skips its unit-select
 * (px-only, opts.fixedUnit) so the cluster is narrower to start with;
 * flex-wrap is the fallback so [width][style][swatch] never clips at the
 * panel's 260px minimum — the style select wraps to its own line rather than
 * shrinking to an illegible sliver. */
.st-cp-border .st-cp-num { flex: 0 0 58px; }
.st-cp-border .st-cp-nsel { flex: 1 1 96px; max-width: none; min-width: 64px; }

/* per-field save state */
/* #5 — error-only now (idle/saved status moved into each row's leading dot). */
.st-cp-save { display: inline-flex; align-items: center; gap: var(--space-2); align-self: flex-start; font-size: var(--type-xs); font-family: var(--font-mono); padding: 4px var(--space-2); border-radius: var(--radius-xs); background: color-mix(in oklab, var(--status-error) 14%, var(--bg-2)); border: 1px solid var(--status-error); color: var(--status-error); }
.st-cp-save.is-saved { color: var(--status-success); }
.st-cp-save.is-saved svg { color: var(--status-success); }

/* Advanced — the two-hatch escape (custom CSS property + custom HTML attribute) */
.st-cp-adv { border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-0); overflow: hidden; }
.st-cp-advhd { width: 100%; appearance: none; cursor: pointer; display: flex; align-items: center; gap: var(--space-2); border: 0; background: transparent; color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); padding: var(--space-2) var(--space-3); }
.st-cp-advhd svg { color: var(--fg-2); }
.st-cp-advbody { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 var(--space-3) var(--space-3); }
.st-cp-advgrp { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--fg-2); margin-top: var(--space-1); }
/* #3 — custom prop/attr rows are ONE line: [name] [value] [×]. The reset glyph
 * used to wrap to a second line; a trailing × close button keeps it on one row. */
.st-cp-kv { display: grid; grid-template-columns: 1fr 1fr auto; gap: var(--space-2); align-items: center; }
.st-cp-kvx { flex: none; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; appearance: none; cursor: pointer; background: transparent; border: 0; color: var(--fg-3); padding: 0; border-radius: var(--radius-xs); }
.st-cp-kvx:hover { color: var(--status-error); background: var(--bg-3); }
.st-cp-kvx:focus-visible { outline: none; color: var(--status-error); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-cp-kv .st-cp-numin { background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); }
.st-cp-kv.has-warn .st-cp-numin { border-color: var(--status-warn); }
.st-cp-warn { font-size: 10px; color: var(--status-warn); font-family: var(--font-mono); }
.st-cp-add { align-self: flex-start; appearance: none; cursor: pointer; border: 1px dashed var(--border-default); background: transparent; color: var(--fg-1); font-family: var(--font-mono); font-size: var(--type-xs); border-radius: var(--radius-xs); padding: 4px var(--space-2); }
.st-cp-add:hover { border-color: var(--accent); color: var(--fg-0); }
.st-cp-note { font-size: 10px; color: var(--fg-2); font-style: italic; }

/* Stage M — Fixed / Hug / Fill sizing-mode segmented control (per axis). */
.st-cp-modes { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-1); }
/* handoff — Fixed/Hug/Fill uses the shared Segmented (.st-cp-seg) component,
 * stretched full-width, with a leading W/H axis label. */
.st-cp-modeseg { display: flex; align-items: center; gap: var(--space-2); }
.st-cp-modeax { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); }
/* handoff — Size mode row: grid-aligned with the other rows (label column +
 * control column), the compact Segmented right-aligned to match the number
 * inputs below, at the same 26px input height. Neutral active, mono lowercase. */
.st-cp-moderow { display: grid; grid-template-columns: 14px 92px 1fr; align-items: center; column-gap: var(--space-3); min-height: 32px; padding: 3px 0; }
.st-cp-modelabel { grid-column: 2; font-size: var(--type-xs); color: var(--fg-1); }
.st-cp-modeseg { grid-column: 3; display: flex; justify-content: flex-end; }
.st-cp-modeseg .st-cp-seg { flex: none; display: inline-flex; height: 26px; background: var(--bg-2); border-radius: var(--radius-sm); }
.st-cp-modeseg .st-cp-segbtn { flex: none; display: inline-flex; align-items: center; font-family: var(--font-mono); font-size: var(--type-xs); text-transform: lowercase; color: var(--fg-2); min-width: 0; min-height: 0; padding: 0 var(--space-4); }
.st-cp-modeseg .st-cp-segbtn.is-active { background: var(--bg-4); color: var(--fg-0); }
.st-cp-modeseg .st-cp-segbtn:hover:not(.is-active) { background: var(--bg-3); color: var(--fg-0); }
/* .st-cp-modebtn — still used by the artboard height-sizing control (not CssKnobs). */
.st-cp-modebtn { flex: 1; appearance: none; cursor: pointer; border: 1px solid var(--border-default); border-left-width: 0; background: var(--bg-2); color: var(--fg-2); font-family: var(--font-mono); font-size: 10px; text-transform: lowercase; min-height: 24px; padding: 0 var(--space-2); }
.st-cp-modebtn:first-of-type { border-left-width: 1px; border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.st-cp-modebtn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.st-cp-modebtn:hover:not(.is-active):not(:disabled) { background: var(--bg-3); color: var(--fg-0); }
.st-cp-modebtn.is-active { background: var(--bg-4); color: var(--fg-0); }
.st-cp-modebtn:disabled { opacity: 0.5; cursor: default; }
/* Stage M — sub-header for the flex-child row group + the make-flex CTA. */
.st-cp-subhd { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); text-transform: uppercase; letter-spacing: 0.04em; margin-top: var(--space-2); }
.st-cp-makeflex { align-self: flex-start; appearance: none; cursor: pointer; border: 1px dashed var(--border-default); background: transparent; color: var(--fg-1); font-family: var(--font-mono); font-size: var(--type-xs); border-radius: var(--radius-xs); padding: 4px var(--space-2); }
.st-cp-makeflex:hover:not(:disabled) { border-color: var(--accent); color: var(--fg-0); }
.st-cp-makeflex:disabled { opacity: 0.5; cursor: default; }

/* feature-3-web-artboards T5 — Grid section's track-list editor. */
.st-cp-gridtracks { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-1) 0; }
.st-cp-gridtracks + .st-cp-gridtracks { margin-top: var(--space-2); border-top: 1px solid var(--border-subtle); padding-top: var(--space-2); }
.st-cp-gridtracks-hd { display: flex; align-items: center; justify-content: space-between; }
.st-cp-gridtracks-label { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--fg-2); }
.st-cp-gridtracks-add { min-height: 22px; padding: 0 var(--space-2); font-size: 10px; }
.st-cp-gridtrack-row { display: flex; align-items: center; gap: var(--space-1); }
.st-cp-gridtrack-row .st-cp-nsel { flex: 1 1 auto; }
.st-cp-gridtrack-remove { flex: 0 0 auto; min-height: 22px; min-width: 22px; padding: 0; justify-content: center; color: var(--fg-2); }
.st-cp-gridtrack-remove:hover:not(:disabled) { color: var(--status-error); }

/* provenance legend */
.st-cp-legend { display: flex; flex-wrap: wrap; gap: var(--space-3); padding-top: var(--space-1); border-top: 1px solid var(--border-subtle); }
.st-cp-legend span { display: inline-flex; align-items: center; gap: var(--space-1); font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); }

/* box-model link-all-sides toggle (replaces the cryptic modifier-key chips) */
.st-cp-boxlink { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.st-cp-linkbtn { appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; min-height: 24px; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); color: var(--fg-1); font-family: var(--font-mono); font-size: 10px; padding: 0 8px; }
.st-cp-linkbtn.is-on { border-color: var(--accent); color: var(--fg-0); background: var(--accent-tint); }
.st-cp-linkglyph { width: 13px; height: 9px; border: 1.5px solid currentColor; border-radius: 4px; }
.st-cp-linkhint { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); }

/* per-corner border-radius: split toggle + 4-corner inputs (TL/TR/BL/BR) */
.st-cp-split { flex: none; width: 24px; height: 24px; appearance: none; cursor: pointer; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); position: relative; }
.st-cp-split.is-on { border-color: var(--accent); background: var(--accent-tint); }
.st-cp-split::before { content: ""; position: absolute; inset: 6px; border: 1.5px solid var(--fg-1); border-radius: 3px; }
.st-cp-split.is-on::before { border-color: var(--accent); border-style: dashed; }
.st-cp-corners { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-1); margin: 0 0 var(--space-1) 18px; }
.st-cp-cornerf { display: flex; align-items: center; gap: 6px; min-height: 24px; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); padding: 0 8px; }
.st-cp-cornerf span { font-family: var(--font-mono); font-size: 10px; color: var(--fg-2); }
.st-cp-cornerf input { flex: 1; min-width: 0; width: 100%; appearance: none; border: 0; background: transparent; color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; padding: 0; }
.st-cp-cornerf input:focus { outline: none; }

/* Phase 12.2 PORT-only controls — the live panel uses native <select>/<input>
   for real interactivity + a11y where the Studio.tsx spec used styled buttons. */
/* The port mounts an absolute `inset:0` fill span + a hidden color <input>
   INSIDE the swatch (the spec's swatch was decorative-only, so the ported rule
   has no `position`). Without `relative` the fill anchored to `.maude` and
   painted the element's computed colour across the ENTIRE window (dark element
   → black screen, light → white), and the invisible input swallowed every
   click. The old `.st-css-swatch` had `position:relative` for exactly this. */
.st-cp-swatch { position: relative; overflow: hidden; }
.st-cp-caret { flex: none; color: var(--fg-2); font-size: 9px; width: 9px; text-align: center; }
.st-cp-fin { flex: 1 1 auto; min-width: 0; width: 100%; box-sizing: border-box; appearance: none; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); padding: 4px var(--space-2); min-height: 26px; transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out); }
.st-cp-fin::placeholder { color: var(--fg-2); }
.st-cp-fin:hover { border-color: var(--border-strong); }
/* maude signature focus — border goes accent + a 3px tint halo (DS focus spec). */
.st-cp-fin:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-nsel { flex: 1 1 auto; min-width: 0; box-sizing: border-box; cursor: pointer; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); color: var(--fg-0); font-family: var(--font-body); font-size: var(--type-xs); padding: 3px var(--space-2); min-height: 26px; transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out); }
.st-cp-nsel:hover { border-color: var(--border-strong); }
.st-cp-nsel:focus, .st-cp-nsel:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-nsel--tok { flex: 0 1 auto; max-width: 108px; font-family: var(--font-mono); color: var(--fg-2); background: var(--bg-2); }
.st-cp-nsel--mini { flex: 0 1 auto; max-width: 92px; }
.st-cp-unitsel { flex: none; cursor: pointer; appearance: none; border: 0; border-left: 1px solid var(--border-subtle); background: var(--bg-2); color: var(--fg-2); font-family: var(--font-mono); font-size: 10px; padding: 0 4px; }
/* Phase 12.3 (W2.1) — token picker as a popover. The trigger is a compact
 * variables button (◇ glyph); bound state tints it accent. */
.st-cp-tokbtn { flex: none; width: 24px; height: 26px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; appearance: none; background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-xs); color: var(--fg-2); padding: 0; }
.st-cp-tokbtn:hover { color: var(--fg-0); border-color: var(--border-strong); }
.st-cp-tokbtn:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-cp-tokbtn.is-bound { color: var(--accent); border-color: var(--accent-muted); background: var(--accent-tint); }
/* the glyph — a small rotated square (variable diamond, Figma-ish) */
.st-cp-tokbtn-glyph { width: 8px; height: 8px; border: 1.5px solid currentColor; border-radius: 1px; transform: rotate(45deg); }
.st-cp-tokbtn.is-bound .st-cp-tokbtn-glyph { background: currentColor; }
/* the floating popover (portalled to body, fixed-positioned) */
.st-cp-pop { position: fixed; z-index: 1000; overflow-y: auto; background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-md); box-shadow: var(--shadow-md); padding: var(--space-2); }
.st-cp-pop-empty { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); padding: var(--space-2); }
/* sticky search over the token list */
.st-cp-pop-search { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: var(--space-2); padding: 0 0 var(--space-2); margin: calc(-1 * var(--space-2)) 0 0; background: var(--bg-2); color: var(--fg-2); }
.st-cp-pop-search svg { flex: none; margin-left: var(--space-1); }
.st-cp-pop-search input { flex: 1 1 auto; min-width: 0; appearance: none; background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-xs); color: var(--fg-0); font-family: var(--font-body); font-size: var(--type-xs); padding: 4px var(--space-2); }
.st-cp-pop-search input::placeholder { color: var(--fg-3); }
.st-cp-pop-search input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
/* #4 — colour popover tabs (Custom picker · Variables list) */
.st-cp-poptabs { display: flex; border-bottom: 1px solid var(--border-subtle); margin: calc(-1 * var(--space-2)) calc(-1 * var(--space-2)) var(--space-2); }
.st-cp-poptab { flex: 1; appearance: none; border: 0; background: transparent; cursor: pointer; font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-2); padding: var(--space-3); border-bottom: 2px solid transparent; }
.st-cp-poptab.is-active { color: var(--fg-0); border-bottom-color: var(--accent); }
.st-cp-poptab:hover:not(.is-active) { color: var(--fg-1); }
/* #6 — the unified HSV colour picker (Custom tab): saturation/value square +
 * hue slider + eyedropper + hex field. The swatch on the colour row is the only
 * trigger (no separate native picker). */
.st-cp-cpick { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-1); }
/* handoff — hex row on top + preview circle + RGB fields (design parity) */
.st-cp-cpick-hexrow { display: flex; align-items: center; gap: var(--space-2); }
.st-cp-cpick-hexsw { flex: none; width: 34px; height: 26px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); }
.st-cp-cpick-hex { flex: 1 1 auto; min-width: 0; appearance: none; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); color: var(--fg-0); font-family: var(--font-mono); font-size: var(--type-xs); padding: 4px var(--space-2); }
.st-cp-cpick-hex:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-cpick-preview { flex: none; width: 20px; height: 20px; border-radius: 50%; border: 1px solid var(--border-default); }
.st-cp-cpick-rgb { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
.st-cp-cpick-rgbf { display: grid; gap: 2px; justify-items: center; }
.st-cp-cpick-rgbf input { width: 100%; text-align: center; appearance: none; border: 1px solid var(--border-default); border-radius: var(--radius-xs); background: var(--bg-3); color: var(--fg-0); font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--type-xs); padding: 3px 2px; }
.st-cp-cpick-rgbf input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.st-cp-cpick-rgbf span { font-family: var(--font-mono); font-size: 9px; color: var(--fg-3); }
.st-cp-swatch--trigger { position: relative; overflow: hidden; cursor: pointer; appearance: none; padding: 0; }
.st-cp-swatch--trigger.is-bound { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-cp-cpick-sv { position: relative; display: block; width: 100%; height: 120px; border-radius: var(--radius-sm); border: 1px solid var(--border-default); overflow: hidden; cursor: crosshair; padding: 0; touch-action: none; }
.st-cp-cpick-svwhite { position: absolute; inset: 0; background: linear-gradient(to right, #fff, transparent); }
.st-cp-cpick-svblack { position: absolute; inset: 0; background: linear-gradient(to top, #000, transparent); }
.st-cp-cpick-knob { position: absolute; width: 12px; height: 12px; border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,0.5); transform: translate(-50%, -50%); pointer-events: none; }
.st-cp-cpick-controls { display: flex; align-items: center; gap: var(--space-2); }
.st-cp-cpick-eye { flex: none; width: 26px; height: 16px; display: inline-flex; align-items: center; justify-content: center; appearance: none; cursor: pointer; background: transparent; border: 0; color: var(--fg-2); padding: 0; border-radius: var(--radius-xs); }
.st-cp-cpick-eye:hover { color: var(--fg-0); }
.st-cp-cpick-hue { position: relative; flex: 1 1 auto; height: 12px; border-radius: var(--radius-pill); border: 1px solid var(--border-default); cursor: pointer; padding: 0; touch-action: none; background: linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%); }
.st-cp-cpick-huethumb { position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 1px solid rgba(0,0,0,0.4); box-shadow: 0 1px 3px rgba(0,0,0,0.4); transform: translate(-50%, -50%); pointer-events: none; }
/* W3 — per-design-system grouping. The DS name labels each group when >1 DS. */
.st-cp-pop-group + .st-cp-pop-group { margin-top: var(--space-2); }
.st-cp-pop-ds { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--fg-2); padding: 2px var(--space-1) 4px; position: sticky; top: 30px; background: var(--bg-2); z-index: 1; }
/* color: swatch grid */
.st-cp-pop-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.st-cp-pop-sw { aspect-ratio: 1; min-height: 26px; cursor: pointer; appearance: none; border: 1px solid var(--border-subtle); border-radius: var(--radius-xs); padding: 0; }
.st-cp-pop-sw:hover { border-color: var(--fg-2); transform: scale(1.06); }
.st-cp-pop-sw.is-on { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.st-cp-pop-sw:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
/* value: variable list (name + resolved value) */
.st-cp-pop-list { display: flex; flex-direction: column; gap: 1px; }
.st-cp-pop-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); cursor: pointer; appearance: none; background: transparent; border: 0; border-radius: var(--radius-xs); padding: 5px var(--space-2); text-align: left; }
.st-cp-pop-row:hover { background: var(--bg-3); }
.st-cp-pop-row.is-on { background: var(--accent-tint); }
.st-cp-pop-row:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-tint); }
.st-cp-pop-name { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-0); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* #2 — colour Variables as a list row: [swatch] [name] [value] */
.st-cp-pop-crow { justify-content: flex-start; }
.st-cp-pop-crow .st-cp-pop-name { flex: 1 1 auto; min-width: 0; }
.st-cp-pop-cswatch { flex: none; width: 16px; height: 16px; border-radius: var(--radius-xs); border: 1px solid var(--border-default); }
.st-cp-pop-val { flex: none; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 10px; color: var(--fg-2); }
.st-cp-pop-row.is-on .st-cp-pop-name { color: var(--accent); }
.st-cp-fs { flex: none; width: 14px; text-align: center; font-family: var(--font-mono); font-size: 11px; }
.st-cp-fs.is-saving { color: var(--fg-3); }
.st-cp-fs.is-saved { color: var(--status-success); }
.st-cp-fs.is-err { color: var(--status-warn); cursor: help; }

/* shared focus ring for the panel's interactive controls (incl. native selects) */
.st-cp button:focus-visible, .st-cp input:focus-visible, .st-cp select:focus-visible, .st-cp-token:focus-visible, .st-cp-track:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* ═══ DS-parity polish (specimen sweep) ═══════════════════════════════════════
 * Gaps found auditing the shell against `.design/system/maude/preview/*`:
 * focus-visible coverage, the DS input focus ring, select chevron, unified
 * thin scrollbars, tooltip bubbles. */

/* Catch-all keyboard focus — the DS focus specimen's ONE ring: 2px accent
 * outline at 2px offset wrapped in a 5px --accent-tint halo (`focus.css`
 * .fo-chip). :focus-visible only — mouse clicks never paint it. Inputs are
 * NOT here — they take the DS input recipe (accent border + 3px tint ring). */
.maude :is(button, [role="tab"], select, summary, a):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--accent-tint);
}
/* tight rows inside scrollers — the inset variant so the ring never clips
 * (focus.css .fo-tree .tree-row recipe). */
.maude :is(.st-row, .st-dd-item, .st-pal-item, .st-layer, .st-tree-sec-hd, .st-cm-group-hd):focus-visible {
  outline-offset: -2px;
  box-shadow: inset 0 0 0 5px var(--accent-tint);
}

/* DS input recipe (`_components.css` .input:focus) — accent hairline + 3px tint
 * ring, never the default UA outline. */
.st-search-box:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
  color: var(--fg-2);
}
.st-search-box input:focus { outline: none; }
.st-newboard input:focus,
.st-newboard input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.st-field:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
.st-select:hover { border-color: var(--border-strong); background-color: var(--bg-3); }
.st-select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
}
/* palette search — the container is the field; the inner input stays naked */
.st-pal-search input:focus { outline: none; }
.st-pal-search:focus-within { border-bottom-color: var(--accent-muted); }

/* select chevron — `appearance:none` dropped the UA arrow and left the control
 * affordance-less. Data-URIs can't read tokens, so the stroke is the resolved
 * --fg-1 per theme (dark ≈ #c0c4cf, light ≈ #4f5563). */
.st-select {
  padding-right: 30px;
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23c0c4cf' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3.5 6 8 10.5 12.5 6'/%3E%3C/svg%3E");
}
.maude[data-theme="light"] .st-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%234f5563' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3.5 6 8 10.5 12.5 6'/%3E%3C/svg%3E");
}

/* unified thin scrollbars — one material everywhere (tree, panels, palette,
 * system view, modals). Hairline thumb, transparent track. */
.maude * {
  scrollbar-width: thin;
  scrollbar-color: var(--border-default) transparent;
}
.maude ::-webkit-scrollbar { width: 8px; height: 8px; }
.maude ::-webkit-scrollbar-track { background: transparent; }
.maude ::-webkit-scrollbar-thumb {
  background: var(--border-default);
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
.maude ::-webkit-scrollbar-thumb:hover { background-color: var(--border-strong); }

/* tooltip bubble — DS `components-tooltips` recipe (bg-2 hairline bubble), CSS
 * attr-driven so chrome controls opt in via `data-tip` without a JS layer.
 * 500ms reveal delay ≈ native tooltip timing; reduced-motion shows instantly. */
.maude [data-tip] { position: relative; }
.maude [data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 9200;
  white-space: nowrap;
  padding: var(--space-2) var(--space-3);
  background: var(--bg-2);
  color: var(--fg-0);
  font-family: var(--font-body);
  font-size: var(--type-xs);
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  line-height: 1;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-soft) var(--ease-out);
}
.maude [data-tip]:hover::after,
.maude [data-tip]:focus-visible::after {
  opacity: 1;
  transition-delay: 500ms;
}
/* bottom-bar + right-edge hosts flip/clamp so the bubble stays on screen */
.maude [data-tip][data-tip-pos="top"]::after { top: auto; bottom: calc(100% + 7px); }
.maude [data-tip][data-tip-pos="left"]::after { top: 50%; left: auto; right: calc(100% + 7px); transform: translateY(-50%); }

/* ═══ Behavioral polish (specimen sweep, round 2) ═════════════════════════════ */

/* ─── Panel grip — DS components-resize-panels recipe ──────────────────────
 * 8px hit area; the panel's own border is the at-rest hairline, the grip seam
 * surfaces accent + grip dots on hover/focus/drag. col-resize everywhere
 * while dragging; iframes drop pointer events so they can't eat the stream. */
.st-grip {
  flex: 0 0 8px;
  width: 8px;
  position: relative;
  cursor: col-resize;
  display: grid;
  place-items: center;
  background: transparent;
  /* sit over the adjacent panel borders so the accent seam reads centered */
  margin: 0 -4px;
  z-index: 25;
}
.st-grip::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 1px;
  transform: translateX(-50%);
  background: transparent;
  transition: background var(--dur-flip) var(--ease-out), width var(--dur-flip) var(--ease-out);
}
.st-grip:hover::before,
.st-grip:focus-visible::before,
.st-grip.is-active::before { background: var(--accent); width: 2px; }
.st-grip-dots {
  width: 6px; height: 18px;
  color: var(--accent);
  opacity: 0;
  position: relative;
  transition: opacity var(--dur-flip) var(--ease-out);
}
.st-grip:hover .st-grip-dots,
.st-grip:focus-visible .st-grip-dots,
.st-grip.is-active .st-grip-dots { opacity: 1; }
/* specimen recipe — inset ring on the narrow hit area (the seam + dots already
 * surface accent, this keeps a proper outline for WCAG focus visibility) */
.st-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.st-body.is-resizing { cursor: col-resize; user-select: none; }
.st-body.is-resizing iframe { pointer-events: none; }
.st-sidebar.is-resizing, .st-rpanel.is-resizing { transition: none; }

/* ─── Canvas-compile skeleton — DS skeletons recipe (.skel pulse) ──────────── */
.st-canvas-loading {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  pointer-events: none;
  z-index: 5;
  /* 180ms appearance delay — warm canvases mount in <150ms and never flash it */
  opacity: 0;
  animation: st-loading-in var(--dur-soft) var(--ease-out) 180ms forwards;
}
@keyframes st-loading-in { to { opacity: 1; } }
.st-skel-card {
  width: 300px;
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  animation: st-pop var(--dur-panel) var(--ease-out);
}
.st-skel-cap {
  font-size: var(--type-xs); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--fg-3);
}
.skel {
  display: block;
  background: var(--bg-3);
  border-radius: var(--radius-xs);
  animation: sk-pulse calc(var(--dur-route) * 3) var(--ease-in-out) infinite alternate;
}
@keyframes sk-pulse { from { opacity: 0.45; } to { opacity: 0.95; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; opacity: 0.7; } }
.st-skel-thumb { height: 96px; border-radius: var(--radius-sm); }
.st-skel-line { height: 10px; }

/* ─── Canvas failed to load (issue #115) ──────────────────────────────────────
 * Replaces the blank pane the 15s skeleton cap used to leave behind. Same card
 * geometry as the skeleton so the transition from "compiling" to "it didn't"
 * reads as one surface changing state, not a new thing appearing. Interactive
 * (the skeleton is `pointer-events: none`; this one has a button). */
.st-canvas-error {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  z-index: 6;
  background: var(--canvas-bg);
}
.st-canvas-error-card {
  width: 360px; max-width: calc(100% - var(--space-8));
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  animation: st-pop var(--dur-panel) var(--ease-out);
}
.st-canvas-error-title {
  font-family: var(--font-display); font-size: var(--type-base); font-weight: 600;
  color: var(--fg-0);
}
.st-canvas-error-body { font-size: var(--type-sm); line-height: 1.6; color: var(--fg-2); }
.st-canvas-error-body code {
  font-family: var(--font-mono); font-size: var(--type-xs);
  background: var(--bg-2); color: var(--accent);
  padding: 1px 5px; border-radius: var(--radius-xs);
}
.st-canvas-error-card .btn { align-self: flex-start; }
@media (prefers-reduced-motion: reduce) { .st-canvas-error-card { animation: none; } }

/* ─── Micro-motion — hover/disclosure transitions on the dense surfaces ───── */
.st-row,
.st-comment,
.st-fmt,
.st-cm-filter,
.st-rp-tab,
.st-dd-item,
.st-pal-item,
.st-layer,
.st-export-recent-row {
  transition: background var(--dur-soft) var(--ease-out),
              border-color var(--dur-soft) var(--ease-out),
              color var(--dur-soft) var(--ease-out);
}
/* tree disclosure chevron — one glyph, rotated (animatable) */
.st-chev { transition: transform var(--dur-flip) var(--ease-out); }
.st-chev.is-open { transform: rotate(90deg); }
/* right dock slides in as a panel (DS motion role: panel) */
.st-rpanel { animation: st-panel-in var(--dur-panel) var(--ease-out); }
@keyframes st-panel-in { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }

/* ─── Keyboard-shortcuts overlay — DS components-shortcuts-overlay recipe ──── */
.so-overlay {
  position: relative;
  width: 100%;
  max-width: 720px;
  background: var(--bg-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
  margin-top: -4vh;
  animation: so-enter var(--dur-panel) var(--ease-out) both;
}
@keyframes so-enter {
  0% { opacity: 0; transform: translateY(-6px) scale(0.99); }
  100% { opacity: 1; transform: none; }
}
.so-overlay-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin: 0 0 var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.so-title {
  font-family: var(--font-display);
  font-size: var(--type-lg);
  line-height: var(--lh-lg);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--fg-0);
}
.so-trigger { font-size: var(--type-xs); color: var(--fg-2); }
.so-columns {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6) var(--space-7);
}
.so-section-hd {
  margin: 0 0 var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--type-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--fg-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border-subtle);
}
/* the canvas-tools column reads as the in-canvas scope — accent-muted header */
.so-section--tools .so-section-hd {
  color: var(--accent);
  border-bottom-color: color-mix(in oklab, var(--accent) 40%, var(--border-subtle));
}
.so-list { display: flex; flex-direction: column; gap: var(--space-1); margin: 0; }
.so-pair {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-1) var(--space-1);
  border-radius: var(--radius-xs);
}
.so-pair:hover { background: var(--bg-2); }
.so-pair dt { font-size: var(--type-sm); color: var(--fg-1); }
.so-pair dd { margin: 0; justify-self: end; }
.so-combos { display: inline-flex; align-items: center; gap: var(--space-2); }
.so-combo { display: inline-flex; align-items: center; gap: var(--space-1); }
.so-or { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-3); padding: 0 1px; }
.so-overlay-ft {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--type-xs);
  color: var(--fg-2);
}
@media (max-width: 640px) { .so-columns { grid-template-columns: 1fr; } }

/* ─── Agent presence pulse — DS motion-presence role (scale+opacity ring) ──── */
.st-avatar.is-pulsing::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--av-hue);
  animation: st-presence-ring 1600ms var(--ease-out) infinite;
  pointer-events: none;
}
.st-avatar { position: relative; }
@keyframes st-presence-ring {
  0% { opacity: 0.9; transform: scale(1); }
  70%, 100% { opacity: 0; transform: scale(1.45); }
}
@media (prefers-reduced-motion: reduce) { .st-avatar.is-pulsing::after { animation: none; opacity: 0; } }

/* ── Phase 27 (E2) — GitPanel (Changes / History), mockup-faithful ────────────
 * Ported 1:1 from `.design/ui/GitPanel.css`. The DS treatments the mock LIFTS
 * (.panel/.tabbar/.tab/.textarea/.callout/.check) are folded into the gp-* names
 * so they don't collide with the existing shell classes. Every value a token. */
.gp-panel { display: flex; flex-direction: column; min-height: 0; background: var(--bg-1); }

/* header: title + "N unsaved" pill + close, then the Changes/History tabbar */
.gp-head { flex: none; }
.gp-panel-hd { display: flex; align-items: center; gap: var(--space-2); height: 40px; padding: 0 var(--space-2) 0 var(--space-4); border-bottom: 1px solid var(--border-default); }
.gp-panel-title { font-family: var(--font-display); font-weight: 600; font-size: var(--type-md); color: var(--fg-0); flex: none; }
.gp-count { font-family: var(--font-mono); font-size: var(--type-xs); font-weight: 600; padding: 1px var(--space-2); border-radius: var(--radius-pill); background: var(--accent-tint); color: var(--accent); border: 1px solid var(--accent-muted); white-space: nowrap; flex: none; }
.gp-spacer { flex: 1; min-width: var(--space-2); }
.gp-draft { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); display: inline-flex; align-items: center; gap: var(--space-1); padding: 1px var(--space-2); border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); white-space: nowrap; min-width: 0; flex: 0 1 auto; }
.gp-draft b { color: var(--fg-0); font-weight: 600; overflow: hidden; text-overflow: ellipsis; max-width: 90px; }
.gp-draft .gp-sep { color: var(--fg-3); }
.gp-x { appearance: none; border: none; background: transparent; color: var(--fg-2); font-size: 16px; line-height: 1; cursor: pointer; padding: 2px 5px; border-radius: var(--radius-xs); }
.gp-x:hover { color: var(--fg-1); background: var(--bg-3); }

/* ── Timeline (DDR-148) — BOTTOM-docked transport + per-sequence track ── */
.tl-panel { position: relative; display: flex; flex-direction: column; min-height: 0; width: 100%; background: var(--bg-1); border-top: 1px solid var(--border-default); user-select: none; -webkit-user-select: none; }
/* DDR-150 P4 — drop-media-to-insert affordance */
.tl-panel.is-drop { outline: 2px dashed var(--accent); outline-offset: -3px; background: color-mix(in oklch, var(--accent) 8%, var(--bg-1)); }
/* drag the top edge to resize the panel taller/shorter */
.tl-resize-handle { position: absolute; top: -3px; left: 0; right: 0; height: 8px; cursor: ns-resize; z-index: 6; touch-action: none; }
.tl-resize-handle::after { content: ""; position: absolute; top: 3px; left: 50%; transform: translateX(-50%); width: 44px; height: 3px; border-radius: 2px; background: var(--fg-2); opacity: 0; transition: opacity 0.12s; }
.tl-resize-handle:hover::after { opacity: 0.55; }
.tl-volume { width: 66px; height: 4px; margin: 0 2px 0 4px; accent-color: var(--accent); cursor: pointer; }
.tl-head { display: flex; align-items: center; gap: var(--space-2); height: 40px; padding: 0 var(--space-3) 0 var(--space-3); border-bottom: 1px solid var(--border-subtle); flex: none; }
.tl-title { font-family: var(--font-display); font-weight: 600; font-size: var(--type-md); color: var(--fg-0); }
.tl-spacer { flex: 1; }
.tl-meta { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); white-space: nowrap; }
/* Task 4 — zoom slider in the transport head. */
.tl-zoom { width: 90px; accent-color: var(--accent); }
/* Task 4 — labels stay pinned while the scaled track scrolls horizontally. */
.tl-row-label { position: sticky; left: 0; z-index: 3; background: var(--bg-1); }
/* Task 5 — the three-band storyline layout. */
.tl-band-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.tl-band-tag--story { color: var(--fg-1); font-weight: 600; }
.tl-row--storyline { height: 44px; }
.tl-row--overlay { height: 24px; }
.tl-row--overlay .tl-seq-block { top: 2px; bottom: 2px; }
.tl-storyline-track .tl-seq-block.tl-beat { border-radius: 0; border-right-width: 0; }
.tl-storyline-track .tl-seq-block.tl-beat:first-child { border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); }
/* ⧓ seam chip between storyline beats (read-only until transition edit lands). */
.tl-seam {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--bg-0);
  border: 1px solid var(--accent-muted, var(--accent));
  color: var(--fg-1);
  font-size: 13px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  z-index: 2;
  pointer-events: auto;
  transition: transform var(--dur-1, 120ms) var(--ease-out, ease), border-color var(--dur-1, 120ms) ease;
}
.tl-seam:hover { transform: translateY(-50%) scale(1.12); border-color: var(--accent); color: var(--accent); }
/* WKWebView-safe shell prompt modal (window.prompt is a no-op in Tauri). */
.st-prompt { width: 420px; max-width: 90vw; }
.st-prompt .st-input {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--bg-3);
  background: var(--bg-0);
  color: var(--fg-0);
  font-size: var(--type-sm);
  outline: none;
}
.st-prompt .st-input:focus { border-color: var(--accent); }
/* Task 23 — timeline comment pins (💬 strip above the ruler). */
.tl-comments-strip { position: absolute; top: -2px; left: 0; right: 0; height: 18px; z-index: 5; pointer-events: none; }
.tl-comment-pin {
  position: absolute;
  top: 0;
  width: 16px;
  height: 16px;
  display: grid;
  place-items: center;
  border: none;
  background: none;
  font-size: 11px;
  cursor: pointer;
  pointer-events: auto;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}
.tl-comment-pin.is-resolved { opacity: 0.4; }
.tl-comment-pin.is-detached::after {
  content: '!';
  position: absolute;
  top: -3px;
  right: -3px;
  font-size: 8px;
  color: #ef4444;
  font-weight: 700;
}
.tlci-comment-text { margin: 0; font-size: var(--type-sm); color: var(--fg-0); line-height: 1.5; white-space: pre-wrap; }
/* Task 21 — AI placeholder blocks: dashed accent slate. */
.tl-seq-block[data-kind="placeholder"] {
  border-style: dashed;
  border-color: var(--accent);
  background: color-mix(in oklab, var(--accent) 12%, var(--bg-2));
}
.tl-kind[data-kind="placeholder"] { color: var(--accent); background: color-mix(in oklab, var(--accent) 18%, var(--bg-3)); }
/* Task 17 — "+" affordance on hard-cut seams. Sits ABOVE the lane so it never
   collides with trim handles / replace buttons at block edges. */
.tl-seam-add {
  opacity: 0;
  top: -12px;
  transform: none;
  width: 22px;
  height: 22px;
  cursor: pointer;
  background: var(--bg-1);
  transition: opacity var(--dur-1, 120ms) ease, border-color var(--dur-1, 120ms) ease;
}
.tl-seam-add svg { display: block; }
.tl-storyline-track:hover .tl-seam-add { opacity: 0.85; }
.tl-seam-add:hover { opacity: 1; transform: none; border-color: var(--accent); color: var(--accent); }
/* Inspector text tab */
.tlci-textarea {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--bg-3);
  background: var(--bg-0);
  color: var(--fg-0);
  font-size: var(--type-sm);
  font-family: inherit;
}
.tlci-textarea:focus { outline: none; border-color: var(--accent); }
/* Task 9 — the clip inspector popover (Speed · Audio · Crop · Grade · Transition). */
.tlci {
  position: fixed;
  z-index: 90;
  width: 264px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  font-size: var(--type-sm);
}
/* DS voice (components-inspector-controls / .st-cp-*): mono uppercase micro-
   labels, hairline --border-subtle separations, squared segments over pill
   chips, --accent-tint for the active state (dogfood 2026-07-30, image #30). */
.tlci-head { display: flex; align-items: center; gap: var(--space-2); padding: 7px 10px; cursor: grab; border-bottom: 1px solid var(--border-subtle, var(--bg-3)); }
.tlci-title { font-family: var(--font-mono); font-size: var(--type-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide, 0.08em); color: var(--fg-2); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tlci-x { border: none; background: none; color: var(--fg-2); font-size: 14px; cursor: pointer; padding: 0 4px; }
.tlci-x:hover { color: var(--fg-0); }
.tlci-tabs { display: flex; margin: 8px 10px 0; border: 1px solid var(--border-subtle, var(--bg-3)); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-2); }
.tlci-tab { flex: 1; border: none; border-right: 1px solid var(--border-subtle, var(--bg-3)); background: transparent; color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); text-transform: lowercase; padding: 5px 2px; cursor: pointer; }
.tlci-tab:last-child { border-right: 0; }
.tlci-tab:hover:not(.is-on) { background: var(--bg-4, var(--bg-3)); }
.tlci-tab.is-on { background: var(--accent-tint, var(--bg-3)); color: var(--fg-0); }
.tlci-body { padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.tlci-row { display: flex; align-items: center; gap: 8px; }
.tlci-lbl { width: 76px; flex: none; color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide, 0.08em); }
.tlci-presets { display: flex; flex-wrap: wrap; gap: 4px; }
.tlci-chip { border: 1px solid var(--border-subtle, var(--bg-3)); background: var(--bg-2); color: var(--fg-1); font-family: var(--font-mono); font-size: var(--type-xs); padding: 3px 8px; border-radius: var(--radius-sm); cursor: pointer; }
.tlci-chip:hover:not(.is-on) { background: var(--bg-4, var(--bg-3)); color: var(--fg-0); }
.tlci-chip.is-on { background: var(--accent-tint, var(--bg-3)); border-color: var(--accent); color: var(--fg-0); }
.tlci-btn { border: 1px solid var(--border-subtle, var(--bg-3)); background: var(--bg-2); color: var(--fg-0); font-family: var(--font-mono); font-size: var(--type-xs); padding: 5px 10px; border-radius: var(--radius-sm); cursor: pointer; align-self: flex-start; }
.tlci-btn:hover { border-color: var(--accent); background: var(--bg-4, var(--bg-3)); }
.tlci-note { margin: 0; color: var(--fg-3); font-size: 10px; line-height: 1.5; }
/* Phase 2 — block chips (speed / mute) + the left in-point trim handle. */
.tl-chip { position: relative; z-index: 1; font-family: var(--font-mono); font-size: 9px; padding: 0 4px; border-radius: 3px; background: var(--bg-0); color: var(--fg-1); border: 1px solid var(--bg-3); margin-right: 3px; }
.tl-seq-trim-in {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 7px;
  cursor: ew-resize;
  z-index: 3;
  border-radius: 2px;
}
.tl-seq-trim-in:hover { background: color-mix(in oklab, var(--accent) 50%, transparent); }
/* Task 8 — live trim/move delta tooltip; red at a clamp (source bounds / 1f). */
.tl-trim-tip {
  position: absolute;
  top: -20px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--bg-0);
  border: 1px solid var(--accent-muted, var(--accent));
  color: var(--fg-0);
  font-family: var(--font-mono);
  font-size: 10px;
  white-space: nowrap;
  z-index: 6;
  pointer-events: none;
}
.tl-trim-tip.is-clamped { border-color: #ef4444; color: #ef4444; }
/* Task 7 — filmstrip thumbnails behind the clip label + real waveforms. */
.tl-strip {
  position: absolute;
  inset: 0;
  display: flex;
  overflow: hidden;
  border-radius: inherit;
  opacity: 0.55;
  pointer-events: none;
}
.tl-strip img { flex: 1 1 0; min-width: 0; object-fit: cover; height: 100%; }
.tl-seq-block .tl-kind, .tl-seq-block .tl-seq-name { position: relative; z-index: 1; }
.tl-wave-real { fill: currentColor; stroke: none; opacity: 0.85; }
/* Task 6 — magnetic reorder: siblings glide to their preview slots, the
   dragged beat floats above. */
/* superseded by the tokenised rule below */
.tl-seq-block.is-dragging { z-index: 4; opacity: 0.85; cursor: grabbing; }
/* Task 6 — file-drop insertion caret. */
.tl-drop-caret {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  background: var(--accent);
  border-radius: 1px;
  z-index: 5;
  pointer-events: none;
}
.tl-drop-caret::before {
  content: '';
  position: absolute;
  top: -3px;
  left: -3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}
/* Task 3 — selected clip: the same accent outline vocabulary as canvas
   selection, so "selected" means one thing everywhere. */
.tl-seq-block.is-selected {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  z-index: 2;
}
/* Long-comp badge — comp length beyond the 900-frame safe export tier. */
.tl-long-badge {
  font-family: var(--font-mono);
  font-size: var(--type-xs);
  color: var(--accent);
  border: 1px solid color-mix(in oklab, var(--accent) 45%, transparent);
  border-radius: 4px;
  padding: 0 6px;
  white-space: nowrap;
  cursor: help;
}
.tl-x { appearance: none; border: none; background: transparent; color: var(--fg-2); font-size: 16px; line-height: 1; cursor: pointer; padding: 2px 6px; border-radius: var(--radius-xs); }
.tl-x:hover { color: var(--fg-1); background: var(--bg-3); }
.tl-empty { padding: var(--space-4); color: var(--fg-2); font-size: var(--type-sm); line-height: 1.5; }
.tl-empty code, .tl-empty b { font-family: var(--font-mono); font-size: var(--type-xs); }
.tl-empty code { background: var(--bg-2); padding: 1px 4px; border-radius: var(--radius-xs); color: var(--fg-1); }
.tl-btn { appearance: none; display: grid; place-items: center; width: 28px; height: 28px; border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); color: var(--fg-1); cursor: pointer; transition: background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
.tl-btn:hover { background: var(--bg-3); color: var(--fg-0); }
.tl-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tl-btn.is-on { background: var(--accent-tint); border-color: var(--accent-muted); color: var(--accent); }
.tl-btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.tl-btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-fg); }
/* issue #75 — which artboard's comp this timeline is scoped to (multi-comp only). */
.tl-artboard { margin-left: var(--space-2); padding: 2px 7px; border-radius: 999px; border: 1px solid var(--border-default); background: var(--bg-2); color: var(--fg-1); font-size: var(--type-xs); line-height: 1.4; max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The shell could not resolve the artboard — read as a warning, not as a name. */
.tl-artboard.is-unknown { color: var(--fg-3); border-style: dashed; font-style: italic; }
.tl-readout { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); display: inline-flex; align-items: baseline; gap: 4px; margin-left: var(--space-2); }
.tl-readout b { color: var(--fg-0); font-weight: 600; }
.tl-readout .tl-sep { color: var(--fg-3); }
.tl-readout .tl-time { color: var(--accent); margin-left: var(--space-2); }
/* the scrolling track area */
.tl-scroll { flex: 1; min-height: 0; overflow: auto; padding: var(--space-2) var(--space-3) var(--space-3); }
.tl-tracks { position: relative; min-width: 100%; display: flex; flex-direction: column; gap: 6px; padding-top: 20px; cursor: ew-resize; }
.tl-ruler { position: absolute; top: 0; left: 96px; right: 0; height: 16px; }
.tl-tick { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border-subtle); }
.tl-tick-label { position: absolute; top: -1px; left: 3px; font-family: var(--font-mono); font-size: 9px; color: var(--fg-3); white-space: nowrap; }
.tl-row { display: flex; align-items: center; gap: var(--space-2); height: 30px; }
.tl-row-label { flex: none; width: 88px; display: flex; align-items: center; justify-content: flex-end; gap: 3px; font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); overflow: hidden; white-space: nowrap; text-align: right; }
.tl-row-label-text { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* DDR-150 dogfood #6 — per-row media-kind identity (video / image / audio / JSX). */
.tl-kind { flex: none; width: 14px; height: 14px; display: grid; place-items: center; border-radius: 3px; font-size: 8px; line-height: 1; color: var(--fg-2); background: var(--bg-3); }
.tl-kind[data-kind="video"] { color: #7dd3fc; background: color-mix(in oklch, #0ea5e9 22%, var(--bg-3)); }
.tl-kind[data-kind="image"] { color: #86efac; background: color-mix(in oklch, #22c55e 20%, var(--bg-3)); }
.tl-kind[data-kind="audio"] { color: #fcd34d; background: color-mix(in oklch, #f59e0b 20%, var(--bg-3)); }
.tl-kind[data-kind="jsx"] { color: var(--fg-2); font-style: italic; }
/* DDR-150 dogfood — the right-click clip menu reuses the canvas's shared
   .dc-context-menu component. Its injected CSS reads --maude-chrome-* tokens
   that the CANVAS defines (dark floating chrome) but the SHELL never set — so it
   fell back to white and looked nothing like the canvas menu. Define the same
   dark chrome tokens ON the menu so shell + canvas menus match. */
.dc-context-menu {
  --maude-chrome-bg-0: oklch(0.165 0.012 255);
  --maude-chrome-fg-0: oklch(0.955 0.005 250);
  --maude-chrome-border: oklch(0.290 0.012 255);
  --maude-chrome-shadow: rgba(0, 0, 0, 0.46);
  --maude-chrome-font-mono: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}
/* Clip layer decomposition — expand toggle + indented sub-rows. */
.tl-expand { flex: none; width: 16px; height: 16px; display: grid; place-items: center; padding: 0; border: none; background: transparent; color: var(--fg-1); font-size: 10px; line-height: 1; cursor: pointer; border-radius: 3px; }
.tl-expand:hover:not(.tl-expand--spacer) { color: var(--fg-0); background: var(--accent); }
.tl-expand--spacer { width: 16px; cursor: default; pointer-events: none; }
.tl-row--layer .tl-row-label { color: var(--fg-2); }
.tl-row--layer { opacity: 0.92; }
.tl-layer-indent { flex: none; width: 10px; }
.tl-layer-block { top: 5px; bottom: 5px; opacity: 0.7; border-style: dashed; }
/* Hidden clip — dimmed + hatched so it reads as "won't render" but keeps its slot. */
.tl-seq-block.is-hidden { opacity: 0.4; background-image: repeating-linear-gradient(45deg, transparent, transparent 5px, rgba(0,0,0,0.25) 5px, rgba(0,0,0,0.25) 10px); }
.tl-seq-block.is-hidden .tl-seq-name { text-decoration: line-through; }
/* Kind tint on the block itself — a video clip reads different from JSX motion. */
.tl-seq-block[data-kind="video"] { border-color: color-mix(in oklch, #0ea5e9 55%, var(--accent-muted)); background: color-mix(in oklch, #0ea5e9 16%, var(--bg-2)); }
.tl-seq-block[data-kind="image"] { border-color: color-mix(in oklch, #22c55e 45%, var(--accent-muted)); background: color-mix(in oklch, #22c55e 13%, var(--bg-2)); }
/* DDR-150 P5 — z-order raise/lower. Stacked ▲/▼; later sibling paints on top. */
.tl-seq-reorder { display: inline-flex; flex-direction: column; flex: none; opacity: 0; transition: opacity var(--dur-1, 120ms) ease; }
.tl-row:hover .tl-seq-reorder { opacity: 0.6; }
.tl-seq-reorder:hover, .tl-seq-reorder:focus-within { opacity: 1; }
.tl-reorder-btn { width: 13px; height: 8px; display: grid; place-items: center; padding: 0; border: none; border-radius: 2px; background: transparent; color: var(--fg-2); font-size: 7px; line-height: 1; cursor: pointer; }
.tl-reorder-btn:hover:not(:disabled) { background: var(--accent); color: var(--accent-fg, #fff); }
.tl-reorder-btn:disabled { opacity: 0.25; cursor: default; }
@media (prefers-reduced-motion: reduce) { .tl-seq-reorder { transition: none; } }
.tl-row-track { position: relative; flex: 1; height: 100%; background: var(--bg-2); border-radius: var(--radius-sm); }
.tl-seq-block { position: absolute; top: 3px; bottom: 3px; appearance: none; border: 1px solid var(--accent-muted); border-radius: var(--radius-xs); background: color-mix(in oklch, var(--accent) 20%, var(--bg-2)); color: var(--fg-0); cursor: pointer; overflow: hidden; padding: 0; min-width: 6px; transition: background var(--dur-soft) var(--ease-out); }
.tl-seq-block:hover { background: color-mix(in oklch, var(--accent) 32%, var(--bg-2)); }
.tl-seq-block:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tl-seq-name { position: absolute; left: 6px; top: 50%; transform: translateY(-50%); font-family: var(--font-mono); font-size: 10px; font-weight: 600; color: var(--fg-0); pointer-events: none; white-space: nowrap; }
.tl-seq-block.is-resizing { background: color-mix(in oklch, var(--accent) 42%, var(--bg-2)); border-color: var(--accent); }
/* drag-to-retime handle at the block's right edge */
.tl-seq-resize { position: absolute; top: 3px; bottom: 3px; width: 10px; z-index: 4; cursor: ew-resize; border-radius: 2px; touch-action: none; }
.tl-seq-resize::after { content: ""; position: absolute; top: 20%; bottom: 20%; left: 4px; width: 2px; border-radius: 1px; background: var(--fg-2); opacity: 0; }
.tl-seq-resize:hover::after { opacity: 0.9; background: var(--accent); }
/* DDR-150 P3 — per-clip remove (×). Subtle until the row is hovered. */
.tl-seq-remove { position: absolute; top: 3px; width: 15px; height: 15px; z-index: 5; display: grid; place-items: center; padding: 0; border: none; border-radius: var(--radius-xs); background: color-mix(in oklch, var(--bg-0) 70%, transparent); color: var(--fg-1); font-size: 13px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity var(--dur-1, 120ms) ease; }
.tl-row:hover .tl-seq-remove { opacity: 0.7; }
.tl-seq-remove:hover { opacity: 1; background: var(--status-err, #dc2626); color: #fff; }
.tl-seq-block.is-moving { cursor: grabbing; box-shadow: 0 0 0 1px var(--accent); }
/* DDR-150 P3 — per-clip replace-media (⇄). */
.tl-seq-replace { position: absolute; top: 3px; width: 15px; height: 15px; z-index: 5; display: grid; place-items: center; padding: 0; border: none; border-radius: var(--radius-xs); background: color-mix(in oklch, var(--bg-0) 70%, transparent); color: var(--fg-1); font-size: 11px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity var(--dur-1, 120ms) ease; }
.tl-row:hover .tl-seq-replace { opacity: 0.7; }
.tl-seq-replace:hover { opacity: 1; background: var(--accent); color: var(--accent-fg, #fff); }
/* DDR-150 P5 Task 14 — keyframe markers are click-to-seek */
.tl-kf { position: absolute; top: 3px; bottom: 3px; min-width: 3px; border-radius: 2px; background: var(--accent); opacity: 0.85; pointer-events: auto; cursor: pointer; }
.tl-kf:hover { opacity: 1; box-shadow: 0 0 0 1px var(--fg-0); }
/* audio / music bed row — a distinct teal so it reads as a separate layer */
.tl-audio-block { position: absolute; top: 3px; bottom: 3px; border: 1px solid color-mix(in oklch, var(--status-ok, #16a34a) 60%, transparent); border-radius: var(--radius-xs); background: color-mix(in oklch, var(--status-ok, #16a34a) 18%, var(--bg-2)); overflow: hidden; min-width: 6px; }
.tl-audio-block .tl-seq-name { color: var(--fg-0); opacity: 0.9; }
.tl-wave { position: absolute; inset: 3px 6px; width: calc(100% - 12px); height: calc(100% - 6px); fill: none; stroke: color-mix(in oklch, var(--status-ok, #16a34a) 80%, var(--fg-2)); stroke-width: 1; opacity: 0.55; pointer-events: none; }
.tl-playhead { position: absolute; top: 16px; bottom: 0; width: 2px; background: var(--fg-0); box-shadow: 0 0 0 1px var(--bg-1); pointer-events: none; z-index: 3; }
.tl-playhead::before { content: ""; position: absolute; top: -4px; left: -4px; border: 5px solid transparent; border-top-color: var(--fg-0); }
@media (prefers-reduced-motion: reduce) { .tl-btn, .tl-seq-block { transition: none; } }
/* tabbar/tab — DS treatment folded in */
.gp-tabs { display: flex; gap: var(--space-1); padding: var(--space-2) var(--space-3) 0; border-bottom: 1px solid var(--border-subtle); }
.gp-tab { appearance: none; border: 0; background: transparent; font-size: var(--type-sm); color: var(--fg-2); font-family: var(--font-body); padding: var(--space-3) var(--space-4); cursor: pointer; border-bottom: 2px solid transparent; }
.gp-tab:hover { color: var(--fg-1); }
.gp-tab.is-active { color: var(--fg-0); border-bottom-color: var(--accent); }

/* the changed-file list */
.gp-list { flex: 1; overflow-y: auto; padding: var(--space-2) 0; min-height: 0; }
.gp-group-hd { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4) var(--space-2); font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); }
.gp-group-count { color: var(--fg-2); }
.gp-file { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4); border-radius: var(--radius-sm); margin: 0 var(--space-2); }
.gp-file:hover { background: var(--bg-2); }
.gp-file.is-checked { background: color-mix(in oklab, var(--accent-tint) 60%, transparent); }
.gp-check { flex: 0 0 auto; width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.gp-file-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; cursor: pointer; appearance: none; background: none; border: none; padding: 0; text-align: left; }
.gp-file-name { color: var(--fg-0); font-size: var(--type-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gp-file-path { color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gp-file.is-checked .gp-file-path { color: var(--fg-1); }
.gp-file-text:hover .gp-file-name { color: var(--accent); }
.gp-discard { flex: 0 0 auto; opacity: 0; color: var(--fg-2); background: none; border: none; padding: var(--space-1); border-radius: var(--radius-xs); cursor: pointer; transition: opacity var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
.gp-file:hover .gp-discard, .gp-file:focus-within .gp-discard { opacity: 1; }
.gp-discard:hover { color: var(--status-error); background: var(--bg-3); }
.gp-discard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-xs); opacity: 1; }

/* DDR-115 follow-up — canvas-grouped changes: a canvas + its collapsed
   supporting files (Layout & settings, Annotations) as one logical unit. */
.gp-unit { display: flex; flex-direction: column; }
.gp-unit-hd .gp-file-name { font-weight: 500; }
.gp-disclose { flex: 0 0 auto; display: grid; place-items: center; color: var(--fg-2); background: none; border: none; padding: var(--space-1); border-radius: var(--radius-xs); cursor: pointer; transition: transform var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out); }
.gp-disclose.is-open { transform: rotate(90deg); }
.gp-disclose:hover { color: var(--fg-0); }
.gp-disclose:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gp-support { margin: 0 var(--space-2) var(--space-1) var(--space-6); border-left: 1px solid var(--border-default); padding-left: var(--space-2); }
.gp-support-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-1) var(--space-2); min-width: 0; }
.gp-support-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.gp-support-row .gp-file-name { color: var(--fg-1); font-size: var(--type-sm); }

/* M / A / D / U dirty badge — solid for M/A/D, dashed outline for U (untracked) */
.gp-badge { flex: 0 0 auto; width: 16px; height: 16px; border-radius: var(--radius-xs); display: grid; place-items: center; font-family: var(--font-mono); font-size: 10px; font-weight: 600; line-height: 1; color: oklch(0.11 0.012 260); }
.gp-badge[data-kind="M"] { background: var(--status-warn); }
.gp-badge[data-kind="A"] { background: var(--status-success); }
.gp-badge[data-kind="D"] { background: var(--status-error); }
.gp-badge[data-kind="U"] { background: transparent; border: 1px dashed var(--border-strong); color: var(--fg-2); }

/* composer footer: select-all · message · Save version / Save all · hint */
.gp-compose { flex: none; border-top: 1px solid var(--border-default); padding: var(--space-3) var(--space-4) var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); background: var(--bg-1); }
.gp-selectall { display: inline-flex; align-items: center; gap: var(--space-2); align-self: flex-start; appearance: none; background: none; border: none; padding: 0; font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-1); cursor: pointer; }
.gp-msg { font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-0); background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4); width: 100%; resize: none; min-height: 64px; transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out); }
.gp-msg::placeholder { color: var(--fg-2); }
.gp-msg:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
.gp-compose-actions { display: flex; align-items: center; gap: var(--space-3); }
.gp-save { flex: 1; justify-content: center; }
.gp-save:disabled, .gp-save[aria-disabled="true"], .gp-publish:disabled, .gp-publish[aria-disabled="true"] { background: var(--bg-3); color: var(--fg-3); border-color: var(--border-default); cursor: not-allowed; }
.gp-hint { font-size: var(--type-xs); color: var(--fg-2); }
/* cloud-managed posture (DDR-218) — the one save mechanism, named */
.gp-cloud-note { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-1) 0; font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-base); }
.gp-cloud-note svg { color: var(--accent); flex: 0 0 auto; }

/* publish / get-latest bar */
.gp-publishbar { flex: none; border-top: 1px solid var(--border-default); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); background: var(--bg-1); }
.gp-publish { width: 100%; justify-content: center; }
.gp-nudge { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); border-radius: var(--radius-sm); }
.gp-nudge-text { flex: 1; font-size: var(--type-sm); }
.gp-nudge-text b { color: var(--fg-0); font-weight: 600; }
.gp-nudge-text span { color: var(--fg-1); }
.gp-dot-pulse { width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--status-info); flex: 0 0 auto; box-shadow: 0 0 0 0 color-mix(in oklab, var(--status-info) 60%, transparent); animation: gp-pulse 2.4s var(--ease-out) infinite; }
@keyframes gp-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--status-info) 55%, transparent); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
@media (prefers-reduced-motion: reduce) { .gp-dot-pulse { animation: none; } }

/* callout (banner / conflict) — uses the client .callout, gp- adds layout */
.gp-callout-col { display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.gp-callout-actions { display: flex; gap: var(--space-3); margin-top: var(--space-2); }
.gp-pad { padding: var(--space-4) var(--space-4) 0; }
.gp-sect-label { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); padding: var(--space-4) var(--space-4) var(--space-2); }

/* History timeline with rail */
.gp-history { padding: var(--space-2) var(--space-3); display: flex; flex-direction: column; gap: 0; overflow-y: auto; min-height: 0; }
.gp-version { display: grid; grid-template-columns: 18px 1fr auto; gap: var(--space-3); padding: var(--space-3) var(--space-2); align-items: start; position: relative; }
.gp-version-rail { display: grid; place-items: center; position: relative; }
.gp-version-node { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--accent); margin-top: 4px; z-index: 1; }
.gp-version:not(:last-child) .gp-version-rail::after { content: ""; position: absolute; top: 12px; bottom: -12px; width: 1px; background: var(--border-default); }
.gp-version-body { display: flex; flex-direction: column; min-width: 0; }
.gp-version-msg { color: var(--fg-0); font-size: var(--type-sm); overflow: hidden; text-overflow: ellipsis; }
.gp-version-meta { color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); margin-top: 2px; }
.gp-version-when { color: var(--fg-2); font-family: var(--font-mono); font-size: var(--type-xs); white-space: nowrap; transition: opacity var(--dur-soft) ease; }
/* accepted revisions (T27/T28) — a row carries its own actions, so it is not a button */
.gp-version-actions { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: calc(-1 * var(--space-1)); }

/* phase-27.1 — per-file History rows are click-to-preview when a canvas is open */
.gp-history-scope { color: var(--fg-1); font-size: var(--type-xs); padding: var(--space-1) var(--space-2) var(--space-2); margin: 0; }
.gp-history-scope b { color: var(--fg-0); }
.gp-history-hint { color: var(--fg-2); font-size: var(--type-xs); text-align: center; padding: var(--space-3) var(--space-2); margin: 0; }
.gp-version--clickable { width: 100%; text-align: left; font: inherit; color: inherit; background: none; border: 0; border-radius: var(--radius-sm); cursor: pointer; appearance: none; transition: background var(--dur-soft) ease; }
.gp-version--clickable:hover { background: var(--bg-2); }
.gp-version--clickable:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.gp-version-cue { position: absolute; top: var(--space-2); right: var(--space-2); display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: var(--radius-pill); background: var(--accent-tint); color: var(--accent); font-size: var(--type-xs); font-weight: 600; opacity: 0; pointer-events: none; transition: opacity var(--dur-soft) ease; }
.gp-version--clickable:hover .gp-version-cue,
.gp-version--clickable:focus-visible .gp-version-cue { opacity: 1; }
.gp-version--clickable:hover .gp-version-when,
.gp-version--clickable:focus-visible .gp-version-when { opacity: 0; }

/* empty state — "Nothing to save" */
.gp-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-4); padding: var(--space-8) var(--space-6); text-align: center; }
.gp-empty-glyph { width: 52px; height: 52px; border-radius: var(--radius-pill); display: grid; place-items: center; background: color-mix(in oklab, var(--status-success) 16%, transparent); color: var(--status-success); }
.gp-empty-glyph--publish { background: var(--accent-tint); color: var(--accent); }
.gp-empty h3 { font-family: var(--font-display); font-size: var(--type-lg); color: var(--fg-0); margin: 0; font-weight: 600; }
.gp-empty p { color: var(--fg-1); font-size: var(--type-sm); max-width: 30ch; margin: 0; }

/* tree dirty badge — mirrors the activity-overlay badge style (DDR-075) */
.st-git-badge { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; margin-left: auto; border-radius: var(--radius-xs); font-family: var(--font-mono); font-size: 9px; font-weight: 700; line-height: 1; color: oklch(0.11 0.012 260); flex: none; }
.st-git-badge[data-kind="M"] { background: var(--status-warn); }
.st-git-badge[data-kind="A"] { background: var(--status-success); }
.st-git-badge[data-kind="D"] { background: var(--status-error); }
.st-git-badge[data-kind="U"] { background: transparent; border: 1px dashed var(--border-strong); color: var(--fg-2); }

/* ── Phase 27 (E2) — DiffView: clean rendered before/after, SYNCED zoom/pan ────
 * Ported from `.design/ui/DiffView.css`. Each pane renders a CLEAN canvas
 * (hide-chrome: no toolbar/minimap/devtools) inside a zoom/pan viewport. Both
 * panes share ONE view transform (locked): scroll to zoom, drag to pan, both
 * track the same region. Header reuses the app brand (.st-brand). */
/* The shared .st-scrim top-anchors short dialogs (place-items:start center + 12vh
 * pad). The DiffView sheet is tall (92vh), so top-anchoring overflows the bottom
 * (12vh + 92vh > 100vh — the footer got cut off). Center it instead. */
.dv-scrim { place-items: center; padding-top: 0; }
.dv-sheet { width: min(1280px, 96vw); height: min(900px, 92vh); display: flex; flex-direction: column; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden; }
.dv-hd { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-default); flex: none; }
.dv-hd .st-brand { padding-right: var(--space-3); border-right: 1px solid var(--border-default); }
.dv-title { font-family: var(--font-display); font-weight: 600; font-size: var(--type-lg); color: var(--fg-0); }
.dv-file { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); font-family: var(--font-mono); font-size: var(--type-sm); color: var(--fg-1); }
.dv-spacer { flex: 1; }
.dv-close { appearance: none; border: none; background: transparent; color: var(--fg-2); cursor: pointer; padding: var(--space-2); border-radius: var(--radius-xs); display: grid; place-items: center; }
.dv-close:hover { color: var(--fg-0); background: var(--bg-3); }
/* segmented mode toggle (DS .seg) */
.dv-seg { display: inline-flex; border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-2); }
.dv-seg-btn { appearance: none; border: 0; background: transparent; color: var(--fg-2); font-size: var(--type-xs); font-family: var(--font-mono); padding: var(--space-2) var(--space-4); cursor: pointer; }
.dv-seg-btn[aria-pressed="true"] { background: var(--bg-4); color: var(--fg-0); }
.dv-seg-btn + .dv-seg-btn { border-left: 1px solid var(--border-subtle); }

/* phase-27.1 — "Saved version" picker: pick which past version the before pane shows */
.dv-verpick { display: inline-flex; align-items: center; gap: var(--space-2); }
.dv-verpick-lbl { color: var(--fg-2); font-size: var(--type-xs); }
.dv-verpick-sel { appearance: none; border: 1px solid var(--border-default); border-radius: var(--radius-sm); background: var(--bg-2); color: var(--fg-0); font-size: var(--type-xs); font-family: var(--font-mono); padding: var(--space-2) var(--space-5) var(--space-2) var(--space-3); max-width: 22ch; cursor: pointer; background-image: linear-gradient(45deg, transparent 50%, var(--fg-2) 50%), linear-gradient(135deg, var(--fg-2) 50%, transparent 50%); background-position: right 12px center, right 7px center; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.dv-verpick-sel:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

.dv-stage { padding: var(--space-4) var(--space-5) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); flex: 1; min-height: 0; }
.dv-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); align-items: stretch; flex: 1; min-height: 0; }
.dv-col { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; min-height: 0; }
.dv-col-hd { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.dv-col-tag { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); display: inline-flex; align-items: center; gap: var(--space-1); }
.dv-col-tag.is-after { color: var(--accent); }
.dv-col-who { color: var(--fg-2); font-size: var(--type-xs); margin-left: auto; }

/* the rendered-canvas thumbnail = a zoom/pan viewport over a clean iframe */
.dv-thumb { position: relative; flex: 1; min-height: 0; background: var(--bg-0); border: 1px solid var(--border-default); border-radius: var(--radius-md); overflow: hidden; }
.dv-thumb.is-after { border-color: var(--accent-muted); }
.dv-thumb.ring-mine { box-shadow: 0 0 0 2px var(--accent); border-color: var(--accent); }
.dv-thumb.ring-theirs { box-shadow: 0 0 0 2px var(--status-info); border-color: var(--status-info); }
.dv-viewport { position: absolute; inset: 0; overflow: hidden; cursor: grab; touch-action: none; }
.dv-viewport.is-panning { cursor: grabbing; }
.dv-frame-wrap { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform-origin: 0 0; will-change: transform; }
.dv-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: var(--bg-0); display: block; pointer-events: none; }
.dv-thumb-note { position: absolute; inset: 0; display: grid; place-items: center; padding: var(--space-4); text-align: center; font-size: var(--type-xs); color: var(--fg-3); background: repeating-linear-gradient(45deg, var(--bg-1), var(--bg-1) 8px, var(--bg-2) 8px, var(--bg-2) 16px); }

/* shared zoom toolbar — drives the locked view for both panes */
.dv-zoombar { display: inline-flex; align-items: center; gap: var(--space-1); align-self: center; background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-pill); padding: 2px; flex: none; }
.dv-zoom-btn { appearance: none; border: none; background: transparent; color: var(--fg-1); cursor: pointer; width: 26px; height: 22px; border-radius: var(--radius-pill); font-size: var(--type-sm); line-height: 1; display: grid; place-items: center; }
.dv-zoom-btn:hover { background: var(--bg-3); color: var(--fg-0); }
.dv-zoom-val { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); min-width: 44px; text-align: center; cursor: pointer; appearance: none; border: none; background: transparent; }
.dv-zoom-val:hover { color: var(--fg-0); }
.dv-zoom-sync { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-3); padding-left: var(--space-2); border-left: 1px solid var(--border-subtle); margin-left: var(--space-1); }

/* overlay / slider compare (shares the locked view; frozen layers for the wipe) */
.dv-overlay { --dv-split: 52%; position: relative; flex: 1; min-height: 0; margin: 0 auto; width: 100%; max-width: 900px; background: var(--bg-0); border: 1px solid var(--border-default); border-radius: var(--radius-md); overflow: hidden; }
.dv-overlay-layer { position: absolute; inset: 0; }
.dv-overlay-after { position: absolute; inset: 0; clip-path: inset(0 0 0 var(--dv-split)); }
.dv-split { position: absolute; top: 0; bottom: 0; left: var(--dv-split); width: 2px; background: var(--accent); z-index: 3; }
.dv-split-handle { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 26px; height: 26px; border-radius: var(--radius-pill); background: var(--accent); color: var(--accent-fg); display: grid; place-items: center; box-shadow: var(--shadow-md); cursor: ew-resize; }
.dv-split-handle:focus-visible { outline: 2px solid var(--fg-0); outline-offset: 2px; }
.dv-overlay-tag { position: absolute; bottom: var(--space-3); font-family: var(--font-mono); font-size: var(--type-xs); padding: 2px var(--space-3); border-radius: var(--radius-sm); background: color-mix(in oklab, var(--bg-0) 70%, transparent); color: var(--fg-1); z-index: 4; }
.dv-overlay-tag.l { left: var(--space-3); }
.dv-overlay-tag.r { right: var(--space-3); color: var(--accent); }

/* conflict picker */
.dv-pick-intro { padding: var(--space-4) var(--space-6) 0; flex: none; }
.dv-picker { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); padding: var(--space-4) var(--space-6) var(--space-2); flex: none; }
.dv-pick { text-align: left; appearance: none; cursor: pointer; background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-md); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); color: var(--fg-1); }
.dv-pick:hover { border-color: var(--border-strong); background: var(--bg-3); }
.dv-pick.is-rec { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); background: var(--accent-tint); }
.dv-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dv-pick.is-rec .dv-pick-desc { color: var(--fg-1); }
.dv-pick-hd { display: flex; align-items: center; gap: var(--space-2); }
.dv-pick-title { font-weight: 600; color: var(--fg-0); font-size: var(--type-sm); }
.dv-pick-rec { margin-left: auto; font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--accent-fg); background: var(--accent); border-radius: var(--radius-pill); padding: 1px var(--space-2); }
.dv-pick-desc { font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-xs); }

/* footer */
.dv-ft { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-6); border-top: 1px solid var(--border-default); flex: none; }
.dv-note { color: var(--fg-2); font-size: var(--type-xs); flex: 1; }

/* ── Phase 28 (E3) — GitHub identity rail + create/pull/share dialogs.
 *    All chrome is the SHELL maude DS: solid surfaces (var(--bg-1)/2) and the
 *    .st-dialog scrim+card treatment — NEVER the canvas-side `.panel` (it isn't in
 *    the client bundle, which made the cards transparent). The identity rail docks
 *    at the BOTTOM of the sidebar as a compact avatar; the menu opens upward. */

/* text inputs — the maude DS .input/.textarea recipe (lifted from the canvas-side
 * _components.css, which isn't in the client bundle → my fields fell back to native).
 * Scoped to the github dialogs so it can't collide with the shell's .st-search/.st-field. */
.gi-dialog .input, .cp-dialog .input, .gi-dialog .textarea, .cp-dialog .textarea, .rb-dialog .textarea {
  font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-0);
  background: var(--bg-3); border: 1px solid var(--border-default); border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4); width: 100%;
  transition: border-color var(--dur-soft) var(--ease-out), box-shadow var(--dur-soft) var(--ease-out);
}
.gi-dialog .input::placeholder, .cp-dialog .input::placeholder,
.gi-dialog .textarea::placeholder, .cp-dialog .textarea::placeholder,
.rb-dialog .textarea::placeholder { color: var(--fg-3); }
.gi-dialog .input:focus, .cp-dialog .input:focus, .gi-dialog .textarea:focus, .cp-dialog .textarea:focus, .rb-dialog .textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint);
}
.cp-dialog .textarea { resize: vertical; min-height: 76px; }

/* identity rail — sidebar footer */
.gi-rail { position: relative; flex: 0 0 auto; margin-top: auto; padding: var(--space-2) var(--space-3); border-top: 1px solid var(--border-default); display: flex; flex-direction: column; gap: var(--space-2); }
/* Truncation the code already assumed: CloudBar.jsx documents `title` as "the
   full sentence on hover (the rail truncates)" — and this rule did not exist,
   so a long hub-supplied project name wrapped and grew, pushing the rail into
   adjacent chrome. Its sibling .gi-rail-err has carried the same three
   properties all along. `anywhere` so a single unbreakable 60-char token
   cannot overflow horizontally either. */
.gi-rail-hint { font-size: var(--type-xs); color: var(--fg-2); padding: var(--space-1) var(--space-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: anywhere; }
.gi-rail-signin { width: 100%; justify-content: center; }
.gi-rail-confirm { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; padding: var(--space-2); border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-2); }
/* …but the deep-link confirm strip is a paragraph that MUST wrap — it explains
   both sides of a consent decision, and one ellipsised line would hide half of
   what the person is agreeing to. */
.gi-rail-confirm .gi-rail-hint { flex: 1 1 100%; padding: 0; white-space: normal; overflow: visible; }
.gi-rail-err { font-size: var(--type-xs); color: var(--status-error); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gi-avatar { border-radius: var(--radius-pill); display: grid; place-items: center; font-family: var(--font-mono); font-size: 10px; font-weight: 600; color: var(--accent-fg); background: var(--accent); flex: 0 0 auto; }
.gi-rail-account { display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: var(--space-1) var(--space-2); border: 1px solid transparent; border-radius: var(--radius-md); background: transparent; color: var(--fg-0); cursor: pointer; text-align: left; }
.gi-rail-account:hover { background: var(--bg-2); }
.gi-rail-account.is-open { background: var(--bg-2); border-color: var(--border-default); }
.gi-rail-account:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gi-rail-login { flex: 1; min-width: 0; font-family: var(--font-mono); font-size: var(--type-sm); color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gi-rail-caret { color: var(--fg-2); flex: 0 0 auto; display: inline-flex; }

/* account menu — opens UPWARD, solid surface */
.gi-menu { position: absolute; bottom: calc(100% + var(--space-1)); left: var(--space-3); right: var(--space-3); z-index: 9500; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: var(--space-2); }
.gi-menu-hd { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-2) var(--space-3); border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-1); }
.gi-menu-id { display: flex; flex-direction: column; min-width: 0; }
.gi-menu-name { font-weight: 600; color: var(--fg-0); font-size: var(--type-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gi-menu-login { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
.gi-menu-item { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--fg-1); font-size: var(--type-sm); cursor: pointer; text-align: left; }
.gi-menu-item svg { color: var(--fg-2); }
.gi-menu-item:hover { background: var(--bg-2); color: var(--fg-0); }
.gi-menu-item:hover svg { color: var(--fg-1); }
.gi-menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* the already-linked project's row — a state, not an action (fix 7, sync RCA) */
.gi-menu-item.is-connected { cursor: default; }
.gi-menu-item.is-connected:hover { background: transparent; color: var(--fg-1); }
.gi-menu-item.is-connected:hover svg { color: var(--fg-2); }
.gi-menu-item--danger, .gi-menu-item--danger svg { color: var(--status-error); }
.gi-menu-item--danger:hover { background: color-mix(in oklab, var(--status-error) 14%, transparent); color: var(--status-error); }
.gi-menu-sep { height: 1px; background: var(--border-subtle); margin: var(--space-1) 0; }

/* shared dialog shell (device-code + create/pull/share) — lifts .st-scrim/.st-dialog */
.gi-modal, .cp-modal { position: fixed; inset: 0; display: grid; place-items: center; z-index: 9600; padding: var(--space-6); }
.gi-scrim, .cp-scrim { position: fixed; inset: 0; background: color-mix(in oklab, var(--bg-0) 72%, transparent); }
.gi-dialog, .cp-dialog { position: relative; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); display: flex; flex-direction: column; overflow: hidden; animation: st-pop var(--dur-route) var(--ease-out); }

/* device-code dialog */
.gi-dialog--code { width: min(460px, 92vw); padding: var(--space-6); gap: var(--space-5); }
.gi-dc-head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--space-3); }
.gi-dc-head h2 { margin: 0; font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); }
.gi-dc-marks { display: grid; place-items: center; width: 52px; height: 52px; border-radius: var(--radius-lg); background: var(--bg-2); border: 1px solid var(--border-default); color: var(--fg-0); }
.gi-dc-head p { margin: 0; color: var(--fg-2); font-size: var(--type-sm); line-height: var(--lh-base); max-width: 38ch; }
.gi-dc-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.gi-dc-steps li { display: flex; align-items: flex-start; gap: var(--space-3); }
.gi-dc-step-n { flex: 0 0 auto; width: 22px; height: 22px; display: grid; place-items: center; border-radius: var(--radius-pill); background: var(--accent-tint); border: 1px solid var(--accent-muted); color: var(--accent); font-family: var(--font-mono); font-size: var(--type-xs); font-weight: 600; }
.gi-dc-step-tx { font-size: var(--type-sm); color: var(--fg-1); line-height: var(--lh-base); display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.gi-dc-url { font-family: var(--font-mono); color: var(--fg-0); background: var(--bg-2); border: 1px solid var(--border-subtle); border-radius: var(--radius-xs); padding: 1px var(--space-2); }
.gi-code { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-5); border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--bg-2); }
.gi-code-val { font-family: var(--font-mono); font-size: var(--type-2xl); font-weight: 600; letter-spacing: 0.16em; color: var(--fg-0); }
.gi-code-copy { flex: 0 0 auto; }
/* the manual path out of the device dialog — always rendered, never a fallback
   that only appears once something has already failed */
.gi-dc-link { display: flex; flex-direction: column; gap: var(--space-2); }
.gi-dc-link-lbl { font-size: var(--type-xs); color: var(--fg-2); }
.gi-dc-link-row { display: flex; align-items: center; gap: var(--space-2); }
.gi-dc-link-a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--type-xs); color: var(--accent); text-decoration: none; cursor: pointer; }
.gi-dc-link-a:hover { text-decoration: underline; }
.gi-dc-link-a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gi-dc-status { display: flex; align-items: center; gap: var(--space-3); font-size: var(--type-sm); color: var(--fg-2); }
.gi-pulse { width: 9px; height: 9px; flex: 0 0 auto; border-radius: var(--radius-pill); background: var(--status-info); animation: gi-pulse 1.8s var(--ease-out) infinite; }
@keyframes gi-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--status-info) 55%, transparent); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
.gi-dc-foot { display: flex; align-items: center; gap: var(--space-3); }
.gi-dc-foot-note { font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-sm); }

/* maude:// decision modal — same dialog family, one job: name both sides */
.gi-dl-pair { display: flex; align-items: stretch; gap: var(--space-3); }
.gi-dl-side { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-2); }
.gi-dl-lbl { font-size: var(--type-xs); color: var(--fg-2); }
.gi-dl-val { font-family: var(--font-mono); font-size: var(--type-sm); font-weight: 600; color: var(--fg-0); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gi-dl-arrow { flex: 0 0 auto; display: grid; place-items: center; color: var(--fg-2); }
.gi-dl-what { margin: 0; font-size: var(--type-sm); color: var(--fg-1); line-height: var(--lh-base); }
.gi-dl-what code { font-family: var(--font-mono); font-size: var(--type-xs); background: var(--bg-2); border: 1px solid var(--border-subtle); border-radius: var(--radius-xs); padding: 1px var(--space-1); }
.gi-dl-note { margin: 0; font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-base); }
/* The warn colour rides the border + wash ONLY — `--status-warn` as text fails
   AA at this size (DDR-097's file-tree badge fix; the ACP elicitation warning
   carries the same note). Text stays on --fg-1/--fg-0. */
.gi-dl-warn { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); border: 1px solid var(--status-warn); border-radius: var(--radius-md); background: color-mix(in oklab, var(--status-warn) 12%, transparent); font-size: var(--type-sm); line-height: var(--lh-base); color: var(--fg-1); }
.gi-dl-warn strong { color: var(--fg-0); }

/* create / pull / share dialog */
.cp-dialog { width: min(560px, 94vw); max-height: 88vh; }
.cp-dialog-hd { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-5) var(--space-5) var(--space-4); border-bottom: 1px solid var(--border-subtle); flex: none; }
.cp-dialog-titles { flex: 1; min-width: 0; }
.cp-dialog-hd h2 { margin: 0; font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); }
.cp-dialog-hd p { margin: var(--space-1) 0 0; font-size: var(--type-sm); color: var(--fg-2); line-height: var(--lh-base); }
.cp-body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-5); overflow: auto; }
.cp-body--list { gap: var(--space-3); }
.cp-ft { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-subtle); background: var(--bg-1); flex: none; }
.cp-spacer { flex: 1; }
.cp-cl-glyph { flex: 0 0 auto; display: inline-flex; }
.cp-field { display: flex; flex-direction: column; gap: var(--space-2); }
.cp-field-label { font-size: var(--type-sm); font-weight: 600; color: var(--fg-0); display: flex; align-items: center; gap: var(--space-2); }
.cp-optional { font-weight: 400; font-size: var(--type-xs); color: var(--fg-2); text-transform: lowercase; }
.cp-field-help { font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-base); }
.cp-field-help b { color: var(--fg-1); font-family: var(--font-mono); font-weight: 500; }
.cp-input, .cp-textarea { width: 100%; }
.cp-textarea { resize: none; }
.cp-seg { width: 100%; }
.cp-seg button { flex: 1; justify-content: center; gap: var(--space-2); }
.cp-seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.cp-invite { display: flex; align-items: center; gap: var(--space-2); position: relative; }
.cp-invite-at { position: absolute; left: var(--space-3); font-family: var(--font-mono); color: var(--fg-2); pointer-events: none; }
.cp-dialog .cp-invite-input { flex: 1; padding-left: calc(var(--space-3) + 0.9em); font-family: var(--font-mono); }
.cp-invite-btn { flex: 0 0 auto; }
.cp-repolist { display: flex; flex-direction: column; gap: var(--space-1); max-height: 360px; overflow: auto; }
.cp-repo { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-3); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); background: var(--bg-2); color: var(--fg-0); cursor: pointer; text-align: left; }
.cp-repo:hover:not(:disabled) { border-color: var(--accent); background: var(--bg-3); }
.cp-repo:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cp-repo:disabled { cursor: default; opacity: 0.6; }
.cp-repo.is-busy { opacity: 1; border-color: var(--accent); }
.cp-repo > svg:first-child { color: var(--fg-2); flex: 0 0 auto; }
.cp-repo-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cp-repo-name { font-weight: 600; font-size: var(--type-sm); color: var(--fg-0); }
.cp-repo-meta { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); }
.cp-repo-go { color: var(--fg-3); flex: 0 0 auto; display: inline-flex; }
.cp-repo:hover:not(:disabled) .cp-repo-go { color: var(--accent); }
.cp-repo.is-busy .cp-repo-go { color: var(--accent); }
.cp-spin { animation: cp-spin 0.9s linear infinite; transform-origin: center; }
@keyframes cp-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) { .gi-pulse, .cp-spin { animation: none; } .gi-dialog, .cp-dialog { animation: none; } }

/* ─── Presentation Mode ────────────────────────────────────────────────────
   View ▸ Presentation Mode — a non-destructive "artboards only" overlay. Hides
   every piece of shell chrome while leaving the canvas viewport (.main) mounted
   so its pan/zoom + open tabs survive an exit. The two structural rules below
   hide (a) the menubar + status bar — the .st-shell children that aren't the
   body — and (b) the sidebar / collapsed rail / resize grips / side panels —
   the .st-body children that aren't the viewport. The canvas iframe hides its
   OWN floating chrome (minimap, zoom pill, tool palette, annotations, comment
   pins) via the dgn:'view-chrome' bridge. Escape hatch: Esc or the pill. */
.maude.is-present .st-shell > :not(.st-body) { display: none !important; }
.maude.is-present .st-body > :not(.main) { display: none !important; }
/* Top-level banners (.st-banner — SyncBanner + the "repo state changed" notice)
   are DELIBERATELY left visible in present mode: they're the DDR-102 fail-closed
   sync/divergence warnings, and an untrusted canvas (DDR-054) must not be able to
   silence a security-relevant notice by entering Presentation Mode (phase-28
   audit F-1). They're transient + rare, so they don't clutter a clean view. */

/* Floating escape-hatch pill — the only chrome visible while presenting.
   Deliberately understated (55% opacity) so it doesn't intrude on a clean
   screenshot, brightening to full on hover/focus. */
.st-present-exit {
  position: fixed; top: var(--space-4); right: var(--space-4); z-index: 200;
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  appearance: none; cursor: pointer;
  font-family: var(--font-body); font-size: var(--type-sm); color: var(--fg-1);
  background: var(--bg-1); border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  box-shadow: 0 4px 16px rgb(0 0 0 / 0.18);
  opacity: 0.72;
  transition: opacity var(--dur-soft) var(--ease-out),
    background var(--dur-soft) var(--ease-out), color var(--dur-soft) var(--ease-out);
}
.st-present-exit:hover,
.st-present-exit:focus-visible { opacity: 1; background: var(--bg-3); color: var(--fg-0); }
.st-present-exit > svg { color: var(--fg-2); flex: 0 0 auto; }
.st-present-exit:hover > svg,
.st-present-exit:focus-visible > svg { color: var(--accent); }
.st-present-exit-kbd {
  font-family: var(--font-mono); font-size: var(--type-xs);
  color: var(--fg-3); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs); padding: 1px 5px; line-height: 1.4;
}
@media (prefers-reduced-motion: reduce) { .st-present-exit { transition: none; } }

/* ── Phase 29 (E4) — OnboardingWizard (first-run). Ported from the approved
   `.design/ui/Onboarding.tsx` mockup (≥4.5/5); ob-* classes, every value a token. ── */
.ob-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: var(--bg-0);
  display: flex;
}
.ob-shell {
  position: absolute; inset: 0;
  display: flex;
  background: var(--bg-0); color: var(--fg-0);
  font-family: var(--font-body); font-size: var(--type-base); line-height: var(--lh-base);
  overflow: hidden;
}
.ob-rail {
  flex: 0 0 372px; display: flex; flex-direction: column; gap: var(--space-7);
  padding: var(--space-8) var(--space-7);
  background: radial-gradient(120% 90% at 0% 0%, var(--accent-tint) 0%, transparent 55%), var(--bg-1);
  border-right: 1px solid var(--border-default);
}
.ob-rail-brand { display: inline-flex; align-items: center; gap: var(--space-3); }
/* maude mark tile — lifted from system/maude/preview/logo.css `.lg-mark`: spark in
 * --accent-fg on the indigo, bottom-right corner squared (bubble), accent-tint halo. */
.ob-mark { display: grid; place-items: center; flex: 0 0 auto; background: var(--accent); color: var(--accent-fg); border-radius: 24% 24% 0 24%; box-shadow: 0 0 0 3px var(--accent-tint); }
.ob-mark svg { width: 100%; height: 100%; display: block; }
.ob-rail-wordmark { font-family: var(--font-display); font-size: var(--type-xl); font-weight: 600; letter-spacing: var(--tracking-tight); }
.ob-rail-h { margin: 0 0 var(--space-3); font-family: var(--font-display); font-size: var(--type-2xl); line-height: var(--lh-xl); font-weight: 600; letter-spacing: var(--tracking-tight); color: var(--fg-0); }
.ob-rail-lede p { margin: 0; max-width: 30ch; color: var(--fg-2); font-size: var(--type-md); line-height: var(--lh-lg); }
.ob-rail-reassure { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.ob-rail-reassure li { display: flex; align-items: center; gap: var(--space-3); color: var(--fg-1); font-size: var(--type-sm); }
.ob-rail-tick { flex: 0 0 auto; width: 20px; height: 20px; display: grid; place-items: center; border-radius: var(--radius-pill); background: var(--accent-tint); color: var(--accent); }
.ob-rail-signed { display: inline-flex; align-items: center; gap: var(--space-3); align-self: flex-start; padding: var(--space-2) var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-pill); background: var(--bg-2); font-size: var(--type-sm); color: var(--fg-1); }
.ob-rail-signed b { color: var(--fg-0); font-weight: 600; }
.ob-rail-signed-dot { width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--presence-online); box-shadow: 0 0 0 3px color-mix(in oklab, var(--presence-online) 28%, transparent); }
.ob-rail-foot { margin-top: auto; color: var(--fg-2); font-size: var(--type-xs); font-family: var(--font-mono); }

.ob-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-6); padding: var(--space-8) clamp(var(--space-7), 6vw, 96px); overflow: auto; }
.ob-back { align-self: flex-start; display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3) var(--space-1) var(--space-2); border: 1px solid var(--border-default); border-radius: var(--radius-pill); background: var(--bg-1); color: var(--fg-1); font-size: var(--type-sm); cursor: pointer; }
.ob-back:hover { border-color: var(--border-strong); color: var(--fg-0); }
.ob-back:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ob-head { display: flex; flex-direction: column; gap: var(--space-2); }
.ob-eyebrow { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--accent); }
.ob-head h1 { margin: 0; font-family: var(--font-display); font-size: var(--type-3xl); line-height: var(--lh-2xl); font-weight: 600; letter-spacing: var(--tracking-tight); }
.ob-head p { margin: 0; max-width: 56ch; color: var(--fg-2); font-size: var(--type-md); line-height: var(--lh-lg); }
.ob-watch-intro { align-self: flex-start; display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1); padding: var(--space-2) var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-pill); background: var(--bg-1); color: var(--fg-1); font-size: var(--type-sm); cursor: pointer; }
.ob-watch-intro:hover { border-color: var(--border-strong); color: var(--fg-0); background: var(--bg-2); }
.ob-watch-intro:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.ob-doors { display: flex; flex-direction: column; gap: var(--space-4); max-width: 720px; }
.ob-door { position: relative; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-4); width: 100%; text-align: left; padding: var(--space-5); border: 1px solid var(--border-default); border-radius: var(--radius-lg); background: var(--bg-1); color: inherit; cursor: pointer; transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out), transform var(--dur-soft) var(--ease-out); }
.ob-door:hover { border-color: var(--border-strong); background: var(--bg-2); transform: translateY(-1px); }
.ob-door:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ob-door:disabled { opacity: 0.6; cursor: default; }
.ob-door--primary { padding: var(--space-6); border-color: color-mix(in oklab, var(--accent) 55%, transparent); background: linear-gradient(180deg, var(--accent-tint) 0%, transparent 70%), var(--bg-1); box-shadow: var(--shadow-md); }
.ob-door--primary:hover { border-color: var(--accent); }
.ob-door--advanced { background: var(--bg-1); border-style: dashed; border-color: var(--border-strong); }
.ob-door--advanced:hover { background: var(--bg-2); }
.ob-door-icon { width: 48px; height: 48px; display: grid; place-items: center; border-radius: var(--radius-md); background: var(--bg-3); color: var(--fg-1); border: 1px solid var(--border-subtle); }
.ob-door-icon--gh { background: var(--fg-0); color: var(--bg-0); border-color: transparent; }
.ob-door-icon--quiet { width: 40px; height: 40px; background: var(--bg-2); color: var(--fg-2); }
.ob-door-tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ob-door-title { display: inline-flex; align-items: center; gap: var(--space-3); font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); }
.ob-door--primary .ob-door-title { font-size: var(--type-xl); }
.ob-door-sub { color: var(--fg-2); font-size: var(--type-sm); line-height: var(--lh-md); }
.ob-door-tag { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--accent); padding: 2px var(--space-2); border-radius: var(--radius-pill); background: var(--accent-tint); }
.ob-door-adv { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); padding: 1px var(--space-2); border: 1px solid var(--border-default); border-radius: var(--radius-sm); }
.ob-door-cta { display: flex; }
.ob-door-btn { pointer-events: none; white-space: nowrap; }
.ob-door-go { color: var(--fg-3); display: grid; place-items: center; }
.ob-door:hover .ob-door-go { color: var(--fg-1); }
.ob-foot-note { margin: 0; color: var(--fg-2); font-size: var(--type-xs); }

/* Opt-in crash reporting checkbox (Phase 32 / Task 4) — quiet footer affordance. */
.ob-crash-optin { display: flex; align-items: flex-start; gap: var(--space-2); max-width: 560px; margin: var(--space-3) 0 0; color: var(--fg-2); font-size: var(--type-xs); line-height: var(--lh-md); cursor: pointer; text-align: left; }
.ob-crash-optin input { margin-top: 2px; flex: 0 0 auto; accent-color: var(--accent); cursor: pointer; }

/* AI-editing readiness strip (Phase 33 / DDR-128) — non-blocking, collapsible. */
.ob-readiness { max-width: 560px; margin: var(--space-3) 0 0; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); background: var(--bg-1); text-align: left; }
.ob-readiness-sum { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3); cursor: pointer; list-style: none; font-size: var(--type-sm); color: var(--fg-1); }
.ob-readiness-sum::-webkit-details-marker { display: none; }
.ob-readiness-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; }
.ob-readiness-dot--ok { background: var(--status-success); }
.ob-readiness-dot--warn { background: var(--status-warning, var(--status-info)); }
.ob-readiness-lede { font-weight: 600; color: var(--fg-0); }
.ob-readiness-hint { margin-left: auto; color: var(--fg-3); font-size: var(--type-xs); }
.ob-readiness-body { padding: 0 var(--space-3) var(--space-3); display: flex; flex-direction: column; gap: var(--space-3); }
.ob-readiness-note { margin: 0; color: var(--fg-2); font-size: var(--type-xs); line-height: var(--lh-md); }

.ob-create { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-4); width: 100%; max-width: 720px; text-align: left; padding: var(--space-5); border: 1px solid color-mix(in oklab, var(--accent) 45%, transparent); border-radius: var(--radius-lg); background: linear-gradient(180deg, var(--accent-tint) 0%, transparent 80%), var(--bg-1); cursor: pointer; color: inherit; transition: border-color var(--dur-soft) var(--ease-out); }
.ob-create:hover { border-color: var(--accent); }
.ob-create:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ob-create-icon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: var(--radius-md); background: var(--accent); color: var(--accent-fg); }
.ob-create-tx { display: flex; flex-direction: column; gap: 2px; }
.ob-create-title { font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); }
.ob-create-sub { color: var(--fg-2); font-size: var(--type-sm); }
.ob-create-btn { pointer-events: none; }
.ob-section-label { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); margin-top: var(--space-2); }
.ob-repolist { display: flex; flex-direction: column; gap: var(--space-2); max-width: 720px; }
.ob-repo { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-4); width: 100%; text-align: left; padding: var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-1); color: inherit; cursor: pointer; transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
.ob-repo:hover { border-color: var(--border-strong); background: var(--bg-2); }
.ob-repo:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ob-repo:disabled { opacity: 0.6; cursor: default; }
.ob-repo-icon { color: var(--fg-2); display: grid; place-items: center; }
.ob-repo-tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ob-repo-name { font-weight: 600; color: var(--fg-0); }
.ob-repo-meta { color: var(--fg-2); font-size: var(--type-xs); font-family: var(--font-mono); }
.ob-repo-go { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--fg-2); font-size: var(--type-sm); white-space: nowrap; padding: var(--space-1) var(--space-3); border-radius: var(--radius-sm); }
.ob-repo:hover .ob-repo-go { color: var(--accent); background: var(--accent-tint); }

.ob-drop { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3); width: 100%; max-width: 720px; padding: var(--space-8) var(--space-6); border: 1.5px dashed var(--border-strong); border-radius: var(--radius-lg); background: var(--bg-1); text-align: center; color: inherit; cursor: pointer; }
.ob-drop:hover { border-color: var(--accent); }
.ob-drop:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ob-drop:disabled { opacity: 0.6; cursor: default; }
.ob-drop-glyph { width: 64px; height: 64px; display: grid; place-items: center; border-radius: var(--radius-lg); background: var(--bg-3); color: var(--accent); margin-bottom: var(--space-2); }
.ob-drop-title { font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); }
.ob-drop-or { color: var(--fg-2); font-size: var(--type-sm); }
.ob-callout { max-width: 720px; }
.ob-callout-glyph { flex: 0 0 auto; display: grid; place-items: center; }

.ob-form { display: flex; flex-direction: column; gap: var(--space-4); max-width: 560px; }
.ob-field { display: flex; flex-direction: column; gap: var(--space-2); }
.ob-field-label { font-size: var(--type-sm); font-weight: 600; color: var(--fg-1); }
.ob-field-wrap { position: relative; display: flex; align-items: center; }
.ob-field-pre { position: absolute; left: var(--space-3); color: var(--fg-3); pointer-events: none; }
.ob-input { width: 100%; }
.ob-field-wrap .ob-input { padding-left: calc(var(--space-3) * 2 + 16px); font-family: var(--font-mono); }
.ob-form-actions { display: flex; gap: var(--space-3); margin-top: var(--space-1); }

.ob-toast { position: fixed; bottom: var(--space-5); left: 50%; transform: translateX(-50%); max-width: 480px; z-index: 101; box-shadow: var(--shadow-lg); }
.ob-spin { animation: ob-spin 0.8s linear infinite; }
@keyframes ob-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .ob-door, .ob-create, .ob-repo, .ob-back { transition-duration: 1ms; }
  .ob-door:hover { transform: none; }
  .ob-spin { animation-duration: 1ms; }
}

/* ── Team projects (plan T22) — the designer's way in: recent managed copies,
   Maude Cloud projects, a team server sign-in. Composes the ob-* door parts; the
   dialog frame reuses gi-modal/gi-dialog from the project switcher. ── */
.gi-dl-open { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); padding-bottom: var(--space-4); border-bottom: 1px solid var(--border-default); }
.sp-ai-held { display: flex; flex-direction: column; gap: var(--space-2); }
.sp-ai-actions { display: flex; gap: var(--space-2); }
/* ── SourceConflictPanel (plan T28) — two versions, line by line. ── */
.gi-dialog.scp-dialog { width: min(760px, 94vw); max-height: min(820px, 90vh); overflow: hidden; display: flex; flex-direction: column; padding: var(--space-6); gap: var(--space-4); }
.scp-legend { display: flex; gap: var(--space-4); font-size: var(--type-xs); color: var(--fg-2); }
.scp-key::before { content: ''; display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: var(--space-2); vertical-align: -1px; }
.scp-key--mine::before { background: color-mix(in oklch, var(--status-warn) 45%, transparent); }
.scp-key--theirs::before { background: color-mix(in oklch, var(--status-info) 45%, transparent); }
.scp-diff { flex: 1; min-height: 120px; overflow: auto; border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-1); font-family: var(--font-mono); font-size: var(--type-xs); line-height: 1.55; }
.scp-diff:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.scp-line { display: flex; gap: var(--space-2); padding: 0 var(--space-3); white-space: pre; }
.scp-line code { font: inherit; color: var(--fg-1); }
.scp-mark { width: 1ch; color: var(--fg-3); flex: none; }
.scp-line--mine { background: color-mix(in oklch, var(--status-warn) 14%, transparent); }
.scp-line--theirs { background: color-mix(in oklch, var(--status-info) 14%, transparent); }
.scp-line--skip { color: var(--fg-3); font-style: italic; }
.scp-line--skip code { color: var(--fg-3); }
.scp-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.scp-hint { font-size: var(--type-xs); color: var(--fg-2); }
.scp-error { margin: 0; color: var(--status-error); font-size: var(--type-sm); }
.tp { display: flex; flex-direction: column; gap: var(--space-5); max-width: 720px; }
.tp-section { display: flex; flex-direction: column; gap: var(--space-3); }
.tp-device { display: flex; flex-direction: column; gap: var(--space-3); max-width: 560px; }
.tp-device .ob-form-actions { align-items: center; justify-content: space-between; }
.gi-dialog.tp-dialog { width: min(620px, 94vw); max-height: min(760px, 90vh); overflow: auto; padding: var(--space-6); gap: var(--space-4); }
.tp-dialog-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.tp-dialog-head h2 { margin: 0; font-size: var(--type-lg); color: var(--fg-0); }
.tp-dialog-head p { margin: var(--space-1) 0 0; color: var(--fg-2); font-size: var(--type-sm); }

/* ── Phase 29 (E4) — RepoBranchSwitcher. REDESIGNED to the approved mockup
   (.design/ui/RepoBranchSwitcher.tsx): a compact ONE-LINE dock at the BOTTOM of the
   sidebar (above the IdentityBar avatar) that opens ONE popup UPWARD. Mirrors the
   gi-rail/gi-menu anatomy so the two bottom surfaces read as one dock. ── */
.rb-dock-wrap {
  flex: 0 0 auto;
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-3);
  border-top: 1px solid var(--border-default);
  background: var(--bg-1);
  box-shadow: 0 -10px 18px -12px color-mix(in oklab, var(--bg-0) 80%, transparent);
}
.rb-dock { position: relative; }
/* Proactive "remote has updates" nudge — a full-width primary button above the dock
   trigger, shown when the tracking remote is ahead (status.remoteAhead). */
.rb-getlatest { width: 100%; justify-content: flex-start; gap: var(--space-2); animation: rb-getlatest-in var(--dur-soft, 160ms) var(--ease-out, ease-out); }
.rb-getlatest-tx { flex: 0 0 auto; }
.rb-getlatest-sub { margin-left: auto; font-weight: 500; opacity: 0.9; font-size: var(--type-xs); white-space: nowrap; }
@keyframes rb-getlatest-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .rb-getlatest, .rb-resume { animation: none; } }
/* "Continue on <draft>" resume nudge — a subtle secondary row (not the primary blue),
   shown above the dock trigger when you're on the Shared version but have a draft. */
.rb-resume { display: flex; align-items: center; gap: var(--space-1); width: 100%; animation: rb-getlatest-in var(--dur-soft, 160ms) var(--ease-out, ease-out); }
.rb-resume-go { flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-2); min-width: 0; text-align: left; padding: var(--space-2) var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-2); color: var(--fg-1); cursor: pointer; font-size: var(--type-sm); transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out); }
.rb-resume-go:hover { border-color: var(--border-strong); background: var(--bg-3); }
.rb-resume-go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rb-resume-icon { color: var(--status-warn); flex: 0 0 auto; display: grid; place-items: center; }
.rb-resume-tx { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-resume-arrow { color: var(--fg-3); flex: 0 0 auto; }
.rb-resume-x { flex: 0 0 auto; display: grid; place-items: center; width: 28px; height: 28px; border: none; border-radius: var(--radius-md); background: transparent; color: var(--fg-3); cursor: pointer; }
.rb-resume-x:hover { background: var(--bg-3); color: var(--fg-1); }
.rb-resume-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The compact one-line trigger — "📁 <project> · ◐ <version> ⌃" */
.rb-trigger {
  display: flex; align-items: center; gap: var(--space-2);
  width: 100%; text-align: left;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-default); border-radius: var(--radius-md);
  background: var(--bg-2); color: var(--fg-1); cursor: pointer; font-size: var(--type-sm);
  transition: border-color var(--dur-soft) var(--ease-out), background var(--dur-soft) var(--ease-out);
}
.rb-trigger:hover, .rb-trigger.is-open { border-color: var(--border-strong); background: var(--bg-3); }
.rb-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rb-trigger-icon { color: var(--accent); flex: 0 0 auto; display: grid; place-items: center; }
.rb-trigger-proj { font-weight: 600; color: var(--fg-0); flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-trigger-sep { color: var(--fg-3); flex: 0 0 auto; }
.rb-trigger-ver { display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; flex: 1 1 auto; color: var(--presence-online); }
.rb-trigger-ver.is-draft { color: var(--status-warn); }
.rb-trigger-ver-name { color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-trigger-caret { color: var(--fg-2); flex: 0 0 auto; }
/* Web studio: the switcher degrades to a read-only awareness badge (DDR-119).
   Git vocab ("branch: X"), no hover affordance, no actions — the dev switches
   from their terminal. Neutral colour distinguishes it from the native dock's
   green "Shared version" / amber draft. */
.rb-trigger--ro { cursor: default; }
.rb-trigger--ro:hover { border-color: var(--border-default); background: var(--bg-2); }
.rb-trigger-ver--ro { color: var(--fg-2); flex: 0 1 auto; }
.rb-trigger-ver--ro .rb-trigger-ver-name { color: var(--fg-1); font-family: var(--font-mono); font-size: var(--type-xs); }
/* GitPanel read-only footer hint (web studio — actions live in the terminal). */
.gp-ro-hint { padding: var(--space-3) var(--space-4); color: var(--fg-2); }

/* feature-sync-progress-modal — the Sync panel (per-file sync rows). Reuses
 * the gp- head chrome; sp- covers only the sync-specific rows/sections. */
.sp-panel { display: flex; flex-direction: column; }
.sp-body { flex: 1; overflow-y: auto; padding-bottom: var(--space-4); }
.sp-note { display: flex; align-items: flex-start; gap: var(--space-2); padding: var(--space-2) var(--space-1) var(--space-2); font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-base); }
.sp-note-dot { width: 7px; height: 7px; margin-top: 3px; border-radius: var(--radius-pill); background: var(--status-warn); flex: none; }
.sp-note-dot.is-synced { background: var(--presence-online); }
.sp-note-dot.is-refused, .sp-note-dot.is-stalled, .sp-note-dot.is-offline { background: var(--status-error); }
.sp-note > .btn { flex: none; white-space: nowrap; }
.sp-sect-attention { color: var(--status-error); }
.sp-list { list-style: none; margin: 0; padding: 0; }
.sp-row { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-4); font-size: var(--type-sm); color: var(--fg-1); min-width: 0; }
.sp-row-dot { width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--status-warn); flex: none; }
.sp-row.is-connected .sp-row-dot { background: var(--presence-online); }
.sp-row.is-auth-rejected .sp-row-dot { background: var(--status-error); }
.sp-row-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); font-size: var(--type-xs); }
.sp-row-state { flex: none; font-size: var(--type-xs); color: var(--fg-2); }
.sp-row.is-auth-rejected .sp-row-state { color: var(--status-error); }
.sp-truncated { padding: var(--space-1) var(--space-4); font-size: var(--type-xs); color: var(--fg-2); }
.sp-assets-line { padding: var(--space-1) var(--space-4); font-size: var(--type-sm); color: var(--fg-1); }
.sp-assets-active { padding: 0 var(--space-4); font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-assets-retry { padding: var(--space-1) var(--space-4); font-size: var(--type-xs); color: var(--fg-2); }
/* A held breaker is not an error and not routine — it is waiting for a person. */
.sp-assets-retry strong { color: var(--fg-0); }
.sp-held-paths { margin-top: var(--space-1); }
.sp-held-paths summary { cursor: pointer; color: var(--fg-1); }
.sp-held-paths ul { margin: var(--space-1) 0 0; padding-left: var(--space-4); max-height: 12rem; overflow-y: auto; }
.sp-held-paths li { font-family: var(--font-mono, monospace); word-break: break-all; }
/* feature-sync-resync-and-out-of-process-sweep — Resync (header) re-runs the
 * whole sync; Cancel (assets line) stops only the upload sweep. */
.sp-resync { appearance: none; flex: none; font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-1); background: var(--bg-2); border: 1px solid var(--border-default); border-radius: var(--radius-sm); padding: 2px var(--space-2); cursor: pointer; transition: color var(--dur-soft) var(--ease-out), border-color var(--dur-soft) var(--ease-out); }
.sp-resync:hover:not(:disabled) { color: var(--fg-0); border-color: var(--border-strong); }
.sp-resync:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.sp-resync:disabled { color: var(--fg-3); cursor: default; }
.sp-resync-note { padding: 0 var(--space-4) var(--space-2); font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-base); }
/* Consent-class notices (feature-before-first-external-users Task 1) — a warm
   card at the top of the panel body: says what leaves this machine, dismissed
   per (notice, hub) on this machine. */
.sp-notice { margin: var(--space-2) var(--space-4); padding: var(--space-2) var(--space-3); border: 1px solid var(--status-warn); border-radius: var(--radius-md); background: color-mix(in oklab, var(--status-warn) 8%, transparent); }
.sp-notice-text { margin: 0 0 var(--space-1); font-size: var(--type-xs); color: var(--fg-1); line-height: var(--lh-base); }
.sp-notice-dismiss { appearance: none; font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-2); background: transparent; border: 0; padding: 0; cursor: pointer; text-decoration: underline; }
.sp-notice-dismiss:hover { color: var(--fg-0); }
.sp-notice-dismiss:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* First-upgrade sync consent (feature-before-first-external-users Task 2) —
   rides the shared .st-scrim/.st-dialog shell. */
.st-consent .st-dialog-bd { font-size: var(--type-sm); color: var(--fg-1); line-height: var(--lh-base); }
.st-consent .st-dialog-bd p { margin: 0 0 var(--space-2); }
.st-consent-list { margin: 0 0 var(--space-2); padding-left: var(--space-4); display: flex; flex-direction: column; gap: var(--space-1); }
.st-consent-fine { font-size: var(--type-xs); color: var(--fg-2); }
.st-consent-note { font-size: var(--type-xs); color: var(--status-error); }
.st-consent .st-dialog-ft { display: flex; justify-content: flex-end; gap: var(--space-2); }

/* Sync settings (feature-before-first-external-users Task 2) — the three
   toggles that used to mean "edit linkedHub.* JSON by hand". */
.sp-setting { display: flex; align-items: flex-start; gap: var(--space-2); padding: var(--space-1) var(--space-4); font-size: var(--type-sm); color: var(--fg-1); cursor: pointer; }
.sp-setting input[type='checkbox'] { margin-top: 2px; accent-color: var(--accent); flex: none; }
.sp-setting > span { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sp-setting small { font-size: var(--type-xs); color: var(--fg-2); line-height: var(--lh-base); }
.sp-setting-select { align-items: center; justify-content: space-between; }
.sp-setting-select select { font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-1); background: var(--bg-2); border: 1px solid var(--stroke-1); border-radius: var(--radius-sm); padding: 2px var(--space-1); flex: none; }
.sp-setting-select select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.sp-assets-cancel { appearance: none; margin-left: var(--space-2); font-family: var(--font-body); font-size: var(--type-xs); color: var(--fg-2); background: transparent; border: 0; padding: 0; cursor: pointer; text-decoration: underline; }
.sp-assets-cancel:hover { color: var(--status-error); }
.sp-assets-cancel:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* The popup — opens UPWARD from the dock (gi-menu anatomy). SOLID opaque menu
 * surface + border here (NOT the canvas `.panel`, which isn't in the client bundle
 * — phase-28 lesson; the tree must never bleed through). */
.rb-pop { padding: var(--space-2); display: flex; flex-direction: column; gap: 1px; background: var(--bg-2); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.rb-pop--up { position: absolute; left: 0; right: 0; bottom: calc(100% + var(--space-1)); z-index: 30; max-height: 600px; overflow-y: auto; }
.rb-pop-hd, .rb-pop-grouplabel { font-family: var(--font-mono); font-size: var(--type-xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--fg-2); padding: var(--space-2) var(--space-3) var(--space-1); }
.rb-pop-grouplabel { padding-top: var(--space-3); }
.rb-pop-item { display: flex; align-items: center; gap: var(--space-3); width: 100%; text-align: left; padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--fg-1); cursor: pointer; transition: background var(--dur-soft) var(--ease-out); }
.rb-pop-item:hover { background: var(--bg-2); }
.rb-pop-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.rb-pop-item.is-current { background: var(--accent-tint); }
.rb-pop-item--action { color: var(--accent); }
.rb-pop-icon { flex: 0 0 auto; color: var(--fg-2); display: grid; place-items: center; }
.rb-pop-item--action .rb-pop-icon { color: var(--accent); }
.rb-pop-icon--shared { color: var(--presence-online); }
.rb-pop-icon--draft { color: var(--status-warn); }
/* a remote-only draft (on the team's remote, not downloaded yet) reads quieter
 * than a local draft — it's a "could open" not a "yours". */
.rb-pop-icon--remote { color: var(--fg-2); }
.rb-pop-icon--spin svg { animation: rb-pop-spin 0.6s linear infinite; transform-origin: 50% 50%; }
@keyframes rb-pop-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .rb-pop-icon--spin svg { animation: none; } }
.rb-pop-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0; }
.rb-pop-name { font-weight: 600; font-size: var(--type-sm); color: var(--fg-0); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-pop-item--action .rb-pop-name { color: var(--accent); }
.rb-pop-sub { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-pop-item.is-current .rb-pop-sub { color: var(--fg-1); }
.rb-pop-check { color: var(--accent); flex: 0 0 auto; }
.rb-pop-sep { height: 1px; background: var(--border-default); margin: var(--space-2); }
/* draft filter — shown only once the draft list is long enough to warrant it. */
.rb-search { padding: var(--space-1) var(--space-2) var(--space-2); }
.rb-search-input { width: 100%; }
.rb-pop-empty { font-family: var(--font-mono); font-size: var(--type-xs); color: var(--fg-2); padding: var(--space-2) var(--space-3); }
/* fold-back CTA (Task 7) — the one filled action in the Version section. Compact:
 * type-sm title + type-xs sub + tight padding, so it reads as a strong row, not a
 * giant banner. */
.rb-fold { display: flex; align-items: center; gap: var(--space-2); width: 100%; text-align: left; margin: var(--space-2) 0; padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-sm); background: var(--accent); color: var(--accent-fg); cursor: pointer; transition: background var(--dur-soft) var(--ease-out); }
.rb-fold:hover { background: var(--accent-hover); }
.rb-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rb-fold-icon { flex: 0 0 auto; display: grid; place-items: center; color: var(--accent-fg); }
.rb-fold-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rb-fold-title { font-weight: 600; font-size: var(--type-sm); line-height: var(--lh-sm); color: var(--accent-fg); }
.rb-fold-sub { font-size: var(--type-xs); line-height: var(--lh-sm); color: var(--accent-fg); }
/* new-draft inline form (anchored upward above the dock). Solid bg (not `.panel`). */
.rb-newdraft { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); }
.rb-newdraft--up { position: absolute; left: 0; right: 0; bottom: calc(100% + var(--space-1)); z-index: 30; background: var(--bg-1); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.rb-newdraft-field { display: flex; flex-direction: column; gap: var(--space-2); }
.rb-newdraft-label { font-size: var(--type-sm); font-weight: 600; color: var(--fg-1); }
.rb-newdraft-input { width: 100%; }
.rb-newdraft-actions { display: flex; gap: var(--space-2); justify-content: flex-end; }
.rb-newdraft-err, .rb-switcher-err { color: var(--status-error); font-size: var(--type-xs); }
/* In-popup, non-blocking notice (DDR-133) — a Fetch failure shows here, contextual
   to the action, and never hides the branch list rendered above it. */
.rb-pop-notice { margin: var(--space-1) var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); background: color-mix(in oklch, var(--status-error) 12%, transparent); color: var(--status-error); font-size: var(--type-xs); line-height: var(--lh-md); }
.rb-newdraft-hint { margin: 0; color: var(--fg-2); font-size: var(--type-xs); line-height: var(--lh-md); }
/* switching state (compact, in the dock). */
.rb-switching { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-md); background: var(--bg-2); color: var(--fg-1); font-size: var(--type-sm); }
.rb-switching b { color: var(--fg-0); }
.rb-spin { color: var(--accent); animation: rb-spin 0.8s linear infinite; flex: 0 0 auto; }
@keyframes rb-spin { to { transform: rotate(360deg); } }
/* fold-back confirm sheet (modal over the shell). */
.rb-scrim { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: var(--space-6); background: color-mix(in oklab, var(--bg-0) 64%, transparent); backdrop-filter: blur(2px); }
.rb-sheet { width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-6); background: var(--bg-1); border: 1px solid var(--border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); text-align: left; }
.rb-sheet-icon { width: 38px; height: 38px; border-radius: var(--radius-md); display: grid; place-items: center; color: var(--accent); background: var(--accent-tint); margin-bottom: var(--space-1); }
.rb-sheet-title { margin: 0; font-family: var(--font-display); font-size: var(--type-lg); font-weight: 600; color: var(--fg-0); letter-spacing: var(--tracking-tight); }
.rb-sheet-body { margin: 0; color: var(--fg-1); font-size: var(--type-md); line-height: var(--lh-md); }
.rb-sheet-body b { color: var(--fg-0); font-weight: 600; }
.rb-sheet-meta { margin: 0; color: var(--fg-2); font-size: var(--type-sm); line-height: var(--lh-md); }
.rb-pr-url { font-family: var(--font-mono, ui-monospace, monospace); font-size: var(--type-xs); word-break: break-all; user-select: all; opacity: 0.8; }
.rb-sheet-actions { display: flex; gap: var(--space-2); justify-content: flex-end; margin-top: var(--space-2); }
@media (prefers-reduced-motion: reduce) {
  .rb-spin { animation-duration: 1ms; }
  .rb-trigger, .rb-pop-item, .rb-fold, .rb-identity-account { transition-duration: 1ms; }
}

}

/* ── enhanced-video-editing visual pass (FCP/iMovie proportions) ──────────── */
.tl-row--storyline { height: 64px; }
.tl-row--overlay { height: 36px; }
.tl-row--overlay .tl-seq-block { top: 3px; bottom: 3px; }
.tl-storyline-track .tl-seq-block { border-radius: 6px; }
.tl-storyline-track .tl-seq-block.tl-beat { border-right: 1px solid var(--bg-0); }
/* Filmstrip fills the block; identity moves into a small scrimmed chip. */
.tl-strip { opacity: 1; }
.tl-seq-block .tl-seq-name {
  position: absolute;
  left: 6px;
  bottom: 4px;
  max-width: calc(100% - 12px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  z-index: 1;
}
.tl-seq-block .tl-kind { position: absolute; top: 4px; left: 6px; z-index: 1; }
/* Overlay layers read FCP-purple; audio stays green via data-kind. */
.tl-row--overlay .tl-seq-block[data-kind="video"],
.tl-row--overlay .tl-seq-block[data-kind="image"] {
  border-color: color-mix(in oklch, #8b5cf6 55%, var(--accent-muted));
  background: color-mix(in oklch, #8b5cf6 16%, var(--bg-2));
}
/* Ruler: quieter frame ticks, prominent second ticks. */
.tl-ruler { height: 20px; border-bottom: 1px solid var(--bg-3); }
.tl-tick { background: none; bottom: auto; width: 0; border-left: 1px solid var(--bg-3); height: 6px; top: 14px; }
.tl-tick.is-major { height: 12px; top: 8px; border-left-color: var(--fg-3); }
.tl-tick-label { top: -12px; left: 3px; font-size: 9px; color: var(--fg-3); }
.tl-tick.is-major .tl-tick-label { color: var(--fg-2); }
/* Playhead: strong line + grab head, FCP style. */
.tl-playhead { width: 2px; background: var(--accent); }
.tl-playhead::before {
  content: '';
  position: absolute;
  top: -1px;
  left: -5px;
  width: 12px;
  height: 10px;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 0, 100% 45%, 50% 100%, 0 45%);
}
.tl-tracks { padding-top: 24px; min-height: 100%; }

/* ── Debate-driven UX pass: figure/ground, identity, predictive feedback ──── */
/* One dominant lane: the storyline is an inset trough; overlays recede. */
.tl-storyline-track {
  background: color-mix(in oklab, var(--fg-0) 7%, var(--bg-2));
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.18);
  border-radius: var(--radius-sm);
}
.tl-row--overlay .tl-row-track { background: color-mix(in oklab, var(--bg-2) 55%, var(--bg-1)); }
.tl-row--audio .tl-row-track { background: color-mix(in oklab, #22c55e 6%, var(--bg-1)); }
/* Blocks read as physical objects: stronger fill + inner top highlight. */
.tl-seq-block {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 1px 2px rgba(0, 0, 0, 0.12);
}
.tl-storyline-track .tl-seq-block.tl-beat {
  background: color-mix(in oklab, #0ea5e9 22%, var(--bg-1));
  border-color: color-mix(in oklab, #0ea5e9 60%, var(--bg-3));
}
/* Lane identity: V1/V2/A1 chips in a left-aligned gutter. */
.tl-row-label { justify-content: flex-start; padding-left: 6px; gap: 5px; }
.tl-lane-id {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  color: var(--fg-2);
  border: 1px solid var(--bg-3);
  border-radius: 3px;
  padding: 0 4px;
  background: var(--bg-2);
}
.tl-lane-id--story { color: var(--fg-0); border-color: var(--accent); background: color-mix(in oklab, var(--accent) 14%, var(--bg-2)); }
.tl-lane-id--audio { color: #15803d; border-color: color-mix(in oklab, #22c55e 45%, var(--bg-3)); }
/* Dogfood 2026-07-30 — vertical layer reorder: the V-chip is the drag handle. */
.tl-lane-id--grab { cursor: grab; touch-action: none; }
.tl-lane-id--grab:hover { border-color: var(--accent); color: var(--fg-0); }
.tl-row.is-layer-dragging { opacity: 0.6; }
.tl-row.is-layer-dragging .tl-lane-id--grab { cursor: grabbing; }
.tl-row.is-layer-target {
  box-shadow: inset 0 0 0 1px var(--accent);
  background: color-mix(in oklab, var(--accent) 8%, transparent);
}
/* Comment tool armed: the whole track area places pins. */
.tl-panel.is-commenting .tl-row-track,
.tl-panel.is-commenting .tl-seq-block,
.tl-panel.is-commenting .tl-ruler { cursor: crosshair; }
/* In-place 💬 badge pinned ON a clip at the comment's frame offset. */
.tl-clip-pin {
  position: absolute;
  top: -7px;
  width: 16px;
  height: 16px;
  display: grid;
  place-items: center;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  z-index: 4;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}
.tl-clip-pin.is-resolved { opacity: 0.4; }
/* Expand chevron on a decomposable storyline beat (old scene components). */
.tl-beat-expand {
  position: absolute;
  left: 3px;
  top: 3px;
  width: 15px;
  height: 15px;
  display: grid;
  place-items: center;
  font-size: 9px;
  color: var(--fg-2);
  background: color-mix(in oklab, var(--bg-0) 70%, transparent);
  border-radius: 3px;
  cursor: pointer;
  z-index: 3;
}
.tl-beat-expand:hover { color: var(--fg-0); background: var(--bg-0); }
/* Image overlays show the still itself. */
.tl-strip--img img { flex: 1 1 auto; width: 100%; object-fit: cover; }
/* Dragged beat LIFTS (grabbing hand, shadow, slight scale) — compositor-only. */
.tl-seq-block.is-dragging {
  cursor: grabbing;
  opacity: 0.95;
  transform: scale(1.02);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3);
  z-index: 6;
}
/* Neighbour shuffle + drops ride the DS motion tokens, not hardcoded ms. */
.tl-storyline-track.is-reordering .tl-seq-block:not(.is-dragging) {
  transition: left var(--dur-2, 160ms) var(--ease-out, ease-out);
}
/* Vertical layer-move target: the storyline glows while a clip hovers over it. */
.tl-storyline-track.is-drop-target {
  outline: 2px dashed var(--accent);
  outline-offset: -2px;
  background: color-mix(in oklab, var(--accent) 10%, var(--bg-2));
}
/* Snap confirmation: momentary accent rule at the latched frame. */
.tl-snapline {
  position: absolute;
  top: 18px;
  bottom: 0;
  width: 1px;
  background: var(--accent);
  box-shadow: 0 0 6px var(--accent);
  z-index: 5;
  pointer-events: none;
  animation: tl-snap-pulse 0.35s var(--ease-out, ease-out);
}
@keyframes tl-snap-pulse {
  0% { opacity: 1; }
  100% { opacity: 0.25; }
}
/* Playhead carries its own timecode. */
.tl-playhead-time {
  position: absolute;
  top: -2px;
  left: 8px;
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--bg-0);
  background: var(--accent);
  border-radius: 3px;
  padding: 0 4px;
  white-space: nowrap;
}
/* Affordances visible at REST (promote on hover) — zero-opacity told nothing. */
.tl-seq-resize, .tl-seq-trim-in {
  opacity: 0.35;
  background: color-mix(in oklab, var(--fg-0) 18%, transparent);
  border-radius: 2px;
}
.tl-seq-resize:hover, .tl-seq-trim-in:hover { opacity: 1; background: var(--accent); }
.tl-seam { opacity: 0.8; }
/* The dead space below the lanes IS the new-layer drop target. */
.tl-newlayer-zone {
  flex: 1;
  min-height: 44px;
  margin-top: 6px;
  border: 1.5px dashed var(--bg-3);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  color: var(--fg-3);
  font-size: var(--type-xs);
  font-family: var(--font-mono);
  transition: border-color var(--dur-2, 160ms) var(--ease-out, ease-out), background var(--dur-2, 160ms) var(--ease-out, ease-out);
}
.tl-newlayer-zone.is-active, .tl-panel.is-drop .tl-newlayer-zone {
  border-color: var(--accent);
  color: var(--fg-1);
  background: color-mix(in oklab, var(--accent) 7%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .tl-snapline { animation: none; }
  .tl-storyline-track.is-reordering .tl-seq-block:not(.is-dragging) { transition: none; }
  .tl-newlayer-zone { transition: none; }
}
