/* WS Payment Central — the redesign's component layer.
   ============================================================================================================

   THE COMPONENTS ARE THE HANDOFF'S, VERBATIM. Everything below the bridge is copied from
   docs/design/payment-central.css unchanged: the shell, the cards and tiles, the tables, the controls and the
   notices, exactly as the redesign specifies them. Editing a rule here to suit one screen is the thing this
   file exists to prevent -- that is what a per-screen override is, and the whole theming contract rests on
   there not being any.

   THE TOKENS ARE NOT. The handoff's sheet declares its own palette and its own [data-pc-theme] scopes. This
   console already has five themes on its own tokens (see styles.css), scored by
   tools/check-admin-ui-contrast.mjs, so importing a SECOND palette would mean two sets of colours, two sets
   of theme scopes, and a contrast gate that reads one of them. The bridge below maps every --pc-* colour onto
   the token that already carries it, which is why:

     * every .pc-* component is themed by all five themes on the day it is used, with no per-component work;
     * the contrast gate keeps scoring the real values, because the real values never moved;
     * there are NO COLOUR LITERALS in this file at all, so it needs no exemption from the guard in
       AdminUiSourceTests that forbids them outside styles.css.

   THE RAIL HAS ITS OWN TOKEN SET, AND SINCE 2026-09-16 IT FOLLOWS THE THEME. This entry asserted that the
   rail was "the one surface the redesign holds fixed rather than theming" and that a black sidebar in every
   theme was the settled answer; the platform owner asked for the opposite, so that claim is retired. The
   handoff does draw it black in every theme and the deviation is deliberate.

   The tokens are still declared per theme scope in styles.css as --rail-*, and that is what made the change
   a palette edit rather than a rewrite: every rule below already spent --pc-sidebar-*, so the ground moved
   without a single component rule changing. --pc-sidebar-accent is the one addition -- the accent AS PAINTED
   ON THE RAIL, because #ff701f is 2.65:1 on a light one.

   LOADED AFTER styles.css, so the bridge can read tokens that file declares. See index.html.
   ============================================================================================================ */

:root {
  /* ---- ink */
  --pc-ink: var(--text);
  --pc-body: var(--text-body);
  --pc-secondary: var(--text-secondary);
  --pc-disabled-ink: var(--text-disabled);
  /* The em-dash in an empty matrix cell: a mark, not a value, so it takes the strong BORDER rather than an
     ink. Bridged to --border-strong because that is the token already scored as a non-text mark. */
  --pc-empty: var(--border-strong);

  /* ---- grounds */
  --pc-surface: var(--surface);
  --pc-wash: var(--surface-sunken);
  --pc-hairline: var(--border);
  --pc-page: var(--bg);

  /* ---- the rail. Fixed across themes by the redesign; see the header. */
  --pc-sidebar-bg: var(--rail-bg);
  --pc-sidebar-rest: var(--rail-rest);
  --pc-sidebar-hover: var(--rail-hover);
  --pc-sidebar-active: var(--rail-active);
  --pc-sidebar-label: var(--rail-label);
  /* Text ON the rail, its hairline, and its resting muted state. Three more than the handoff
     names, because its sheet spent literals for them and this file may hold none. */
  --pc-sidebar-ink: var(--rail-ink);
  --pc-sidebar-line: var(--rail-line);
  --pc-sidebar-muted: var(--rail-muted);
  /* The accent AS PAINTED ON THE RAIL. The rail is its own ground, so the content accent is
     the wrong value on it: #ff701f is 2.65:1 on a light rail. Same hue, one step darker where
     the ground demands it -- exactly --accent-text's relationship to --accent, one surface
     over. Three things spend it: the environment chip, the selected bar and its icon. */
  --pc-sidebar-accent: var(--rail-accent);

  /* ---- action and consequence. The invariant the handoff is loudest about: --pc-accent is ACTION and
     --pc-alarm is CONSEQUENCE, never interchangeable. They bridge to the two tokens this console already
     keeps apart for the same reason. */
  --pc-accent: var(--accent);
  --pc-accent-press: var(--accent-hover);
  /* The ring, NOT the fill. --pc-accent is 2.77:1 on white and a focus ring owes 3:1
     (WCAG 1.4.11), so this is the same hue darkened to clear it. */
  --pc-focus: var(--focus);
  --pc-on-accent: var(--accent-ink);
  --pc-alarm: var(--danger-ink);
  --pc-alarm-wash: var(--danger-wash);

  /* ---- verdicts. Re-picked per theme by styles.css, which is what keeps them mutually distinguishable in
     high contrast without this file knowing anything about themes. */
  --pc-verdict-good-fg: var(--ok-ink);
  --pc-verdict-good-bg: var(--ok-wash);
  --pc-verdict-good-br: var(--ok-border);
  --pc-verdict-warn-fg: var(--warn-ink);
  --pc-verdict-warn-bg: var(--warn-wash);
  --pc-verdict-warn-br: var(--warn-border);
  --pc-verdict-flat-fg: var(--neutral-ink);
  --pc-verdict-flat-bg: var(--neutral-wash);
  --pc-verdict-flat-br: var(--neutral-border);

  /* ---- density and motion, bridged to the two the preference already drives, so compact and reduced
     motion reach every redesign component without a second mechanism. */
  --pc-pad-cell: var(--pad-cell);
  --pc-motion: 240ms;

  /* ---- geometry and type, from the handoff unchanged: these are not palette. */
  --pc-font-display: "Playfair Display", Georgia, serif;
  --pc-font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
  --pc-font-mono: ui-monospace, Menlo, Consolas, monospace;
  --pc-fs-title: 34px;
  --pc-fs-card-title: 22px;
  --pc-fs-lede: 14px;
  --pc-fs-base: 13px;
  --pc-fs-caption: 12px;
  --pc-fs-label: 10px;
  --pc-gap-block: 24px;
  --pc-gap-grid: 16px;
  --pc-gap-control: 12px;
  --pc-pad-card: 20px;
  --pc-pad-head: 10px 20px;
  --pc-radius-card: 8px;
  --pc-radius-control: 4px;
  --pc-radius-check: 3px;
  --pc-radius-pill: 999px;
  --pc-content-max: 1180px;
  --pc-prose-max: 820px;
  --pc-sidebar-w: 228px;
}

/* ── Base ───────────────────────────────────────────────────────────────── */

.pc {
  display: flex;
  min-height: 100vh;
  margin: 0;
  font-family: var(--pc-font-body);
  color: var(--pc-ink);
  background: var(--pc-page);
}

.pc code { font-family: var(--pc-font-mono); }

.pc a { color: var(--pc-ink); text-decoration: underline; }
.pc a:hover { color: var(--pc-accent); }

.pc :focus-visible {
  outline: 2px solid var(--pc-focus);
  outline-offset: 2px;
}

/* ── Shell ──────────────────────────────────────────────────────────────── */

