/* ADR-033 htmx pilot — page chrome + SCR-20 recipes. Token roles only
   (design/tokens.json via tokens.css), no literal colors/fonts — see
   CLAUDE.md's UI work section. tokens.css (linked before this file) already
   supplies the global input/select/focus-ring rules (toolbar search/filter
   control recipe, ADR-032), so this file only adds page-specific layout. */

/* MS-25 PRN-05 audit (2026-07-10, dark theme measured 1.6:1): no base link
   rule existed anywhere in the htmx pages, so every <a> (queue Ticket-ID
   links, back-links, approvals links) fell back to the UA default link-blue
   — this file is htmx-only (React's own build has its own css, untouched
   here). :visited is set the same as the unvisited state so a visited link
   doesn't silently reintroduce a UA purple that was never audited.
   ui-lint-allow: semantic-text — the canonical link rule; measured >=4.5:1
   on every surface step it's actually used against (canvas/surface-1/
   surface-2 both bindings, MS-25/26 audits; ADR-039 initial marker).
   :visited merged into the same rule (ADR-039 sweep) — same value, so the
   two separate declarations were redundant duplication, not a deliberate
   divergence. */
a,
a:visited {
  color: var(--accent);
}

.shell__topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1.5rem;
  background: var(--surface-1);
  border-bottom: 1px solid var(--hairline);
}

.shell__logo {
  font-weight: 700;
  /* ui-lint-allow: semantic-text — brand wordmark ("ICR"), not a status
     signal; sits on the topbar's surface-1, measured 4.863:1 light /
     6.635:1 dark (>= 4.5:1 floor, ADR-039 sweep). */
  color: var(--accent);
}

.shell__title {
  flex: 1;
  color: var(--ink);
  font-size: var(--text-md);
}

.shell__theme-toggle {
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.375rem 0.75rem;
  color: var(--ink);
  cursor: pointer;
}

/* MS-40 (ADR-047, closes OQ-36) — the avatar's account-menu wrapper. The
   "Log out" control itself reuses .btn.btn--secondary verbatim (already
   PRN-05 audited, e.g. this same file's ticket-fields panel actions) rather
   than a new button recipe for a single action. */
.shell__account {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* MS-40 audit fix (Finding 1) — this is a real <button> now (focusable
   identity control, not a decorative span), so the UA button chrome
   (background/border/padding) is reset back to how the plain label used to
   look; :focus-visible (tokens.css) already supplies the focus ring, no
   override needed here. */
.shell__account-label {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  white-space: nowrap;
  cursor: default;
}

.shell__main {
  max-width: 960px;
  margin: 0 auto;
  padding: 1.5rem;
}

/* Known-gap banner — same recipe as design/DESIGN-SYSTEM.md's "Known-gap
   banner" / src/web/src/components/KnownGapBanner.css (tinted background,
   never a side-stripe border; leading glyph carries severity, never
   color-alone). Reproduced here rather than shared across stacks because
   the two apps have no shared component layer yet (ADR-033 is the pilot
   that will eventually change that). */
.known-gap-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-sm);
  line-height: var(--leading-ui);
  color: var(--ink-muted);
  background: var(--surface-2);
  margin: 0.75rem 0;
}
.known-gap-banner::before {
  flex-shrink: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-ui);
}
/* ADR-039: background uses the accent-tint role (was color-mix(in oklch,
   var(--accent) N%, ...) — OKLCH interpolates hue as an angle, so mixing
   toward a near-neutral spun the tint through violet at low percentages).
   Border reverts to plain hairline: this is a decorative container border
   (ADR-039 challenge-gate c), not a meaningful semantic border — the ⓘ/⚠/⛔
   glyph + ink text already carry the severity. */
.known-gap-banner--info {
  background: var(--accent-tint);
  border-color: var(--hairline);
  color: var(--ink);
}
/* ui-lint-allow: semantic-text — glyph-only span (ⓘ), paired with the
   banner's own ink-text message; not color-alone (PRODUCT.md a11y rule). */
.known-gap-banner--info::before {
  content: 'ⓘ';
  color: var(--accent);
}
.known-gap-banner--caution {
  background: var(--warn-tint);
  border-color: var(--hairline);
  color: var(--ink);
}
/* ui-lint-allow: semantic-text — glyph-only span (⚠), paired with the
   banner's own ink-text message; not color-alone (PRODUCT.md a11y rule). */
.known-gap-banner--caution::before {
  content: '⚠';
  color: var(--warn);
}
.known-gap-banner--blocking {
  background: var(--danger-tint);
  border-color: var(--hairline);
  color: var(--ink);
}
/* ui-lint-allow: semantic-text — glyph-only span (⛔), paired with the
   banner's own ink-text message; not color-alone (PRODUCT.md a11y rule). */
.known-gap-banner--blocking::before {
  content: '⛔';
  color: var(--danger);
}

/* Save-error banner (SCR-20 "Save error" state) — role="alert", danger tint,
   same tinted-background construction as the known-gap banner above, never
   a side-stripe border. */
.ticket-type-field-config__error {
  background: var(--danger-tint);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.625rem 0.875rem;
  color: var(--ink);
  font-size: var(--text-sm);
  margin-bottom: 0.75rem;
}

.ticket-type-field-config__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}

.ticket-type-field-config__header h1 {
  font-size: var(--text-display);
  margin: 0 0 0.25rem;
}

.ticket-type-field-config__tenant {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

.ticket-type-field-config__subtitle {
  color: var(--ink-muted);
  font-size: var(--text-sm);
  margin: 0 0 1.5rem;
}
/* ADR-044 decision 4: spacing-only rule on top of the shared
   .known-gap-banner--info classes (applied together in the .hbs), same
   "spacing only, never re-set color" convention as
   .ai-draft-panel__disclosure (see that rule's own comment, ~line 1730). */
.ticket-type-field-config__disclosure {
  margin: 0 0 1rem;
}

.ticket-type-field-config__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.ticket-type-field-config__toolbar label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

/* ADR-025 boardroom register — bordered panel, identical treatment to
   SCR-12/SCR-13's panels (design/DESIGN-SYSTEM.md's "Config-as-data grid"). */
.ticket-type-field-config__panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
  margin-bottom: 2rem;
}

