/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   Platform Console — the console's ONLY stylesheet.

   SPEC-00 §9. One file, linked from index.html beside tokens.css and shell.css. NO injected
   <style> blocks: that is production's pattern, and a codebase with a shared stylesheet that also
   injects per module loads the console's rules in a different order than everything else's, which
   is how a cascade bug that only appears on second navigation gets built.

   PREFIX: pc-. Sub-modules use compound segments so one grep finds everything —
   pc- shell/core · pc-org- · pc-usr- · pc-rec- · pc-rev- · pc-dbg-.
   Taken elsewhere and avoided: dl- la- ma- rt- rw- sr- tr- un- unc- wr-.

   EVERY VALUE IS A TOKEN. A hard-coded hex is a bug that only appears in one theme. This file adds
   no tokens; if something here needed a value tokens.css does not have, that is a bug in the
   design and gets reported rather than invented.

   AND NEVER `background: var(--*-fg)`. The -fg tokens are FOREGROUNDS. A red fill built from
   --danger-fg reads fine in light (#b02a24) and disappears in dark (#fca5a5, ~1.6:1). Every solid
   fill here is --alert-bg/--alert-fg or a -bg token. tokens.css carries this as a written warning.

   prefers-reduced-motion is handled by ONE global rule in shell.css. Nothing per-component here.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── the locked scope control — §3.3 ────────────────────────────────────────────────────────────
   A third state of the EXISTING .scope, not a new component. Same box, same position, same height
   as the Mine/Organization segmented control, so nothing shifts when the mode changes and the eye
   lands in the same place. Not pressable: no hover, no cursor change, role="note", aria-disabled.
   It lives on the rail, so it takes the rail's own tokens — never --bg-card. */
.pc-scope-locked {
  display: flex; flex-direction: column; gap: var(--space-1);
  margin: 0 var(--space-5) var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-rail-active);
  border: 1px solid transparent; border-radius: var(--radius-md);
  cursor: default;
}
.pc-scope-k {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--rail-label);
}
.pc-scope-v {
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
  color: var(--rail-text-active); line-height: var(--leading-tight);
}
/* Collapsed, the two lines cannot fit. The box stays — its PRESENCE is the signal — and the value
   is carried by the title attribute instead. */
[data-rail="collapsed"]:not([data-panel="peeking"]) .pc-scope-locked { margin: 0 var(--space-3) var(--space-5);
  padding: var(--space-4) var(--space-2); align-items: center; }
[data-rail="collapsed"]:not([data-panel="peeking"]) .pc-scope-k { font-size: 0; }
[data-rail="collapsed"]:not([data-panel="peeking"]) .pc-scope-k::after {
  content: "ALL"; font-size: var(--text-2xs); letter-spacing: var(--tracking-wide);
}
[data-rail="collapsed"]:not([data-panel="peeking"]) .pc-scope-v { display: none; }

/* The return item. Same .rail-item anatomy; the arrow reads as "out", so it gets the muted
   treatment of a utility rather than the weight of a destination. */
.pc-rail-back { color: var(--rail-label); }
.pc-rail-back:hover { color: var(--rail-text-active); }

/* The rail count slot. Empty by default and collapses to nothing, so an absent count occupies no
   space rather than reserving a gap that reads as a missing number. */
.pc-railcount { margin-left: auto; display: inline-flex; align-items: center; }
[data-rail="collapsed"]:not([data-panel="peeking"]) .pc-railcount { display: none; }

/* ── counts, unknowns, attribution, freshness ───────────────────────────────────────────────────
   .pc-pip is a FILLED badge, so --alert-bg/--alert-fg. It follows .rail-count.alert's pattern,
   which already pairs them correctly. */
.pc-pip {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  background: var(--alert-bg); color: var(--alert-fg);
  border-radius: var(--radius-pill); padding: 1px var(--space-4); min-width: 18px;
  text-align: center; line-height: var(--leading-snug);
}
/* Unknown is not zero, and it must not look like a count. No fill, no urgency — a dot that says
   nobody counted, not a number that says nobody has any. */
.pc-pip-unk {
  background: none; color: var(--text-muted);
  border: 1px solid var(--border); padding: 0 var(--space-4);
}
.rail-item .pc-pip-unk { border-color: var(--rail-label); color: var(--rail-label); }

.pc-unk { color: var(--text-muted); font-style: normal; }

.pc-claim { display: inline-flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  align-items: baseline; }
.pc-claim-w { font-size: var(--text-sm); color: var(--text-secondary);
  font-weight: var(--weight-medium); }
.pc-claim-d { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xs); color: var(--text-muted); }

.pc-fresh { font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xs); color: var(--text-muted); }

/* ── the four panel states — §5.2 ───────────────────────────────────────────────────────────────
   loading · empty · failed · unwired, and the three non-ok states MUST NOT look alike.
   `failed` is a bug and `unwired` is unbuilt: the fix is different, and conflating them sends
   somebody to debug a thing that was never built. So failed is solid-bordered and red, unwired is
   DASHED and amber — the dash is the "nothing is here yet" signal, readable before the colour. */

/* Skeleton rows, not a spinner. A spinner hides how much is coming. */
.pc-skel { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-5) 0; }
.pc-skel-row { height: var(--space-9); border-radius: var(--radius-sm); background: var(--bg-subtle); }

.pc-state {
  border-radius: var(--radius-card); padding: var(--space-7);
  max-width: 680px;   /* prose. The page is 1500px; a sentence at 1500px is unreadable. */
}
.pc-state-t {
  margin: 0 0 var(--space-3); font-size: var(--text-md);
  font-weight: var(--weight-semibold); line-height: var(--leading-snug);
}
.pc-state-b {
  margin: 0 0 var(--space-5); font-size: var(--text-sm);
  color: var(--text-secondary); line-height: var(--leading-normal);
}
.pc-state-n { margin: 0; font-size: var(--text-xs); line-height: var(--leading-normal); }

/* failed — a bug. Solid border, retain the retry. --danger-fg is used for TEXT ONLY. */
.pc-state-failed {
  background: var(--danger-bg); border: 1px solid var(--danger-border);
}
.pc-state-failed .pc-state-t { color: var(--danger-fg); }
.pc-state-failed .pc-state-n { color: var(--text-muted); margin-bottom: var(--space-6); }

/* unwired — unbuilt. Dashed border, and the Needs: line is the round-two backlog.
   A panel with no read behind it ships showing THIS. It never ships showing an empty table:
   `Curation 0` claims every record on the platform has been examined, and a record nobody has
   examined is unknown, not clean. */
.pc-state-unwired {
  background: var(--warning-bg); border: 1px dashed var(--warning-border);
}
.pc-state-unwired .pc-state-t { color: var(--warning-fg); }
.pc-need-k {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--text-muted); margin-right: var(--space-4);
}
.pc-need-v {
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--text-secondary); background: var(--bg-sunken);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm);
}