/* FIXED, WHICH THE HANDOFF SAYS IN THREE WORDS AND THIS MISSED. "Fixed sidebar, 228px" -- and without
   it the rail is an ordinary column in a flex row, so the PAGE scrolling takes the rail with it. On a
   long screen the destinations scroll off the top and the theme switch is only reachable by scrolling to
   the bottom, which is how it reads as missing. Reported from the deployed site, and no test could see
   it: every spec addresses the rail by selector, and a selector does not care where the element is.

   height:100vh WITH ITS OWN overflow-y, not just `position: sticky`. The rail is taller than a short
   window once twelve destinations, the theme block and the footnote are in it; sticky alone would pin
   the top and let the bottom sit below the fold permanently, which is the same complaint one layer in. */
.pc-sidebar {
  width: var(--pc-sidebar-w);
  flex: 0 0 var(--pc-sidebar-w);
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  padding: 24px 0;
  background: var(--pc-sidebar-bg);
  color: var(--pc-sidebar-rest);
}

.pc-nav { flex: none; display: flex; flex-direction: column; gap: 1px; padding: 0 8px; }

.pc-nav-group {
  padding: 16px 6px 5px;
  font-size: var(--pc-fs-label);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pc-sidebar-label);
}

.pc-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  border-radius: var(--pc-radius-control);
  font-size: var(--pc-fs-base);
  color: var(--pc-sidebar-rest);
  text-decoration: none;
}
.pc-nav-item:hover { background: var(--pc-sidebar-hover); color: var(--pc-sidebar-rest); }

/* SCOPED UNDER .pc TO OUT-SPECIFY `.pc a`, which sets an underline and the ink colour for links in the
   content column. The handoff's prototype drew its nav items as <button>, so that rule never reached
   them; this console uses real anchors -- they carry an href, so middle-click and "copy link" work -- and
   an anchor inside .pc picks up the content link treatment unless something says otherwise. Left as it
   was, every destination rendered as dark underlined text on a black rail: unreadable, and the first
   thing visible in a screenshot. */
.pc .pc-nav-item { color: var(--pc-sidebar-rest); text-decoration: none; }
.pc .pc-nav-item:hover { color: var(--pc-sidebar-ink); text-decoration: none; }
.pc .pc-nav-item[aria-current] { color: var(--pc-sidebar-ink); }
.pc .pc-theme-all { color: var(--pc-sidebar-muted); }
.pc .pc-theme-all:hover { color: var(--pc-sidebar-ink); }

.pc-nav-item[aria-current] {
  background: var(--pc-sidebar-active);
  color: var(--pc-sidebar-ink);
  font-weight: 700;
  box-shadow: inset 2px 0 0 var(--pc-sidebar-accent);
}

/* ---- tabs, the step rail, and the two-option chooser --------------------------------------------------
   The handoff's prototype drew all three with inline styles, so its stylesheet declares none of them.
   They are components rather than one screen's markup: the retokenization wizard uses them today and any
   screen with a sequence will want the same rail. */

/* TABS, NOT A SEGMENTED CONTROL. `.pc-seg` already exists and is the right thing for a FILTER over one
   table -- Active/Inactive/All. These are three different VIEWS of one feature, each with its own
   content, which is what a tab means and what a segmented control does not. */
.pc-tabs {
  display: flex; gap: var(--pc-gap-block); align-items: flex-end;
  border-bottom: 1px solid var(--pc-hairline);
}
.pc-tab {
  appearance: none; border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: var(--pc-fs-lede);
  padding: 0 0 10px; margin-bottom: -1px;
  color: var(--pc-secondary); border-bottom: 2px solid transparent;
}
.pc-tab:hover { color: var(--pc-ink); }
/* THE CHOSEN TAB TAKES INK AND WEIGHT, and the accent carries the underline. The word is never accent
   coloured: that is the handoff's rule about the accent failing as text, and it holds here. */
.pc-tab[aria-selected="true"] {
  color: var(--pc-ink); font-weight: 600; border-bottom-color: var(--pc-accent);
}
.pc-tab-count { margin-left: 6px; color: var(--pc-secondary); font-weight: 400; }

/* The step rail is defined with the rest of the wizard at the end of this file: it is a
   BUTTON now, not a list item, and the two sets of rules belong together. */
.pc-step-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pc-step-title { font-size: var(--pc-fs-base); font-weight: 600; color: var(--pc-ink); }
/* THE META LINE IS THE POINT OF THE RAIL. "Nothing picked yet", "No file attached", "Irreversible" --
   a numbered list without it says only how many steps there are. */
.pc-step-meta { font-size: var(--pc-fs-caption); color: var(--pc-secondary); }

/* "This run": what the wizard currently holds, under the rail. */
.pc-thisrun {
  padding: 14px;
  border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-card);
  background: var(--pc-wash);
  display: flex; flex-direction: column; gap: 4px;
}
.pc-thisrun-label {
  font-size: var(--pc-fs-label); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pc-secondary);
}
.pc-thisrun-name { font-size: var(--pc-fs-base); font-weight: 600; color: var(--pc-ink); }
.pc-thisrun-line { font-size: var(--pc-fs-caption); color: var(--pc-secondary); }

/* The two-option chooser. Side by side, each carrying what it COSTS rather than only what it does. */
.pc-optgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--pc-gap-grid); }
.pc-opt {
  display: flex; gap: 10px; align-items: flex-start;
  padding: var(--pc-pad-card);
  border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-card);
  background: var(--pc-surface); cursor: pointer;
}
.pc-opt:hover { background: var(--pc-wash); }
.pc-opt--chosen { border-color: var(--pc-accent); }
.pc-opt input[type="radio"] { margin-top: 2px; accent-color: var(--pc-accent); flex: none; }
.pc-opt-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pc-opt-name { font-size: var(--pc-fs-lede); font-weight: 600; color: var(--pc-ink); }
.pc-opt-note { font-size: var(--pc-fs-base); line-height: 1.5; color: var(--pc-secondary); }
/* THE RISK TAG, and it is the reason these are cards rather than radio rows. One of these two operations
   cannot be undone and the other can be re-run; that is the single most important difference between
   them, and a description alone buries it in a sentence. Uppercase and tracked, in the verdict colours,
   so the pair can be told apart before either is read. */
