/*
 * app.css — Layout and component styles for the Agent Pack Hub prototype.
 *
 * Consumes tokens.css variables (var(--...)) exclusively. No literal color
 * value is authored here — every color traces back to a named token in
 * tokens.css. Structural values (1px hairlines, 100% widths) are fine;
 * design spacing always uses var(--space-*).
 *
 * Security note (SPEC-070 T-06 / project rule): a CSS rule is NEVER used to
 * hide a restricted record. Any pack reaching markup this stylesheet styles
 * has already been authorized by the data layer — display/visibility rules
 * below are purely presentational (hover, focus, selection, empty states),
 * never an access boundary.
 *
 * Class-name contract: each top-level screen region carries a
 * data-component="<name>" attribute (matched by component JS in later
 * plans). Sub-parts of a component use a BEM-style `component__part`
 * class, e.g. `.pack-card__name` inside `[data-component="pack-card"]`.
 * State is expressed with `.is-*` modifier classes (`.is-selected`,
 * `.is-highlighted`, `.is-active`, `.is-collapsed`).
 */

* {
  box-sizing: border-box;
}

/* html, body anchor the app-shell flex column to a DEFINITE ancestor
   height. Without this, #app-root's flex:1 1 auto and the child
   height:100% rule on catalog-view/account-screen/not-found resolve their
   percentage against an auto-height ancestor (per the CSS spec, a
   percentage height against a no-explicit-height ancestor resolves to
   auto) — the flex-grow then has nothing to grow into and the panes lose
   their internal overflow scroll containment (content runs under the two
   persistent bars below). Phase 2 UI-SPEC "App shell restructuring". */
html, body {
  height: 100%;
}

/* body is now a column-flex shell: demo-toolbar, then app-header (both
   flex: 0 0 auto), then #app-root (flex: 1 1 auto) filling the rest (D-08). */
body {
  margin: 0;
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  font-weight: var(--font-weight-regular);
  color: var(--color-ink);
  background: var(--color-surface);
  display: flex;
  flex-direction: column;
}

/* Accent focus ring on every interactive element — 1st reserved accent use */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* #app-root is the flex-growing shell child underneath the two persistent
   bars — min-height: 0 is required so its own overflow-scrolling children
   (catalog-view/account-screen/not-found) can shrink below their content
   size instead of forcing the flex column to grow past the viewport. */
#app-root {
  flex: 1 1 auto;
  min-height: 0;
}

/* ---------------------------------------------------------------------
   App header — persistent chrome above the demo toolbar and #app-root,
   never hidden (unlike the demo toolbar below it). Home link + (only when
   signed in) the current user's own name -> #/account.
   --------------------------------------------------------------------- */

[data-component="app-header"] {
  background: var(--color-surface-secondary);
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-sm) var(--space-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
}

[data-component="app-header"] .app-header__product {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  text-decoration: none;
}

/* Plain underlined link, ink color — accent stays reserved (see below) */
[data-component="app-header"] .app-header__collection-link,
[data-component="app-header"] .app-header__account-link {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------
   Demo toolbar — hideable scaffolding control surface, now sitting ABOVE
   the app header on a deliberately distinct `ink` background (D-08) so it
   reads as tooling, never mistaken for the product's own light chrome.
   --------------------------------------------------------------------- */

[data-component="demo-toolbar"] {
  background: var(--color-ink);
  color: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-sm) var(--space-md);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  flex: 0 0 auto;
}

[data-component="demo-toolbar"] .demo-toolbar__section-heading {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-surface);
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

[data-component="demo-toolbar"] .demo-toolbar__field {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

[data-component="demo-toolbar"] .demo-toolbar__field-label {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-surface);
}

/* Toolbar's own <select> controls — identical recipe to lifecycle-filter
   select (40px height, surface background, 1px muted border, 6px radius).
   Deliberately NOT inverted: these stay small light fields sitting ON the
   dark bar (UI-SPEC "Foreground" row) — do not "fix" this to match the
   ink/surface inversion above. */
[data-component="demo-toolbar"] select {
  height: 40px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink);
  background: var(--color-surface);
}

/* Ghost buttons on the dark bar (D-08b) — scoped contrast override, not a
   new button variant: surface-colored border/text so "Empty catalog",
   "Hide demo controls", and "Reset demo" stay legible on `ink`. The base
   .button--ghost rule below is unchanged and still serves other screens on
   light backgrounds. `transparent` is a CSS keyword, not an invented token. */
[data-component="demo-toolbar"] .button--ghost {
  background: transparent;
  border-color: var(--color-surface);
  color: var(--color-surface);
}

/* Toolbar focus ring — pinned to `--color-surface`, never the themed
   `--color-accent` token (code review WR-02). The global :focus-visible
   rule above rides --color-accent, which now varies per platform view;
   against the toolbar's `ink` background two of the three accent values
   (default 2.34:1, copilot-admin 2.13:1) fall below the WCAG 3:1 focus-
   indicator minimum. The toolbar is explicitly non-product tooling (D-08),
   not one of the three themed views, so its focus ring stays fixed and
   ink-safe regardless of the active theme. */
