/*
 * Gate Ledger design language — light/dark/high-contrast themes, WCAG-checked contrast. Tokens and component styles ported from web/prototypes/design-language.prototype.html (#69) and web/prototypes/module-editor.prototype.html (#72), the two prototypes this screen's restyle is based on. See those files' own header comments for the hand-computed WCAG 2.1 contrast ratios behind each colour pair.
 *
 * Fonts: the prototypes loaded Space Grotesk / IBM Plex from Google Fonts for preview purposes only — gantry has no CDN-at-runtime dependency (every other browser dep is served from node_modules via the import map), so this stylesheet lists them as the *preferred* family with a system-font fallback chain, rather than fetching them. Self-hosting those two families under node_modules is follow-on work, not part of this ticket.
 */

:root {
  --font-display: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --radius: 2px;
  --hairline: 1px;
  --border-strong: 1px;
}

/* LIGHT (default) — paper/ink/vellum */
[data-theme='light'] {
  --bg: #EDEBE6;
  --bg-raised: #F5F3EE;
  --text: #1B1E22;
  --text-muted: #4A4740;
  --line: #B9B3A4;
  --line-strong: #5B5648; /* 6.88:1 vs bg */
  --focus-ring: #1B1E22;

  --stamp-draft-bg: #8A5A1F;
  --stamp-draft-fg: #F5F1E8;
  --stamp-agreed-bg: #295C40;
  --stamp-agreed-fg: #F5F1E8;
  --stamp-review-bg: #4A4740;
  --stamp-review-fg: #F5F1E8;
  /* 6.40:1 vs bg, 6.76:1 vs fg — per web/prototypes/instance-setup-wizard.
     prototype.html's own header comment flagging this as a candidate to
     fold back in once a real error/danger stamp was needed elsewhere
     (#78 is that use; #80 shipped it first with the same value). */
  --stamp-error-bg: #8C3A2B;
  --stamp-error-fg: #F5F1E8;
}

/* DARK — inverted paper/ink, not pure black */
[data-theme='dark'] {
  --bg: #1B1E22;
  --bg-raised: #24272C;
  --text: #EDEBE6;
  --text-muted: #B9B3A4;
  --line: #3A3D42;
  --line-strong: #8A8578; /* 4.55:1 vs bg */
  --focus-ring: #EDEBE6;

  --stamp-draft-bg: #D9A548;
  --stamp-draft-fg: #1B1E22;
  --stamp-agreed-bg: #6FBF97;
  --stamp-agreed-fg: #1B1E22;
  --stamp-review-bg: #B9B3A4;
  --stamp-review-fg: #1B1E22;
  --stamp-error-bg: #F2836B;  /* 6.56:1 vs bg */
  --stamp-error-fg: #1B1E22;
}

/* HIGH CONTRAST — pure black/white, bold solid borders, no hairlines */
[data-theme='hc'] {
  --bg: #000000;
  --bg-raised: #000000;
  --text: #FFFFFF;
  --text-muted: #FFFFFF;
  --line: #FFFFFF;
  --line-strong: #FFFFFF;
  --focus-ring: #FFD400;

  --stamp-draft-bg: #FFB000;
  --stamp-draft-fg: #000000;
  --stamp-agreed-bg: #00C853;
  --stamp-agreed-fg: #000000;
  --stamp-review-bg: #000000;
  --stamp-review-fg: #FFFFFF;
  --stamp-error-bg: #FF6B57;  /* 7.49:1 vs bg */
  --stamp-error-fg: #000000;

  --hairline: 2px;
  --border-strong: 3px;
  --radius: 0px;
}

* { box-sizing: border-box; }

html { background: var(--bg); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
}

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

a { color: inherit; }
:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }

header {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 32px 20px;
  border-bottom: var(--border-strong) solid var(--line-strong);
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand svg { flex-shrink: 0; }
/* `.btn`'s default `margin: 0.5rem 0.5rem 0 0` would drop every header button
   (incl. the instance switcher) below the zero-margin `.instance-ref` badge in
   this centred flex row — the row's own `gap` handles spacing. */
.brand .btn { margin: 0; }
.brand h1 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  font-size: 22px;
  margin: 0;
  flex: 1;
}
.theme-toggle { margin: 0; text-transform: capitalize; }
/* WI200/docs/adr/0024's numeric reference — shown next to the instance name so it's discoverable on screen, not just in the URL bar. */
.instance-ref {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: 4px;
  padding: 2px 6px;
}
/* #145: once the header title switches to the instance's display name, its slug moves here — a
   small secondary badge beside `.instance-ref`, same treatment, so it stays visible without
   competing with the display name for the primary spot. Only rendered when a name is actually
   set (AppHeader), so a no-name instance's header is byte-for-byte what it was before this. */
.instance-slug {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: 4px;
  padding: 2px 6px;
}

/*
 * Instance switcher (#112) — a toggle button in AppHeader plus an
 * absolutely-positioned panel, structurally modeled on `.chip .menu`'s own
 * popup-menu shape below, but conditionally rendered (see web/app.js's
 * InstanceSwitcher) rather than display-toggled via a parent class, since
 * it isn't nested inside a per-item click-outside wrapper the way
 * SwimlaneChip's own menu is.
 */
.instance-switcher { position: relative; }
.instance-switcher .menu {
  position: absolute;
  left: 0;
  top: 30px;
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 220px;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px 0;
}
.instance-switcher .switcher-heading {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  padding: 6px 12px 2px;
}
.instance-switcher .switcher-item { display: block; padding: 6px 12px; text-decoration: none; color: var(--text); font-size: 13px; }
.instance-switcher .switcher-item:hover { background: var(--bg); }
.instance-switcher .switcher-item .def { display: block; font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); }
.instance-switcher .switcher-empty { padding: 6px 12px; font-size: 12px; color: var(--text-muted); margin: 0; }
.instance-switcher .switcher-escape,
.instance-switcher .switcher-back {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-top: var(--hairline) solid var(--line);
  padding: 8px 12px;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
  font-family: var(--font-body);
  text-decoration: none;
}
.instance-switcher .switcher-escape:hover,
.instance-switcher .switcher-back:hover { color: var(--text); background: var(--bg); }
.instance-switcher .switcher-group + .switcher-group { border-top: var(--hairline) solid var(--line); margin-top: 4px; padding-top: 4px; }

#stage-line { color: var(--text-muted); margin: 6px 0 0; font-size: 13px; }
#stage-nav { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
#stage-nav button.stage-current { border-color: var(--line-strong); }

/*
 * View-mode toolbar (#79) — a toolbar segmented control (Markdown / Split / Rendered) for the whole module-editor screen, ported from Variant A of web/prototypes/module-editor.prototype.html (#72).
 *
 * Sticky (#135) — the bar pins to the top of the viewport once scrolled past,
 * so markdown/split/rendered switching stays reachable while scrolling long
 * modules. Its parent is #app (full page height), so it sticks for the whole
 * scroll; z-index sits above in-flow content, below the field popovers (9)
 * — an open Headings/Insert menu must stay visible if its anchor scrolls
 * beneath the pinned bar — and below modal backdrops (20).
 */
.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 1120px;
  margin: 0 auto;
  padding: 14px 32px;
  background: var(--bg-raised);
  border-bottom: var(--hairline) solid var(--line);
  position: sticky;
  top: 0;
  z-index: 8;
}
/*
 * Suppressed while a field panel owns the screen (#135): a full-screen field
 * covers the viewport anyway, and un-sticking keeps the bar out of the
 * layout entirely for as long as <html> carries data-field-fullscreen.
 */
[data-field-fullscreen] .toolbar { position: static; }
.segmented { display: inline-flex; border: var(--border-strong) solid var(--line-strong); border-radius: var(--radius); overflow: hidden; }
.segmented button { border: none; border-right: var(--hairline) solid var(--line-strong); border-radius: 0; margin: 0; }
.segmented button:last-child { border-right: none; }

/*
 * Right-hand side of the view-mode toolbar (#114) — "Clear all fields" and
 * "Render" (which opens the render-artefact-picker dialog), replacing the
 * old per-stage stage-actions bar and per-artefact Render button set.
 */
.toolbar-left, .toolbar-actions { display: flex; align-items: center; }
.toolbar-left { gap: 14px; min-width: 0; }
.toolbar-actions .btn { margin: 0 0 0 8px; }
.toolbar-field { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.toolbar-field > span:first-child { text-transform: uppercase; letter-spacing: 0.08em; }
.artefact-selector .artefact-value {
  font: 600 12px var(--font-body);
  color: var(--text);
}
/* #151: an Artefact that doesn't count toward its gate (`satisfies-gate: false`). */
.artefact-gate-hint { font-style: italic; font-weight: 400; color: var(--text-muted); }

/* View-mode visibility, driven by data-view-mode on main#modules (#79, #374).
 * Visual and Markdown are one editor; Split adds the Visual pane beside the source. */
main:not([data-view-mode='split']) .field-markdown .visual-pane { display: none; }

@media (max-width: 680px) {
  .toolbar { align-items: stretch; flex-direction: column; gap: 10px; }
  .toolbar-left { flex-wrap: wrap; }
  .toolbar-actions { justify-content: flex-end; flex-wrap: wrap; }
  .artefact-dropdown > .btn { max-width: min(280px, 65vw); overflow: hidden; text-overflow: ellipsis; }
}

main#modules, .load-error, .loading {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 32px 140px;
}

/*
 * `.btn` styles any `<button class="btn">` or `<a class="btn">` alike — the instance dashboard (#77) uses real `<a>` navigation (e.g. "Open editor", "+ New instance") so preact-iso's anchor-click interception handles it as client-side routing, not a `<button onClick>` that would need its own manual `route()` call to the same effect.
 */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  padding: 8px 14px;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  margin: 0.5rem 0.5rem 0 0;
}
.btn.primary { background: var(--text); color: var(--bg); border-color: var(--text); }
.btn.ghost { background: transparent; border-color: var(--line); }
.btn.small { padding: 5px 10px; font-size: 12px; }
.btn.active { background: var(--text); color: var(--bg); border-color: var(--text); }
button.btn:disabled { opacity: 0.4; cursor: not-allowed; }