.pc-opt-tag {
  font-size: var(--pc-fs-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
}
.pc-opt-tag--danger { color: var(--pc-alarm); }
.pc-opt-tag--safe { color: var(--pc-verdict-good-fg); }

/* The wizard's two columns: the rail, then the panel being worked in. */
.pc-wizard {
  display: grid; grid-template-columns: 268px minmax(0, 1fr);
  gap: 28px; align-items: start;
}
@media (max-width: 900px) { .pc-wizard { grid-template-columns: minmax(0, 1fr); } }
.pc-wizard-rail { display: flex; flex-direction: column; gap: var(--pc-gap-grid); }

/* ---- the rail's own furniture ---------------------------------------------------------------------
   Six classes the handoff's markup uses and its stylesheet does not declare, because the prototype drew
   them with inline styles. They sit here rather than in styles.css so that everything painting ON the
   rail spends the same --pc-sidebar-* bridge, and so a reader looking for the rail finds all of it in
   one place. */

.pc-brandmark {
  flex: none;
  display: flex; align-items: center; gap: 10px;
  padding: 18px 16px 14px;
}
/* NO FILL AND NO RADIUS: this was an accent-coloured square holding the letters WS, and it is now the
   WorldStrides symbol, which carries its own colour. A tinted plate behind a logo is a second brand
   colour competing with the one in the logo. */
.pc-brandmark-dot {
  flex: none; width: 26px; height: 26px;
  object-fit: contain;
}
.pc-brandmark-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pc-brandmark-name {
  font-size: var(--pc-fs-base); font-weight: 600; color: var(--pc-sidebar-ink);
}
/* THE ENVIRONMENT BADGE IS THE ONE THING ON THE RAIL THAT MUST NOT BE MISSED, because every destructive
   control in this console does the same thing in dev and in production. Uppercase and tracked so it
   reads as a label rather than as part of the product name. */
.pc-brandmark-env {
  font-size: 9px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--pc-sidebar-accent);
}

.pc-cmd-trigger {
  /* flex:none, because .pc-sidebar is a flex COLUMN with free space in it -- without this the trigger
     grows to eat the gap above the nav and renders as a tall empty box. */
  flex: none;
  display: flex; align-items: center; gap: 8px;
  margin: 0 12px 14px; padding: 7px 10px;
  border: 1px solid var(--pc-sidebar-line); border-radius: var(--pc-radius-control);
  background: transparent; color: var(--pc-sidebar-muted);
  font-family: inherit; font-size: var(--pc-fs-caption); cursor: pointer;
  transition: color var(--pc-motion) ease, border-color var(--pc-motion) ease;
}
.pc-cmd-trigger:hover { color: var(--pc-sidebar-ink); border-color: var(--pc-sidebar-rest); }
.pc-cmd-label { flex: 1 1 auto; text-align: left; }

/* PUSHED TO THE BOTTOM by margin-top:auto on the block above the footnote, so the rail's foot sits at the
   foot whatever the nav's height -- rather than floating under the last destination on a short list. */
.pc-theme-block { margin-top: auto; padding: 0 12px 10px; display: flex; flex-direction: column; gap: 6px; }
.pc-theme-label {
  margin: 0; font-size: var(--pc-fs-label); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pc-sidebar-label);
}
.pc-theme-all {
  align-self: flex-start; padding: 0; border: 0; background: none;
  font-family: inherit; font-size: var(--pc-fs-caption);
  color: var(--pc-sidebar-muted); text-decoration: underline; cursor: pointer;
}
.pc-theme-all:hover { color: var(--pc-sidebar-ink); }

.pc-sidebar-foot {
  margin: 0; padding: 0 16px 18px;
  font-size: 11px; line-height: 1.5; color: var(--pc-sidebar-label);
}

.pc-nav-icon { flex: 0 0 16px; display: flex; color: var(--pc-sidebar-label); }
.pc-nav-item[aria-current] .pc-nav-icon { color: var(--pc-sidebar-accent); }

.pc-whoami {
  padding: 24px 20px 0;
  font-size: var(--pc-fs-caption);
  color: var(--pc-secondary);
}

.pc-main { flex: 1 1 auto; min-width: 0; }

/* VERTICAL PADDING ONLY, because this band is rendered INSIDE the content column rather than as a sibling
   of it. The handoff's prototype puts the header outside .pc-content and pads both; here PageHead is a
   screen's own first element -- which is what lets a screen own its title, eyebrow and actions -- so
   re-padding horizontally would inset the band from text that is already inset, and at a narrow viewport
   the two paddings plus an unbreakable title pushed the PAGE sideways. Measured at 480px: 28px of
   document overflow, with no single element wider than the viewport. */
.pc-header {
  padding: 4px 0 0;
  background: var(--pc-surface);
  border-bottom: 1px solid var(--pc-hairline);
}
.pc-header-inner {
  max-width: var(--pc-content-max);
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* 12px, NOT THE HANDOFF'S 24. This console tests that the 51-row grids start ABOVE THE FOLD at a
     720px viewport, and the redesign's header is taller than the one it replaces -- an eyebrow, a 34px
     display title and a subtitle where there used to be a heading and a lede. Something had to give,
     and it is the padding under a band rather than the promise that an operator can see the first row
     of a 51-row table without scrolling. */
  padding-bottom: 12px;
}

.pc-crumb { font-size: var(--pc-fs-caption); color: var(--pc-secondary); }
.pc-crumb-sep { color: var(--pc-hairline); }
.pc-crumb-here { color: var(--pc-ink); font-weight: 600; }

/* The eyebrow: the group of work a screen belongs to, above its title. It takes the ACCENT, which is
   legal here and would not be on body text -- 10px/700 at .12em tracking is read as a marker, and the
   handoff's own rule is that the accent carries state through borders, fills and marks, never through
   prose. */
/* THE EYEBROW IS GREY WITH AN ACCENT BAR, not accent-coloured text. The handoff's mock sets it
   explicitly -- `color="#5B5B5B" accent-bar` -- and the distinction is the invariant this file is
   loudest about: --pc-accent is ACTION. A whole line of small caps painted in the action colour reads
   as something you can press, on the one element on the page that is purely a label. */
.pc-eyebrow {
  margin: 0;
  display: flex; align-items: center; gap: 10px;
  font-size: var(--pc-fs-label); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pc-secondary);
}
.pc-eyebrow::before {
  content: ""; flex: none; width: 20px; height: 2px; background: var(--pc-accent);
}

/* Title and its actions on one row. The actions wrap under the title rather than squeezing it, because a
   34px display face reflows badly and a button row does not. */
.pc-title-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--pc-gap-grid); flex-wrap: wrap;
}

/* A 34px display face and a one-word title are a min-content floor: "Retokenization" will not wrap, so at
   a narrow viewport it sets the width of everything above it. Allowed to break rather than to overflow --
   an awkward break is recoverable and a page that scrolls sideways is the thing this console promises it
   does not do. */
.pc-title {
  overflow-wrap: anywhere;
  margin: 0;
  font-family: var(--pc-font-display);
  font-weight: 300;
  font-size: var(--pc-fs-title);
  line-height: 1.1;
}

/* The subtitle is where a screen says what it can and cannot tell you. Never decorative. */
.pc-subtitle {
  margin: 0;
  max-width: var(--pc-prose-max);
  font-size: var(--pc-fs-lede);
  line-height: 1.6;
  color: var(--pc-secondary);
}

.pc-content { padding: 32px; background: var(--pc-page); }
.pc-content-inner {
  max-width: var(--pc-content-max);
  display: flex;
  flex-direction: column;
  gap: var(--pc-gap-block);
  animation: pc-fade var(--pc-motion) ease-out;
  /* MIN-WIDTH:0, for the reason .pc-main carries it: this is a grid/flex container whose default minimum
     is its CONTENT's, so a 7-column table inside it sets the page width instead of scrolling inside its
     own .table-scroll. The console's promise is that the TABLE scrolls sideways and the PAGE does not,
     and that promise is one declaration deep. */
  min-width: 0;
}