[data-component="demo-toolbar"] :focus-visible {
  outline-color: var(--color-surface);
}

/* Collapsed-toolbar tab ("Show demo controls") — the collapsed-state
   control, fixed top-right at the same z-index tier as
   .reset-confirm-overlay's backdrop. Renders in #demo-toolbar-mount
   OUTSIDE [data-component="demo-toolbar"], over the light page surface, so
   it correctly keeps the base (non-inverted) ghost look. */
.demo-toolbar-tab {
  position: fixed;
  top: var(--space-sm);
  right: var(--space-sm);
  z-index: 20;
}

/* ---------------------------------------------------------------------
   Three-pane list-detail layout (desktop >= 1024px)
   --------------------------------------------------------------------- */

[data-component="catalog-view"] {
  display: flex;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

[data-component="filter-rail"] {
  flex: 0 0 280px;
  width: 280px;
  background: var(--color-surface-secondary);
  padding: var(--space-lg) var(--space-md);
  border-right: 1px solid var(--color-border);
  overflow-y: auto;
  height: 100%;
}

[data-component="pack-list"] {
  flex: 1 1 auto;
  min-width: 360px;
  max-width: 520px;
  background: var(--color-surface);
  padding: var(--space-md);
  border-right: 1px solid var(--color-border);
  overflow-y: auto;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

[data-component="pack-detail"] {
  flex: 1 1 auto;
  min-width: 480px;
  background: var(--color-surface);
  padding: var(--space-2xl);
  overflow-y: auto;
  height: 100%;
}

/* Initial state, nothing selected: centered placeholder inside pack-detail */
[data-component="pack-detail"] .pack-detail__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  gap: var(--space-sm);
}

[data-component="pack-detail"] .pack-detail__empty-heading {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0;
}

[data-component="pack-detail"] .pack-detail__empty-body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: 0;
}

/* Narrow viewport: collapse to a single visible pane (sensible default,
   not a locked requirement — deprioritize under time pressure). */
@media (max-width: 767px) {
  [data-component="catalog-view"] {
    flex-direction: column;
    height: auto;
    overflow: visible;
  }

  [data-component="filter-rail"] {
    width: 100%;
    flex: 0 0 auto;
    border-right: none;
    border-bottom: 1px solid var(--color-border);
  }

  [data-component="filter-rail"].is-collapsed {
    display: none;
  }

  [data-component="pack-list"],
  [data-component="pack-detail"] {
    width: 100%;
    max-width: none;
    min-width: 0;
    flex: 1 1 auto;
    border-right: none;
  }
}

/* ---------------------------------------------------------------------
   Filter rail
   --------------------------------------------------------------------- */

[data-component="filter-rail"] .filter-rail__section {
  margin-bottom: var(--space-lg);
}

[data-component="collection-detail"] .collection-detail__eyebrow,
[data-component="collection-detail"] .collection-detail__group-heading,
[data-component="filter-rail"] .filter-rail__section-heading {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-muted);
  margin: 0 0 var(--space-sm) 0;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* Applied/active facet chip — 3rd reserved accent use */
[data-component="filter-rail"] .filter-rail__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink);
  background: var(--color-surface);
  cursor: pointer;
}

[data-component="filter-rail"] .filter-rail__chip.is-active {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

/* Applied-chips wrapper (WR-02) — without this, simultaneously-applied
   facet chips render touching each other with no gap. */
[data-component="filter-rail"] .filter-rail__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

/* Lifecycle-stage native <select> control (WR-02) — matches the
   area-combobox input's own visual treatment (40px, same border/radius). */
[data-component="lifecycle-filter"] select {
  width: 100%;
  height: 40px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink);
  background: var(--color-surface);
}

/* ---------------------------------------------------------------------
   Pack card (one per result-list row) — no image, field order locked
   ---------------------------------------------------------------------
   name -> use-case -> description -> footer (author + rating) */

[data-component="pack-card"] {
  display: flex;
  flex-direction: column;
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  cursor: pointer;
  text-align: left;
  width: 100%;
}

/* Hover (pointer, not keyboard) — neutral shift only, never accent */
[data-component="pack-card"]:hover {
  background: var(--color-surface-secondary);
}

/* Selected/currently-open — 2nd reserved accent use: 4px left border,
   replacing the default 1px border on that edge only */
[data-component="pack-card"].is-selected {
  border-left: 4px solid var(--color-accent);
}

[data-component="pack-card"] .pack-card__name {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

[data-component="pack-card"] .pack-card__use-case {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: var(--space-xs) 0 0 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

[data-component="pack-card"] .pack-card__description {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: var(--space-sm) 0 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

[data-component="pack-card"] .pack-card__footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-sm);
}

[data-component="pack-card"] .pack-card__author {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-regular);
  color: var(--color-ink-muted);
}

/* Rating footer slot: markup is entirely absent (not rendered empty) when
   the pack is unrated — a component-JS concern, not a CSS one. */
[data-component="pack-card"] .pack-card__rating {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
}

/* ---------------------------------------------------------------------
   Area combobox (inside filter-rail) — W3C APG combobox-with-listbox
   ARIA structure implemented by component JS; visual treatment only here.
   --------------------------------------------------------------------- */