/*
 * Status pill — used by the module editor's own module status (not currently surfaced in this screen's markup) and by the instance dashboard's (#77) stage/gate/status/owner detail pane and swimlane chips.
 */
.stamp {
  display: inline-block;
  padding: 3px 8px;
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.07em;
}
.stamp.draft  { background: var(--stamp-draft-bg);  color: var(--stamp-draft-fg); }
.stamp.review { background: var(--stamp-review-bg); color: var(--stamp-review-fg); }
.stamp.agreed { background: var(--stamp-agreed-bg); color: var(--stamp-agreed-fg); }
.stamp.error  { background: var(--stamp-error-bg);  color: var(--stamp-error-fg); }

.module { border-top: var(--hairline) solid var(--line); padding-top: 20px; margin-top: 28px; }
.module h2 { font-family: var(--font-display); font-weight: 600; font-size: 17px; margin: 0 0 4px; }
.module .purpose { color: var(--text-muted); font-style: italic; font-size: 13px; margin: 0 0 16px; }
/* #152: a module the stage mounts read-only — its saved content, no editors, and a note naming the
 * earlier stage where it is edited. */
.module .read-only-note { font-size: 12px; color: var(--text-muted); background: var(--bg-raised); border-left: var(--border-strong) solid var(--line-strong); padding: 6px 10px; margin: 4px 0 12px; }
.field-read-only .read-only-value { font-size: 14px; margin: 0; }
.field-read-only .read-only-value.muted { color: var(--text-muted); font-style: italic; font-size: 13px; }
.field-read-only .read-only-value > :first-child { margin-top: 0; }
.field-read-only .read-only-value > :last-child { margin-bottom: 0; }

/* Render dialog (#114) — the artefact list inside the modal opened by the
 * toolbar's "Render" button. */
.render-artefact-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.render-artefact-list .btn { width: 100%; margin: 0; text-align: left; }
/* Deliberately a literal black, not a theme token — a toggled artefact
 * should read as "selected for this batch" identically in every theme,
 * not blend into whichever theme's own emphasis color already means
 * something else (see .btn.active). */
.render-artefact-list .btn.toggled,
.render-artefact-list .btn.toggled:hover { background: #000; color: #fff; border-color: #000; }

/* Work item details card (#111, folded into by #213) — sits at the top of
   the instance screen, above the modules, so it reads as a header card
   rather than one more section: a raised box (the only bordered panel on
   this screen) with its fields laid out as a wrapping grid, each distinct.
   #213 folded the old standalone "Request Review" and "Review / Sign-off"
   panels' entire functionality into this one card (one "Check status"
   button, a richer reviews list, and the sign-off flow) — there is no
   longer a separate bottom-of-page section for any of it. */
.synced-fields-panel { border: var(--border-strong) solid var(--line-strong); background: var(--bg-raised); padding: 16px 20px; margin-top: 32px; margin-bottom: 32px; }
.panel-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 12px; }
.panel-header h2 { margin: 0; }
.panel-header-actions { display: flex; align-items: center; gap: 8px; }
.synced-fields-panel h2 { font-family: var(--font-display); font-weight: 600; font-size: 17px; margin: 0 0 12px; }
.synced-fields-grid { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: flex-end; }
.synced-field { display: flex; flex-direction: column; gap: 4px; min-width: 160px; }
.synced-field .field-label { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); }
.synced-field .text-field { max-width: 320px; }
.synced-field-wide { flex: 1 1 260px; }
.synced-value { font-size: 14px; padding: 6px 0; margin: 0; }

/* Reviews & sign-off sub-card (#197, consolidated by #213) — the single
   place on the page for both: a two-column layout (stacking on narrow
   viewports) sitting directly inside the details card, each side its own
   richer per-row list (reviewer name, work item link, status) rather than
   the old compact one-line summary — that summary and the standalone
   panels' own rich lists were the same data shown twice; this is the one
   copy. Every action here reads/writes through the card's shared state;
   the only "Check status" control is the button in .panel-header above. */
.review-signoff-card { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 20px; padding-top: 16px; border-top: var(--hairline) solid var(--line); }
.review-signoff-section { min-width: 0; }
/* The "not the current stage" hint is a full-width note above the two
   columns — without this it takes the first grid cell and pushes Reviews
   and Sign-off out of their columns. */
.review-signoff-card .stage-advance-hint { grid-column: 1 / -1; margin: 0; }
.review-signoff-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.review-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.review-list li { display: flex; gap: 10px; justify-content: space-between; align-items: baseline; font-size: 13px; }
.review-reviewer { overflow-wrap: anywhere; }
.review-meta { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.review-status { color: var(--text-muted); }
.signoff-pr-ref { margin: 8px 0 0; font-size: 13px; }
.signoff-actions { display: flex; align-items: center; gap: 8px; }

/* Review grouping by outcome (#215) — once a stage's Reviews list grows
   past a couple of requests, `.reviews-section` renders one `.review-group`
   per non-empty outcome bucket (pending / changes-requested / approved,
   see web/app.js's `classifyReviewOutcome`) instead of one flat
   `.review-list`; two or fewer reviews still render that same flat list
   directly, no group labels. */
.review-group + .review-group { margin-top: 14px; }
.review-group-label { display: flex; align-items: center; gap: 8px; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); margin-bottom: 6px; }

/* Commit history (#225) — the trigger now lives in `.panel-header`
   alongside "Check status"; the full-history modal (CommitHistoryDialog)
   is the one place to see every commit. */

.advance-stage-panel { border-top: var(--border-strong) solid var(--line-strong); padding-top: 20px; margin-top: 32px; }
.advance-stage-panel h2 { font-family: var(--font-display); font-weight: 600; font-size: 17px; margin: 0 0 8px; }

.request-approval-commits { margin: 0; padding-left: 20px; }
.request-approval-commits li { display: flex; gap: 12px; justify-content: space-between; margin: 4px 0; }
.request-approval-commits li span { overflow-wrap: anywhere; }
.request-approval-commits time { color: var(--text-muted); white-space: nowrap; }

.review-request-list { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; }
.review-request-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px 12px; align-items: end; }
.reviewer-field { min-width: 0; }
.review-request-result { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; font-size: 12px; text-align: right; }
.review-request-row > .save-status { grid-column: 1 / -1; margin: 0; }

@media (max-width: 760px) {
  .review-signoff-card { grid-template-columns: 1fr; gap: 20px; }
}

/* Flash highlight animation (WI154, #145 Part 1) — brief background pulse on
   the Work item details card when the view-bar's "Review / Sign-off"
   shortcut scrolls to it (#213 retargeted this from the old standalone
   sign-off panel to the merged card), giving the user a visual anchor.
   Triggered sequenced *after* the smooth scroll settles (via `scrollend` or
   a ~300 ms timeout fallback) so the eye catches it at rest; one-shot and
   self-clearing via `animationend` so it never persists, and still fires
   when the panel is already in view. The flash cycles through pulses of
   the raised background, then holds transparent. `prefers-reduced-motion`
   (above, line 98) kills the animation entirely, leaving the panel simply
   scrolled-into-view. */
@keyframes panel-flash {
  0%   { background: var(--bg-raised); }
  33%  { background: transparent; }
  66%  { background: var(--bg-raised); }
  100% { background: transparent; }
}
.synced-fields-panel.flash { animation: panel-flash 1.2s ease-out; }

/*
 * Identity picker (#145 Part 2) — a combobox-style input with a
 * typeahead dropdown, used in place of every plain text input for
 * people fields (workspace Owner, per-instance required-reviewer
 * override, instance Assignee). The input shows the display name
 * while the underlying value is a uniqueName. Debounced search
 * against the `GET /api/identities` endpoint; a clear button
 * (×) lets the user blank the field.
 */