.ticket-type-field-config__table {
  width: 100%;
  border-collapse: collapse;
}

/* PRN-05 dual-binding audit, 2026-07-10: ink-subtle on surface-3 measured
   4.457:1/4.472:1 in the two bindings, ~0.04 short of WCAG's 4.5:1 —
   surface-1 (where ink-subtle clears ~5.15:1/5.54:1 per the same audit)
   is a page-level fix, not a token change. */
.ticket-type-field-config__table thead {
  background: var(--surface-1);
}

.ticket-type-field-config__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  padding: 0.5rem 0.75rem;
}

.ticket-type-field-config__table td {
  padding: 0.5rem 0.75rem;
  border-top: 1px solid var(--hairline);
  color: var(--ink);
}

/* Locked identity fields (type_key/field_key) must render ink-subtle even
   inside a table cell — .ticket-type-field-config__table td's own (0,2,1)
   rule otherwise beats .ticket-type-field-config__locked's (0,1,0) and wins
   on specificity, silently overriding it back to ink (PRN-05 audit,
   2026-07-10). */
.ticket-type-field-config__table td.ticket-type-field-config__locked {
  color: var(--ink-subtle);
}

.ticket-type-field-config__table tr[data-row] {
  cursor: pointer;
}

.ticket-type-field-config__table tr[data-row]:hover {
  background: var(--surface-2);
}

.ticket-type-field-config__order {
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono); /* tokens.json role, not a literal font */
}

/* Locked identity fields (type_key/field_key) render as plain text once a
   definition has been saved once — design/screens/SCR-20's "Locked identity
   fields" state, direct fix for ADR-027's rename-drift objection. */
.ticket-type-field-config__locked {
  color: var(--ink-subtle);
}

.ticket-type-field-config__field {
  margin-bottom: 0.875rem;
}

.ticket-type-field-config__field label {
  display: block;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  margin-bottom: 0.25rem;
}

.ticket-type-field-config__field input,
.ticket-type-field-config__field select {
  width: 100%;
}

.ticket-type-field-config__field-checkbox {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.ticket-type-field-config__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

.btn {
  border-radius: 6px;
  padding: 0.5rem 1rem;
  font-size: var(--text-base);
  cursor: pointer;
  border: 1px solid transparent;
}

.btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}

.btn--primary:hover {
  background: var(--accent-hover);
}

.btn--secondary {
  background: var(--surface-2);
  color: var(--ink);
  border-color: var(--hairline);
}

/* ============================================================
   MS-24 — SCR-11 Org Admin shell + SCR-12..16 hosted screens.
   Class names reused verbatim from src/web/src/screens/AdminShell.css and
   siblings so both stacks read as the same design system while React
   stays live (ADR-033) — not shared code (no shared component layer
   exists yet between the two apps), same posture ticket-fields' banner
   reuse above already documents.
   ============================================================ */

.shell__main--admin {
  max-width: none;
  margin: 0;
  padding: 0;
}

.admin-shell__body {
  display: flex;
  min-height: calc(100vh - 3.25rem);
}

.admin-shell__nav {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  width: 14rem;
  flex-shrink: 0;
  padding: 1rem 0.75rem;
  background: var(--surface-1);
  border-right: 1px solid var(--hairline);
}

.admin-shell__nav-item {
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
  font-size: var(--text-base);
}

.admin-shell__nav-item:hover {
  background: var(--surface-2);
}

.admin-shell__nav-item--active {
  background: var(--surface-2);
  /* ui-lint-allow: semantic-text — shell nav active-item text, re-audited
     MS-24 (light accent's ADR-032 lightness fix): 4.551:1 light / 6.102:1
     dark, both >= 4.5:1 (ADR-039 initial marker). */
  color: var(--accent);
  font-weight: 600;
}

.admin-shell__content {
  flex: 1;
  min-width: 0;
  /* ADR-025 boardroom register: matches the 32-40px section rhythm used
     inside each hosted content screen (SCR-12..16). */
  padding: 2rem;
}

@media (max-width: 640px) {
  .admin-shell__nav {
    width: 3.5rem;
    padding: 1rem 0.375rem;
  }
  .admin-shell__nav-item {
    text-align: center;
    font-size: 0;
    padding: 0.5rem 0.25rem;
  }
  .admin-shell__nav-item::before {
    content: '•';
    font-size: var(--text-lg);
  }
}

/* Impersonation banner (ADR-020, DESIGN-SYSTEM.md's "Impersonation banner"
   recipe) — mirrors src/web/src/components/ImpersonationBanner.css
   exactly (same "no on-warn role exists" reasoning: border + icon carry
   the warn tone, not a background/text color pairing the dual-theme audit
   hasn't checked). */
.impersonation-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 1rem;
  background: var(--surface-2);
  border-bottom: 3px solid var(--warn);
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 600;
}
/* PRN-05 audit, 2026-07-10 BLOCKER: an author `display` rule always beats
   the UA stylesheet's `[hidden] { display: none }`, so the unconditional
   `display: flex` above was rendering this banner always-on (blank, since
   admin-impersonation.js never filled it in) on every admin page, even
   with no impersonation session — the exact ADR-020 violation this banner
   exists to prevent, in reverse. `[hidden]` must win explicitly. */