[data-component="area-combobox"] {
  position: relative;
  width: 100%;
}

[data-component="area-combobox"] .area-combobox__input {
  width: 100%;
  height: 40px;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  background: var(--color-surface);
}

[data-component="area-combobox"] .area-combobox__input::placeholder {
  color: var(--color-ink-muted);
}

[data-component="area-combobox"] .area-combobox__popup {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  width: 100%;
  max-height: 320px;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  margin: 0;
  padding: 0;
  list-style: none;
  z-index: 10;
}

[data-component="area-combobox"] .area-combobox__option {
  padding: var(--space-sm) var(--space-md);
  cursor: pointer;
}

[data-component="area-combobox"] .area-combobox__option-primary {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  display: block;
}

[data-component="area-combobox"] .area-combobox__option-secondary {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  display: block;
}

/* Highlighted option (aria-activedescendant target) — 2nd reserved accent
   use, mixed at 10% via color-mix so the tint always derives from the
   accent token rather than a second hardcoded literal. */
[data-component="area-combobox"] .area-combobox__option.is-highlighted {
  background: color-mix(in srgb, var(--color-accent) 10%, var(--color-surface));
}

[data-component="area-combobox"] .area-combobox__group-toggle {
  display: block;
  margin-top: var(--space-sm);
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}

/* Icon-only controls (search/clear affordances): minimum 44x44 hit target
   per WCAG 2.5.5 — pad the button, don't enlarge the glyph. Each such
   control also needs an aria-label, applied by component JS. */
[data-component="area-combobox"] .area-combobox__icon-button {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-ink-muted);
}

/* ---------------------------------------------------------------------
   Pack detail body — sections render in the fixed SPEC-030 order:
   Purpose, Context, When to use this, When NOT to use this, Persona,
   Objectives, Workflow, Examples, Guardrails, Deployment context,
   Changelog. Open density (lg/xl/2xl spacing tokens).
   --------------------------------------------------------------------- */

[data-component="pack-detail"] .pack-detail__header {
  margin-bottom: var(--space-xl);
}

[data-component="collection-detail"] .collection-detail__title,
[data-component="pack-detail"] .pack-detail__title {
  font-size: var(--font-size-display);
  line-height: var(--line-height-display);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0 0 var(--space-sm) 0;
}

[data-component="collection-detail"] .collection-detail__context,
[data-component="pack-detail"] .pack-detail__meta {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
}

[data-component="pack-detail"] .pack-detail__capabilities {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-md);
}

[data-component="pack-detail"] .pack-detail__capability-pill {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink);
  background: var(--color-surface-secondary);
  border-radius: var(--radius);
  padding: var(--space-xs) var(--space-sm);
}

[data-component="pack-detail"] .pack-detail__deployment {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

/* External-link affordance: icon-only, 44x44 hit target (WCAG 2.5.5) */
[data-component="pack-detail"] .pack-detail__deployment-link {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-ink);
}

[data-component="pack-detail"] .pack-detail__section {
  margin-top: var(--space-xl);
}

[data-component="pack-detail"] .pack-detail__section:first-of-type {
  margin-top: 0;
}

/* Also reused verbatim by the account-screen component (Areas / Your
   records headings) and the submission-form component (fieldset legends,
   04-UI-SPEC.md "Typography") — extended here rather than forked
   (02-UI-SPEC.md "Reused-class styling note"). */
[data-component="pack-detail"] .pack-detail__section-heading,
[data-component="account-screen"] .pack-detail__section-heading,
[data-component="submission-form"] .pack-detail__section-heading,
[data-component="moderation-review"] .pack-detail__section-heading {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0 0 var(--space-sm) 0;
}

[data-component="pack-detail"] .pack-detail__section-body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  margin: 0;
}

[data-component="pack-detail"] .pack-detail__workflow {
  margin: 0;
  padding-left: var(--space-lg);
}

[data-component="pack-detail"] .pack-detail__workflow li {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
}

[data-component="pack-detail"] .pack-detail__changelog {
  margin: 0;
  padding: 0;
  list-style: none;
}

[data-component="pack-detail"] .pack-detail__changelog li {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  margin-top: var(--space-xs);
}

/* Guardrails — distinct visual treatment (safety-relevant, not just
   another prose block): surface-secondary fill, ink left border
   (never accent — accent stays reserved for the 3 uses above). Also
   reused verbatim by the submission-form component for the Guardrails
   body field and the tools_forbidden checkbox group — both get the same
   safety box (04-UI-SPEC.md Field Inventory #19 / Body sections #9) —
   extended here rather than forked (02-UI-SPEC.md "Reused-class styling
   note"). */
[data-component="pack-detail"] .pack-detail__guardrails,
[data-component="submission-form"] .pack-detail__guardrails {
  background: var(--color-surface-secondary);
  border-left: 4px solid var(--color-ink);
  padding: var(--space-md);
  border-radius: var(--radius);
}

/* Header sub-parts not covered above: use-case line, area chips, and the
   author/rating meta line's own children (WR-01). */