/* ── environment badges — §5.6 ──────────────────────────────────────────────────────────────────
   Built on the existing .badge. Four values plus two never-guess cases.

   `sandbox` is LEGACY and deliberately the quietest of the four: before 2026-09-01 both dev and
   dev2 reported it, so such a row cannot be resolved to either and must never be relabelled. It is
   not an error — the row is fine, it is just less specific than a new one. */
.pc-env-prod   { background: var(--danger-bg);  color: var(--danger-fg);  border-color: var(--danger-border); }
.pc-env-dev    { background: var(--info-bg);    color: var(--info-fg);    border-color: var(--info-border); }
.pc-env-dev2   { background: var(--ai-bg);      color: var(--ai-fg);      border-color: var(--ai-border); }
.pc-env-legacy { background: var(--neutral-bg); color: var(--text-muted); border-color: var(--neutral-border);
                 border-style: dashed; }
/* Neither of these may borrow a known colour. A dev2 session coloured as production is a false
   statement about where a bug happened, made by the tool you are using to find the bug. */
.pc-env-unknown { background: var(--neutral-bg); color: var(--neutral-fg); border-color: var(--border-strong); }
.pc-env-missing { background: none; color: var(--text-muted); border-color: var(--border);
                  border-style: dashed; }

/* ── consequence lists inside wpd_confirm — §5.7 ────────────────────────────────────────────────
   wpd_confirm's card is 380px max and its <p> is centred. A consequence list must read as a list,
   so it left-aligns inside that centred card. Do not widen the dialog; do not write a fifth
   consequence to make the box look balanced. */
.pc-conseq, .pc-retains {
  margin: var(--space-4) 0 0; padding-left: var(--space-7);
  text-align: left; font-size: var(--text-sm); line-height: var(--leading-normal);
}
.pc-conseq li { margin-bottom: var(--space-3); color: var(--text-secondary); }
.pc-retains { border-top: 1px solid var(--border); padding-top: var(--space-4); }
.pc-retains li { margin-bottom: var(--space-3); color: var(--text-muted); }

/* ── the decision card — §6 ─────────────────────────────────────────────────────────────────────
   The console's signature element and the one place to spend boldness. Everything else is a table.

   NOT THE HATCH SPINE. A record card's 6px left spine is a repeating-linear-gradient in an
   --estate-* colour, and .hatch-surface is 45°, .hatch-mineral is −45°, .hatch-both is
   crosshatched — that is DOMAIN MEANING, not decoration. A decision card is not a land record and
   has no estate; putting hatch on it would make the console's most prominent element assert a
   mineral estate it knows nothing about.

   6px hatched means record. 4px SOLID means decision. Two signatures, one glance apart, and
   neither borrows the other's meaning. */
.pc-decision {
  position: relative; max-width: 900px;   /* prose — §9.3 */
  background: var(--bg-card);
  border: 1px solid var(--border); border-left: 4px solid var(--warning-border);
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  padding: var(--space-7); margin-bottom: var(--space-6);
}
.pc-decision-approved { border-left-color: var(--success-border); }
.pc-decision-declined { border-left-color: var(--neutral-border); }
.pc-decision-failed   { border-left-color: var(--danger-border); }

.pc-decision-head {
  display: flex; align-items: baseline; gap: var(--space-5); flex-wrap: wrap;
  padding-bottom: var(--space-5); border-bottom: 1px solid var(--border-subtle);
}
.pc-decision-what { font-size: var(--text-lg); font-weight: var(--weight-semibold);
  line-height: var(--leading-tight); }
.pc-decision-what a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--border-strong); }
.pc-decision-what a:hover { color: var(--accent-500); border-bottom-color: var(--accent-500); }
/* A missing object is named, not linked and not shown as a uuid. */
.pc-decision-gone { font-style: italic; color: var(--text-muted); font-weight: var(--weight-regular); }
.pc-decision-kind {
  margin-left: auto; font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
}

/* A definition grid: label left, value right. Body caps at ~72 characters — a consequence sentence
   across 1500px is 200 characters and unreadable. */
.pc-decision-rows { display: grid; grid-template-columns: 150px 1fr; gap: var(--space-5) var(--space-6);
  padding: var(--space-6) 0; }
.pc-decision-k {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
  padding-top: var(--space-1);
}
.pc-decision-v { font-size: var(--text-sm); color: var(--text-primary);
  line-height: var(--leading-normal); max-width: 72ch; }
.pc-decision-v q { color: var(--text-secondary); font-style: italic; }

/* The two outcomes. Both rows ALWAYS present: a decision surface showing only the loud option's
   consequence is not showing a decision. */
.pc-decision-outcomes {
  display: grid; grid-template-columns: 150px 1fr; gap: var(--space-5) var(--space-6);
  padding: var(--space-6) 0; border-top: 1px solid var(--border-subtle);
}

/* BOTH BUTTONS EQUAL WEIGHT. Not one .btn-primary and one ghost. A quiet Retain beside a solid
   Delete is a nudge toward destruction on the one screen where that is least acceptable — so they
   are the same size, the same padding, and differ only in the colour that says which one is the
   one-way door. */
.pc-decision-acts {
  display: flex; gap: var(--space-5); justify-content: flex-end;
  padding-top: var(--space-6); border-top: 1px solid var(--border-subtle);
}
.pc-decision-acts .btn { min-width: 140px; justify-content: center; }
.pc-act-danger {
  background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger-fg);
}
.pc-act-danger:hover { background: var(--danger-bg); border-color: var(--danger-fg); }

/* ── the ghost bar — §8 ─────────────────────────────────────────────────────────────────────────
   Fixed and top-anchored on EVERY page while ghosting.

   z-index 9850: above the doc popout (9800) and below modals (9900), so a wpd_confirm opened from
   the console sits above the bar. The token ladder in tokens.css (--z-modal:3000 …) is DEAD —
   nothing uses it, every module hard-codes, and the real ladder is 9000…9999. Adding a slot to the
   dead ladder does nothing, so the number is named here.

   NO `top:` VALUE. sandbox-banner.js sweeps fixed top-anchored elements and offsets them
   centrally, correcting when the banner wraps to two lines. Hard-coding top:40px here would
   overlap the moment it does. */
/* Purple/striped was tried 2026-09-10 to Mike's spec ("much like the sandbox but ... purple
   themed") and REVERTED the same day on his word: "ok dark navy is fine". The banner he was asking
   for already existed; what he had actually hit was that entering an org you ALREADY administer is
   a plain switch, not a ghost, so no bar paints at all (see ASK-uiux-console-user-and-org-detail
   §5, open with UI/UX). The colour was never the problem, so it is back as it was. */