@keyframes pc-fade {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

/* ── Cards, tiles ───────────────────────────────────────────────────────── */

.pc-card {
  background: var(--pc-surface);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  overflow: hidden;
}

.pc-card-head {
  display: flex;
  align-items: center;
  gap: var(--pc-gap-control);
  flex-wrap: wrap;
  padding: 16px var(--pc-pad-card);
  border-bottom: 1px solid var(--pc-hairline);
}
.pc-card-head--wash { background: var(--pc-wash); }

.pc-card-title {
  margin: 0;
  font-family: var(--pc-font-display);
  font-weight: 300;
  font-size: var(--pc-fs-card-title);
  line-height: 1.1;
}

.pc-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--pc-gap-grid);
}

.pc-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: var(--pc-pad-card);
  background: var(--pc-surface);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
}

.pc-label {
  font-size: var(--pc-fs-label);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pc-secondary);
}

.pc-figure {
  font-family: var(--pc-font-display);
  font-weight: 300;
  font-size: 44px;
  line-height: 1;
}
.pc-figure--alarm { color: var(--pc-alarm); }

/* A failed read is a word standing in place of the figure, never a zero beside it. */
.pc-unread {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--pc-alarm);
}
.pc-unread::before {
  content: "";
  width: 3px;
  align-self: stretch;
  border-radius: 2px;
  background: currentColor;
}

.pc-count {
  padding: 2px 7px;
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-control);
  font-size: 11px;
  font-weight: 700;
  color: var(--pc-secondary);
}

/* A count assembled per brand is a floor. Say so next to it. */
.pc-floor { font-size: var(--pc-fs-caption); font-weight: 700; color: var(--pc-alarm); }

/* ── Tables ─────────────────────────────────────────────────────────────── */

.pc-scroll { overflow-x: auto; }
.pc-scroll--tall { max-height: 560px; overflow-y: auto; }

.pc-table { width: 100%; border-collapse: collapse; font-size: var(--pc-fs-base); }

/* The caption carries the row grain and the caveat. It is content, not a label. */
.pc-table caption {
  caption-side: bottom;
  text-align: left;
  padding: var(--pc-pad-cell);
  font-size: var(--pc-fs-caption);
  line-height: 1.5;
  color: var(--pc-secondary);
}

.pc-table thead tr { background: var(--pc-wash); border-bottom: 1px solid var(--pc-hairline); }

.pc-table th[scope="col"] {
  padding: var(--pc-pad-head);
  text-align: left;
  font-size: var(--pc-fs-label);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pc-secondary);
}
.pc-table th[scope="col"].is-sorted { color: var(--pc-ink); }
.pc-table th[scope="col"] .pc-ro {
  display: block;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--pc-disabled-ink);
}

.pc-table thead th { position: sticky; top: 0; background: var(--pc-wash); }
.pc-scroll:not(.pc-scroll--tall) .pc-table thead th { position: static; }

.pc-table tbody tr { border-bottom: 1px solid var(--pc-hairline); }
.pc-table tbody tr:hover { background: var(--pc-wash); }

.pc-table td,
.pc-table tbody th { padding: var(--pc-pad-cell); color: var(--pc-body); }
.pc-table tbody th { text-align: left; font-weight: 400; color: var(--pc-ink); }

.pc-nowrap { white-space: nowrap; }
.pc-num { text-align: right; font-variant-numeric: tabular-nums; }
.pc-wrap-cell { min-width: 300px; }
.pc-cell-stack { display: flex; flex-direction: column; gap: 2px; }
.pc-cell-inline { display: flex; align-items: baseline; gap: 8px; }
.pc-cell-actions { display: flex; gap: 8px; justify-content: flex-end; }

.pc-sub { font-size: var(--pc-fs-caption); color: var(--pc-secondary); }
.pc-em-dash { text-align: center; color: var(--pc-empty); }

/* Vaulted-at and points-at-today are different facts. This marks which one a row shows. */
.pc-qualifier { font-size: var(--pc-fs-caption); color: var(--pc-secondary); }
.pc-qualifier--changed { color: var(--pc-alarm); }

/* ── Controls ───────────────────────────────────────────────────────────── */

.pc-btn {
  font-family: inherit;
  font-size: var(--pc-fs-base);
  font-weight: 700;
  border-radius: var(--pc-radius-control);
  padding: 10px 18px;
  cursor: pointer;
}

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

.pc-btn-secondary { border: 1px solid var(--pc-hairline); background: var(--pc-surface); color: var(--pc-ink); }
.pc-btn-secondary:hover { background: var(--pc-wash); }

.pc-btn-outline-ink { border: 1px solid var(--pc-ink); background: var(--pc-surface); color: var(--pc-ink); }
.pc-btn-outline-ink:hover { background: var(--pc-wash); }

/* Destructive is an outline, never a fill — a filled red button gets clicked by accident. */
.pc-btn-destructive { border: 1.5px solid var(--pc-alarm); background: var(--pc-surface); color: var(--pc-alarm); }
.pc-btn-destructive:hover { background: var(--pc-alarm-wash); }

.pc-btn-text {
  border: 0;
  background: none;
  padding: 0;
  font-family: inherit;
  font-size: var(--pc-fs-base);
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
}
.pc-btn-text:hover { color: var(--pc-accent); }

.pc-btn-row { padding: 6px 12px; font-size: var(--pc-fs-caption); }
.pc-btn-icon { width: 30px; height: 30px; padding: 0; }

.pc-btn:disabled,
.pc-btn-text:disabled {
  background: var(--pc-hairline);
  border-color: var(--pc-hairline);
  color: var(--pc-secondary);
  cursor: not-allowed;
}
.pc-btn-secondary:disabled,
.pc-btn-destructive:disabled { background: var(--pc-surface); }

.pc-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pc-field > span { composes: pc-label; }

.pc-input,
.pc-select,
.pc-textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  font-family: inherit;
  font-size: var(--pc-fs-base);
  background: var(--pc-surface);
  border: 1.5px solid var(--pc-hairline);
  border-radius: var(--pc-radius-control);
}
.pc-input--lg { padding: 11px 14px; font-size: var(--pc-fs-lede); }
.pc-input--mono,
.pc-textarea--mono { font-family: var(--pc-font-mono); }
.pc-textarea { resize: vertical; }

.pc-input:focus,
.pc-select:focus,
.pc-textarea:focus { border-color: var(--pc-ink); outline: none; }

.pc-filterbar {
  display: flex;
  align-items: center;
  gap: var(--pc-gap-grid);
  flex-wrap: wrap;
  padding: 14px var(--pc-pad-card);
  background: var(--pc-wash);
  border-bottom: 1px solid var(--pc-hairline);
}
.pc-filtergrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--pc-gap-grid);
}