.impersonation-banner[hidden] {
  display: none;
}
.impersonation-banner__text::before {
  content: '⚠ ';
}
.impersonation-banner__end {
  background: var(--surface-1);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.25rem 0.75rem;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

/* ---------- SCR-12 Priority Matrix Config ---------- */
.priority-matrix {
  max-width: 52rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.priority-matrix__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}
.priority-matrix__header h1 {
  font-size: var(--text-xl);
  margin: 0;
}
.priority-matrix__tenant {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.priority-matrix__subtitle {
  color: var(--ink-muted);
  font-size: var(--text-sm);
  margin: 0;
}
.priority-matrix__panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.priority-matrix__confirm {
  background: var(--ok-tint);
  border: 1px solid var(--hairline);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-sm);
  margin: 0 0 0.75rem;
}
.priority-matrix__save-error {
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  /* PRN-05 audit, 2026-07-10 MAJOR: color:danger on this tint measured
     4.302:1 in light — the danger role carries its meaning via the
     border/tint, not body text (ink already clears 14+:1 here), same
     pattern the Catalog/Ticket-Fields error banners already use. */
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-sm);
  margin: 0 0 0.75rem;
}
.priority-matrix__section-heading {
  font-size: var(--text-lg);
  margin: 1.5rem 0 0.5rem;
}
.priority-matrix__grid,
.priority-matrix__thresholds {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.5rem;
}
.priority-matrix__grid thead tr,
.priority-matrix__thresholds thead tr {
  background: var(--surface-2);
}
.priority-matrix__grid th,
.priority-matrix__thresholds th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
}
.priority-matrix__grid td,
.priority-matrix__thresholds td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
  color: var(--ink);
  background: var(--surface-1);
}
.priority-matrix__grid select {
  background: var(--surface-1);
  border: 1px solid var(--input-border);
  border-radius: 6px;
  padding: 0.25rem 0.5rem;
  color: var(--ink);
}
.priority-matrix__thresholds input[type='number'] {
  width: 6rem;
  background: var(--surface-1);
  border: 1px solid var(--input-border);
  border-radius: 6px;
  padding: 0.375rem 0.5rem;
  color: var(--ink);
  font-size: var(--text-sm);
}
.priority-matrix__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* ---------- SCR-13 SLA Target Config ---------- */
.sla-target-config {
  max-width: 52rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.sla-target-config__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}
.sla-target-config__header h1 {
  font-size: var(--text-xl);
  margin: 0;
}
.sla-target-config__tenant {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.sla-target-config__subtitle {
  color: var(--ink-muted);
  font-size: var(--text-sm);
  margin: 0;
}
.sla-target-config__panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.sla-target-config__calendar {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin: 0 0 1rem;
  color: var(--ink);
  font-size: var(--text-sm);
}
.sla-target-config__calendar-label {
  font-weight: 600;
}
.sla-target-config__calendar-note {
  color: var(--ink-subtle);
  font-size: var(--text-xs);
}
.sla-target-config__save-error {
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  /* PRN-05 audit, 2026-07-10 MAJOR: same fix as priority-matrix's save-error
     above — color:danger on this tint measured 4.302:1 in light; danger is
     carried by the border/tint, not body text. */
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-sm);
  margin: 0 0 0.75rem;
}
.sla-target-config__table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.5rem;
}
.sla-target-config__table thead tr {
  background: var(--surface-3);
}
.sla-target-config__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
}
.sla-target-config__table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
  color: var(--ink);
  background: var(--surface-2);
}
.sla-target-config__table input[type='text'] {
  width: 6rem;
  background: var(--surface-1);
  border: 1px solid var(--input-border);
  border-radius: 6px;
  padding: 0.375rem 0.5rem;
  color: var(--ink);
  font-size: var(--text-sm);
}
.sla-target-config__escalate-cell {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
/* ADR-039 sweep: this rule set the exact same value the base `a { color:
   var(--accent) } rule already applies (same specificity family, so it was
   never overriding anything) — removed as a redundant color-mix-adjacent
   semantic-text site rather than adding a second allowlist marker next to
   the base `a` rule's. */
.sla-target-config__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* ---------- SCR-14 Catalog Item Management ---------- */
.catalog-items {
  max-width: 52rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.catalog-items__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.catalog-items__header h1 {
  font-size: var(--text-xl);
  margin: 0;
}
.catalog-items__panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
  margin-top: 1rem;
}
.catalog-items__filters {
  display: flex;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  flex-wrap: wrap;
}
.catalog-items__filter {
  background: var(--surface-2);
  border: 1px solid var(--input-border);
  border-radius: 999px;
  padding: 0.25rem 0.75rem;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  cursor: pointer;
}
.catalog-items__filter--active {
  background: var(--surface-3);
  color: var(--ink);
  font-weight: 600;
}
/* ADR-039 sweep: `color: var(--warn)` on this pill's own label text was the
   exact semantic-text bug the new lint rule now catches mechanically (the
   PRN-05 comment this replaces already measured it failing, 2.749:1 light,
   when combined with --active) — fixed to the ink+border convention rather
   than allowlisted. The pill's own label text ("Change (pre-authorized)")
   already names the governed state, so `ink` text loses no meaning; `warn`
   still carries the signal via the border, now the warn-border role
   (>=3:1 non-text floor, measured 3.782:1 light / 3.963:1 dark) instead of
   the bare `warn` value (was 3.176/9.199 — passing, but not the pinned
   role). This also makes the old --active.--governed override below moot
   (both states now render `ink`), so it's removed rather than kept dead. */
.catalog-items__filter--governed {
  border-color: var(--warn-border);
  color: var(--ink);
}
.catalog-items__form {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 1rem;
}
.catalog-items__form label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}
.catalog-items__form input[type='text'],
.catalog-items__form select {
  background: var(--surface-1);
  border: 1px solid var(--input-border);
  border-radius: 6px;
  padding: 0.375rem 0.625rem;
  color: var(--ink);
}
.catalog-items__form-error {
  background: var(--danger-tint);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.625rem 0.875rem;
  color: var(--ink);
  font-size: var(--text-sm);
  margin-bottom: 0.75rem;
}
.catalog-items__confirm {
  background: var(--surface-1);
  border: 1px solid var(--warn);
  border-radius: 6px;
  padding: 0.625rem;
  font-size: var(--text-sm);
  color: var(--ink);
}
.catalog-items__confirm label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}
.catalog-items__form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
.catalog-items__save-btn {
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: 6px;
  padding: 0.375rem 0.875rem;
  font-weight: 600;
  cursor: pointer;
}
.catalog-items__table {
  width: 100%;
  border-collapse: collapse;
}
.catalog-items__table thead tr {
  background: var(--surface-2);
}
.catalog-items__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
}
.catalog-items__table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
  color: var(--ink);
  background: var(--surface-1);
}
/* Governed-row marker (DESIGN-SYSTEM.md) — tinted row background, not a
   side-stripe border; the "Change (pre-authorized)" text label already
   carries the meaning (never color-alone). ADR-039: the warn-tint role
   replaces the ad-hoc color-mix (was 8% — the role's own low-chroma design
   already reads as a subtle wash at full strength, no percentage knob
   needed). */