[data-component="collection-detail"] .collection-detail__subtitle,
[data-component="pack-detail"] .pack-detail__use-case {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: var(--space-sm) 0 0 0;
}

/* Also reused verbatim by the account-screen component's Areas section —
   extended here rather than forked (02-UI-SPEC.md "Reused-class styling
   note"). */
[data-component="pack-detail"] .pack-detail__area-chips,
[data-component="account-screen"] .pack-detail__area-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  list-style: none;
  margin: var(--space-sm) 0 0 0;
  padding: 0;
}

[data-component="pack-detail"] .pack-detail__area-chip,
[data-component="account-screen"] .pack-detail__area-chip {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  background: var(--color-surface-secondary);
  border-radius: var(--radius);
  padding: var(--space-xs) var(--space-sm);
}

[data-component="pack-detail"] .pack-detail__author {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
}

[data-component="pack-detail"] .pack-detail__rating {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
}

/* Bindings row — same pill treatment as the capability strip. */
[data-component="pack-detail"] .pack-detail__bindings {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-sm);
}

[data-component="pack-detail"] .pack-detail__deployment-status {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
}

/* Real Download action (D-06) — filled-accent primary button, replacing
   the old read-only switch labels; occupies the same DOM slot so no other
   section of the detail panel shifts. */
[data-component="pack-detail"] .pack-detail__download-action {
  margin-top: var(--space-md);
}

/* Denied state: one quiet line, never a disabled-looking button. */
[data-component="pack-detail"] .pack-detail__download-unavailable {
  display: block;
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  margin-top: var(--space-md);
}

/* Permission-gated Edit control (D-05) — reuses the ghost button look;
   absent entirely (no rule needed) when authorize() denies it. */
[data-component="pack-detail"] .pack-detail__edit-action {
  margin-top: var(--space-sm);
}

/* Derived risk tier line — never a trusted authored value (SPEC-030 §8). */
[data-component="pack-detail"] .pack-detail__risk-tier {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: var(--space-sm) 0 0 0;
}

/* Forward relations list (D-025) — plain underlined ink links, matching the
   not-found/"Clear filters" convention (accent stays reserved, see above). */
[data-component="pack-detail"] .pack-detail__relations {
  margin: 0;
  padding: 0;
  list-style: none;
}

[data-component="pack-detail"] .pack-detail__relation {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  margin-top: var(--space-xs);
}

[data-component="pack-detail"] .pack-detail__relation a {
  color: var(--color-ink);
  text-decoration: underline;
}

[data-component="collection-detail"] .collection-detail__hidden-count,
[data-component="pack-detail"] .pack-detail__relation-hidden {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  margin-top: var(--space-xs);
  display: block;
}

/* ---------------------------------------------------------------------
   Not-found state — replaces the detail panel, or the full view for a
   bad direct pack-detail deep link.
   --------------------------------------------------------------------- */

[data-component="not-found"] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: var(--space-2xl);
  text-align: center;
  gap: var(--space-sm);
}

[data-component="not-found"] .not-found__heading {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0;
}

[data-component="not-found"] .not-found__body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: 0;
}

/* Plain underlined link, ink color — accent stays reserved (see above) */
[data-component="not-found"] .not-found__link {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------
   Account screen (#/account, D-07, R2-05) — single-pane, open-density
   profile screen. app.js sets #app-root's own data-component to
   "account-screen-view" for this route (mirroring the catalog-view/
   not-found "root IS the state" convention); account-screen.js's own
   returned root, nested one level inside, carries data-component=
   "account-screen" and is what the rules below style.
   --------------------------------------------------------------------- */

[data-component="account-screen-view"] {
  height: 100%;
}

[data-component="account-screen"] {
  height: 100%;
  background: var(--color-surface);
  padding: var(--space-2xl);
  overflow-y: auto;
}

/* Single-column profile content, capped so prose/lists stay scannable */
[data-component="account-screen"] .account-screen__content {
  max-width: 640px;
  margin: 0 auto;
}

[data-component="account-screen"] .account-screen__back-link,
[data-component="collection-detail"] .collection-detail__back-link,
[data-component="moderation-queue"] .moderation-queue__back-link {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
}

[data-component="account-screen"] .account-screen__header {
  margin-top: var(--space-xl);
  margin-bottom: var(--space-xl);
}

[data-component="account-screen"] .account-screen__name {
  font-size: var(--font-size-display);
  line-height: var(--line-height-display);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0 0 var(--space-sm) 0;
}

/* pack-detail__capability-pill recipe, plus the 600-weight label spec
   calls for on the role badge specifically. Reused verbatim by the
   moderation-queue Type/Imported badges (05-UI-SPEC.md). */
[data-component="account-screen"] .account-screen__role-badge,
[data-component="moderation-queue"] .account-screen__role-badge {
  display: inline-block;
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  background: var(--color-surface-secondary);
  border-radius: var(--radius);
  padding: var(--space-xs) var(--space-sm);
}

[data-component="account-screen"] .account-screen__section {
  margin-top: var(--space-xl);
}

[data-component="account-screen"] .account-screen__no-areas {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  margin: 0;
}

[data-component="account-screen"] .account-screen__records {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
}

/* ---------------------------------------------------------------------
   Pack-list empty/no-results state — mirrors the pack-detail__empty
   pattern (same tokens, same typography roles), scoped to the list pane
   instead of the detail pane. Two copy variants (app.js decides which):
   "No packs to show" (no active filters) vs "No packs match your
   filters" (facet-filtered to zero), the latter with an inline
   "Clear filters" action.
   --------------------------------------------------------------------- */

/* The active view's on-screen label (D-01, R3-01) — unconditional chrome
   rendered for every view, including "All Packs", not only on the
   empty-result branch. Deliberately its own selector rather than
   comma-extending .pack-list__empty-heading below, because that rule is
   an empty-state variant and this one is not. */
[data-component="pack-list"] .pack-list__view-heading {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0;
}

/* Also reused verbatim by the account-screen component's empty "Your
   records" state — extended here rather than forked (02-UI-SPEC.md
   "Reused-class styling note"). */
[data-component="pack-list"] .pack-list__empty,
[data-component="account-screen"] .pack-list__empty,
[data-component="collection-detail"] .pack-list__empty,
[data-component="moderation-queue"] .pack-list__empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-lg) var(--space-sm);
  text-align: left;
}