.identity-picker { position: relative; flex: 1 1 auto; }
.identity-picker input {
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 8px 11px;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
  width: 100%;
}
.identity-picker input::placeholder { color: var(--text-muted); }
.identity-picker input.has-error { border-color: var(--stamp-error-bg); }
.identity-picker .clear-btn {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
}
.identity-picker .clear-btn:hover { color: var(--text); }
.identity-picker .identity-dropdown {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  margin-top: 2px;
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  max-height: 220px;
  overflow-y: auto;
}
.identity-picker .identity-dropdown.open { display: block; }
.identity-picker .identity-dropdown .identity-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  font-size: 13px;
  font-family: var(--font-body);
  color: var(--text);
  background: none;
  border: none;
  cursor: pointer;
  box-sizing: border-box;
}
.identity-picker .identity-dropdown .identity-option:hover { background: var(--bg); }
.identity-picker .identity-dropdown .identity-option .name { font-weight: 600; }
.identity-picker .identity-dropdown .identity-option .email { font-size: 11px; color: var(--text-muted); margin-left: 6px; }
.identity-picker .identity-dropdown .no-results { padding: 8px 12px; font-size: 12px; color: var(--text-muted); }
/* #10, docs/adr/0040: a person who resolves but can't be assigned a GitHub issue — shown, not hidden, but not selectable. */
.identity-picker .identity-dropdown .identity-option.blocked { cursor: not-allowed; opacity: 0.6; }
.identity-picker .identity-dropdown .identity-option.blocked:hover { background: none; }
.identity-picker .identity-dropdown .identity-option .blocked-reason { display: block; font-size: 11px; color: var(--stamp-error-bg, #b91c1c); margin-top: 2px; }

.field { margin-top: 20px; }
.field label { font-family: var(--font-display); font-weight: 600; font-size: 13px; display: block; margin-bottom: 6px; }
.field h3.field-heading { font-family: var(--font-display); font-weight: 600; font-size: 13px; display: block; margin: 0 0 6px; }
.guidance { color: var(--text-muted); font-size: 12px; margin: 0 0 8px; }

/* Stage navigation dropdown (WI232) — inline in ViewModeToolbar to the right of the artefact selector */
.stage-navigation { margin: 0; display: inline-flex; align-items: center; }
/* Neutralise .btn's default 0.5rem top/right margin so the trigger sits on the
   same baseline as the segmented view-mode buttons (which reset it too). */
.stage-navigation .btn { margin: 0; }
/* Mode, Artefact and Navigation open one kind of menu, at one font size (WI #379). */
.stage-navigation-dropdown,
.view-mode-dropdown,
.artefact-dropdown { position: relative; display: inline-flex; }
.view-mode-dropdown .btn,
.artefact-dropdown .btn { margin: 0; }
.artefact-dropdown > .btn { max-width: 280px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stage-navigation-dropdown .menu,
.view-mode-dropdown .menu,
.artefact-dropdown .menu {
  display: none;
  position: absolute;
  left: 0;
  top: 100%;
  margin-top: 6px;
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 220px;
  max-width: 360px;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px 0;
}
.stage-navigation-dropdown.menu-open .menu,
.view-mode-dropdown.menu-open .menu,
.artefact-dropdown.menu-open .menu { display: block; }
/* The current view: weight and a leading bar, not generated text — a CSS
 * ::before glyph would join the option's accessible name. */
.view-mode-dropdown .nav-item[aria-checked='true'],
.artefact-dropdown .nav-item[aria-checked='true'] { font-weight: 600; box-shadow: inset 3px 0 0 var(--text); }
.stage-navigation-dropdown .nav-item,
.view-mode-dropdown .nav-item,
.artefact-dropdown .nav-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text);
  background: none;
  border: none;
  cursor: pointer;
  box-sizing: border-box;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stage-navigation-dropdown .nav-item:hover,
.view-mode-dropdown .nav-item:hover,
.artefact-dropdown .nav-item:hover { background: var(--bg); }
.stage-navigation-dropdown .nav-item-h3 { padding-left: 24px; }

.field-markdown .split { display: flex; gap: 16px; align-items: stretch; }
/* The toolbar mounts inside this pane above the editor host, so the pair
 * reads as one attached control (#133): toolbar flush on top, editor below. */
.field-markdown .editor-pane,
.field-markdown .visual-pane { display: flex; flex-direction: column; min-width: 0; flex: 1 1 0; }
.field-markdown .editor-host {
  flex: 1;
  min-width: 0;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  min-height: 100px;
}
.field-markdown .editor-host .cm-editor { height: 100%; }
/* The pane being edited (#374 follow-up): unmistakable in Split, where source
 * and Visual panes sit side by side. The whole host takes a thick focus-ring
 * frame — whether focus is in its text or in one of its Visual table cells —
 * and CodeMirror's own faint dotted focus outline is retired in its favour. */
.field-markdown .editor-host .cm-editor.cm-focused { outline: none; }
.field-markdown .editor-host { transition: box-shadow 0.12s, border-color 0.12s; }
.field-markdown .editor-host:focus-within {
  border-color: var(--focus-ring);
  box-shadow: 0 0 0 2px var(--focus-ring);
}
/* In Split the pane not being edited recedes, so the active one reads at a glance. */
main[data-view-mode='split'] .field-markdown .split:focus-within .editor-host:not(:focus-within) {
  opacity: 0.72;
}
.field-markdown .editor-host .cm-content,
.field-markdown .editor-host .cm-gutters {
  font-family: var(--font-mono);
  font-size: 13px;
}
/* WI #353: a ```mermaid fence rendered in place (web/lib/mermaid.js). The
 * figure is a plain block so the diagram sizes to the field's width; a
 * diagram that failed to parse keeps its <pre> and gains a muted note. */
.field-markdown .md-rendered figure.mermaid-diagram {
  margin: 12px 0;
  overflow-x: auto;
  background: #fff;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: 8px;
}
.field-markdown .md-rendered figure.mermaid-diagram svg { max-width: 100%; height: auto; }
.field-markdown .md-rendered pre.mermaid-error { border-left: 3px solid var(--danger, #b00020); }
.field-markdown .md-rendered .mermaid-error-note { color: var(--text-muted, #666); font-size: 12px; margin: -6px 0 12px; }

/*
 * Formatting toolbar (#133) — one slim strip per focused markdown field.
 * The B/I/S letters are deliberately unadorned spans that CSS styles to
 * demonstrate their own effect (bold weight, italic slant, line-through) in
 * every theme, per the ticket's "self-demonstrating" requirement; the other
 * buttons use small currentColor stroke icons so light/dark/high-contrast
 * all come free.
 */
.md-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px;
  padding: 3px 5px;
  margin-bottom: -1px;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
}
.md-toolbar + .split .editor-host {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
/* The table strip (#134, Markdown view only) stacks above the formatting toolbar as one attached
 * unit: it carries the top radius, and the toolbar beneath it squares off. */
.md-toolbar.table-toolbar + .md-toolbar {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.md-btn {
  appearance: none;
  border: none;
  background: none;
  color: var(--text-muted);
  min-width: 26px;
  height: 24px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 12px;
}
.md-btn:hover { color: var(--text); background: var(--bg); }
.md-btn svg { display: block; }
.md-letter { font-size: 13px; line-height: 1; font-family: var(--font-body); }
.md-letter-bold { font-weight: 700; }
.md-letter-italic { font-style: italic; }
.md-letter-strike { text-decoration: line-through; }
.md-glyph { letter-spacing: -1px; }
.md-quote-glyph {
  font-family: var(--font-display);
  font-size: 15px;
  line-height: 1;
  transform: translateY(-2px);
}
.md-sep { width: 1px; height: 16px; background: var(--line); margin: 0 4px; }
.md-toolbar [data-command="fullscreen"] { margin-left: auto; }
.md-headings,
.md-lists {
  position: relative;
}
.md-headings .menu,
.md-lists .menu {
  display: none;
  position: absolute;
  right: 0;
  top: 27px;
  /* Above the sticky view bar (#135): scrolling with the menu open must not
   * slide it underneath the pinned toolbar. */
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 130px;
}
.md-headings .menu-open .menu,
.md-lists .menu-open .menu { display: block; }
.md-headings .menu button,
.md-lists .menu button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 8px 12px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text);
  cursor: pointer;
  box-sizing: border-box;
}
.md-headings .menu button:hover,
.md-lists .menu button:hover { background: var(--bg); }

/*
 * Full-screen field expansion (#135) — the field's own wrapper is the
 * full-screen element, so the UA's "fills the viewport" default is re-flowed
 * into the Gate Ledger layout: label keeps its natural height
 * while the split row takes everything that's left, meaning markdown mode
 * gets a full-height editor, split mode gets BOTH panes filling the screen,
 * and each pane scrolls internally rather than pushing the toolbar away.
 */
.field-markdown:fullscreen {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  padding: 20px 32px 28px;
  overflow: auto;
}
.field-markdown:fullscreen .split {
  flex: 1 1 auto;
  min-height: 240px;
}
.field-markdown:fullscreen > label,
.field-markdown:fullscreen > .guidance,
.field-markdown:fullscreen > .insert-area { flex-shrink: 0; }

.field-list .list-row { display: flex; gap: 8px; margin-bottom: 6px; align-items: flex-start; }
.field-list input,
.field-list textarea {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.5;
  padding: 7px 10px;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
}
.field-list textarea {
  resize: none;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.field-list input::placeholder,
.field-list textarea::placeholder { color: var(--text-muted); }

.field-select select,
.field-text input[type='text'],
.field-date input[type='date'] {
  width: 100%;
  max-width: 420px;
  font-family: var(--font-body, inherit);
  font-size: 13px;
  padding: 7px 10px;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
}
.field-select select:has(option.field-select-offlist:checked) { border-color: var(--warning, #b06a00); }
.field-select-warning { font-size: 12px; color: var(--warning, #b06a00); margin: 6px 0 0; }

.select-checkboxes { display: flex; flex-direction: column; gap: 4px; }
.select-checkbox-row { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: normal; cursor: pointer; }
.select-checkbox-row input[type='checkbox'] { margin: 0; }
.select-checkbox-row.field-select-offlist span { color: var(--warning, #b06a00); }

.save-status { font-size: 0.9rem; color: var(--text-muted); min-height: 1.2em; margin-top: 0.5rem; white-space: pre-line; }
.load-error, .loading { padding-top: 48px; color: var(--text-muted); }

/*
 * Instance dashboard (#77) — the landing screen at `/`. Layout treatments adapted from web/prototypes/instance-dashboard.prototype.html's variants B (master-detail, the default) and C (stage swimlanes); variant A (ledger register) wasn't chosen and isn't implemented. Same tokens and `.btn`/`.stamp` components as the rest of this stylesheet — nothing dashboard-specific is re-invented here beyond layout.
 */
main.dashboard {
  max-width: 1120px;
  margin: 0 auto;
  padding: 40px 32px 140px;
}
.dashboard-topbar { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: 24px; }
.dashboard-heading { display: flex; align-items: center; gap: 10px; }
.dashboard-heading svg { flex-shrink: 0; }
.dashboard-topbar h1 { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.01em; font-size: 26px; margin: 0; }
.dashboard-controls { display: flex; align-items: center; gap: 10px; }
.lede { color: var(--text-muted); margin: 6px 0 0; max-width: 70ch; }

/* Archived-instance banner (#223) — shown at the top of the module editor for an archived instance. */
.archived-banner {
  margin: 0 auto 16px;
  max-width: 1120px;
  padding: 10px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted);
  border-radius: 8px;
  background: var(--surface-raised, transparent);
  color: var(--text-muted);
  font-size: 14px;
}

/* Stage-branch "behind main" sync banner (WI #286) — reuses the archived-banner
   look but needs a gap from the horizontal rule it sits under. */
.stage-sync-banner {
  margin-top: 16px;
}

/* Archived instances (#223) — a collapsed list below the active dashboard views. */
.archived-panel { margin-top: 32px; border-top: 1px solid var(--border); padding-top: 16px; }
.archived-panel > summary { cursor: pointer; color: var(--text-muted); font-size: 14px; user-select: none; }
.archived-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.archived-row { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px; }
.archived-row .name { font-weight: 600; }
.archived-row .def { color: var(--text-muted); font-size: 13px; }
.archived-row .btn { margin-left: auto; }

.view-toggle { position: relative; display: inline-flex; }
.view-toggle .menu {
  display: none;
  position: absolute;
  right: 0;
  top: 100%;
  margin-top: 6px;
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 140px;
}
.view-toggle.menu-open .menu { display: block; }
.view-toggle .menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text);
  background: none;
  border: none;
  box-sizing: border-box;
  cursor: pointer;
  white-space: nowrap;
}
.view-toggle .menu button:hover,
.view-toggle .menu button.selected { background: var(--bg); }
.view-toggle .menu button.selected { font-weight: 600; }

.dashboard-empty {
  text-align: center;
  color: var(--text-muted);
  padding: 80px 20px;
  border: var(--hairline) dashed var(--line);
  border-radius: var(--radius);
}
.dashboard-empty p { margin: 0 0 16px; }

/* ---------- Master-detail ---------- */
.master-detail {
  display: grid;
  grid-template-columns: 320px 1fr;
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  min-height: 480px;
}
.master-detail .list-pane { border-right: var(--hairline) solid var(--line); padding: 16px; background: var(--bg-raised); }
.master-detail .list-pane .search { width: 100%; margin-bottom: 12px; box-sizing: border-box; }
.master-detail .list-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 8px;
  border-radius: var(--radius);
  cursor: pointer;
  border: var(--hairline) solid transparent;
}
.master-detail .list-item:hover { background: var(--bg); }
.master-detail .list-item.selected { border-color: var(--line-strong); background: var(--bg); }
.master-detail .list-item .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.master-detail .list-item .dot.agreed { background: var(--stamp-agreed-bg); }
.master-detail .list-item .dot.draft { background: var(--stamp-draft-bg); }
/* #122: a registered-but-unrepresented workspace that's confirmed unreadable (web/lib/dashboardWorkspaces.js) — same red as .stamp.error, so "can't read this" reads as a distinct severity from the neutral .dot.draft its "nothing registered yet" sibling shares with "in progress". */
.master-detail .list-item .dot.unreadable { background: var(--stamp-error-bg); }
.master-detail .list-item .meta { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.master-detail .list-item .meta .name { font-family: var(--font-display); font-weight: 600; font-size: 14px; overflow-wrap: anywhere; min-width: 0; }
.master-detail .list-item .meta .def { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); overflow-wrap: anywhere; min-width: 0; }
.master-detail .detail-pane { padding: 28px; }
.master-detail .detail-pane h2 { font-family: var(--font-display); font-weight: 600; font-size: 20px; margin: 0 0 4px; }
.master-detail .workspace-subtitle { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); margin: 0 0 8px; }
.master-detail .workspace-detail-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.master-detail .workspace-detail-head .btn { flex: none; }
.master-detail .workspace-settings-link { font-size: 13px; margin: 0 0 20px; }
.instance-card .field-label { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted); margin-bottom: 2px; }
.instance-card .assignee { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
.master-detail .detail-actions { display: flex; gap: 10px; }
.master-detail .placeholder { color: var(--text-muted); text-align: center; padding: 80px 20px; }

/*
 * One card per instance under the selected workspace (#102) — replaces the single-instance `.detail-ledger` the old flat dashboard showed: a workspace can hold several instances at once, so the detail pane lists one of these per instance rather than one ledger for "the" selected instance.
 */
.workspace-instances { display: flex; flex-direction: column; gap: 16px; }
.instance-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 20px;
  padding: 16px 20px;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
}
.instance-card-content { min-width: 0; }
.instance-card-header { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.instance-card-header .name { font-family: var(--font-display); font-weight: 600; font-size: 16px; }
.instance-card-header .def { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
.instance-card-header .ref { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
.instance-card-status { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; }
.pr-badge { padding: 2px 5px; border: var(--hairline) solid var(--line-strong); border-radius: var(--radius); font-family: var(--font-mono); font-size: 10px; font-weight: 600; letter-spacing: 0.04em; }
.instance-card-context { display: flex; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.stage-position { font-family: var(--font-display); font-size: 13px; }
.updated-at { color: var(--text-muted); font-family: var(--font-mono); font-size: 11px; }
.instance-card-row { margin-bottom: 4px; }
.manage-card {
  align-self: start;
  min-width: 150px;
  padding: 10px 12px;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}
.manage-card h3 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.manage-link {
  display: block;
  color: var(--text);
  font-size: 12px;
  line-height: 1.5;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.manage-link + .manage-link { margin-top: 4px; }

@media (max-width: 700px) {
  .instance-card { grid-template-columns: 1fr; }
  .manage-card { justify-self: stretch; }
}

/* ---------- Local workspaces, blended into the master-detail list (#296/A5, reworked by #306) ---------- */
/* WI #357: a local workspace's instances now render through the same .instance-card / .workspace-instances
   rules every other workspace kind uses (see InstanceCard, web/app.js) — the plain-row .local-instance-list/
   .local-instance-row styling above is retired along with that code path. */
.local-workspace-recovery p { margin: 0 0 8px; color: var(--text-muted); font-size: 13px; }

/* ---------- Stage swimlanes ---------- */
.swimlane-group + .swimlane-group { margin-top: 32px; }
.swimlane-group-title { font-family: var(--font-display); font-weight: 600; font-size: 15px; margin: 0 0 12px; }
.swimlanes .lanes { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.swimlanes .lane { border: var(--hairline) solid var(--line); border-radius: var(--radius); background: var(--bg-raised); min-height: 200px; padding: 12px; }
.swimlanes .lane-header { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 10px; margin-bottom: 10px; border-bottom: var(--border-strong) solid var(--line-strong); }
.swimlanes .lane-header .stage-name { font-family: var(--font-display); font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }
.swimlanes .lane-header .count { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }
.swimlanes .empty-lane { color: var(--text-muted); font-size: 12px; text-align: center; padding: 20px 8px; border: 1px dashed var(--line); border-radius: var(--radius); }

.chip { position: relative; border: var(--hairline) solid var(--line); border-radius: var(--radius); background: var(--bg); padding: 10px 12px; margin-bottom: 10px; }
.chip .name { font-family: var(--font-display); font-weight: 600; font-size: 13px; }
.chip .def { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); margin: 3px 0 6px; }
.chip .chip-foot { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.chip .assignee { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); }
.chip .menu-btn { line-height: 1; }
.chip .menu {
  display: none;
  position: absolute;
  right: 8px;
  top: 34px;
  z-index: 5;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 130px;
}
.chip.menu-open .menu { display: block; }
.chip .menu button, .chip .menu a {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 8px 12px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  box-sizing: border-box;
}
.chip .menu button:hover, .chip .menu a:hover { background: var(--bg); }

/*
 * Per-field Insert dropdown (#132) — every markdown field carries its own
 * "Insert ▾" control offering Section / List, replacing #80's single
 * "+ Insert asset" button after each module. The trigger keeps that button's
 * quiet mono-underlined look so it reads as an affordance, not chrome; the
 * popup reuses the exact menu shape of .settings-menu (#107), just anchored
 * under the field instead of the header.
 */
.insert-dropdown { position: relative; display: inline-flex; margin-top: 10px; }
.insert-trigger {
  background: none;
  border: none;
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 12px;
  text-decoration: underline dotted;
  cursor: pointer;
  padding: 0;
}
.insert-trigger:hover { color: var(--text); }
.insert-dropdown .menu {
  display: none;
  position: absolute;
  left: 0;
  top: 100%;
  margin-top: 6px;
  /* Above the sticky view bar, same as the Headings menu (#135). */
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 120px;
}
.insert-dropdown.menu-open .menu { display: block; }
.insert-dropdown .menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text);
  background: none;
  border: none;
  cursor: pointer;
  box-sizing: border-box;
  white-space: nowrap;
}
.insert-dropdown .menu button:hover { background: var(--bg); }
.insert-dropdown .menu.menu-up,
.table-picker .menu.menu-up {
  top: auto;
  bottom: 100%;
  margin-top: 0;
  margin-bottom: 6px;
}
/* The size grid (#134) hangs off the same anchor as Insert ▾ itself: the
 * wrapper is the positioned ancestor both menus share, so the grid opens
 * directly under the trigger that summoned it. */
/*
 * Shared insertion-point bar (WI263) — generalises WI259's dashed-bar look
 * so every per-field Insert ▾ uses the same visual language as the
 * top-of-page bar. Slim, left-aligned, dashed so it reads as an insertion
 * point rather than another field heading. Vertical margin is tight so a
 * column of field → bar → field → bar doesn't look noisy; the page-level
 * top bar keeps a slightly larger top margin to separate from the stage chrome.
 */
.insert-bar,
.top-insert-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: var(--bg-raised);
  position: relative;
}
.insert-bar { margin: 8px 0 6px; }
.top-insert-bar { margin: 16px 0 4px; }
.insert-bar .insert-dropdown,
.top-insert-bar .insert-dropdown { margin-top: 0; }
.insert-bar[hidden],
.top-insert-bar[hidden] { display: none; }
/* Deprecated: per-field wrapper before WI263 — kept for backwards compat if
 * any cached markup still references it; new code should use .insert-bar. */
.insert-area { position: relative; display: inline-flex; margin-top: 10px; }
.md-toolbar .table-picker { position: relative; display: inline-flex; }
.table-picker .menu {
  display: none;
  position: absolute;
  left: 0;
  top: 100%;
  margin-top: 6px;
  z-index: 5;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  padding: 8px;
}
.table-picker.menu-open .menu { display: block; }
.table-picker-grid {
  display: grid;
  grid-template-columns: repeat(8, 18px);
  gap: 2px;
}
.table-picker-cell {
  appearance: none;
  width: 18px;
  height: 18px;
  padding: 0;
  background: var(--bg);
  border: var(--hairline) solid var(--line);
  border-radius: 2px;
  cursor: pointer;
}
.table-picker-cell.lit { background: var(--text); border-color: var(--text); }
.table-picker-caption {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-muted);
  padding-top: 6px;
  text-align: center;
}

.field-markdown .md-rendered img.asset-thumb {
  display: block;
  width: 100%;
  max-width: 260px;
  height: auto;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  margin: 6px 0 4px;
}

.field-markdown .md-rendered .asset-source {
  font-size: 11px;
  color: var(--text-muted);
  font-style: italic;
  margin: 2px 0 8px;
  overflow-wrap: anywhere;
}
.field-markdown .md-rendered .asset-source em { font-style: italic; }

/* Visual view (#148, restored after #374 dropped it) — images fill the content width,
 * representative of the exported .docx, which scales them to the page's text width.
 * Split view keeps the 260px thumbnail cap above for editing convenience. */
main[data-view-mode='visual'] .field-markdown .md-rendered img.asset-thumb {
  max-width: 100%;
}


.modal-backdrop {
  display: flex;
  position: fixed;
  inset: 0;
  background: rgba(27, 30, 34, 0.5);
  z-index: 20;
  align-items: center;
  justify-content: center;
}
.modal {
  width: 520px;
  max-width: 92vw;
  max-height: 85vh;
  overflow: auto;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  padding: 20px;
}
.modal h3 { font-family: var(--font-display); font-weight: 600; font-size: 16px; margin: 0 0 16px; }
.modal-tabs {
  display: flex;
  gap: 0;
  border-bottom: var(--border-strong) solid var(--line-strong);
  margin-bottom: 16px;
}
.modal-tabs button {
  flex: 1;
  background: none;
  border: none;
  padding: 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.modal-tabs button.active { color: var(--text); border-bottom: 2px solid var(--text); margin-bottom: -2px; }
.modal-actions { margin-top: 16px; display: flex; align-items: center; justify-content: flex-end; gap: 8px; }

/* WI #359 — the Render dialog's docx/md toggle, sitting immediately left of the Render
   button in .modal-actions (a flex row, so DOM order here is visual order). */
.render-format-toggle { display: flex; align-items: center; gap: 12px; margin: 0; padding: 0; border: 0; }
.render-format-toggle label { display: flex; align-items: center; gap: 4px; font-size: 0.9em; }

.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;
}

.field-label {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-muted);
  margin-bottom: 6px;
}
input.text-field {
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 8px 11px;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
  width: 100%;
}
input.text-field.has-error { border-color: var(--stamp-error-bg); }
.inline-error { color: var(--stamp-error-bg); font-size: 12px; margin-top: 6px; }
.upload-field { margin-bottom: 14px; }

.grid-library {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.grid-library .card {
  cursor: pointer;
  border: none;
  background: none;
  text-align: left;
  padding: 8px;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  font-family: var(--font-body);
  color: var(--text);
}
.grid-library .card:hover { border-color: var(--line-strong); }
.grid-library .card img,
.lib-grid .card img {
  display: block;
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  border-radius: var(--radius);
  border: var(--hairline) solid var(--line);
}
.grid-library .card .name { font-size: 11px; font-weight: 600; margin-top: 6px; }
.grid-library .empty, .lib-grid .empty { color: var(--text-muted); font-size: 13px; grid-column: 1 / -1; }

.asset-library {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 32px 140px;
}
.asset-library h1 { font-family: var(--font-display); font-weight: 600; font-size: 22px; margin: 0 0 4px; }
.asset-library .back-link { display: inline-block; margin-bottom: 20px; font-size: 13px; }
.lib-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
  margin-top: 20px;
}
.lib-grid .card {
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: 12px;
  background: var(--bg-raised);
}
.lib-grid .card .name { font-family: var(--font-display); font-weight: 600; font-size: 13px; margin: 8px 0 2px; }
.lib-grid .card .meta { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); overflow-wrap: anywhere; }
.lib-grid .card .used-badge { margin-top: 8px; }

/*
 * ---------- Instance setup wizard (#78) ----------
 * Ported from web/prototypes/instance-setup-wizard.prototype.html's variant C ("progressive single page") — the tokens/classes above (fonts, .btn, .stamp, hairlines) are reused as-is; these are the wizard-specific additions, scoped with a `wizard-` prefix or nested under .wizard-page so they can't collide with the module editor's own `.field`/`.result` naming.
 *
 * `.wizard-header`/`.wizard-page`'s base proportions (max-width/margin/padding) are grouped with `.settings-header`/`.settings-page` below — both are the same simple centered-single-column screen shell, just with genuinely different content per screen (no `h2`/`.lede`-style rules are shared, only this literal box model), so writing the same four declarations out twice under two unrelated-looking class names would be pure duplication with no corresponding difference in intent. Each screen still only ever carries its own class in markup — this is a shared rule, not one screen's class applied to the other's markup (the coupling a #101 review pass flagged and this replaces).
 */
.wizard-header, .settings-header {
  max-width: 860px;
  margin: 0 auto;
  padding: 32px 32px 20px;
  border-bottom: var(--border-strong) solid var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.wizard-header h1, .settings-header h1 { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.01em; font-size: 20px; margin: 0; flex: 1; }

/* ---------- User Guide (#193) ---------- */
.guide-header {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 32px 20px;
  border-bottom: var(--border-strong) solid var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.guide-header h1 { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.01em; font-size: 22px; margin: 0; }
.guide-page {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 32px 140px;
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 48px;
  align-items: start;
}
.guide-navigation { position: sticky; top: 24px; }
.guide-navigation h2 { font-family: var(--font-display); font-size: 13px; margin: 0 0 10px; }
.guide-navigation ol { list-style: none; padding: 0; margin: 0; border-left: var(--hairline) solid var(--line); }
.guide-navigation li { padding: 4px 0 4px 12px; font-size: 13px; }
.guide-navigation li a { text-decoration: none; }
.guide-navigation li a:hover { text-decoration: underline; }
.guide-navigation li.pending a { color: var(--text-muted); }
.guide-navigation li span { display: block; color: var(--text-muted); font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; }
.guide-content { min-width: 0; max-width: 72ch; }
.guide-content h1 { font-family: var(--font-display); font-size: 28px; line-height: 1.2; margin: 0 0 20px; }
.guide-content h2 { font-family: var(--font-display); font-size: 21px; line-height: 1.25; margin: 40px 0 12px; scroll-margin-top: 24px; }
.guide-content h2:first-of-type { margin-top: 0; }
.guide-content p { margin: 0 0 14px; }
.guide-content ul { margin: 0 0 18px; padding-left: 22px; }
.guide-content li { margin: 5px 0; }
.guide-content code { font-family: var(--font-mono); font-size: 0.9em; }
.guide-content h3 { font-family: var(--font-display); font-size: 17px; line-height: 1.3; margin: 28px 0 10px; scroll-margin-top: 24px; }
.guide-content h4 { font-family: var(--font-display); font-size: 15px; line-height: 1.3; margin: 24px 0 8px; scroll-margin-top: 24px; }
/* Reference tables (Definition Reference Guide) are wider than the 72ch prose column —
   they scroll inside their own box so the page itself never scrolls sideways. */
.guide-content table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: 13px;
  line-height: 1.4;
  margin: 0 0 20px;
}
.guide-content th,
.guide-content td { border: var(--hairline) solid var(--line); padding: 6px 8px; text-align: left; vertical-align: top; min-width: 12ch; }
.guide-content th { font-weight: 600; white-space: nowrap; }
.guide-content img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 10px 0 22px;
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  cursor: zoom-in;
}
.guide-content img:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.guide-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  background: rgba(0, 0, 0, 0.82);
  cursor: zoom-out;
}
.guide-lightbox img {
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--radius);
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.5);
}
.guide-lightbox-close {
  position: fixed;
  top: 14px;
  right: 20px;
  padding: 6px 10px;
  font-size: 26px;
  line-height: 1;
  color: #fff;
  background: none;
  border: none;
  cursor: pointer;
}

@media (max-width: 760px) {
  .app-header .brand { flex-wrap: wrap; }
  .app-header .brand h1 { min-width: 0; }
  .guide-page { display: block; }
  .guide-navigation { position: static; margin-bottom: 32px; }
  .guide-navigation ol { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-left: none; border-top: var(--hairline) solid var(--line); padding-top: 8px; }
  .guide-navigation li { padding-left: 0; padding-right: 12px; }
}

.wizard-page, .settings-page { max-width: 860px; margin: 0 auto; padding: 32px 32px 140px; }
.wizard-page h2 { font-family: var(--font-display); font-weight: 600; font-size: 22px; margin: 0; }
.wizard-page .lede { color: var(--text-muted); margin: 6px 0 28px; max-width: 70ch; }

.wizard-field { margin-bottom: 24px; }
.wizard-field label { font-family: var(--font-display); font-weight: 600; font-size: 13px; display: block; margin-bottom: 8px; }
.wizard-input {
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 8px 11px;
  border-radius: var(--radius);
  border: var(--border-strong) solid var(--line-strong);
  background: var(--bg-raised);
  color: var(--text);
  width: 100%;
}
.check-row { margin-top: 10px; }
.wizard-field-hint { margin: 8px 0 0; color: var(--text-muted); font-size: 12px; }
.wizard-changelog-toggle > summary { cursor: pointer; color: var(--text-muted); font-size: 12px; user-select: none; margin-top: 8px; }
.wizard-changelog { margin-top: 10px; padding: 10px 12px; border: var(--hairline) solid var(--line); background: var(--bg-raised); border-radius: var(--radius); font-size: 13px; }
.wizard-changelog h1, .wizard-changelog h2, .wizard-changelog h3 { font-family: var(--font-display); margin: 0 0 8px; }
.wizard-changelog p { margin: 0 0 8px; }
.btn-link { background: none; border: none; color: var(--text); text-decoration: underline; cursor: pointer; padding: 0; font: inherit; font-size: inherit; }

/* The "+ New Workspace" wizard's (#110/#126) pick-vs-register toggle —
   reuses `.btn`/`.btn.active` wholesale, just grouped with a small gap. */
.wizard-mode-toggle { display: flex; gap: 8px; }

.result-card {
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
  padding: 16px 18px;
  margin-bottom: 24px;
}
.result-card h3 { margin: 0 0 12px; }
.result-card .result-note { margin: 0; color: var(--text-muted); font-size: 13px; }
.result-row { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: var(--hairline) solid var(--line); font-size: 13px; }
.result-row:last-child { border-bottom: none; }
.result-row .k { color: var(--text-muted); }
.result-row .v { font-family: var(--font-mono); }

.dismiss-banner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--stamp-error-bg);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-top: 10px;
}
.dismiss-banner button { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 16px; line-height: 1; }