.pc-seg { display: flex; border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-control); overflow: hidden; }
.pc-seg-opt {
  border: 0;
  border-right: 1px solid var(--pc-hairline);
  padding: 7px 16px;
  font-family: inherit;
  font-size: var(--pc-fs-caption);
  background: var(--pc-surface);
  color: var(--pc-secondary);
  cursor: pointer;
}
.pc-seg-opt:last-child { border-right: 0; }
.pc-seg-opt[aria-pressed="true"] { background: var(--pc-ink); color: var(--pc-surface); font-weight: 700; }

.pc-check { display: flex; align-items: center; gap: 8px; border: 0; background: none; padding: 0; font-family: inherit; font-size: var(--pc-fs-base); font-weight: 700; cursor: pointer; }
.pc-check:hover { color: var(--pc-accent); }
.pc-check-box {
  width: 15px;
  height: 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--pc-ink);
  border-radius: var(--pc-radius-check);
  background: var(--pc-surface);
  font-size: 11px;
  line-height: 1;
}
.pc-check[aria-pressed="true"] .pc-check-box,
.pc-cell-check .pc-check-box--on { background: var(--pc-ink); color: var(--pc-surface); }

.pc-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 3px 10px;
  background: var(--pc-wash);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-pill);
}
.pc-pill-n { font-size: 11px; font-weight: 700; color: var(--pc-secondary); }

.pc-priority {
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--pc-radius-control);
  background: var(--pc-ink);
  color: var(--pc-surface);
  font-size: var(--pc-fs-caption);
  font-weight: 700;
}

/* ── Notices ────────────────────────────────────────────────────────────── */

/* One bar per screen, under the header. Never per row. */
.pc-notice {
  display: flex;
  align-items: center;
  gap: var(--pc-gap-grid);
  flex-wrap: wrap;
  padding: 14px 18px;
  background: var(--pc-surface);
  border: 1px solid var(--pc-hairline);
  border-left: 3px solid var(--pc-secondary);
  border-radius: var(--pc-radius-card);
}
.pc-notice-body { display: flex; flex-direction: column; gap: 3px; flex: 1 1 320px; min-width: 0; }
.pc-notice-kicker { composes: pc-label; }
.pc-notice-text { font-size: var(--pc-fs-base); line-height: 1.55; color: var(--pc-body); }

.pc-notice--locked { border-left-color: var(--pc-secondary); }
.pc-notice--unlocked { border-left-color: var(--pc-accent); }
.pc-notice--alarm { border-left-color: var(--pc-alarm); }

.pc-notice--unlocked .pc-notice-kicker { color: var(--pc-accent); }
.pc-notice--alarm .pc-notice-kicker { color: var(--pc-alarm); }

/* Caveats are load-bearing: they are the reason a number is not misread. */
.pc-caveats {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: var(--pc-pad-card);
  border-top: 1px solid var(--pc-hairline);
}
.pc-caveats p {
  margin: 0;
  max-width: var(--pc-prose-max);
  font-size: var(--pc-fs-base);
  line-height: 1.6;
  color: var(--pc-secondary);
}
.pc-caveats strong { color: var(--pc-ink); }
.pc-caveat--consequence { color: var(--pc-alarm) !important; }
.pc-caveat--consequence strong { color: var(--pc-alarm); }

.pc-dirty { font-size: var(--pc-fs-caption); font-weight: 700; color: var(--pc-ink); align-self: center; }
.pc-dirty--alarm { color: var(--pc-alarm); }

/* An empty result is not the same as an unreadable one. The copy inside says which. */
.pc-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 48px 24px;
}
.pc-empty-title { font-family: var(--pc-font-display); font-weight: 300; font-size: var(--pc-fs-card-title); }
.pc-empty-note {
  margin: 0;
  max-width: 460px;
  text-align: center;
  font-size: var(--pc-fs-base);
  line-height: 1.6;
  color: var(--pc-secondary);
}

.pc-pager {
  display: flex;
  align-items: center;
  gap: var(--pc-gap-control);
  padding: 14px var(--pc-pad-card);
  border-top: 1px solid var(--pc-hairline);
}
.pc-pager-pos { font-size: var(--pc-fs-caption); color: var(--pc-secondary); font-variant-numeric: tabular-nums; }

/* ── Verdict badges ─────────────────────────────────────────────────────── */

/* Color never carries the meaning on its own — the wording inside does. These only reinforce it,
 * and every theme re-picks all three so they stay mutually distinguishable. */
.pc-verdict {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: var(--pc-radius-pill);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}
.pc-verdict--good {
  color: var(--pc-verdict-good-fg);
  background: var(--pc-verdict-good-bg);
  border: 1px solid var(--pc-verdict-good-br);
}
.pc-verdict--warn {
  color: var(--pc-verdict-warn-fg);
  background: var(--pc-verdict-warn-bg);
  border: 1px solid var(--pc-verdict-warn-br);
}
.pc-verdict--flat {
  color: var(--pc-verdict-flat-fg);
  background: var(--pc-verdict-flat-bg);
  border: 1px solid var(--pc-verdict-flat-br);
}

/* ── Preferences ────────────────────────────────────────────────────────── */

.pc-pref-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--pc-gap-grid);
  padding: var(--pc-pad-card);
}

.pc-pref-option {
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
  padding: 16px;
  font-family: inherit;
  background: var(--pc-surface);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  cursor: pointer;
}
.pc-pref-option:hover { background: var(--pc-wash); }
.pc-pref-option[aria-pressed="true"] { border: 2px solid var(--pc-accent); }

.pc-pref-swatch {
  display: flex;
  height: 44px;
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-control);
  overflow: hidden;
}
.pc-pref-swatch > span { flex: 1 1 50%; }

.pc-pref-name { font-size: var(--pc-fs-lede); }
.pc-pref-option[aria-pressed="true"] .pc-pref-name { font-weight: 700; }
/* The word is the accessible label, so it takes ink — the 2px accent border carries the state
 * visually. The accent at 11px would not clear 4.5:1 on any of the light grounds. */
.pc-pref-selected { font-size: 11px; font-weight: 700; color: var(--pc-ink); }
.pc-pref-note { font-size: var(--pc-fs-caption); line-height: 1.5; color: var(--pc-secondary); }

/* Quick theme switch in the sidebar footer — changes the theme immediately, no save step. */
.pc-theme-quick {
  display: flex;
  border: 1px solid var(--pc-sidebar-line);
  border-radius: var(--pc-radius-control);
  overflow: hidden;
}
.pc-theme-quick button {
  flex: 1 1 0;
  min-width: 0;
  border: 0;
  border-right: 1px solid var(--pc-sidebar-line);
  padding: 6px 4px;
  font-family: inherit;
  font-size: 11px;
  background: transparent;
  color: var(--pc-sidebar-muted);
  cursor: pointer;
}
.pc-theme-quick button:last-child { border-right: 0; }
.pc-theme-quick button:hover { color: var(--pc-sidebar-ink); }
.pc-theme-quick button[aria-pressed="true"] {
  background: var(--pc-sidebar-active);
  color: var(--pc-sidebar-ink);
  font-weight: 700;
}