.catalog-items__row--governed td {
  background: var(--warn-tint);
}
.catalog-items__empty {
  color: var(--ink-muted);
}

/* ---------- SCR-15 User & Role Management ---------- */
.user-role-mgmt {
  max-width: 52rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.user-role-mgmt h1 {
  font-size: var(--text-xl);
  margin: 0;
}
.user-role-mgmt__panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.user-role-mgmt__toolbar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.user-role-mgmt__toolbar input[type='search'] {
  min-width: 16rem;
}
.user-role-mgmt__role-filter {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.user-role-mgmt__table {
  width: 100%;
  border-collapse: collapse;
}
.user-role-mgmt__table thead tr {
  background: var(--surface-2);
}
.user-role-mgmt__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
}
.user-role-mgmt__table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
  color: var(--ink);
  background: var(--surface-1);
}
.user-role-mgmt__email,
.user-role-mgmt__auth-source {
  color: var(--ink-muted);
}
.user-role-mgmt__table select {
  padding: 0.25rem 0.5rem;
}
.user-role-mgmt__pending-actions {
  margin-left: 0.5rem;
  display: inline-flex;
  gap: 0.375rem;
}
.user-role-mgmt__pending-actions button {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.25rem 0.625rem;
  color: var(--ink);
  cursor: pointer;
  font-size: var(--text-sm);
}
.user-role-mgmt__pending-actions button:first-child {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  font-weight: 600;
}
/* ADR-039 sweep: this role="alert" text (views/admin/users/row.hbs) already
   states "error"/the failure reason in words — fixed to ink rather than
   allowlisted, matching the ink+tint/border convention every boxed error
   on this page already uses (color was the only signal here, no box). */
.user-role-mgmt__save-error {
  color: var(--ink);
  font-size: var(--text-sm);
  margin-top: 0.375rem;
}
.user-role-mgmt__empty {
  color: var(--ink-muted);
}

/* ---------- SCR-16 Approver Config ---------- */
.approver-config {
  max-width: 44rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.approver-config h1 {
  font-size: var(--text-xl);
  margin: 0;
}
.approver-config__panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.approver-config__list {
  list-style: none;
  padding: 0;
  margin: 0;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  overflow: hidden;
}
.approver-config__row {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0.875rem;
  background: var(--surface-2);
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
}
.approver-config__row:last-child {
  border-bottom: none;
}
/* ADR-039 sweep: aria-hidden decorative bullet — every row in this list is
   the same "role=Approver" state (no per-row variance to signal), so `ok`
   was an unearned semantic claim, not an actual status. Fixed to
   ink-subtle rather than allowlisted. */
.approver-config__dot {
  color: var(--ink-subtle);
}
.approver-config__name {
  font-weight: 600;
}
.approver-config__email {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.approver-config__role-label {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
  margin-left: auto;
}
.approver-config__empty {
  color: var(--ink-muted);
}

/* ===== MS-25 — SCR-06..10 Agent shell (Queue / Ticket Detail / Approvals /
   Knowledge Review). Token roles only (PRN-03/ADR-001), no literal colors. */

/* "Status pill" recipe (DESIGN-SYSTEM.md) — neutral default, ok/warn/danger
   semantic variants. Reused for ticket status, SLA clock state, article
   status, and approval decision — the class is always the raw literal
   value from the view model, matched by attribute selector groups below
   rather than one class per possible string. */
.status-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: var(--text-sm);
  background: var(--surface-2);
  color: var(--ink-muted);
  white-space: nowrap;
}
.status-pill--ok,
.status-pill--closed,
.status-pill--resolved,
.status-pill--met,
.status-pill--published,
.status-pill--approved,
.status-pill--fulfilled {
  background: var(--ok-tint);
  color: var(--ink);
}
.status-pill--warn,
.status-pill--paused {
  background: var(--warn-tint);
  color: var(--ink);
}
.status-pill--danger,
.status-pill--breached,
.status-pill--rejected,
.status-pill--cancelled {
  background: var(--danger-tint);
  color: var(--ink);
}
/* SCR-19's own narrow, documented exception (design/screens/SCR-19-
   impersonation-history.md Theme bindings): "a running StatusPill,
   accent-toned" for an active impersonation session's Duration column —
   not a general status-pill semantic, just this one screen's literal ask. */
.status-pill--accent {
  /* ADR-039: accent-tint role replaces the color-mix (was 16% — same hue-
     drift risk as every other tint site). Chief Architect gate (MS-26 Wave
     A, fix 3): text on the old ad-hoc tint measured 3.923:1 light — under
     floor; the role's own ink-on-tint pin (tokens.contrast.test.ts) is
     >=4.5:1 both bindings. Matches every other pill variant above (ok/warn/
     danger all use ink text, tint carries the semantic) — SCR-19's
     documented exception is the accent-TONED variant existing at all, not
     accent-colored text. */
  background: var(--accent-tint);
  color: var(--ink);
}

.type-tag {
  display: inline-flex;
  padding: 0.1rem 0.5rem;
  border-radius: 6px;
  border: 1px solid var(--hairline);
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

/* "SLA clock card" recipe */
.sla-clock-card {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--surface-1);
  margin-bottom: 0.5rem;
}
.sla-clock-card__type {
  font-weight: 600;
  color: var(--ink);
  min-width: 6rem;
}
.sla-clock-card__meta {
  color: var(--ink-muted);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

/* Ticket Queue (SCR-07) */
.ticket-queue-web__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.5rem;
}
.ticket-queue-web__toolbar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin: 0.75rem 0;
  flex-wrap: wrap;
}
.ticket-queue-web__count,
.ticket-queue-web__sort-note {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
}
.ticket-queue-web__table {
  width: 100%;
  border-collapse: collapse;
}
.ticket-queue-web__table thead tr {
  /* MS-25 PRN-05 audit (2026-07-10): the "surface-step" bug (same class SCR-20
     hit) — with no explicit background this row rendered on body's bare
     surface-3, putting ink-subtle header text at 4.457:1 (just under the 4.5
     floor). An explicit surface-2 step (same elevation SCR-11's admin tables
     use) clears it in both theme bindings. */
  background: var(--surface-2);
  border-bottom: 1px solid var(--hairline);
}
.ticket-queue-web__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  padding: 0.4rem 0.5rem;
}
.ticket-queue-web__table tbody tr {
  /* MS-25 PRN-05 re-audit (2026-07-10): the accent-link instance of the same
     surface-step bug — the Ticket-#### link (base `a { color: var(--accent) }`)
     rendered directly on body's bare surface-3, measuring 4.225:1 in light
     (under the 4.5 floor). Same surface-1 step the approvals card already
     uses for its own Ticket-#### link (that one already passed, confirming
     surface-1 is the right fix here too) — not a token change.
  */
  background: var(--surface-1);
}
.ticket-queue-web__table td {
  padding: 0.5rem;
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
}
.ticket-queue-web__id {
  font-family: var(--font-mono); /* tokens.json role, not a literal font */
  font-variant-numeric: tabular-nums;
}
.ticket-queue-web__empty {
  color: var(--ink-muted);
  padding: 1rem 0;
}