.pc-ghost-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index:var(--z-ghost-bar);
  display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap;
  padding: var(--space-4) var(--gutter);
  background: var(--bg-banner); color: var(--text-on-dark);
  border-bottom: 1px solid var(--alert-bg);
  font-size: var(--text-sm);
}
.pc-ghost-k {
  font-size: var(--text-2xs); font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  background: var(--alert-bg); color: var(--alert-fg);
  padding: 2px var(--space-4); border-radius: var(--radius-pill);
}
.pc-ghost-org { font-weight: var(--weight-semibold); }
/* The consequence people forget, on the bar rather than in help: every read and write follows the
   ghost, so a runsheet made while ghosting carries the ghosted org's name. */
.pc-ghost-note { color: var(--rail-text); min-width: 0; }
.pc-ghost-exit { margin-left: auto; flex: 0 0 auto; }

/* ── the 900px breakpoint — §9.4 ────────────────────────────────────────────────────────────────
   Below it the rail changes, tables become .rowcards, and [data-secondary] items are hidden. */
@media (max-width: 900px) {
  .pc-state { max-width: none; }
  .pc-decision { padding: var(--space-6); }
  /* The definition grid stops being a grid — 150px of label beside 40 characters of value is
     unreadable on a phone. */
  .pc-decision-rows, .pc-decision-outcomes { grid-template-columns: 1fr; gap: var(--space-3); }
  .pc-decision-k { padding-top: var(--space-4); }
  /* Buttons go full-width and stack, DESTRUCTIVE SECOND — the thumb rests over the lower half of
     a phone, and the one-way door should not be what it rests on. */
  .pc-decision-acts { flex-direction: column-reverse; }
  .pc-decision-acts .btn { width: 100%; }
  /* The bar wraps to two lines and Exit stays on the first, so the way out never scrolls away.
     The sweep corrects everything else's offset for the taller bar. */
  .pc-ghost-bar { padding: var(--space-4) var(--gutter-phone); }
  .pc-ghost-note { flex-basis: 100%; order: 3; }
  .pc-ghost-exit { order: 2; }
}

/* ── Organizations — the detail sheet (SPEC-01 §5) ──────────────────────────────────────────────
   720px, right-anchored, and z-slot 9400 — deliberately BELOW the document sheet at 9500 so a link
   out of this sheet into a document opens above it rather than behind it. A panel opening behind
   another reads to a user as "it does not open." The ladder in tokens.css is dead (--z-modal is
   3000 and unused), so the number is named here. */
/* The identity form that replaces the facts band while editing (UI/UX §1.1). Deliberately plain —
   it occupies the band's place, so it should not read as a heavier surface than the thing it stands
   in for. Save and Cancel are equal weight; the primary is Save because it is the act, not because
   Cancel is discouraged. */
.pc-ed { padding: var(--space-6) 0; }
.pc-ed-row { display: grid; grid-template-columns: 140px minmax(0,1fr); gap: var(--space-5);
  align-items: center; max-width: 620px; }
.pc-ed-lab { font-size: var(--text-sm); color: var(--text-muted); }
.pc-ed-in {
  font-family: inherit; font-size: var(--text-md); color: var(--text-primary);
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-btn); padding: var(--space-4) var(--space-5);
  min-height: var(--target-min-dense); width: 100%;
}
.pc-ed-in:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 1px; }
.pc-ed-actions { display: flex; gap: var(--space-4); margin-top: var(--space-6); }
@media (max-width: 900px) {
  .pc-ed-row { grid-template-columns: 1fr; gap: var(--space-2); align-items: stretch; }
}

/* ── The console's record screen (PC.recordScreen) ──────────────────────────────────────────────
   One shell for the user and organization details, replacing two 720px panels that were appended to
   <body>. The facts row is the part that earns the width: four facts side by side is what the 720px
   panel could not do, and it is why the user detail looked half empty in the screenshots rather
   than too big.

   NO FIXED POSITIONING ANYWHERE HERE, deliberately. That is the whole difference from the sheets it
   replaces — this renders inside the console's host and cannot outlive its route. */
.pc-rs .nav-back { margin-bottom: var(--space-6); }
.pc-rs-head {
  display: flex; align-items: flex-start; gap: var(--space-6);
  padding-bottom: var(--space-6); border-bottom: 1px solid var(--border);
}
.pc-rs-id { min-width: 0; }            /* or a long name pushes the actions off the row */
.pc-rs-title {
  margin: 0; font-size: var(--text-2xl); font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight); line-height: var(--leading-tight);
}
.pc-rs-sub {
  margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--text-muted);
  font-family: var(--font-mono);
}
.pc-rs-actions { margin-left: auto; flex: 0 0 auto; display: flex; gap: var(--space-4); flex-wrap: wrap; }

/* The facts band. `auto-fit` rather than a fixed column count: four facts lay out side by side on a
   wide screen and reflow on a narrow one without a second rule, and a screen with three facts does
   not leave a gap where a fourth would have been. */
.pc-rs-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-6) var(--space-8);
  padding: var(--space-7) 0; border-bottom: 1px solid var(--border-subtle);
}
.pc-rs-k {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
}
.pc-rs-v {
  margin-top: var(--space-2); font-size: var(--text-lg); color: var(--text-primary);
  line-height: var(--leading-tight); overflow-wrap: anywhere;
}
.pc-rs-sec { padding: var(--space-7) 0; border-bottom: 1px solid var(--border-subtle); }
.pc-rs-sec:last-child { border-bottom: 0; }
.pc-rs-h {
  margin: 0 0 var(--space-5); font-size: var(--text-2xs);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text-muted);
}
@media (max-width: 900px) {
  .pc-rs-head { flex-direction: column; }
  .pc-rs-actions { margin-left: 0; }
  .pc-rs-facts { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--space-5); }
}

/* THE CLASS CARRIES THE STYLING, not an id-scoped descendant selector. This rule read
   `#pcOrgSheet .pc-org-sheet` and therefore matched NEITHER of two live sheets:

     · the USER sheet — `openUserSheet` wraps its markup in `#pcUsrSheet`, a different id, so a
       user detail rendered `position:static` at the FOOT OF THE DOCUMENT. Measured: top 1027px
       against a 1000px viewport, i.e. entirely below the fold. Mike, debug session
       mtvv986b-299u5t: "when clicking into a user the screen does not render correctly but
       populates at the bottom of the screen."
     · the ORG-NOT-FOUND sheet — platform-orgs.js:255 sets `id` AND `class` on the SAME element,
       and a descendant combinator cannot match the element carrying the id. Same silent failure,
       reachable from any stale org link.

   A class describing what a thing IS should not depend on which id happens to wrap it. The z-slot
   note below is unchanged and still the reason for the number. */