/* ============================================================================================================
   THE CONSOLE'S OWN COMPONENT VOCABULARY, GIVEN THE REDESIGN'S APPEARANCE.

   WHY THIS EXISTS RATHER THAN FIFTEEN REWRITTEN SCREENS. The redesign is a change of APPEARANCE over the
   same information: a card is still a card, a table is still a table, a verdict badge still says the same
   word. The screens already have a component vocabulary for all of it -- .section, .grid, .badge, .stats --
   and rewriting fifteen files to say .pc-card instead of .section would change ~300 spec selectors to
   produce the same pixels. What the handoff actually asks for is that every colour resolve through a token
   and every surface look like the system; both are satisfied by giving the existing classes the redesign's
   rules.

   WHERE A SCREEN'S STRUCTURE GENUINELY CHANGES, IT IS PORTED BY HAND. Retokenization became three tabs, a
   five-step rail and two risk-tagged cards, because the mockup rearranges what is on the screen rather than
   restyling it. This layer is for the other kind.

   EVERY RULE HERE SPENDS A --pc-* TOKEN, so these screens theme exactly as the ported ones do and the
   contrast gate keeps scoring the same values. No literals, as everywhere else in this file.
   ============================================================================================================ */

/* ---- cards. A section is the redesign's card: hairline, 8px radius, no shadow. */
.section {
  background: var(--pc-surface);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  box-shadow: none;
}
.section-head {
  padding: 16px var(--pc-pad-card);
  border-bottom: 1px solid var(--pc-hairline);
  background: var(--pc-surface);
}
.section-head h2 {
  font-family: var(--pc-font-display);
  font-weight: 300;
  font-size: var(--pc-fs-card-title);
  line-height: 1.15;
  letter-spacing: 0;
}
/* THE WRITE CARD IS STILL VISIBLY A DIFFERENT KIND OF THING. styles.css argues at length that this
   distinction is the one worth keeping, and the redesign agrees -- it is what the lock bar sits on. */
.section.write { border-color: var(--pc-hairline); }

/* ---- tables. The redesign's table is a hairline grid on a wash header, with generous cells. */
table.grid { border-collapse: collapse; width: 100%; }
table.grid thead th {
  background: var(--pc-wash);
  border-bottom: 1px solid var(--pc-hairline);
  color: var(--pc-secondary);
  font-size: var(--pc-fs-label);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}
table.grid td { border-bottom: 1px solid var(--pc-hairline); color: var(--pc-body); }
table.grid tbody tr:hover { background: var(--pc-wash); }
table.grid caption { background: var(--pc-wash); color: var(--pc-secondary); }

/* ---- verdict badges. Tonal, bordered, and re-picked per theme by the token layer -- which is what keeps
   them mutually distinguishable in high contrast without this rule knowing anything about themes. */
.badge {
  border-radius: var(--pc-radius-pill);
  border: 1px solid var(--pc-verdict-flat-br);
  background: var(--pc-verdict-flat-bg);
  color: var(--pc-verdict-flat-fg);
  font-size: var(--pc-fs-caption);
  font-weight: 600;
}
.badge.ok { border-color: var(--pc-verdict-good-br); background: var(--pc-verdict-good-bg); color: var(--pc-verdict-good-fg); }
.badge.warn { border-color: var(--pc-verdict-warn-br); background: var(--pc-verdict-warn-bg); color: var(--pc-verdict-warn-fg); }
.badge.danger { border-color: var(--pc-alarm); background: var(--pc-alarm-wash); color: var(--pc-alarm); }

/* ---- tiles. The dashboard's figures: a display face at 44px, over a 10px tracked label. */
.stat { background: var(--pc-surface); border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-card); }
.stat .label, .stat dt {
  font-size: var(--pc-fs-label); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--pc-secondary);
}
.stat .value, .stat dd {
  font-family: var(--pc-font-display); font-weight: 300; font-size: 44px; line-height: 1;
  color: var(--pc-ink);
}

/* ---- buttons. Primary is a fill; DESTRUCTIVE IS AN OUTLINE AND MUST STAY ONE -- the handoff's second
   invariant, and the reason is that a filled red button gets clicked by accident. */
.btn { border-radius: var(--pc-radius-control); font-size: var(--pc-fs-base); }
.btn.primary { background: var(--pc-accent); border-color: var(--pc-accent); color: var(--pc-on-accent); }
.btn.primary:hover { background: var(--pc-accent-press); border-color: var(--pc-accent-press); }
.btn.danger {
  background: transparent;
  border-color: var(--pc-alarm);
  color: var(--pc-alarm);
}
.btn.danger:hover { background: var(--pc-alarm-wash); }

/* ---- notes. Load-bearing prose, typed as content rather than as help text. */
.note { font-size: var(--pc-fs-base); line-height: 1.6; color: var(--pc-secondary); }
.note.danger { color: var(--pc-alarm); }
.note.warn { color: var(--pc-verdict-warn-fg); }

/* ---- fields. */
.field > label { font-size: var(--pc-fs-base); font-weight: 600; color: var(--pc-ink); }
.field .help { font-size: var(--pc-fs-caption); line-height: 1.5; color: var(--pc-secondary); }
input[type="text"], input[type="search"], input[type="number"], select, textarea {
  border-radius: var(--pc-radius-control);
  font-size: var(--pc-fs-base);
}

/* ---- the last link in the min-width chain ---------------------------------------------------------
   .pc-main and .pc-content-inner already carry min-width:0. A card and a table's scroller are the two
   remaining containers between them and a wide grid, and a flex/grid item's default minimum is its
   CONTENT's -- so either of them can still hand the page a width nobody asked for. The promise is that
   the TABLE scrolls sideways and the PAGE does not; it takes every link in the chain to keep it. */
.section, .table-scroll, .pc-card, .pc-scroll { min-width: 0; }
.table-scroll, .pc-scroll { overflow-x: auto; }

/* ---- the rail at narrow widths --------------------------------------------------------------------
   THE HANDOFF HAS NO NARROW STORY AND THIS CONSOLE TESTS FOR ONE. `.pc-sidebar` is `flex: 0 0 228px`,
   which is a floor: at a 480px viewport it takes 228 of them whatever else needs the room, and the
   content column is left competing for what is left. Two specs measure exactly that -- the 7-column
   account grid and the 7-column card-type matrix -- and both assert the PAGE does not scroll sideways.
   No amount of min-width:0 downstream fixes a fixed-width sibling.

   SO THE RAIL STOPS BEING A COLUMN AND BECOMES A STRIP. Below 900px the shell stacks, the rail spans the
   width, and its nav scrolls horizontally inside itself -- everything stays reachable, which a
   display:none rail would not, and nothing competes with the content for width. The brandmark, the
   search trigger and the theme block stay where they are in the source, so nothing about focus order or
   the skip link changes.

   900px RATHER THAN A PHONE WIDTH: the wizard's two columns collapse at 900 as well, so the layout has
   one breakpoint rather than two that can disagree. */