[data-component="pack-list"] .pack-list__empty-heading,
[data-component="account-screen"] .pack-list__empty-heading,
[data-component="collection-detail"] .pack-list__empty-heading,
[data-component="moderation-queue"] .pack-list__empty-heading {
  font-size: var(--font-size-heading);
  line-height: var(--line-height-heading);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0;
}

[data-component="pack-list"] .pack-list__empty-body,
[data-component="account-screen"] .pack-list__empty-body,
[data-component="collection-detail"] .pack-list__empty-body,
[data-component="moderation-queue"] .pack-list__empty-body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: 0;
}

/* Inline "Clear filters" action — plain underlined link styling, matching
   the not-found "Back to catalog" convention (ink, never accent). */
[data-component="pack-list"] .pack-list__empty-action {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* ---------------------------------------------------------------------
   Storage-unavailable notice — quiet, informational, dismissible
   (Pitfall 2). Never danger-styled: this is a notice, not an error.
   --------------------------------------------------------------------- */

[data-component="storage-notice"] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-sm);
  background: var(--color-surface-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  color: var(--color-ink);
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
}

[data-component="storage-notice"] .app-notice__dismiss {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--color-ink-muted);
  font-size: var(--font-size-heading);
  line-height: 1;
  cursor: pointer;
}

/* ---------------------------------------------------------------------
   Reset demo — the only destructive/confirmed action this phase. Reset
   demo is now the demo toolbar's own last field (D-08d) and is reachable
   only while the toolbar is expanded; there is no separate fixed-corner
   trigger any more. The confirmation dialog below is unchanged and is
   danger-styled on its confirm action only (Keep browsing stays neutral)
   per the UI-SPEC Copywriting Contract.
   --------------------------------------------------------------------- */

.reset-confirm-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background: color-mix(in srgb, var(--color-ink) 40%, transparent);
  z-index: 30;
}

.reset-confirm-dialog {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  width: 100%;
  max-width: 420px;
  padding: var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius);
}

.reset-confirm__body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  margin: 0;
}

.reset-confirm__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* Generic button pair used only by the Reset-demo dialog this phase — the
   sole destructive/confirmed action (UI-SPEC Copywriting Contract). */
.button {
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  border: 1px solid var(--color-border);
  cursor: pointer;
}

/* First disabled-button state in the prototype (04-UI-SPEC.md "Color").
   A true disabled attribute is correct here: the Submit/Save buttons are
   always visible but conditionally actionable — substituting quiet text,
   as the Download control does, would hide the goal state instead of
   showing it as blocked. This single base pseudo-class rule covers both
   the primary and ghost button variants; no per-variant selector is
   added. */
.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.button--ghost {
  background: var(--color-surface);
  color: var(--color-ink);
}

.button--danger {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: var(--color-surface);
}

/* .button--danger recipe with --color-accent substituted — the 4th
   reserved accent use (UI-SPEC "Color"): the one filled primary button
   this phase adds, the pack-detail panel's real "Download pack" action. */
.button--primary {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-surface);
}

/* ---------------------------------------------------------------------
   Edit-stub notice (D-05) — aliases the reset-confirm-overlay/dialog/
   body/actions rules above verbatim (identical rules, new class names);
   only the copy and single-button layout differ, handled in app.js/
   pack-detail.js, not here.
   --------------------------------------------------------------------- */

.edit-notice-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background: color-mix(in srgb, var(--color-ink) 40%, transparent);
  z-index: 30;
}

.edit-notice-dialog {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  width: 100%;
  max-width: 420px;
  padding: var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius);
}

.edit-notice__body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  margin: 0;
}