.pc-org-sheet {
  position: fixed; top: 0; right: 0; bottom: 0; z-index:var(--z-platform-sheet);
  width: 720px; max-width: 100%;
  background: var(--bg-card); border-left: 1px solid var(--border);
  box-shadow: var(--shadow-modal); overflow-y: auto;
  padding: var(--space-8) var(--gutter) var(--space-11);
}
.pc-org-sheet-head {
  display: flex; align-items: flex-start; gap: var(--space-6);
  padding-bottom: var(--space-6); border-bottom: 1px solid var(--border);
}
.pc-org-sheet-head .btn { margin-left: auto; flex: 0 0 auto; }
.pc-org-name { margin: 0; font-size: var(--text-xl); font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); }
.pc-org-slug { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--text-muted); }

.pc-org-sec { padding: var(--space-7) 0; border-bottom: 1px solid var(--border-subtle); }
.pc-org-h {
  margin: 0 0 var(--space-5); font-size: var(--text-2xs);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text-muted);
}
/* A definition grid, label left and value right — not stacked full-width rows. */
.pc-org-kv { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4) var(--space-6); }
.pc-org-k { font-size: var(--text-sm); color: var(--text-muted); }
.pc-org-v { font-size: var(--text-sm); color: var(--text-primary); }
.pc-org-line { margin: 0 0 var(--space-4); font-size: var(--text-sm); color: var(--text-primary); }
.pc-org-link { font-size: var(--text-sm); color: var(--accent-500); text-decoration: none; }
.pc-org-link:hover { text-decoration: underline; }
/* The consequence sits under the control it belongs to, not in a paragraph above six of them. */
.pc-org-note { margin: var(--space-4) 0 0; font-size: var(--text-xs);
  color: var(--text-muted); line-height: var(--leading-normal); max-width: 62ch; }
.pc-org-danger { border-bottom: 0; }
.pc-org-danger .btn { margin-right: var(--space-4); }

@media (max-width: 900px) {
  .pc-org-sheet { width: 100%; padding: var(--space-6) var(--gutter-phone); }
  .pc-org-kv { grid-template-columns: 1fr; gap: var(--space-2); }
  .pc-org-danger .btn { width: 100%; margin: 0 0 var(--space-4); }
}

/* ── Users (SPEC-02) ────────────────────────────────────────────────────────────────────────────
   The queue sits above the directory, so each region needs to read as a section rather than as a
   heading over a table. */
.pc-usr-region { margin-bottom: var(--space-10); }
.pc-usr-h {
  display: flex; align-items: center; gap: var(--space-5);
  margin: 0 0 var(--space-3); font-size: var(--text-lg);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-tight);
}
.pc-usr-count { display: inline-flex; align-items: center; }
.pc-usr-note {
  margin: 0 0 var(--space-6); font-size: var(--text-sm);
  color: var(--text-secondary); line-height: var(--leading-normal); max-width: 72ch;
}
/* "as typed by them" — the attribution that turns a name into a claim rather than a key. */
.pc-usr-attr { font-size: var(--text-2xs); color: var(--text-muted); }
.pc-usr-more { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--text-muted); }

/* The routing form inside a decision card. It sits between the outcomes and the buttons because it
   is what the approve button consumes — reading downward, you learn the consequence, then supply
   the inputs, then act. */
.pc-usr-route {
  display: flex; flex-wrap: wrap; gap: var(--space-6);
  padding: var(--space-6) 0; border-top: 1px solid var(--border-subtle);
}
.pc-usr-f { display: flex; flex-direction: column; gap: var(--space-2); min-width: 220px; }
.pc-usr-f span {
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
}
.pc-usr-f select {
  font-family: inherit; font-size: var(--text-sm); color: var(--text-primary);
  background: var(--bg-input); border: 1px solid var(--border);
  border-radius: var(--radius-input); padding: var(--space-4) var(--space-5);
  min-height: var(--target-min-dense); cursor: pointer;
}
.pc-usr-f select:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--focus-ring); }
/* A suggestion, explicitly NOT a selection. Muted so it reads as a hint rather than a value. */
.pc-usr-hint {
  flex-basis: 100%; margin: 0; font-size: var(--text-xs);
  color: var(--text-muted); line-height: var(--leading-normal);
}
/* A disabled action carries its reason in `title`, per ListActions' own convention — greying it
   with no explanation is what makes people ask someone instead of reading. */
.pc-decision-acts .btn[disabled] { opacity: .5; cursor: not-allowed; }

@media (max-width: 900px) {
  .pc-usr-route { flex-direction: column; gap: var(--space-4); }
  .pc-usr-f { min-width: 0; }
}

/* ── Records and Operations (SPEC-03) ───────────────────────────────────────────────────────────
   The pill strip is the EXISTING .chip — a pressable filter pill that already carries a count.
   Nothing new is drawn for it. */
.pc-rec-pills {
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  margin-bottom: var(--space-6); padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--border);
}
.pc-rec-fresh { margin: 0 0 var(--space-5); }
/* A legal description is prose in a table cell. It is clamped rather than wrapped so a 500-word
   metes-and-bounds does not set the row height for every other row on the screen. */
.pc-rec-legal {
  display: block; max-width: 380px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--text-secondary); font-size: var(--text-xs);
}
@media (max-width: 900px) {
  .pc-rec-pills { gap: var(--space-3); }
  .pc-rec-legal { max-width: none; white-space: normal; }
}

/* ── the topbar controls (SPEC-06, Option B) ────────────────────────────────────────────────────
   Record and console. The role pill is deliberately untouched. */
.pc-tb-wrap { position: relative; display: inline-flex; }

/* THE WHOLE GLYPH IS THE INDICATOR. A corner dot is not legible at topbar size; a circle that
   fills and pulses is, and it cannot drift out of sync with the button because it IS the button.
   The fill is --alert-bg/--alert-fg, the pair that inverts between themes — never --danger-fg,
   which is a foreground and disappears in dark at ~1.6:1. */
.pc-tb-rec svg { fill: none; }
/* The same rule, on the icon form of the same mark. A drop-shadow ring rather than a box-shadow,
   because the painted shape is the glyph and not its box. */
.pc-tb-rec.is-recording svg { fill: var(--alert-bg); stroke: var(--rail-text-active);
  stroke-width: 1.5; paint-order: stroke fill; }
/* THE PULSE MOVES THE FILL, NEVER THE WHOLE MARK — and it used to move the whole mark.
   This was `opacity` on the container, running `infinite`. Two things were wrong with that once the
   ring exists: opacity fades the RING along with the fill, so the edge that carries the contrast
   disappeared at the bottom of every cycle; and an infinite pulse on a mark that is already red and
   already says "recording" is a blink with no end.

   So the keyframes animate the PAINTED FILL only — background-color on the dot, fill on the glyph —
   and the ring is a separate, unanimated property. Three cycles mark the start, then it holds.
   Reduced motion holds from the first frame; the dot is never the only cue that recording is on. */
.pc-tb-rec.is-recording svg { animation: pc-rec-fill-icon 1.6s ease-in-out 3; }
@keyframes pc-rec-fill-icon { 0%, 100% { fill: var(--alert-bg); } 50% { fill: var(--danger-border); } }
@keyframes pc-rec-pulse { 0%, 100% { background-color: var(--alert-bg); }
                          50%      { background-color: var(--danger-border); } }