/* Ticket Detail Agent Console (SCR-08) */
.ticket-detail-web__topbar {
  /* MS-25 PRN-05 re-audit (2026-07-10): the "‹ Back to Queue" link (base
     `a { color: var(--accent) }`) rendered directly on body's bare
     surface-3, measuring 4.225:1 in light (under the 4.5 floor) — same
     surface-1 elevation SCR-08's own convention already gives the header
     region over the surface-3 canvas, matching
     .ticket-detail-web__description's existing step immediately below. */
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.75rem;
  margin-top: 0.75rem;
}
.ticket-detail-web__header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.75rem;
}
.ticket-detail-web__meta {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.ticket-detail-web__description {
  padding: 0.75rem;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  color: var(--ink);
  margin: 0.5rem 0;
}
.ticket-detail-web__columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin: 1rem 0;
}
.ticket-detail-web__timeline {
  /* MS-25 PRN-05 audit (2026-07-10): same surface-step bug — timeline meta
     text (ink-subtle) rendered directly on body's surface-3 (4.472:1,
     under floor). Explicit surface-1 step matches
     .ticket-detail-web__description's own elevation immediately above it. */
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  list-style: none;
  margin: 0 0 0.75rem;
}
.ticket-detail-web__timeline li {
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
}
.ticket-detail-web__timeline-meta {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
  margin-right: 0.5rem;
}
.ticket-detail-web__empty {
  color: var(--ink-muted);
}
.ticket-detail-web__kv {
  color: var(--ink);
  margin: 0.4rem 0;
}
/* Chief Architect gate (MS-26 Wave A, fix 4): bare `color: var(--danger)`
   on an ambient surface measured 4.336:1/4.479:1 both bindings — under
   floor, and the same class the MS-25 audit had already flagged without a
   fix landing. Same recipe as .ticket-type-field-config__error /
   known-gap-banner's --blocking variant: a self-contained tinted box (own
   background, never dependent on whatever ambient surface it's dropped
   into) with ink text — danger conveyed by the tint/border, not by text
   color reliance. Fixed once here for both consumers (agent Incident panel
   error, now inside its own surface-1 type-panel anyway; the platform
   impersonation form's "reason required"/"already active" error, which has
   no ambient surface step of its own). */
.ticket-detail-web__panel-error {
  background: var(--danger-tint);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 0.625rem 0.875rem;
  color: var(--ink);
  font-size: var(--text-sm);
  margin: 0.5rem 0;
}
.ticket-detail-web__type-panel,
.ticket-detail-web__extra-fields {
  /* MS-25 PRN-05 audit (2026-07-10): same surface-step bug — this panel's
     danger/ink-subtle text (error banners, kv rows) rendered directly on
     body's surface-3 (4.336:1, under floor). Explicit surface-1 step. */
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  margin-top: 1.5rem;
  padding: 1rem;
}
.ticket-detail-web__inline-form,
.ticket-detail-web__type-panel form {
  display: flex;
  gap: 0.5rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin: 0.5rem 0;
}
.ticket-detail-web__type-panel label,
.ticket-detail-web__comment-form textarea {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}
.ticket-detail-web__subtype-group {
  margin-bottom: 1rem;
}
.ticket-detail-web__switch-confirm {
  margin: 0.5rem 0;
  color: var(--ink);
}

/* "Dynamic field group" recipe (ADR-030) */
.dynamic-field-group {
  margin: 0.75rem 0;
  padding: 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--surface-1);
}
.dynamic-field-group__title {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin: 0 0 0.5rem;
}
.dynamic-field-group__fields {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.dynamic-field-group__field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}
.dynamic-field-group__field--boolean {
  flex-direction: row;
  align-items: center;
}
/* ui-lint-allow: semantic-text — glyph-only span ("*" required-marker),
   never the sole signal (the field's own `label` text and, on submit, the
   `__error` message below name the requirement in words). */