.edit-notice__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* ---------------------------------------------------------------------
   Submission form (#/submit, #/submit/:draftId, R4-01/R4-02) — schema-
   generated form for a new agent pack. app.js sets #app-root's own
   data-component to "submission-form-view" for this route (mirroring the
   account-screen-view convention, app.css lines 817-819); submission-
   form.js's own returned root, nested one level inside, carries
   data-component="submission-form" and is what the rules below style.
   --------------------------------------------------------------------- */

[data-component="submission-form-view"] {
  height: 100%;
}

[data-component="submission-form"] {
  height: 100%;
  background: var(--color-surface);
  padding: var(--space-2xl);
  overflow-y: auto;
}

/* Single-column form content, same 640px cap as account-screen__content
   (04-UI-SPEC.md "Screen shell") — reused verbatim, not a new width.
   Also reused verbatim by moderation-review and import-form (05-UI-SPEC.md
   "Screen 2"/"Screen 3" — no new width). */
.moderation-review__content,
.import-form__content,
.submission-form__content {
  max-width: 640px;
  margin: 0 auto;
}

.moderation-review__back-link,
.import-form__back-link,
.submission-form__back-link {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
}

/* Screen title — Display role, identical recipe to account-screen__name
   (app.css lines 846-852). Own selector, not a reuse of that class name:
   this is a screen title, not a person's name. */
.moderation-queue__title,
.moderation-review__title,
.import-form__title,
.submission-form__title {
  font-size: var(--font-size-display);
  line-height: var(--line-height-display);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  margin: 0 0 var(--space-sm) 0;
}

.moderation-queue__intro,
.moderation-review__subtitle,
.import-form__intro,
.submission-form__intro {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: 0;
}

/* Shared input recipe — identical declarations to area-combobox__input
   (app.css lines 444-455).
   Scope decision: 04-UI-SPEC.md recommends also refactoring the three
   existing duplicates (area-combobox__input, [data-component=
   "lifecycle-filter"] select, [data-component="demo-toolbar"] select)
   onto this shared rule. That refactor is deliberately NOT done here —
   those three selectors have shipped through Phases 1-3 human UAT and
   there is no automated visual coverage that would catch a regression.
   .form-input is introduced for the new submission-form controls only;
   consolidating the three existing blocks is left as a follow-up. This
   is a recorded decision, not an oversight. */
.form-input {
  width: 100%;
  height: 40px;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  background: var(--color-surface);
}

textarea.form-input {
  min-height: 96px;
  resize: vertical;
}

.submission-form__fieldset {
  margin-top: var(--space-xl);
  border: none;
  padding: 0;
  min-width: 0;
}

.submission-form__field {
  margin-top: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* Field label — Label role, semibold, ink (not ink-muted). Explicitly NOT
   the filter-rail__section-heading treatment (app.css lines 299-307): no
   uppercase, no letter-spacing — a field label is primary information the
   author must read to fill the field correctly, not secondary grouping
   chrome like a filter-rail heading. */
.submission-form__label {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
}

.submission-form__requirement {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-regular);
  color: var(--color-ink-muted);
}

.moderation-review__full-label,
.import-form__help,
.submission-form__help {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-regular);
  color: var(--color-ink-muted);
  margin: 0;
}

.submission-form__counter {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  text-align: right;
  margin: 0;
}

/* First use of --font-family-mono (declared tokens.css since Phase 1,
   unused until now) — per CLAUDE.md's design-system note "mono face for
   code and identifiers", applied to the read-only generated id preview. */
.submission-form__id-preview {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  font-family: var(--font-family-mono);
}

.submission-form__checkbox-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.submission-form__checkbox-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
}

.submission-form__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  list-style: none;
  padding: 0;
  margin: 0;
}

/* pack-detail__area-chip typographic recipe (app.css lines 674-682),
   copied rather than comma-extended: this variant needs extra layout
   properties (inline-flex + a seated remove control) the read-only chip
   does not. */
.submission-form__chip {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  background: var(--color-surface-secondary);
  border-radius: var(--radius);
  padding: var(--space-xs) var(--space-sm);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

/* area-combobox__icon-button recipe (app.css lines 518-528), copied
   verbatim — WCAG 2.5.5 minimum target, carried forward, not a new
   exception. */
.submission-form__chip-remove,
.submission-form__repeatable-remove {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-ink-muted);
}

.submission-form__repeatable {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.submission-form__repeatable-row {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.submission-form__repeatable-row .form-input {
  flex: 1 1 auto;
}

/* Relies on the existing .button/.button--ghost recipes for its visual;
   only width/alignment are added here. */
.submission-form__repeatable-add {
  width: 100%;
  text-align: center;
}

/* First inline (non-button) use of --color-danger in the prototype
   (previously button-fill only, .button--danger on the Reset-demo
   confirm). Danger against surface recomputes to ≈6.5:1 (WCAG 2.1
   relative-luminance formula), clearing AA (4.5:1) with margin — same
   token value already shipped in tokens.css, no change needed
   (04-UI-SPEC.md "Color"). */
.submission-form__error {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-danger);
  margin: 0;
}

/* A warning is deliberately NOT danger-colored: this project has exactly
   5 color roles and no 6th "warning" color, so warnings are distinguished
   by softer copy ("Consider…"), never by color, from blocking errors
   (04-UI-SPEC.md "Color"). */
.submission-form__warning {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-regular);
  color: var(--color-ink-muted);
  margin: 0;
}