.definition-card {
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  cursor: pointer;
  margin-bottom: 8px;
}
.definition-card.selected { border: var(--border-strong) solid var(--line-strong); background: var(--bg-raised); }
.definition-card .name { font-family: var(--font-display); font-weight: 600; font-size: 14px; }
.definition-card .stages { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); margin-top: 3px; }

.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 16px; }
.compare .col { border: var(--hairline) solid var(--line); border-radius: var(--radius); padding: 14px; }
.compare .col h4 { font-family: var(--font-display); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); margin: 0 0 10px; }
.compare .mono { font-family: var(--font-mono); font-size: 13px; }
.mismatch-flag { margin-top: 10px; font-size: 12px; color: var(--stamp-error-bg); }

/*
 * ---------- Settings screens (#107) ----------
 * Three top-level, tab-free screens — `/settings` (Global Settings), `/settings/workspace` (Workspace Settings, scoped to one instance's own workspace) and `/settings/instance` (Instance Settings) — superseding #101/#104's single tabbed `/settings` shell (no `.settings-tabs` any more; each screen is reached directly, not via a tab strip). `.settings-header`/`.settings-page` have their own classes rather than reusing `.wizard-header`/`.wizard-page` directly in markup — a review pass on #101 flagged that as a fragile, undocumented coupling (these screens aren't wizard steps, and `.wizard-page h2`/`.lede` etc. would otherwise apply here too, only overridden by luck of selector specificity). Their shared base proportions are still declared once, grouped with the wizard's own rules above (see that section's own comment), since it's the same generic page shell, not wizard-specific styling — everything below here is genuinely settings-only.
 */