@media (prefers-reduced-motion: reduce) {
  .pc-tb-rec.is-recording svg { animation: none; }
}

/* The menu recorder.js injects into. Sits under the button, above the app, below modals. */
.pc-tb-menu {
  position: absolute; top: calc(100% + var(--space-4)); right: 0; z-index:var(--z-platform-menu);
  min-width: 260px; padding: var(--space-3);
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-popover);
}
/* recorder.js styles its own control with hard-coded values for production's dropdown. Give the
   rows the app's own sizing so the injected control does not read as a foreign object. */
.pc-tb-menu #_recCtl { border-top: 0; }
.pc-tb-menu button, .pc-tb-menu label {
  font-family: inherit; font-size: var(--text-sm); color: var(--text-primary);
}
/* ANCHORED RIGHT ON A PHONE TOO. This block used to say `right:auto; left:0`, which hangs the menu from its button's LEFT edge — and both
   buttons live at the far right of the bar. Measured 2026-09-18 (WebKit, 390 / 430 / 808 wide, all 21 screens): the account menu opened
   176px past the right edge, the record menu 96px — at 390 only 44px of the account menu was on screen, so the role, the environment
   switch and Sign out could not be reached (Mike, from a phone: "the initial badge drops down and to the right out of the screen").
   The base rule's `right:0` is what keeps it on screen; the max-width is the guard for a phone narrower than the menu. */
@media (max-width: 900px) {
  .pc-tb-menu { min-width: 220px; max-width: calc(100vw - 2 * var(--gutter-phone, 16px)); }
}

/* ── Debug: the session reader (SPEC-05 §4) ─────────────────────────────────────────────────────
   Full-screen, because a timeline plus a detail pane needs the room. z 9400 — the same slot as the
   org sheet, and deliberately BELOW the document sheet at 9500 so anything opened from here lands
   above it rather than behind it. */
#pcDbgReader .pc-dbg-reader {
  position: fixed; inset: 0; z-index:var(--z-platform-sheet);
  display: flex; flex-direction: column;
  background: var(--bg-page);
}
.pc-dbg-head {
  display: flex; align-items: flex-start; gap: var(--space-6); flex: 0 0 auto;
  padding: var(--space-7) var(--gutter);
  background: var(--bg-card); border-bottom: 1px solid var(--border);
}
.pc-dbg-head .btn { margin-left: auto; flex: 0 0 auto; }
.pc-dbg-meta { margin: var(--space-4) 0 0; font-size: var(--text-xs); color: var(--text-muted); }
.pc-dbg-note {
  margin: var(--space-4) 0 0; font-size: var(--text-sm);
  color: var(--text-secondary); max-width: 72ch; line-height: var(--leading-normal);
}
/* An absent note is stated rather than left blank — it is the one chance the recorder gives
   somebody to say what they were trying to do, so its absence is information. */
.pc-dbg-nonote { font-style: italic; color: var(--text-muted); }
.pc-dbg-copy { padding: 2px var(--space-4); min-height: 0; font-size: var(--text-2xs); }

.pc-dbg-tabs { flex: 0 0 auto; margin: 0; padding: 0 var(--gutter); background: var(--bg-card); }
.pc-dbg-pane { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-6) var(--gutter); }
.pc-dbg-foot {
  flex: 0 0 auto; padding: var(--space-5) var(--gutter);
  background: var(--bg-card); border-top: 1px solid var(--border);
}

.pc-dbg-list { list-style: none; margin: 0; padding: 0; }
.pc-dbg-ev {
  display: flex; gap: var(--space-6); align-items: baseline;
  padding: var(--space-4) 0; border-bottom: 1px solid var(--border-subtle);
  font-size: var(--text-sm); line-height: var(--leading-snug);
}
.pc-dbg-t {
  flex: 0 0 auto; width: 190px;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xs); color: var(--text-muted);
}
/* Payloads are long and must not set the row height for the whole log. */
.pc-dbg-b { min-width: 0; overflow-wrap: anywhere; }
.pc-dbg-open { padding: var(--space-2) var(--space-5); min-height: var(--target-min-dense); }

@media (max-width: 900px) {
  .pc-dbg-head { padding: var(--space-6) var(--gutter-phone); flex-wrap: wrap; }
  .pc-dbg-pane, .pc-dbg-foot { padding: var(--space-5) var(--gutter-phone); }
  /* Timeline first, stacked — the timestamp goes above its event rather than beside it. */
  .pc-dbg-ev { flex-direction: column; gap: var(--space-2); }
  .pc-dbg-t { width: auto; }
}

/* ── the recorder's floating badge, suppressed in dev2 — SPEC-06 ────────────────────────────────
   recorder.js draws a fixed REC badge at top:34px right:12px (`#_recInd`) at z-index 2147483647.
   In production that is the ONLY indicator, so it has to float and has to be above everything.

   In dev2 the record button is in the top bar and the whole glyph is the indicator — it fills and
   pulses. The floating badge then lands directly ON the topbar controls at that exact position,
   covering the record button and the avatar. Found by a click that timed out against an invisible
   element rather than by looking, which is the only way this kind of overlap shows up.

   So it is hidden HERE, in the console's own stylesheet, rather than by editing recorder.js —
   the file stays byte-identical across all three environments and production keeps its badge.
   The stop affordance is not lost: the topbar button opens the same control. */
#_recInd { display: none !important; }

/* ── the recorder's own control, hidden in favour of the console's menu ─────────────────────────
   HIDDEN, NOT REMOVED. recorder.js polls for #_recCtl by id to decide whether its control has been
   built (`if (document.getElementById('_recCtl')) { clearInterval(iv); return; }`), so deleting the
   element makes that poller rebuild forever. Hiding satisfies the poll and shows nothing.

   The recorder is driven instead through window.DebugRecorder, which is why recorder.js stays
   byte-identical across all three trees. */
#_recCtl { display: none !important; }

/* ── the menu's own items ───────────────────────────────────────────────────────────────────────
   Full-width rows with real labels. An unlabelled dot on a light pill reads as a text input, not a
   control — which is what the injected version looked like on a dark surface. */