.dynamic-field-group__required {
  color: var(--danger);
}
/* ADR-039 sweep: role="alert" prose message (the group's own error text)
   — fixed to ink rather than allowlisted, matching the ink+wording
   convention the boxed error recipes already use. */
.dynamic-field-group__error {
  color: var(--ink);
  margin: 0.5rem 0 0;
}
.dynamic-field-group__save-btn {
  margin-top: 0.6rem;
}

/* Change Approvals (SCR-09) */
.change-approvals-web__subtitle {
  color: var(--ink-muted);
  margin: 0.25rem 0 1rem;
}
.change-approvals-web__list {
  list-style: none;
  padding: 0;
}
.change-approvals-web__card {
  padding: 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--surface-1);
  margin-bottom: 0.75rem;
}
.change-approvals-web__card-meta {
  display: flex;
  gap: 0.75rem;
  align-items: center;
}
.change-approvals-web__id {
  font-weight: 600;
  color: var(--ink);
}
.change-approvals-web__requested-by,
.change-approvals-web__desc {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.change-approvals-web__decision-form {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.change-approvals-web__empty,
.change-approvals-web__error {
  color: var(--ink-muted);
}

/* Knowledge Review (SCR-10) */
.knowledge-review-web__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.knowledge-review-web__new-form form {
  display: flex;
  gap: 0.5rem;
  align-items: flex-end;
  margin: 0.5rem 0;
}
.knowledge-review-web__toolbar {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  margin: 0.75rem 0;
}
.knowledge-review-web__rows {
  list-style: none;
  padding: 0;
}
.knowledge-review-web__rows li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem;
  border-bottom: 1px solid var(--hairline);
}
.knowledge-review-web__row--active {
  background: var(--surface-2);
}
.knowledge-review-web__row-title {
  color: var(--ink);
  margin-right: 0.5rem;
}
.knowledge-review-web__row-meta {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
}
.knowledge-review-web__detail form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 40rem;
}
.knowledge-review-web__source {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.knowledge-review-web__actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
/* ADR-039 sweep: both are role="alert" prose messages (views/agent/
   knowledge/_worklist.hbs, _detail.hbs) — fixed to ink rather than
   allowlisted. */
.knowledge-review-web__save-error,
.knowledge-review-web__error {
  color: var(--ink);
}
.knowledge-review-web__prompt {
  color: var(--ink-muted);
}

/* ============================================================
   MS-26 — SCR-01..05 Reporter shell (App Shell / Report Intake / Ticket
   Detail Reporter / My Tickets / Knowledge Search) + SCR-17..19 Platform
   Admin shell. Token roles only (PRN-03/ADR-001), no literal colors.
   Ticket-detail-web__*/ticket-queue-web__* classes are reused verbatim for
   SCR-03/04 (read-only variants of the same recipes MS-25 already
   established) — only the screens below with no prior equivalent get new
   classes.
   ============================================================ */

/* MS-12 recipe (design/DESIGN-SYSTEM.md "Identity switcher"), htmx
   equivalent — segmented-control visual. Not present on the Platform Admin
   shell (recipe's own note). */
.identity-switcher {
  display: flex;
  gap: 0.25rem;
  padding: 0.2rem;
  background: var(--surface-2);
  border-radius: 8px;
}
.identity-switcher__item {
  padding: 0.3rem 0.65rem;
  border-radius: 6px;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
}
/* ui-lint-allow: semantic-text — this is an `<a>` (partials/identity-
   switcher.hbs), same value as the audited base `a` rule; re-asserted here
   only to win over the sibling `.identity-switcher__item` class's
   ink-muted at equal specificity. Measured against its own surface-1
   background: 4.863:1 light / 6.635:1 dark. */
.identity-switcher__item--active {
  background: var(--surface-1);
  color: var(--accent);
  font-weight: 600;
}

/* SCR-02 Report Intake */
.report-intake-web__form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 40rem;
  margin-bottom: 1.5rem;
}
.report-intake-web__textarea {
  min-height: 6rem;
}
.report-intake-web__submit {
  align-self: flex-end;
}
.report-intake-web__conversation:empty {
  display: none;
}
.report-intake-web__system-line {
  color: var(--ink-muted);
  margin: 0.35rem 0;
}
.report-intake-web__dedup-offer,
.report-intake-web__confirmation {
  padding: 0.75rem;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--surface-1);
  margin-top: 0.5rem;
}
.report-intake-web__report-anyway-form {
  margin-top: 0.5rem;
}
/* ADR-039 sweep: role="alert" prose message (views/reporter/intake/
   _conversation.hbs) — fixed to ink rather than allowlisted. */
.report-intake-web__error {
  color: var(--ink);
}