.settings-page .settings-section { margin-bottom: 36px; }
.settings-page .settings-section h2 { font-family: var(--font-display); font-weight: 600; font-size: 16px; margin: 0 0 6px; }
.settings-page .settings-section .guidance { margin: 0 0 14px; max-width: 60ch; }
.settings-pat-status, .settings-render-engine-status { margin-bottom: 10px; }
.settings-actions { display: flex; gap: 10px; }

.settings-checkbox { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }

.settings-radio-group { display: flex; flex-direction: column; gap: 10px; }
.settings-radio { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.settings-radio.disabled { color: var(--text-muted); cursor: not-allowed; }
.settings-radio input[disabled] { cursor: not-allowed; }
.settings-radio .stamp { margin-left: 2px; }

/* #117 — the running server's version, as a quiet footer line under the last section rather than a
 * section of its own. Reuses `--text-muted`/`--font-mono`, the same secondary-text and
 * identifier conventions every other incidental fact on these screens already uses. */
.settings-version { color: var(--text-muted); font-size: 12px; }
.settings-version .settings-version-number { font-family: var(--font-mono); }

/*
 * ---------- Workspace Settings (#104, scoped to one workspace by #107) ----------
 * One `.workspace-row`: repo URL, then three `.workspace-field` blocks (owner, PAT override, ticketing-system override) — reuses `.wizard-input`/`.settings-radio-group`/`.stamp` wholesale rather than inventing parallel input/radio/badge styling. `.workspace-list` held one row per registered workspace under #104's old "list every workspace" tab; #107 narrows that same markup/CSS to exactly one row — the instance's own workspace — so `.workspace-list` here always wraps a single `.workspace-row`.
 */
.workspace-list { display: flex; flex-direction: column; gap: 20px; }
.workspace-empty { color: var(--text-muted); }
.workspace-row {
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.workspace-repo-url { font-family: var(--font-mono); font-size: 13px; word-break: break-all; }
.workspace-field label { font-family: var(--font-display); font-weight: 600; font-size: 12px; display: block; margin-bottom: 6px; }
.workspace-field-row { display: flex; align-items: center; gap: 8px; }
.workspace-field-row .wizard-input { flex: 1; }
.workspace-pat-status, .workspace-ticketing-state { margin-bottom: 8px; }
.workspace-field-status { margin-top: 6px; font-size: 12px; color: var(--text-muted); min-height: 1em; }

/* #116 — the workspace's registry id (the key `GANTRY_SHARED_WORKSPACE_PATS` / `GANTRY_MCP_WORKSPACE_PATS` are
 * keyed by), sitting directly under the location it belongs to. Deliberately quieter than the
 * editable fields beneath it — `--text-muted` + `--font-mono`, the same secondary-metadata pairing
 * `.workspace-repo-url`, `.result-row .v` and `.settings-version` already use — because an id is
 * configuration detail, not what the row is opened to see. `user-select: all` so one click selects
 * the whole id, which is the fallback whenever the clipboard API isn't there (a plain-http server is
 * not a secure context); the value is never hidden behind the Copy button. Only rendered for a remote
 * workspace — a Local/server-directory one has no id (see settings.js's `workspaceCredentialMapId`). */
.workspace-id { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-top: -6px; }
.workspace-id-label { font-family: var(--font-display); font-weight: 600; font-size: 12px; color: var(--text-muted); }
.workspace-id-value { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); word-break: break-all; user-select: all; }
.workspace-id-status { font-size: 12px; color: var(--text-muted); }
.workspace-id-hint { flex-basis: 100%; margin: 0; font-size: 12px; color: var(--text-muted); }

/*
 * ---------- Settings dropdown (#107) ----------
 * The module editor header's "Settings" control, once an instance is
 * open: no longer a plain link straight to Global Settings, but a small
 * dropdown offering Global/Workspace/Instance Settings — same open/close-
 * on-outside-click shape as `.chip .menu` (stage swimlanes), just anchored
 * under a header button instead of a dashboard chip.
 */
.settings-menu { position: relative; display: inline-flex; }
.settings-menu .menu {
  display: none;
  position: absolute;
  right: 0;
  top: 100%;
  margin-top: 6px;
  z-index: 9;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  min-width: 160px;
}
.settings-menu.menu-open .menu { display: block; }
.settings-menu .menu a {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  font-size: 12px;
  font-family: var(--font-body);
  color: var(--text);
  text-decoration: none;
  box-sizing: border-box;
  white-space: nowrap;
}
.settings-menu .menu a:hover { background: var(--bg); }

/* ---------- Definition Editor (WI #381) ----------
 * Rebuilt on web/prototypes/definition-editor.prototype.html's variant A (Outline) / variant C
 * (Map) verdict — one toolbar, an Outline-or-Map nav switch over one focus pane, a docked
 * (read-only-for-now, WI #382 wires up Copy) Library panel. `.kicker`/`.mono`/`.muted`/`.pane`
 * are small layout-only helpers scoped to this page rather than promoted to globals. */
.defn-viewer { max-width: 1320px; margin: 0 auto; padding: 20px 24px 60px; }
.defn-viewer .kicker { font-family: var(--font-display); font-weight: 600; font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.defn-viewer .mono { font-family: var(--font-mono); }
.defn-viewer .muted { color: var(--text-muted); }
.defn-viewer .pane { min-height: 0; overflow: auto; }
.defn-id { font-family: var(--font-mono); font-weight: 400; font-size: 12px; color: var(--text-muted); }
.defn-hint { font-size: 11px; }

/* Toolbar */
.defn-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; padding: 10px 14px; border: var(--hairline) solid var(--line); border-radius: var(--radius); background: var(--bg-raised); margin-bottom: 14px; }
.defn-toolbar-left, .defn-toolbar-right { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
.defn-toolbar #defn-version-select { max-width: 200px; }
.defn-switcher { position: relative; }
.defn-switcher .defname { font-family: var(--font-display); font-weight: 600; }
.defn-switcher .menu { display: none; position: absolute; top: calc(100% + 4px); left: 0; width: max-content; min-width: 320px; max-width: min(480px, 90vw); background: var(--bg-raised); border: var(--border-strong) solid var(--line-strong); border-radius: var(--radius); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18); z-index: 20; padding: 8px; max-height: 70vh; overflow: auto; }
.defn-switcher.menu-open .menu { display: block; }
.defn-switcher-menu { display: flex; flex-direction: column; gap: 8px; }
.defn-switcher-group .kicker { display: block; margin: 4px 0; }
.defn-switcher-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 7px 8px; border-radius: var(--radius); cursor: pointer; border: var(--hairline) solid transparent; }
.defn-switcher-row:hover { background: var(--bg); }
.defn-switcher-row.selected { border-color: var(--line-strong); background: var(--bg); }
.defn-switcher-row.archived { opacity: 0.6; border-style: dashed; }
.defn-switcher-row-title { font-family: var(--font-display); font-weight: 600; font-size: 13px; flex: 1 1 100%; min-width: 0; overflow-wrap: anywhere; }
.defn-switcher-row > .btn { margin-left: auto; }
.defn-rail-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.defn-rail-badges .stamp.small { font-size: 10px; }
.defn-switcher-footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; border-top: var(--hairline) solid var(--line); padding-top: 8px; margin-top: 4px; }
.defn-show-archived { font-size: 12px; display: flex; align-items: center; gap: 6px; }
.defn-newdef-panel { display: flex; flex-direction: column; gap: 8px; min-width: 260px; }
.defn-newdef-tabs { display: flex; gap: 6px; }
.defn-clone-actions { display: flex; gap: 6px; }
.defn-view-toggle { display: inline-flex; gap: 4px; }
.defn-problems { color: var(--stamp-error-bg); font-weight: 600; }
.defn-no-problems { font-size: 12px; }
.defn-leave-guard { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 10px 14px; border: var(--border-strong) solid var(--stamp-draft-bg); border-radius: var(--radius); background: var(--bg-raised); margin-bottom: 14px; }