.pc-tb-item {
  display: flex; align-items: center; gap: var(--space-5); width: 100%;
  padding: var(--space-5); border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--text-primary); font-family: inherit;
  font-size: var(--text-sm); text-align: left; text-decoration: none;
  cursor: pointer; min-height: var(--target-min-dense);
}
.pc-tb-item:hover { background: var(--bg-hover); }
.pc-tb-lbl { flex: 1; min-width: 0; }
.pc-tb-primary { font-weight: var(--weight-semibold); }
/* The dot is the state, beside a label that says what pressing it does. */
.pc-tb-dot {
  width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid var(--alert-bg); background: none;
}
/* THE RECORDING DOT FOLLOWS THE SAME RULE AS THE RAIL BADGE AND THE VIEWING-AS PILL (UIUX top-band
   §5): any --alert-bg fill drawn on the dark chrome wears the 1.5px --rail-text-active ring. This dot
   sits on the top bar, where the fill measures 2.70:1 in light theme — under the 3:1 a mark needs.

   IT STAYS RED. "Recording" is red by convention, and that beats the hue table's "red = gone for
   good" for this one mark.

   THE RING IS SOLID AND DOES NOT PULSE: the animation moves the FILL only, so the edge is there at
   every frame of the cycle. An edge that fades is not an edge you can rely on.

   THREE CYCLES, THEN STEADY. It pulsed for the entire recording, which is a blink with no end — and
   the steady red dot already says "recording". Three cycles mark the START, then it holds. Under
   reduced motion it holds from the first frame; the dot is never the only cue, so nothing is lost. */
.pc-tb-dot.is-on { background: var(--alert-bg);
  box-shadow: 0 0 0 1.5px var(--rail-text-active);
  animation: pc-rec-pulse 1.6s ease-in-out 3; }
@media (prefers-reduced-motion: reduce) {
  .pc-tb-dot.is-on { animation: none; }
}
.pc-tb-clock {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-xs); color: var(--text-muted);
}
/* The native checkbox is fine; it just needs the app's accent. That is the whole fix — a custom
   control here would be another lookalike. */
.pc-tb-check input { width: 16px; height: 16px; margin: 0; flex: 0 0 auto;
  accent-color: var(--accent-500); cursor: pointer; }
.pc-tb-sep { height: 1px; margin: var(--space-3) 0; background: var(--border); }

/* The replay surface. rrweb sizes its own iframe; this just gives it room and a ground so a
   light-DOM recording does not sit on a dark page with no edge. */
.pc-dbg-player {
  min-height: 60vh; background: var(--bg-sunken);
  border: 1px solid var(--border); border-radius: var(--radius-card); overflow: auto;
}
.pc-dbg-player .replayer-wrapper { margin: 0 auto; }

/* ── Reviews (SPEC-04) ──────────────────────────────────────────────────────────────────────────
   The four queues do not work the same way — two decide in place, one routes to the record, one
   decides nothing. That line sits under the switcher so the difference is visible before you
   click, rather than learned by opening Curation and finding no buttons. */
.pc-rev-where {
  margin: calc(var(--space-6) * -1) 0 var(--space-6);
  font-size: var(--text-2xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted);
}
.pc-rev-note {
  margin: 0 0 var(--space-7); font-size: var(--text-sm);
  color: var(--text-secondary); line-height: var(--leading-normal); max-width: 72ch;
}
/* A curation card's action is a LINK to the record, not a decision. It is the same size as a
   decision button so the row does not read as lesser, but it is not a danger button — nothing
   here is destroyed, and giving Reject the weight Delete deserves is how a 40-row queue stops
   moving. */
.pc-decision-acts .btn[href] { text-decoration: none; display: inline-flex;
  align-items: center; justify-content: center; }

/* The session handle. Muted because it is a reference, not a measurement — the thing you say out
   loud to point somebody at a recording, not a number anyone reads for meaning. */
.pc-dbg-num { color: var(--text-muted); font-weight: var(--weight-regular); }
.pc-org-name .pc-dbg-num { font-size: var(--text-md); }

/* ── Overview (SPEC-10) ─────────────────────────────────────────────────────────────────────────
   QUEUES ARE CARDS, NUMBERS ARE A STRIP. Inverting that inverts the screen's argument — the work
   is the point and the totals are context. */
.pc-ov-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-6); margin-bottom: var(--space-10);
}
.pc-ov-card {
  display: block; padding: var(--space-7); text-decoration: none; color: inherit;
  background: var(--bg-card); border: 1px solid var(--border);
  border-left: 4px solid var(--warning-border);      /* 4px solid = decision, per SPEC-00 §6.2 */
  border-radius: var(--radius-card); box-shadow: var(--shadow-card);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
a.pc-ov-card:hover { border-color: var(--border-strong); border-left-color: var(--accent-500);
  box-shadow: var(--shadow-popover); }
/* An unwired queue is present and inert — hiding it would claim the platform has three queues. */
.pc-ov-card.is-unwired { border-left-color: var(--warning-border); border-style: dashed;
  background: var(--warning-bg); cursor: default; }
.pc-ov-h {
  margin: 0 0 var(--space-5); font-size: var(--text-2xs);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text-muted);
}
.pc-ov-n {
  margin: 0; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xl); font-weight: var(--weight-bold); line-height: var(--leading-tight);
}
.pc-ov-lbl { margin: var(--space-2) 0 var(--space-5); font-size: var(--text-sm);
  color: var(--text-secondary); }
/* A queue at zero says so in words. Never `0` — on the first screen anybody sees, a zero reads as
   a finding rather than as an absence. */
.pc-ov-none { margin: 0; font-size: var(--text-sm); color: var(--text-muted); font-style: italic; }
.pc-ov-break { margin: 0; padding-left: var(--space-6); list-style: none;
  font-size: var(--text-xs); color: var(--text-muted); line-height: var(--leading-snug); }
.pc-ov-break li { margin-bottom: var(--space-2); }
/* A failed read is contained INSIDE its card, so one broken queue does not take the screen down. */
.pc-ov-fail {
  font-size: var(--text-xs); color: var(--danger-fg); line-height: var(--leading-normal);
  background: var(--danger-bg); border: 1px solid var(--danger-border);
  border-radius: var(--radius-sm); padding: var(--space-5);
}
.pc-ov-strip { border-top: 1px solid var(--border); padding-top: var(--space-7); }
.pc-ov-strip-note { margin: 0 0 var(--space-5); font-size: var(--text-xs); color: var(--text-muted); }
.pc-ov-fact a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--border-strong); }
.pc-ov-fact a:hover { color: var(--accent-500); border-bottom-color: var(--accent-500); }
@media (max-width: 900px) {
  .pc-ov-grid { grid-template-columns: 1fr; gap: var(--space-5); }
}

/* ── the export dialog (SPEC-09 §5.1) ───────────────────────────────────────────────────────────
   z 9900, the modal layer, so it sits above the session reader at 9400 that opened it. */
.pc-exp-back {
  position: fixed; inset: 0; z-index:var(--z-platform-exit); display: flex;
  align-items: center; justify-content: center; padding: var(--space-7);
  background: var(--bg-overlay);
}
.pc-exp-box {
  width: 100%; max-width: 560px; padding: var(--space-8);
  background: var(--bg-modal); border: 1px solid var(--border);
  border-radius: var(--radius-card); box-shadow: var(--shadow-modal);
  max-height: 90vh; overflow-y: auto;
}
.pc-exp-h { margin: 0 0 var(--space-2); font-size: var(--text-lg); font-weight: var(--weight-bold); }
.pc-exp-meta { margin: 0 0 var(--space-7); font-size: var(--text-xs); color: var(--text-muted);
  font-family: var(--font-mono); }