/* SCR-05 Knowledge Search */
.knowledge-search-web__bar {
  display: flex;
  gap: 0.5rem;
  max-width: 32rem;
  margin-bottom: 1rem;
}
.knowledge-search-web__bar input[type='search'] {
  flex: 1;
}
.knowledge-search-web__prompt,
.knowledge-search-web__results-count {
  color: var(--ink-muted);
}
.knowledge-search-web__results {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.knowledge-search-web__article-body {
  color: var(--ink);
  font-size: var(--text-md);
  line-height: 1.6;
  margin: 1rem 0;
  white-space: pre-wrap;
}
.knowledge-search-web__followup {
  color: var(--ink-muted);
}

/* SCR-18 Tenants / Start Impersonation */
.tenant-impersonation-web__acting-as {
  color: var(--ink);
  margin: 0.5rem 0 1rem;
}
.tenant-impersonation-web__form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 28rem;
}
.tenant-impersonation-web__label {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
/* Chief Architect gate (MS-26 Wave A, fix 2): text on ambient background
   measured 2.749:1 light — under floor. Same known-gap-banner convention:
   the glyph alone (⚠, an emoji — not relying on CSS foreground color for
   its own contrast) carries the warn signal, body text is ink. */
.tenant-impersonation-web__warning {
  color: var(--ink);
}
.tenant-impersonation-web__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

/* MS-30 — SCR-21..24 Type Studio. Reuses .btn/.status-pill/.known-gap-banner
   verbatim (no forked copies); new classes below only for the two new
   DESIGN-SYSTEM.md recipes (Lifecycle version bar, AI draft panel) and
   studio-specific grids/panels that have no existing analog. */

/* SCR-21 Type Studio home */
.studio-home {
  max-width: 60rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.studio-home__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}
.studio-home__header h1 {
  font-size: var(--text-xl);
  margin: 0;
}
.studio-home__subtitle {
  color: var(--ink-muted);
}
.studio-home__section {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.studio-home__section-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.75rem;
}
.studio-home__section-header h2 {
  font-size: var(--text-lg);
  margin: 0;
}
.studio-home__table {
  width: 100%;
  border-collapse: collapse;
}
.studio-home__table thead tr {
  background: var(--surface-2);
}
.studio-home__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  padding: 0.5rem 0.75rem;
}
.studio-home__table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.75rem;
  color: var(--ink);
  background: var(--surface-1);
}
/* ADR-039 sweep: `<a class="studio-home__row-link">` (views/admin/studio/
   home/index.hbs, .../types|workflow|template/index.hbs) — the base `a`
   rule already colors it accent at equal-or-lower specificity; this
   re-declaration was redundant, removed rather than marked. */
.studio-home__row-link {
  text-decoration: none;
}
.studio-home__pills {
  display: flex;
  gap: 0.375rem;
  flex-wrap: wrap;
}
/* Retired pill: neutral tint, ink-subtle text — the word "Retired vN"
   always renders, this class only mutes the tint relative to the shared
   .status-pill base (never color-alone, per the recipe). */
.status-pill.studio-home__pill--retired {
  color: var(--ink-subtle);
}
.studio-home__empty {
  color: var(--ink-muted);
  padding: 0.5rem 0;
}
.studio-home__new-panel {
  margin-top: 1rem;
}
/* ui-lint-allow: semantic-text — disclosure-trigger affordance (same
   interactive-text role as a link, `<summary>` can't use the `a` rule).
   Sits on .studio-home__section's surface-1: measured 4.863:1 light /
   6.635:1 dark. */
.studio-home__new-panel summary {
  cursor: pointer;
  color: var(--accent);
}
.studio-home__new-panel form {
  display: flex;
  gap: 0.75rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}