/* Workbench layout: Outline = nav | focus | library ; Map = map (top) then focus | library (bottom) */
.defn-workbench-outline { display: grid; grid-template-columns: 260px minmax(0, 1fr) 280px; gap: 14px; align-items: start; min-height: 60vh; }
.defn-workbench-map { display: grid; grid-template-rows: minmax(180px, 40vh) minmax(0, 1fr); gap: 14px; min-height: 60vh; }
.defn-workbench-map .defn-bottom { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 14px; min-height: 0; }
/* Expanded: the Map takes the whole workbench at its full height; the panes below stay mounted but hidden. */
.defn-workbench-map.expanded { grid-template-rows: auto; }
.defn-workbench-map .defn-bottom[hidden] { display: none; }
.defn-outline, .defn-focus-pane, .defn-library, .defn-map-pane { border: var(--hairline) solid var(--line); border-radius: var(--radius); background: var(--bg-raised); }
.defn-focus-pane { background: var(--bg); padding: 4px 4px 20px; }
@media (max-width: 960px) {
  .defn-workbench-outline { grid-template-columns: 1fr; }
  .defn-workbench-map .defn-bottom { grid-template-columns: 1fr; }
}

/* Outline nav */
.defn-outline { padding: 8px; }
.defn-outline-group { margin-bottom: 10px; }
.defn-outline-group-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 6px; }
.defn-outline-node { display: flex; align-items: center; gap: 6px; padding: 5px 7px; border-radius: var(--radius); cursor: pointer; }
.defn-outline-node:hover { background: var(--bg); }
.defn-outline-node.selected { background: var(--text); color: var(--bg); }
.defn-outline-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.defn-outline-fields { padding-left: 26px; }
.defn-outline-field-node { padding: 3px 6px; font-size: 12px; color: var(--text-muted); cursor: pointer; border-radius: var(--radius); }
.defn-outline-field-node:hover { background: var(--bg); }
.defn-outline-field-node.selected { color: var(--text); font-weight: 600; }
.defn-problem-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--stamp-error-bg); flex: none; }