.pc-exp-row {
  display: flex; align-items: flex-start; gap: var(--space-5);
  padding: var(--space-5); border-radius: var(--radius-sm); cursor: pointer;
}
.pc-exp-row:hover { background: var(--bg-hover); }
/* Disabled with the reason in place of the sub-line — never hidden, or somebody concludes the
   package contains a part it does not. */
.pc-exp-row.is-off { cursor: not-allowed; opacity: .65; }
.pc-exp-row input { width: 16px; height: 16px; margin: 2px 0 0; flex: 0 0 auto;
  accent-color: var(--accent-500); }
.pc-exp-main { flex: 1; min-width: 0; }
.pc-exp-lbl { display: block; font-size: var(--text-sm); font-weight: var(--weight-semibold); }
.pc-exp-sub { display: block; margin-top: var(--space-2); font-size: var(--text-xs);
  color: var(--text-muted); line-height: var(--leading-snug); }
/* Size sits at the moment of choosing, because size is the deciding factor — a 40 MB package
   bounces off the destination. */
.pc-exp-size { flex: 0 0 auto; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums; font-size: var(--text-xs); color: var(--text-secondary); }
.pc-exp-total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid var(--border);
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
}
.pc-exp-total span:last-child { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.pc-exp-warn {
  margin: var(--space-6) 0 0; padding: var(--space-5); font-size: var(--text-xs);
  background: var(--warning-bg); border: 1px solid var(--warning-border);
  border-radius: var(--radius-sm); color: var(--warning-fg); line-height: var(--leading-normal);
}
/* Always present, not only when bodies are ticked. This artifact leaves the machine. */
.pc-exp-note { margin: var(--space-6) 0 0; font-size: var(--text-xs); color: var(--text-muted);
  line-height: var(--leading-normal); }
.pc-exp-acts { display: flex; justify-content: flex-end; gap: var(--space-5);
  margin-top: var(--space-7); }
.pc-exp-acts .btn[disabled] { opacity: .5; cursor: not-allowed; }

/* COVERAGE, as a qualifier on the result rather than a panel state of its own. It sits with the
   answer it qualifies — not in a dashed amber box above it, which said "go and build something"
   about a queue that had run, and which duplicated the empty state's own wording. */
.pc-rev-coverage {
  margin: var(--space-5) 0 0; max-width: 72ch;
  font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-normal);
}

/* The review control sits in the row, next to the badge it changes. Small, because it is a
   one-click action on a list rather than a decision. */
.pc-dbg-mark { padding: 2px var(--space-4); min-height: 0; margin-left: var(--space-4);
  font-size: var(--text-2xs); }
/* The active filter, stated. A default nobody can see is a hidden filter, and on this screen that
   would make "nothing to look at" a setting rather than a fact. */
.pc-dbg-default { margin: var(--space-2) 0 0; font-size: var(--text-xs); color: var(--text-muted); }

/* The account menu. Same popover as the record menu — one shape for both topbar menus. */
/* `font: inherit` WAS A SHORTHAND AND THAT WAS THE BUG. A <button> does not inherit the page font,
   so this rule existed to give it one — but the shorthand resets EVERY font longhand, and at
   (1,1,0) it outranked `.avatar` at (0,1,0) in shell.css, silently discarding that rule's
   font-size and font-weight. The badge rendered at the body's 14px/400 instead of 11px bold, and
   the button's UA `padding: 1px 6px` was never cleared either — on a 28px border-box square that
   leaves a 16px content box for a 21–27px glyph run, so wide initials spilled outside the circle.
   `MW` overhung by 3.7px and `WW` by 5.3px; `CD` (the debug login) happens to fit, which is why
   checking one account read it as merely off-centre.
   font-family alone does the one thing that was actually wanted. */
.avatar#pcAvatar { border: 0; padding: 0; cursor: pointer; font-family: inherit; }
.pc-tb-who { margin: 0; padding: var(--space-4) var(--space-5); font-size: var(--text-xs);
  color: var(--text-muted); overflow-wrap: anywhere; }

/* The scope of the empty-state claim, stated under it. Smaller and muted: it qualifies the line
   above rather than competing with it. */
.pc-ov-none-why { margin: var(--space-2) 0 0; font-size: var(--text-2xs);
  color: var(--text-muted); line-height: 1.4; }

/* ── PC.cardShell — one shell, two shapes ────────────────────────────────────────────────────────
   Built to BUILD-decision-card-contract.md §6 and BUILD-cards-and-operator-linking.md §2.5.
   ALL card CSS lives HERE, never in an injected <style> block — that is production's pattern.
   NO NEW TOKENS. */

.pc-card {
  /* 4px SOLID, NO HATCH. 6px hatched means a RECORD and the hatch encodes estate type; a decision
     is not a record and has no estate. */
  border-left: 4px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  border-top: 1px solid var(--border); border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: var(--space-6);
  margin-bottom: var(--space-5);
  /* CAPS AT 900px INSIDE THE 1500px PAGE. It is prose. */
  max-width: 900px;
}
/* A FINDING IS UNRESOLVED, which is what the warning tone says. */
.pc-card-finding { border-left-color: var(--warning-border); }
.pc-card.is-failed  { border-left-color: var(--danger-border); }
/* `unwired` IS DASHED because the FIX is different: failed is a bug, unwired is unbuilt. */
.pc-card.is-unwired { border-left-style: dashed; border-left-color: var(--neutral-border); }

.pc-card-head { display: flex; align-items: baseline; gap: var(--space-4);
  flex-wrap: wrap; margin-bottom: var(--space-4); }
.pc-card-what { font-size: var(--text-md); font-weight: var(--weight-semibold);
  color: var(--text-primary); flex: 1; min-width: 0; }
.pc-card-what a { color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--border-strong); }
.pc-card-what a:hover { color: var(--accent-500); border-bottom-color: var(--accent-500); }
.pc-card-kind { font-size: var(--text-2xs); text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  padding: 1px var(--space-3); white-space: nowrap; }

.pc-card-rows { display: grid; grid-template-columns: 150px 1fr;
  gap: var(--space-4) var(--space-6); margin-bottom: var(--space-4); }
.pc-card-k { font-size: var(--text-2xs); text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--text-muted);
  font-weight: var(--weight-semibold); }
.pc-card-v { font-size: var(--text-sm); color: var(--text-primary);
  line-height: var(--leading-normal); }
.pc-card-msg { font-size: var(--text-sm); color: var(--text-primary); margin: 0 0 var(--space-4); }
.pc-card-need { font-size: var(--text-2xs); color: var(--text-muted); margin: 0;
  font-family: var(--font-mono); }