@media (max-width: 900px) {
  .pc { flex-direction: column; }

  .pc-sidebar {
    /* STACKED, so the rail is a strip above the content rather than a column beside it -- and a sticky
       100vh strip there would cover the screen. */
    position: static;
    height: auto;
    overflow: visible;
    flex: none;
    width: auto;
    max-width: 100%;
    min-height: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pc-gap-control);
    padding-bottom: 8px;
  }

  /* The nav is the part that has to give: a row that scrolls rather than a column that is 228px wide. */
  .pc-nav {
    flex: 1 1 100%;
    /* min-width:0 AND max-width:100%. A scrolling flex item still has min-width:auto by default, so the
       twelve nowrap destinations set its width and the strip becomes 1500px wide -- which is worse than
       the fixed column it replaced. Measured: the page went from 28px of overflow to 1517px. */
    min-width: 0;
    max-width: 100%;
    flex-direction: row;
    overflow-x: auto;
    gap: 4px;
    padding: 0 8px 4px;
  }
  .pc-nav-item { white-space: nowrap; }
  /* The group labels are a vertical device. In a row they would sit between entries as loose words. */
  .pc-nav-group { display: none; }

  .pc-brandmark { padding: 12px 16px; }
  .pc-cmd-trigger { margin: 0 12px; }
  .pc-theme-block { margin-top: 0; }
  /* The footnote is the least useful thing on a narrow screen and the longest. */
  .pc-sidebar-foot { display: none; }

  .pc-content { padding: 20px 16px; }
}

/* The template offer, directly under the operation it belongs to. */
.pc-templatebar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--pc-gap-grid);
  flex-wrap: wrap;
  padding: var(--pc-pad-card);
  border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-card);
  background: var(--pc-wash);
}
.pc-templatebar-title { margin: 0; font-size: var(--pc-fs-base); font-weight: 600; color: var(--pc-ink); }
.pc-templatebar-note {
  margin: 2px 0 0; font-size: var(--pc-fs-caption); line-height: 1.5; color: var(--pc-secondary);
  max-width: var(--pc-prose-max);
}

/* The sign-in card's wordmark. Bounded by WIDTH with height:auto, so the aspect ratio is the file's and
   not this rule's -- a logo squashed by a hardcoded height is the most conspicuous way to get one wrong. */
.signin-wordmark { display: block; width: 168px; height: auto; }

/* ── The retokenization wizard ────────────────────────────────────────────────────────────────────
 *
 * ONE STEP AT A TIME. The rail is five REACHABLE buttons rather than a numbered list, because a step
 * you have finished is one you may go back to -- which is the only thing that makes a wizard bearable.
 * Forward is refused by `disabled`, so the rail cannot be used to skip the dry run and land on Apply.
 *
 * Every value here is the handoff's: 8px card radius, 4px control radius, 24px panel padding, 20px
 * stack, 1px hairlines, the display face at the card-title size. Nothing is a literal -- the one rule
 * this file exists to keep.
 */

/* The rail follows you down a long panel: at step 3 the counts push the footer well below the fold,
   and a rail that scrolled away would take the only way back with it. */
.pc-wizard-rail { position: sticky; top: var(--pc-gap-grid); align-self: start; }
.pc-wizard-body { min-width: 0; display: flex; flex-direction: column; gap: var(--pc-gap-block); }

.pc-steps { list-style: none; margin: 0; padding: 0; }
.pc-steps > li { display: block; }

/* A BUTTON, so it is reachable by keyboard and announces itself as an action. `text-align: left` and
   the font inherit are the two resets a <button> always needs when it holds prose. */
.pc-step {
  width: 100%;
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: var(--pc-gap-control);
  align-items: start;
  text-align: left;
  padding: 14px var(--pc-gap-grid);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  background: transparent;
  font-family: inherit;
  cursor: pointer;
  transition: background var(--pc-motion) ease-out, border-color var(--pc-motion) ease-out;
}
.pc-step:hover:not(:disabled) { background: var(--pc-surface); }
.pc-step:disabled { cursor: not-allowed; }
.pc-step:disabled .pc-step-title { color: var(--pc-disabled-ink); }
.pc-step--current { border-color: var(--pc-ink); background: var(--pc-surface); }

.pc-step-mark {
  width: 26px;
  height: 26px;
  border-radius: var(--pc-radius-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--pc-fs-caption);
  font-weight: 700;
  background: var(--pc-surface);
  color: var(--pc-secondary);
  border: 1px solid var(--pc-hairline);
}
.pc-step--current .pc-step-mark {
  background: var(--pc-ink);
  color: var(--pc-surface);
  border-color: var(--pc-ink);
}
.pc-step--done .pc-step-mark {
  background: var(--pc-verdict-good-fg);
  color: var(--pc-surface);
  border-color: var(--pc-verdict-good-fg);
}

/* ── One panel ─────────────────────────────────────────────────────────────────────────────────── */

.pc-panel {
  background: var(--pc-surface);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  padding: var(--pc-gap-block);
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
  animation: pc-fade var(--pc-motion) ease-out;
}
/* THE APPLY PANEL IS RINGED IN THE ALARM COLOUR, and it is the only panel in the console that is.
   --pc-alarm is CONSEQUENCE: this is the step that writes rows nothing can revoke. */
.pc-panel--alarm { border-color: var(--pc-alarm); }

.pc-panel > form { display: flex; flex-direction: column; gap: 20px; }

.pc-panelhead { display: flex; flex-direction: column; gap: 6px; }
.pc-panel-lede {
  margin: 0;
  max-width: var(--pc-prose-max);
  font-size: var(--pc-fs-lede);
  line-height: 1.5;
  color: var(--pc-secondary);
  text-wrap: pretty;
}

.pc-kicker {
  margin: 0;
  font-size: var(--pc-fs-caption);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pc-secondary);
}
.pc-kicker--alarm { color: var(--pc-alarm); }
.pc-kicker--good { color: var(--pc-verdict-good-fg); }

.pc-panelfoot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pc-gap-control);
  flex-wrap: wrap;
  border-top: 1px solid var(--pc-hairline);
  padding-top: 20px;
}
/* One step offers two forward actions (skip, or build). They travel together on the right. */
.pc-panelfoot-group { display: flex; align-items: center; gap: var(--pc-gap-control); flex-wrap: wrap; }
/* A panel whose footer holds only a forward action still puts it on the right. */
.pc-panelfoot > :only-child { margin-left: auto; }

.pc-field--prose { max-width: 520px; }

/* ── The drop zone ─────────────────────────────────────────────────────────────────────────────── */

.pc-drop {
  border: 1px dashed var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  background: var(--pc-wash);
  padding: 28px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
  transition: border-color var(--pc-motion) ease-out, background var(--pc-motion) ease-out;
}
.pc-drop--over { border-color: var(--pc-accent); background: var(--pc-surface); }
.pc-drop-title { margin: 0; font-size: var(--pc-fs-lede); font-weight: 700; color: var(--pc-ink); }
.pc-drop-meta { margin: 0; font-size: var(--pc-fs-caption); color: var(--pc-secondary); }