/* Map nav */
.defn-map { display: flex; gap: 12px; align-items: flex-start; padding: 12px; overflow: auto; height: 100%; }
.defn-map-col { flex: 0 0 220px; border: var(--hairline) solid var(--line); background: var(--bg-raised); border-radius: var(--radius); padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 4px; }
.defn-map-col.selected { border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.defn-map-col-unused { border-style: dashed; }
.defn-map-add-row { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.defn-map-col-head { display: flex; align-items: center; gap: 6px; cursor: pointer; padding: 2px 0 4px; }
.defn-map-col-head .t { font-family: var(--font-display); font-weight: 600; font-size: 13px; }
.defn-map-chip { display: flex; align-items: center; gap: 6px; padding: 4px 6px; border: var(--hairline) solid var(--line); border-radius: var(--radius); background: var(--bg); font-size: 12px; cursor: pointer; }
.defn-map-chip.selected { background: var(--text); color: var(--bg); border-color: var(--text); }
.defn-field-count { margin-left: auto; font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.defn-map-chip.selected .defn-field-count, .defn-outline-node.selected .defn-field-count { color: inherit; }
/* A module the focused document(s) draw no fields from: still clickable, visibly out of the flow. */
.defn-map-chip.ghost { opacity: 0.4; border-style: dashed; background: transparent; }
.defn-outline-node.ghost { opacity: 0.4; }
.defn-map-gate { margin-top: 6px; padding-top: 6px; border-top: var(--hairline) solid var(--line); }
.defn-map-achip { display: flex; align-items: center; gap: 6px; padding: 4px 6px; border-radius: var(--radius); font-size: 12px; cursor: pointer; margin-top: 3px; border: var(--hairline) solid transparent; }
.defn-map-achip.selected { background: var(--text); color: var(--bg); }
.defn-map-achip.selected .muted { color: inherit; opacity: 0.75; }

/* Focus pane */
.defn-focus { padding: 14px 18px 30px; }
.defn-focus h2 { font-family: var(--font-display); font-weight: 600; font-size: 18px; margin: 2px 0 10px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.defn-focus-title-input { font-family: var(--font-display); font-weight: 600; font-size: 16px; max-width: 360px; }
.defn-focus-row { display: grid; grid-template-columns: 110px 1fr; gap: 8px 12px; align-items: center; margin-bottom: 12px; }
.defn-focus-row label { margin-bottom: 0; }
.defn-focus-section { margin-top: 18px; }
.defn-focus-section-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.defn-template-row { display: flex; gap: 8px; align-items: center; }
.defn-editor-inline { display: flex; gap: 8px; margin-top: 8px; }

/* Reference docx Replace/Download (WI #385) */
.defn-docx-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.defn-docx-row input[type="file"] { max-width: 220px; font-size: 12px; }
.defn-docx-status { margin-top: 6px; }
.defn-docx-saved { color: var(--stamp-agreed-bg); font-weight: 600; }

/* Chips + droplists (module refs, requires) */
.defn-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.defn-chip { display: inline-flex; align-items: center; gap: 6px; border: var(--hairline) solid var(--line-strong); border-radius: var(--radius); padding: 3px 8px; font-size: 12px; background: var(--bg-raised); }
.defn-chip.optional { border-style: dashed; }
/* #152: a module a stage mounts read-only (carried forward, edited at an earlier stage). */
.defn-chip.read-only { border-style: dotted; }
.defn-read-only-toggle { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--text-muted); cursor: pointer; }
.defn-read-only-toggle input { margin: 0; }
.defn-droplist { border: var(--hairline) dashed var(--line); padding: 8px; border-radius: var(--radius); min-height: 38px; }
.defn-requires-group { margin: 8px 0; }
.defn-requires-group .kicker { display: block; margin-bottom: 4px; cursor: pointer; }

/* Field rows: compact, one expanded at a time */
.defn-field-rows { border-top: var(--hairline) solid var(--line); }
.defn-field-row { border-bottom: var(--hairline) solid var(--line); }
.defn-field-row-head { display: flex; align-items: center; gap: 8px; padding: 7px 4px; cursor: pointer; }
.defn-field-row-head:hover { background: var(--bg); }
.defn-field-row.open .defn-field-row-head { background: var(--bg); }
.defn-field-row-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.defn-field-row-title code { color: var(--text-muted); margin-left: 6px; }
.defn-required { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.defn-field-row-body { padding: 10px 4px 14px 26px; background: var(--bg); }
.defn-field-row-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.defn-move-to-module { max-width: 200px; }
.defn-gate-checks { display: flex; flex-wrap: wrap; gap: 10px; font-size: 12px; }
.defn-gate-checks label { display: flex; align-items: center; gap: 4px; }

/* select field options (#86) */
.defn-options-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }
.defn-option-row { display: flex; align-items: center; gap: 6px; }
.defn-option-row .wizard-input { flex: 1; }

/* artefact filename: pattern authoring (#89) */
.defn-filename-editor { display: flex; flex-direction: column; gap: 6px; }
.defn-filename-tokens { display: flex; flex-wrap: wrap; gap: 6px; }
.defn-filename-token { font-family: var(--font-mono); }
.defn-filename-problems { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 2px; }
.defn-document-control, .defn-satisfies-gate { display: inline-flex; align-items: center; gap: 6px; }

/* Drag and drop */
.defn-drag-handle { cursor: grab; user-select: none; padding: 2px 6px; font-size: 14px; color: var(--text-muted); border: var(--hairline) solid transparent; border-radius: var(--radius); }
.defn-drag-handle:active { cursor: grabbing; }
.defn-dragging { opacity: 0.5; }
.defn-drop-target { outline: 2px dashed var(--stamp-agreed-bg); outline-offset: 2px; background: var(--bg); }
.defn-move-btns { display: inline-flex; gap: 4px; align-items: center; }
.defn-move-btns .btn { margin: 0; padding: 2px 6px; font-size: 11px; line-height: 1; }

/* Template focus view (CodeMirror) */
.defn-template-editor { border: var(--hairline) solid var(--line); border-radius: var(--radius); min-height: 320px; }
.defn-template-editor .cm-editor { height: 100%; min-height: 320px; font-family: var(--font-mono); font-size: 13px; }
.defn-template-error { margin-top: 6px; }
.defn-template-saved { color: var(--stamp-agreed-bg); font-weight: 600; }
.defn-template-actions { display: flex; gap: 8px; margin-top: 10px; }

/* Library panel (docked, read-only shell in WI #381; Copy wired up in WI #382) */
.defn-library { padding: 8px; display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.defn-library-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.defn-library-source-row { display: flex; gap: 6px; }
.defn-library-source { flex: 1; min-width: 0; }
.defn-library-version { flex: 0 0 auto; max-width: 130px; }
.defn-library-tree { overflow: auto; }
.defn-library-group { margin-bottom: 10px; }
.defn-library-node { padding: 3px 6px; font-size: 12px; border-radius: var(--radius); display: flex; align-items: center; gap: 6px; }
.defn-library-node .defn-drag-handle { padding: 0 2px; }
.defn-library-node span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.defn-library-copy-btn { flex: none; padding: 1px 6px; font-size: 11px; }
.defn-library-field { color: var(--text-muted); padding-left: 16px; }

/* "From another definition…" pickers (WI #382) — sit beside the existing "+ Add …" controls */
.defn-library-picker { max-width: 220px; }

/* Copy provenance badge — "from <id> v<n>" (WI #382) */
.defn-from-badge { white-space: nowrap; }

/* Copy confirm panel (WI #382) — blocks interaction with the rest of the page until every id
 * clash is resolved (Confirm) or the copy is abandoned (Cancel); see CopyPlanner's isResolved. */
.defn-copy-modal-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.35); display: flex; align-items: center; justify-content: center; z-index: 40; padding: 16px; }
.defn-copy-modal { background: var(--bg-raised); border: var(--border-strong) solid var(--line-strong); border-radius: var(--radius); padding: 18px 20px; max-width: 480px; width: 100%; max-height: 85vh; overflow: auto; }
.defn-copy-modal h3 { font-family: var(--font-display); font-weight: 600; font-size: 15px; margin: 0 0 10px; }
.defn-copy-section { margin-top: 10px; }
.defn-copy-section ul { margin: 4px 0 0 18px; padding: 0; font-size: 13px; }
.defn-copy-collision { border-top: var(--hairline) solid var(--line); padding: 8px 0; font-size: 13px; }
.defn-copy-collision label { display: inline-flex; align-items: center; gap: 4px; margin-right: 14px; cursor: pointer; }
.defn-copy-rename { margin-top: 6px; display: flex; align-items: center; gap: 8px; }
.defn-copy-modal-actions { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
@media (max-width: 700px) { .defn-toolbar { flex-direction: column; align-items: stretch; } }

/* Promote (WI #387, ADR-0036's Promote section) — one PR per selected library repo, opened from a
 * published workspace definition version; status is read on an explicit Check, never polled. */
.defn-promote-modal-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.35); display: flex; align-items: center; justify-content: center; z-index: 40; padding: 16px; }
.defn-promote-modal { background: var(--bg-raised); border: var(--border-strong) solid var(--line-strong); border-radius: var(--radius); padding: 18px 20px; max-width: 480px; width: 100%; max-height: 85vh; overflow: auto; }
.defn-promote-modal h3 { font-family: var(--font-display); font-weight: 600; font-size: 15px; margin: 0 0 10px; }
.defn-promote-repo-list { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }
.defn-promote-repo-list label { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 13px; }
.defn-promote-modal-actions { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.defn-promotions { border: var(--hairline) solid var(--line); border-radius: var(--radius); padding: 10px 14px; margin: 10px 0; display: flex; flex-direction: column; gap: 8px; }
.defn-promotion-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; }
.defn-promotion-repo { font-weight: 600; }

/* ---------- Visual view (#374, docs/adr/0033) ----------
 * The same CodeMirror editor drawn the way the content reads (web/lib/visualMode.js):
 * body type, no gutters, markdown markers hidden except on the caret's line. */
.field-markdown .cm-editor.cm-visual .cm-content {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.6;
  padding: 8px 10px;
}
.field-markdown .cm-editor.cm-visual .cm-gutters { display: none; }
.field-markdown .cm-editor.cm-visual .cm-activeLine { background: transparent; }
.cm-visual .cm-vh { font-family: var(--font-display); font-weight: 600; line-height: 1.35; }
.cm-visual .cm-vh1 { font-size: 1.75em; }
.cm-visual .cm-vh2 { font-size: 1.5em; }
.cm-visual .cm-vh3 { font-size: 1.3em; }
.cm-visual .cm-vh4 { font-size: 1.15em; }
.cm-visual .cm-vh5 { font-size: 1.05em; }
.cm-visual .cm-vh6 { font-size: 1em; color: var(--text-muted); }
.cm-visual .cm-vstrong { font-weight: 700; }
.cm-visual .cm-vem { font-style: italic; }
.cm-visual .cm-vcode {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--bg);
  padding: 1px 4px;
  border-radius: var(--radius);
}
.cm-visual .cm-vlink { text-decoration: underline; text-underline-offset: 2px; }
.cm-visual .cm-vquote { color: var(--text-muted); font-style: italic; }
.cm-visual .cm-vcodeblock { font-family: var(--font-mono); font-size: 13px; background: var(--bg); }
/* A horizontal rule off the caret's line (WI #376). */
.cm-visual .cm-visual-hr { display: inline-block; width: 100%; height: 0; border-top: 2px solid var(--line-strong); vertical-align: middle; }