.pc-ev { margin: 0 0 var(--space-4); }
.pc-ev-body { display: block; font-size: var(--text-sm); color: var(--text-primary);
  white-space: pre-wrap; word-break: break-word; line-height: var(--leading-normal);
  border-left: 2px solid var(--border); padding-left: var(--space-4); }
.pc-ev-meta { font-size: var(--text-2xs); color: var(--text-muted); margin: var(--space-2) 0 0; }
.pc-ev-more { font: inherit; font-size: var(--text-2xs); background: none; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-secondary); padding: 1px var(--space-3); margin-top: var(--space-2); }
.pc-ev-failed { font-size: var(--text-sm); color: var(--text-primary); }

.pc-chg { display: grid; grid-template-columns: 170px 1fr; gap: var(--space-3) var(--space-5);
  padding: var(--space-3) 0; border-bottom: 1px solid var(--border); }
.pc-chg:last-of-type { border-bottom: 0; }
.pc-chg-l { font-size: var(--text-2xs); text-transform: uppercase; color: var(--text-muted);
  letter-spacing: var(--tracking-wide); font-weight: var(--weight-semibold); }
.pc-chg-v { font-size: var(--text-sm); color: var(--text-primary); }
.pc-chg-now { grid-column: 2; font-size: var(--text-2xs); color: var(--text-primary); }
.pc-chg.is-conflict { background: var(--warning-bg); }

.pc-landed { font-size: var(--text-sm); color: var(--text-primary);
  background: var(--warning-bg); border: 1px solid var(--warning-border);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4); }

.pc-blockers { margin: 0 0 var(--space-4); padding-left: var(--space-6);
  font-size: var(--text-sm); color: var(--danger-fg); }
.pc-blockers li { margin-bottom: var(--space-2); }
.pc-remedies { margin: 0; padding-left: var(--space-5); }
.pc-remedies li { margin-bottom: var(--space-2); }

.pc-inputs { display: flex; gap: var(--space-5); flex-wrap: wrap; margin-bottom: var(--space-4); }
.pc-input { display: flex; flex-direction: column; gap: var(--space-2); }
.pc-input span { font-size: var(--text-2xs); text-transform: uppercase;
  letter-spacing: var(--tracking-wide); color: var(--text-muted);
  font-weight: var(--weight-semibold); }

.pc-acts { display: flex; gap: var(--space-4); flex-wrap: wrap; }
/* BOTH BUTTONS EQUAL WEIGHT. A quiet Retain beside a solid Delete is a nudge toward destruction on
   the one screen where that is least acceptable. */
.pc-acts-two .btn { min-width: 160px; justify-content: center; }
/* --alert-bg / --alert-fg for a solid red fill. NEVER background: var(--danger-fg) — it reads at
   about 1.6:1 in dark. */
.pc-act-danger { color: var(--danger-fg); border-color: var(--danger-border); }
.pc-resolved { font-size: var(--text-sm); color: var(--neutral-fg);
  background: var(--neutral-bg); border: 1px solid var(--neutral-border);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4); margin: 0; }

.pc-skel { height: 18px; border-radius: var(--radius-sm); background: var(--bg-subtle);
  margin-bottom: var(--space-3); }
.pc-skel-sm { height: 12px; width: 60%; }

/* BELOW 900px THEY STACK, DESTRUCTIVE SECOND. */
@media (max-width: 900px) {
  .pc-acts { flex-direction: column-reverse; }
  .pc-acts .btn { width: 100%; }
  .pc-card-rows, .pc-chg { grid-template-columns: 1fr; gap: var(--space-2); }
  .pc-chg-now { grid-column: 1; }
}

/* ── `type:'impact'` — the third shared renderer ────────────────────────────────────────────────
   Three consumers: the deletion review's "what this changes", the merge surface's "12 units and 50
   wells will move", and the operator delete confirm. */
.pc-impact { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.pc-imp { border-bottom: 1px solid var(--border); }
.pc-imp:last-child { border-bottom: 0; }
.pc-imp-h { display: flex; width: 100%; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4); background: none; border: 0; cursor: pointer;
  font: inherit; text-align: left; color: var(--text-primary); }
.pc-imp-h[disabled] { cursor: default; }
.pc-imp-l { flex: 1; min-width: 0; font-size: var(--text-sm); }
.pc-imp-n { font-size: var(--text-2xs); color: var(--text-muted); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
/* THE THIRD STATE. `not recorded` is not `0` — "it touched nothing" and "nobody wrote down what it
   touched" are different facts, and once the row is gone the difference cannot be recovered. */
.pc-imp.is-unknown .pc-imp-n { color: var(--warning-fg); }
.pc-imp-why { margin: 0; padding: 0 var(--space-4) var(--space-4);
  font-size: var(--text-sm); color: var(--warning-fg); max-width: 66ch; }
.pc-imp-b { padding: 0 var(--space-4) var(--space-4); font-size: var(--text-sm);
  color: var(--text-secondary); }

/* `resolved` with something still outstanding — a returned request waiting on the requester, an
   approved deletion waiting to run. Without this, `returned` renders identically to `rejected`. */
.pc-resolved.is-pending { background: var(--warning-bg); border-color: var(--warning-border);
  color: var(--warning-fg); }

/* A NEW ACT ON A SETTLED RECORD, behind a DASHED rule. A solid rule reads as another section of the
   same decision; a dashed one reads as "and separately". The decision stands and was correct — the
   record is being put back, which is why the copy never says Undo. */
.pc-further { margin-top: var(--space-5); padding-top: var(--space-5);
  border-top: 1px dashed var(--border-strong); }
.pc-further-n { margin: 0 0 var(--space-3); font-size: var(--text-sm);
  color: var(--text-secondary); max-width: 66ch; }

/* ── Membership rows on the user record (platform-users.js memberRows) ──────────────────────────────
   Name · role · row control. The first two columns match .pc-org-kv so the section reads the same as
   the rest of the record; the third holds the row's own control (UI/UX §2.1). */
.pc-mem-row { display: grid; grid-template-columns: 140px minmax(0,1fr) auto; gap: var(--space-4) var(--space-6);
  align-items: center; padding: var(--space-3) 0; border-bottom: 1px solid var(--border-subtle); }
.pc-mem-row:last-child { border-bottom: 0; }
.pc-mem-row.is-editing { display: block; }
.pc-mem-row.is-editing .pc-ed { padding: var(--space-3) 0; }
/* Two row controls sit together on the right; the reason for a disabled one spans the row beneath them, as visible
   text rather than a tooltip. */
.pc-mem-acts { display: flex; gap: var(--space-3); justify-self: end; }
.pc-mem-why:empty { display: none; }
.pc-mem-why { grid-column: 1 / -1; font-size: var(--text-xs); color: var(--text-muted); }
@media (max-width: 720px) {
  .pc-mem-row { grid-template-columns: minmax(0,1fr) auto; }
  .pc-mem-row > .pc-org-k { grid-column: 1 / -1; }
}