/* The file input is driven through its own <label>, so the control reads as a button while the input
   stays the real, focusable, test-drivable element. It is CLIPPED rather than `display: none`, which
   would take it out of the accessibility tree and off the keyboard. */
.pc-drop-pick {
  margin-top: 4px;
  display: inline-flex;
  align-items: center;
  padding: 8px 14px;
  border: 1px solid var(--pc-ink);
  border-radius: var(--pc-radius-control);
  background: var(--pc-surface);
  font-size: var(--pc-fs-base);
  font-weight: 700;
  color: var(--pc-ink);
  cursor: pointer;
}
.pc-drop-pick:hover { background: var(--pc-wash); }
.pc-drop-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.pc-drop-input:focus-visible + .pc-drop-pick,
.pc-drop:focus-within .pc-drop-pick { outline: 2px solid var(--pc-focus); outline-offset: 2px; }

/* ── The dry run ───────────────────────────────────────────────────────────────────────────────── */

.pc-runbar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: var(--pc-gap-grid);
  background: var(--pc-verdict-good-bg);
  border: 1px solid var(--pc-verdict-good-br);
  border-radius: var(--pc-radius-card);
}
.pc-runbar-text {
  margin: 0;
  flex: 1 1 260px;
  min-width: 0;
  font-size: var(--pc-fs-base);
  line-height: 1.5;
  color: var(--pc-body);
}

.pc-progress { display: flex; flex-direction: column; gap: 8px; }
.pc-progress-text { margin: 0; font-size: var(--pc-fs-base); font-weight: 600; color: var(--pc-ink); }
.pc-progress-track {
  height: 4px;
  background: var(--pc-hairline);
  border-radius: var(--pc-radius-control);
  overflow: hidden;
}
.pc-progress-bar { width: 40%; height: 100%; background: var(--pc-accent); animation: pc-bar 900ms ease-out infinite; }
@keyframes pc-bar { from { transform: translateX(-100%); } to { transform: translateX(240%); } }
/* An indeterminate bar that never stops is the worst offender under reduced motion, so it holds still
   and reports its state in the text above it instead. */
@media (prefers-reduced-motion: reduce) { .pc-progress-bar { animation: none; width: 100%; } }
[data-pc-reduced-motion="true"] .pc-progress-bar { animation: none; width: 100%; }

.pc-checkresult { display: flex; flex-direction: column; gap: var(--pc-gap-grid); }

.pc-statstrip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--pc-gap-grid);
  border: 1px solid var(--pc-hairline);
  border-radius: var(--pc-radius-card);
  padding: var(--pc-pad-card);
}
.pc-statblock { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* The figure is the display face, as every other headline number in this console is. */
.pc-statblock-num {
  margin: 0;
  font-family: var(--pc-font-display);
  font-weight: 300;
  font-size: 44px;
  line-height: 1;
  color: var(--pc-ink);
  font-variant-numeric: tabular-nums;
}
.pc-statblock-label {
  margin: 0;
  font-size: var(--pc-fs-label);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pc-secondary);
}

.pc-report { border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-card); overflow: hidden; }
.pc-report-head {
  display: flex;
  align-items: center;
  gap: var(--pc-gap-control);
  flex-wrap: wrap;
  padding: 12px var(--pc-gap-grid);
  background: var(--pc-wash);
  border-bottom: 1px solid var(--pc-hairline);
}
.pc-report-title { font-size: var(--pc-fs-caption); font-weight: 700; color: var(--pc-ink); }
.pc-report-link { margin-left: auto; font-size: var(--pc-fs-caption); font-weight: 700; }
.pc-report-note {
  margin: 0;
  padding: 12px var(--pc-gap-grid);
  font-size: var(--pc-fs-caption);
  line-height: 1.5;
  color: var(--pc-secondary);
}

/* ── The apply gate ────────────────────────────────────────────────────────────────────────────── */

.pc-confirm { border: 1px solid var(--pc-hairline); border-radius: var(--pc-radius-card); overflow: hidden; }
.pc-confirm-row {
  display: flex;
  gap: var(--pc-gap-control);
  padding: 13px var(--pc-gap-grid);
  border-bottom: 1px solid var(--pc-hairline);
  font-size: var(--pc-fs-base);
}
.pc-confirm-row:last-child { border-bottom: 0; }
.pc-confirm-key { flex: 0 0 130px; color: var(--pc-secondary); }
.pc-confirm-val { font-weight: 700; min-width: 0; overflow-wrap: anywhere; color: var(--pc-ink); }

.pc-field--gate { max-width: 420px; }
.pc-input--gate { letter-spacing: 0.12em; }
.pc-input--gate:focus { border-color: var(--pc-alarm); outline-color: var(--pc-alarm); }

/* ── Done, and the consequence note ────────────────────────────────────────────────────────────── */

.pc-done {
  padding: var(--pc-pad-card);
  background: var(--pc-verdict-good-bg);
  border: 1px solid var(--pc-verdict-good-br);
  border-radius: var(--pc-radius-card);
  display: flex;
  flex-direction: column;
  gap: 6px;
  animation: pc-fade var(--pc-motion) ease-out;
}
.pc-done-title { margin: 0; font-size: 15px; font-weight: 700; color: var(--pc-verdict-good-fg); }
.pc-done-body { margin: 0; font-size: var(--pc-fs-base); line-height: 1.5; color: var(--pc-body); }

/* The left-barred note that stands wherever LIVE VAULT TOKENS are about to move. It is a bar rather
   than a filled wash on purpose: a filled alarm block beside a filled success block reads as two
   verdicts about the same thing. */
.pc-guard {
  display: flex;
  gap: var(--pc-gap-control);
  padding: var(--pc-gap-grid);
  border: 1px solid var(--pc-alarm);
  border-radius: var(--pc-radius-card);
  background: var(--pc-surface);
}
.pc-guard-bar { flex: 0 0 4px; border-radius: 2px; background: var(--pc-alarm); }
.pc-guard-text { margin: 0; font-size: var(--pc-fs-base); line-height: 1.5; color: var(--pc-body); }

/* ── Run history ───────────────────────────────────────────────────────────────────────────────── */

.pc-history { display: flex; flex-direction: column; gap: var(--pc-gap-grid); }
.pc-history-head { display: flex; align-items: center; gap: var(--pc-gap-control); flex-wrap: wrap; }
.pc-history-filter { margin-left: auto; width: auto; min-width: 240px; }
@media (max-width: 700px) { .pc-history-filter { margin-left: 0; width: 100%; } }

.pc-prose { display: flex; flex-direction: column; gap: 20px; max-width: 760px; }

/* A run reference is long and two of them can differ only in a trailing suffix, so it is rendered
   WHOLE. `text-overflow: ellipsis` here would paint two different runs as the same string -- which is
   how the eight-column table this replaced lost them. */
.pc-runname { overflow-wrap: anywhere; white-space: normal; text-overflow: clip; }