/* Centralised Save (WI #376): blue only while something is unsaved. */
.stage-save { display: inline-flex; align-items: stretch; gap: 8px; }
/* No .btn margin here: it would drop the button below Mode and push Mode away. The
   button takes its height from the row (the text buttons beside it) rather than from
   its icon, so it stays level with Mode whatever font the browser has. */
.stage-save-btn { display: inline-flex; align-items: center; justify-content: center; margin: 0; padding: 0 8px; }
.toolbar-left > .stage-save { align-self: stretch; }
.stage-save-btn svg { display: block; width: 14px; height: 14px; }
.stage-save-state:empty { display: none; }
.stage-save-btn.primary { background: #1F5FBF; border-color: #1F5FBF; color: #FFFFFF; }
.stage-save-state { font-size: 0.85rem; color: var(--text-muted); white-space: nowrap; }
.stage-save-state.error { color: var(--stamp-error-bg); white-space: normal; }
.cm-visual .cm-visual-image { display: block; }
.cm-visual .cm-visual-image p { margin: 0; }
.cm-visual .cm-visual-mermaid { margin: 6px 0; }
.cm-visual .cm-visual-mermaid > .btn { margin: 4px 0 0; }

/* The table grid: a real table over the pipe text. Columns share the width
 * evenly — GFM has nowhere to store one, so there is deliberately no resize. */
.vgrid-wrap { margin: 8px 0; position: relative; overflow-x: auto; padding-bottom: 2px; }
table.vgrid { border-collapse: collapse; table-layout: fixed; width: 100%; font-size: 13px; }
table.vgrid .vgrid-cell {
  border: var(--hairline) solid var(--line);
  padding: 4px 8px;
  vertical-align: top;
  overflow-wrap: anywhere;
  background: var(--bg-raised);
  cursor: text;
}
table.vgrid .vgrid-header .vgrid-cell { font-family: var(--font-display); font-weight: 600; background: var(--bg); }
table.vgrid .vgrid-text { outline: none; min-height: 1.4em; white-space: pre-wrap; }
.vgrid-wrap.readonly table.vgrid .vgrid-cell { cursor: default; }
/* The whole cell is the editing target, so the whole cell lights up. */
table.vgrid .vgrid-cell:focus-within { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
table.vgrid .vgrid-cell.selected,
.vgrid-wrap.sel-all table.vgrid .vgrid-cell { background: color-mix(in srgb, var(--focus-ring) 14%, var(--bg-raised)); }
.vgrid-wrap.sel-all table.vgrid { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
table.vgrid col.vgrid-handlecol { width: 20px; }
table.vgrid .vgrid-handles th { border: none; padding: 0; height: 18px; position: relative; background: transparent; }
table.vgrid .vgrid-rowh { border: none; padding: 0; position: relative; background: transparent; }
/* Handles: invisible until the pointer nears their edge, or a menu pins them. */
.vgrid-handle {
  position: absolute;
  background: var(--line);
  border-radius: 3px;
  opacity: 0;
  transition: opacity 0.12s;
  cursor: grab;
  touch-action: none;
}
.vgrid-colh .vgrid-handle { left: 2px; right: 2px; top: 3px; height: 11px; }
.vgrid-rowh .vgrid-handle { top: 2px; bottom: 2px; left: 4px; width: 11px; }
.vgrid-corner .vgrid-handle { left: 4px; top: 3px; width: 11px; height: 11px; cursor: pointer; }
.vgrid-handle:hover { background: var(--line-strong); }
.vgrid-wrap.show-cols .vgrid-colh .vgrid-handle,
.vgrid-wrap.show-rows .vgrid-rowh .vgrid-handle,
.vgrid-wrap.show-cols .vgrid-corner .vgrid-handle,
.vgrid-wrap.show-rows .vgrid-corner .vgrid-handle,
.vgrid-wrap.pinned .vgrid-handle { opacity: 1; }
.vgrid-handle.on,
.vgrid-colh.drop .vgrid-handle,
.vgrid-rowh.drop .vgrid-handle { background: var(--focus-ring); opacity: 1; }
.vgrid-wrap .vgrid-handle.dragging { cursor: grabbing; opacity: 0.5 !important; }

.vgrid-menu {
  position: fixed;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 210px;
  padding: 4px 0;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}
.vgrid-menu button {
  background: none;
  border: none;
  text-align: left;
  padding: 7px 12px;
  font: 12px var(--font-body);
  color: var(--text);
  cursor: pointer;
}
.vgrid-menu button:hover { background: var(--bg); }
.vgrid-menu button.danger { color: var(--stamp-error-bg); }
.vgrid-menu hr { border: none; border-top: var(--hairline) solid var(--line); margin: 4px 0; }
.vgrid-popover {
  position: fixed;
  z-index: 20;
  width: min(440px, 90vw);
  padding: 10px;
  background: var(--bg-raised);
  border: var(--border-strong) solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}
.vgrid-popover textarea {
  width: 100%;
  box-sizing: border-box;
  min-height: 140px;
  padding: 8px;
  font: 12px/1.5 var(--font-mono);
  color: var(--text);
  background: var(--bg);
  border: var(--hairline) solid var(--line);
  resize: vertical;
}
.vgrid-popover-actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 8px; }
.vgrid-popover-actions .btn { margin: 0; }

/* WI #384 — the local-workspace definition editor (web/pages/local-definition-editor.js).
   Deliberately minimal, mirroring the wizard's own .definition-card/.wizard-input rhythm rather
   than definition-viewer.js's richer drag-and-drop layout — see that page's own header comment
   on why it's a smaller editor. */
.local-definition-create,
.local-definition-editor { max-width: 760px; margin: 0 auto; }
.local-def-element {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  margin-bottom: 12px;
  background: var(--bg-raised);
  border: var(--hairline) solid var(--line);
  border-radius: var(--radius);
}
.local-def-element-header { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.local-def-element-header input.wizard-input { flex: 1 1 160px; }
.local-def-field-block { margin-left: 16px; }
.local-def-field-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.local-def-field-row input.wizard-input { flex: 1 1 140px; }
/* select field options (#86) */
.local-def-options { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin: 6px 0 6px 16px; }
.local-def-option-row { display: flex; align-items: center; gap: 6px; width: 100%; }
.local-def-option-row input.wizard-input { flex: 1 1 140px; }
/* artefact filename: pattern authoring (#89) */
.local-def-filename-tokens { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.local-def-template { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.local-def-template-source { font: 13px/1.5 var(--font-mono); min-height: 160px; }
.local-def-validation { margin: 20px 0; }
.local-def-problems { padding-left: 20px; color: var(--text-error, #b3261e); }