/* Error border is driven off the ARIA attribute rather than a separate
   class, so the visual error state and the assistive-technology state
   cannot drift apart (T-04-20). */
.form-input[aria-invalid="true"] {
  border: 2px solid var(--color-danger);
}

/* Secrets banner (V6, form-level, highest severity) — a recombination of
   two existing mechanics, nothing new: the area-combobox__option.is-
   highlighted color-mix tint (app.css lines 499-501) with --color-danger
   substituted for --color-accent, plus the pack-detail__guardrails
   left-border box (app.css lines 645-650) with --color-danger
   substituted for --color-ink. */
.submission-form__secrets-banner {
  background: color-mix(in srgb, var(--color-danger) 10%, var(--color-surface));
  border-left: 4px solid var(--color-danger);
  padding: var(--space-md);
  border-radius: var(--radius);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
}

/* This prototype's first sticky-positioned element — locked by the
   UI-SPEC, not a nicety: a 26-field form is long and the Submit-disabled
   state must stay visible without scrolling to the bottom. */
.submission-form__actions {
  position: sticky;
  bottom: 0;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  padding: var(--space-md);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Pushes the button pair to the trailing edge, leaving the blocking-count
   and body-length-warning text at the leading edge. */
.submission-form__actions .button:first-of-type {
  margin-left: auto;
}

.submission-form__blocking-count {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-danger);
  margin: 0;
}

.submission-form__body-length-warning {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: 0;
}

/* Copies app-header__account-link's declarations exactly (plain
   underlined ink text) under a new selector so JS/tests can address it
   independently. Not comma-extended with the account-link rule. */
[data-component="app-header"] .app-header__import-link,
[data-component="app-header"] .app-header__moderate-link,
[data-component="app-header"] .app-header__submit-link {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
}

/* "Drafts in progress" account-screen section (D-05, R4-03) — matches
   the existing account-screen__records rhythm. Status badge reuses
   .account-screen__role-badge verbatim; no new badge rule. */
[data-component="account-screen"] .account-screen__drafts {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
}

[data-component="account-screen"] .account-screen__draft-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* Plain underlined link, ink color — matches the not-found/back-link
   convention (accent stays reserved). */
.moderation-queue__pack-link,
[data-component="account-screen"] .account-screen__draft-link {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------
   Moderation queue (#/moderate, R5-01, D-09) — the prototype's first
   <table>. The table layout is locked by SPEC-060 §4a.2/D-09, not chosen
   here. Back-link, title, intro, badge, and empty-state rules are reused
   verbatim by comma-extending the existing recipes above (account-screen
   back-link, submission-form title/intro, account-screen role badge,
   pack-list empty state, account-screen draft link) rather than forking
   new declarations.
   --------------------------------------------------------------------- */

/* Deliberately wider than the 640px shell used by every other screen —
   this one table-layout screen only (SPEC-060 §4a.2/D-09, six columns).
   Do not "correct" this to 640px. */
.moderation-queue__content {
  max-width: 960px;
  margin: 0 auto;
  padding: var(--space-2xl) var(--space-lg);
}

.moderation-queue__table {
  width: 100%;
  border-collapse: collapse;
}

/* Header cell — filter-rail__section-heading's uppercase/letter-spacing
   Label recipe (app.css lines ~299-307), reused verbatim for table column
   headers. */
[data-component="moderation-queue"] th,
[data-component="moderation-review"] th {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  text-align: left;
  padding: var(--space-md);
}

[data-component="moderation-queue"] td,
[data-component="moderation-review"] td {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-regular);
  color: var(--color-ink-muted);
  padding: var(--space-md);
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}

/* Row hover — pack-card:hover's neutral-shift recipe, reused verbatim.
   Never accent on hover. */
[data-component="moderation-queue"] tbody tr:hover {
  background: var(--color-surface-secondary);
}

/* Pack column's link-plus-badges wrapper. */
.moderation-queue__pack-cell {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------------
   Review screen (#/moderate/:packId, R5-02, D-06) — open density, 640px
   content cap (reused verbatim above). Back-link, title, subtitle,
   section-heading, full-label, and th/td cells are reused by
   comma-extending the existing recipes; only flex wrappers and the two
   diff-value colors are genuinely new.
   --------------------------------------------------------------------- */

/* Flex/spacing layer on top of the shared 640px cap above — disjoint
   properties, both rules apply together. */
[data-component="moderation-review"] .moderation-review__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
  padding: var(--space-2xl) var(--space-lg);
}

/* Reviewer checklist — plain <ul>, Body role. */
.moderation-review__checklist {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  margin: 0;
  padding-left: var(--space-lg);
}

.moderation-review__diff-table {
  width: 100%;
  border-collapse: collapse;
}

/* Contrast alone distinguishes old from new — never weight, never a new
   color. */
.moderation-review__previous {
  color: var(--color-ink-muted);
}

.moderation-review__new {
  color: var(--color-ink);
}

.moderation-review__section-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.moderation-review__sections {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* .submission-form__label recipe (Label role, semibold) with
   --color-ink-muted substituted for --color-ink — declared as its own
   rule rather than comma-extended, since the color differs from that
   shared selector list. */
.moderation-review__lead-in {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink-muted);
}

.moderation-review__actions {
  display: flex;
  gap: var(--space-sm);
}

/* pack-detail__download-unavailable recipe (app.css "Denied state" rule),
   copied verbatim under a new class name — same aliasing pattern
   edit-notice-* uses for reset-confirm-* below. */
.moderation-review__self-review-notice {
  display: block;
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  margin-top: var(--space-md);
}

/* ---------------------------------------------------------------------
   Import screen (#/import, R5-03, D-08) — open density, 640px content
   cap (reused verbatim above). Back-link, title, intro, and help are
   reused by comma-extending the existing submission-form recipes; the
   native <input type="file"> chrome is used as-is, no new rule.
   --------------------------------------------------------------------- */

.import-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.import-form__actions {
  display: flex;
  justify-content: flex-end;
}

/* ---------------------------------------------------------------------
   Account-screen extension (D-01) — rejected-record reason line, same
   Body/ink-muted role pack-list__empty-body already fills.
   --------------------------------------------------------------------- */

[data-component="account-screen"] .account-screen__draft-reason {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink-muted);
  margin: 0;
}

/* ---------------------------------------------------------------------
   Reject dialog + import-error dialog — alias the two existing dialog
   recipes (.reset-confirm-*, .edit-notice-*) verbatim under new class
   names, exactly as .edit-notice-* already aliases .reset-confirm-*
   above. Only class names, copy, and button counts differ; the
   declarations below are intentionally identical to their source rules.
   --------------------------------------------------------------------- */

/* Reject dialog — aliases .reset-confirm-overlay/-dialog/__body/__actions
   verbatim (two-button family: "Keep in queue" / "Reject submission"). */
.moderation-reject-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background: color-mix(in srgb, var(--color-ink) 40%, transparent);
  z-index: 30;
}