.studio-home__new-panel label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.studio-home__registrations-summary {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.studio-home__registration-row {
  color: var(--ink);
}

/* "Lifecycle version bar" recipe (design/DESIGN-SYSTEM.md, ADR-037) — first
   content element of SCR-22/SCR-23. State is carried by glyph AND the word
   (never glyph/color-alone). */
.version-bar {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.875rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.version-bar__state {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--ink);
  font-size: var(--text-md);
}
.version-bar__glyph {
  /* Glyph is decorative only — the word (stateLabel) beside it carries the
     meaning, so no color/aria semantics ride on this alone. */
  color: var(--ink-muted);
}
.version-bar__tail {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
}
.version-bar__other-active {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
}
.version-bar__actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
/* Inline (non-native) activation confirm — a <details>/<summary> pair, not
   window.confirm(). */
.version-bar__confirm {
  display: inline-block;
}
.version-bar__confirm summary {
  list-style: none;
  cursor: pointer;
}
.version-bar__confirm summary::-webkit-details-marker {
  display: none;
}
.version-bar__confirm[open] summary {
  display: none;
}
/* ADR-039: activation confirm is a MEANINGFUL semantic border (naming the
   role expectation before an irreversible activation, per the Lifecycle
   version bar recipe) — warn-border role, not a decorative hairline. */
.version-bar__confirm-body {
  background: var(--warn-tint);
  border: 1px solid var(--warn-border);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-top: 0.5rem;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 28rem;
}
.version-bar__confirm-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

/* "AI draft panel" recipe (design/DESIGN-SYSTEM.md, ADR-037/ADR-034) —
   Draft-only, SCR-22. Contains NO activation control by structure. */
.ai-draft-panel {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.ai-draft-panel__label {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.ai-draft-panel textarea {
  width: 100%;
  min-height: 4rem;
  resize: vertical;
}
.ai-draft-panel__actions {
  display: flex;
  justify-content: flex-end;
}
/* PRN-05 audit fix: the disclosure line now carries the known-gap-banner
   --info recipe (accent ~10% tint over surface-1, ink text, the ⓘ glyph
   from that recipe's ::before) instead of plain ink-subtle text — matches
   DESIGN-SYSTEM.md's "AI draft panel" recipe text ("info-tinted") exactly.
   This rule only adds panel-specific spacing on top of the shared
   .known-gap-banner--info classes (applied together in the .hbs), it must
   NOT re-set color/background or it would win the cascade tie and undo the
   tint (same specificity, declared after known-gap-banner in this file). */
.ai-draft-panel__disclosure {
  margin: 0;
}
.ai-draft-panel__progress {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.ai-draft-panel__error {
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-sm);
}
/* Word-chip marker for AI-drafted rows — ink-subtle text, never
   color-alone (the word "ai" itself is the signal). */
.ai-chip {
  display: inline-flex;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  color: var(--ink-subtle);
  font-size: var(--text-xs);
  text-transform: lowercase;
}

/* SCR-22 field grid — same config-as-data table shape as
   .ticket-type-field-config__table, studio-specific class since the
   columns differ (adds an "ai?" column + inline inputs instead of a
   read-only row list). */
.studio-fields {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.studio-fields__heading {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}
.studio-fields__heading h2 {
  font-size: var(--text-lg);
  margin: 0;
}
.studio-fields__table {
  width: 100%;
  border-collapse: collapse;
}
.studio-fields__table thead tr {
  background: var(--surface-2);
}
.studio-fields__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  padding: 0.5rem 0.6rem;
}
.studio-fields__table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.4rem 0.6rem;
  background: var(--surface-1);
  color: var(--ink);
}
.studio-fields__table input[type='text'],
.studio-fields__table input[type='number'],
.studio-fields__table select {
  width: 100%;
  min-width: 6rem;
}
.studio-fields__lineage-note {
  color: var(--ink-subtle);
  font-size: var(--text-sm);
}
.studio-fields__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
.studio-fields__confirm {
  background: var(--ok-tint);
  border: 1px solid var(--hairline);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
}
.studio-fields__error {
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
}

/* SCR-23 workflow editor — status chips (filter-pill vocabulary: neutral
   chips, initial carries an ink-subtle word-label, never color-alone) and
   the transitions+gates grid (each row's gate editor rendered always-inline
   — see web-studio-workflows.controller.ts's header comment). */
.studio-workflow {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.studio-workflow__statuses {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.studio-workflow__chips {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.studio-workflow__chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--ink);
  font-size: var(--text-sm);
}
.studio-workflow__chip-initial-label {
  color: var(--ink-subtle);
  font-size: var(--text-xs);
}
.studio-workflow__add-status {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.studio-workflow__transitions-table {
  width: 100%;
  border-collapse: collapse;
}
.studio-workflow__transitions-table thead tr {
  background: var(--surface-2);
}
.studio-workflow__transitions-table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  padding: 0.5rem 0.6rem;
}
.studio-workflow__transitions-table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.6rem;
  background: var(--surface-1);
  color: var(--ink);
  vertical-align: top;
}
.studio-workflow__gate-editor {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.studio-workflow__gate-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.studio-workflow__gate-note {
  color: var(--ink-subtle);
  font-size: var(--text-xs);
}
.studio-workflow__add-transition {
  display: flex;
  gap: 0.5rem;
  align-items: flex-end;
  flex-wrap: wrap;
}
.studio-workflow__actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}

/* SCR-24 Registered Types & Numbering */
.studio-types {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.studio-types__section {
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.studio-types__section-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0.75rem;
}
.studio-types__section-header h2 {
  font-size: var(--text-lg);
  margin: 0;
}
.studio-types__table {
  width: 100%;
  border-collapse: collapse;
}
.studio-types__table thead tr {
  background: var(--surface-2);
}
.studio-types__table th {
  text-align: left;
  color: var(--ink-subtle);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  padding: 0.5rem 0.6rem;
}
.studio-types__table td {
  border-bottom: 1px solid var(--hairline);
  padding: 0.5rem 0.6rem;
  background: var(--surface-1);
  color: var(--ink);
}
/* Next-number preview column reads like a ticket id — monospace/tabular
   figures, per SCR-24's own Theme bindings note. */
.studio-types__next-number {
  font-variant-numeric: tabular-nums;
  font-family: var(--font-mono); /* tokens.json role, not a literal font */
}
.studio-types__add-panel {
  margin-top: 1rem;
}
/* ui-lint-allow: semantic-text — disclosure-trigger affordance, same
   justification as .studio-home__new-panel summary above (sits on
   .studio-types__section's surface-1: 4.863:1 light / 6.635:1 dark). */
.studio-types__add-panel summary {
  cursor: pointer;
  color: var(--accent);
}
.studio-types__add-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.75rem;
  max-width: 34rem;
}
.studio-types__add-form label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.studio-types__add-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
/* ADR-040/MS-32 (closes OQ-29): word-note for a derived-type range's one
   remaining scope nuance — it applies only on a classification-time
   creation, never on an agent's later setRegisteredType correction. No
   longer a caution marker (the range is live, not inert) — plain subdued
   text, no glyph. */
.studio-types__derived-note {
  color: var(--ink-subtle);
  font-size: var(--text-xs);
}
.studio-types__error {
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
}
.studio-types__narrow-input {
  width: 5rem;
}
.studio-types__confirm {
  background: var(--ok-tint);
  border: 1px solid var(--hairline);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
}

/* ============================================================
   MS-39 — SCR-25/SCR-26 Login screens (ADR-046, closes OQ-35). New card
   layout only — form-control/button/error recipes below all reuse the
   existing tokens.css shared rules and this file's own established
   danger-tint-error convention (studio-types__error / priority-matrix__
   save-error / report-intake-web__error above), no new color values.
   ============================================================ */
.login-web__page {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  padding-top: 2rem;
}
.login-web__card {
  width: 100%;
  max-width: 24rem;
  background: var(--surface-1);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1.5rem;
}
.login-web__heading {
  margin: 0 0 1rem;
  font-size: var(--text-lg);
}
.login-web__form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.login-web__label {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.login-web__submit {
  margin-top: 0.5rem;
}
/* Same danger-tint-background + ink-text construction as every other
   inline form error in this file (studio-types__error etc.) plus a leading
   ⚠ glyph (SCR-25/26 Theme bindings: "danger-tint background, ink text, ⚠
   glyph — never color-alone") — the glyph is icon-only (::before, paired
   with the ink-text message), not the message text itself recoloring, same
   posture as the known-gap-banner glyphs above. */
.login-web__error {
  background: var(--danger-tint);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-sm);
  color: var(--ink);
  margin: 0 0 0.75rem;
}
/* ui-lint-allow: semantic-text — glyph-only ::before (⚠), paired with the
   error's own ink-text message; not color-alone (PRODUCT.md a11y rule),
   same convention as .known-gap-banner--caution::before above. */
.login-web__error::before {
  content: '⚠ ';
  color: var(--danger);
}
.login-web__dev-panel {
  width: 100%;
  max-width: 24rem;
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 1rem 1.25rem;
}
.login-web__dev-panel-title {
  margin: 0 0 0.5rem;
  color: var(--ink-muted);
  font-size: var(--text-sm);
}
.login-web__dev-panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