.moderation-reject-dialog {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  width: 100%;
  max-width: 420px;
  padding: var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius);
}

.moderation-reject__body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  margin: 0;
}

.moderation-reject__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* Label-plus-textarea pair; the textarea itself uses the existing
   unscoped textarea.form-input rule and its label uses the existing
   unscoped .submission-form__label rule — no new rule for either. */
.moderation-reject__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* Import-error dialog — aliases .edit-notice-overlay/-dialog/__body/
   __actions verbatim (single-button family: "Got it"). */
.import-error-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
  background: color-mix(in srgb, var(--color-ink) 40%, transparent);
  z-index: 30;
}

.import-error-dialog {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  width: 100%;
  max-width: 420px;
  padding: var(--space-lg);
  background: var(--color-surface);
  border-radius: var(--radius);
}

.import-error__body {
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-ink);
  margin: 0;
}

.import-error__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* First dialog body in the prototype to list more than one message at
   once (import failure). Each <li> uses the existing unscoped
   .submission-form__error class directly — no CSS change needed there. */
.import-error__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0;
  padding-left: var(--space-md);
}

/* ---------------------------------------------------------------------
   Collection detail / constellation (#/collections/:id, R6-01/R6-02) —
   open density, the same "deliberately wider" wide-screen content-cap
   exception .moderation-queue__content already established, not
   a third arbitrary width value. Reused-recipe typography for eyebrow/
   title/subtitle/context/hidden-count/back-link/empty-states is
   comma-extended into the existing rules above, not restated here. The
   member-card grid below is this phase's only genuinely new layout
   rule — the prototype's first display:grid.
   --------------------------------------------------------------------- */

.collection-detail__content {
  max-width: 960px;
  margin: 0 auto;
  padding: var(--space-2xl) var(--space-lg);
}

[data-component="collection-detail"] .collection-detail__header {
  margin-bottom: var(--space-xl);
}

/* Spacing-only second rule for group-heading — typography (font-size,
   color, text-transform, etc.) comes entirely from the
   filter-rail__section-heading comma-extension above; do not restate it
   here. Major section break between groups, reset to 0 on the first. */
[data-component="collection-detail"] .collection-detail__group-heading {
  margin-top: var(--space-2xl);
  margin-bottom: var(--space-md);
}

[data-component="collection-detail"] .collection-detail__group-heading:first-of-type {
  margin-top: 0;
}

/* Member-card grid — the only genuinely new layout mechanism this phase
   (first display:grid in the prototype). align-items:start is required:
   default stretch would deform a note-less pack-card to match a taller
   neighbour that has a note. No media query needed — the auto-fill
   track list collapses to one column naturally at narrow viewports,
   matching pack-list's own documented mobile-collapse posture. */
[data-component="collection-detail"] .collection-detail__group-members {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-md);
  align-items: start;
}

/* Same Label/ink-muted pairing pack-card__author uses. */
[data-component="collection-detail"] .collection-detail__member-note {
  font-size: var(--font-size-label);
  line-height: var(--line-height-label);
  color: var(--color-ink-muted);
  margin: var(--space-xs) 0 0 0;
}
