/* PDRA app-level styles.
 *
 * Project-specific layout ONLY. The canonical styleguide (tokens.css, base.css,
 * components.css from https://styles.thusdigital.com) is loaded first and is
 * sacrosanct - this sheet loads AFTER it and only positions/composes the app.
 *
 * TOKEN DISCIPLINE (canon-compliance sweep, 2026-08-17): every value here
 * references a REAL styleguide token (see vendor/tokens.css) - the --s-* spacing
 * grid, --r-* radii, --c-* colours, --ff-* families. There are NO --fs-*,
 * --c-text*, --c-surface*, --c-border, --c-focus, --c-on-primary, --c-success,
 * --c-info, --c-warning or --c-danger tokens in the styleguide, so those
 * (previously referenced with hardcoded fallbacks that always rendered) are
 * gone. Font sizes - for which the styleguide defines no tokens - are literal.
 * The app NEVER re-skins .btn / .btn-primary: canonical .btn + its :hover /
 * :focus states from components.css render verbatim everywhere. App button
 * rules touch layout only (width / spacing), never background / border / colour.
 */

/* League Spartan optical correction (Seth ruling, 2026-08-19 gallery session):
   the PD brand face sits high in canon .btn's flex-centred line; nudge the
   glyphs down. Font-specific app-skin adjustment - layout-only, within the
   override layer's remit (not a canon divergence). */
.btn {
  padding-top: 4px;
  text-transform: uppercase;
}

/* A touch of tracking on the filled variants (all-caps benefits from air;
   px not em per the grid ruling - iterate the value by eye). */
.btn-primary,
.btn-secondary,
.btn-amber {
  letter-spacing: 0.5px;
}

/* Large buttons at app scale (Seth-specified 2026-08-19; canon .btn-lg is
   48px / 20px / lh 1). */
.btn-lg {
  font-size: 24px;
  line-height: 24px;
  height: 52px;
}

/* Ghost buttons stay quiet: sentence case, no tracking (Seth ruling -
   tracking never applied to ghost; this exempts it from the .btn caps). */
.btn-ghost {
  text-transform: none;
}

/* Auth-slot ghosts only (page-header account chrome) - Seth-specified
   experiment 2026-08-19: tighter horizontal padding, weight up, and a
   2px downshift via transform (padding nudge zeroed in favour of it). */
.pdra-auth .btn-ghost {
  /* margin-top: 2px; */
  font-weight: 600;
  padding-left: 12px;
  padding-right: 12px;
  /* transform: translateY(2px); */
  /* background-color: pink; */ /* DEBUG tracer - selector proven 2026-08-19 */
  height: 32px; /* Seth-specified - compact header chrome */
}

/* ---- PD brand skin (app-specific token override) ------------------------
   Planning Direct brand applied at TOKEN level per the canonical protocol:
   TD styleguide stays the CORE (vendor CSS untouched); this block re-values
   the core tokens so every canonical component picks up PD brand automatically.
   Source of truth: ~/Developer/pd-web-styleguide.html ("Planning Direct - Web
   Styleguide (Proposed)", PD Brand Document V1.0). League Spartan is loaded
   in index.html. Deeper component skinning (e.g. PD's rich-green primary
   buttons) lands with the PD brand-assets pass. */
:root {
  /* brand */
  --c-primary:   #196131;  /* PD dark green - brand PRIMARY */
  --c-secondary: #00416A;  /* PD navy - SECONDARY in PD web roles */
  --c-tertiary:  #82B29B;  /* PD pale green */
  /* surfaces + ink */
  --c-bg:        #F6FCF9;  /* PD chalk */
  --c-body:      #15171C;  /* PD ink */
  --c-mid:       #5F656D;  /* PD grey-700 - secondary text */
  --c-invert-1:  #C8CCD1;  /* PD grey-300 */
  --c-invert-2:  #E3E5E8;  /* PD grey-200 */
  /* status (PD success on-brand; warning/error PROPOSED in the PD guide) */
  --c-red:        #C0392B;
  --c-red-fade:   #F7E3E1;
  --c-amber:      #E0991E;
  --c-amber-fade: #FBEED7;
  --c-green:      #53B478;  /* PD rich green */
  --c-green-fade: #E4F0E3;
  /* type */
  --ff-display: 'League Spartan', system-ui, -apple-system, sans-serif;
  --ff-body:    'League Spartan', system-ui, -apple-system, sans-serif;
}

/* ---- content + views ----------------------------------------------------
   Per the architect ruling the .pdra-view sections sit DIRECTLY in <body> with
   NO app wrapper. Horizontal centring of each card is handled by the .pdra-view
   rule below; the fixed-chrome offset + side padding come from the vendored
   base.css body rule, so nothing here fights it. The busy state (set by app.js
   during API calls) is a body-level state attribute, not a structural wrapper. */

/* View headings are announced via the aria-live region, never programmatically
   focused (browser focus-highlight overlays ring any focused element regardless
   of page CSS). tabindex="-1" elements are unreachable by Tab, so this ring only
   ever appears from script focus - suppress it; keyboard focus rings elsewhere
   are untouched (core :focus-visible rules still apply). */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible {
  outline: none;
}

/* Visually-hidden utility for the aria-live view announcer. App-prefixed:
   the styleguide has no visually-hidden pattern yet - flagged as a canon
   candidate; swap to the canonical class when it lands. */
.pdra-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

body[data-busy="1"] {
  cursor: progress;
}

body[data-busy="1"] .btn {
  pointer-events: none;
  opacity: 0.6;
}

/* PD header lockup in the canonical brand slot (image is 2x for retina).
   72px lockup needs headroom beyond the canonical 56px header, so the
   chrome height token is re-valued here - vendored base.css body padding
   consumes the var, so the layout reflows without touching core CSS. */
:root {
  --site-header-height: 88px;
}

/* Fixed-size lockup: flex-shrink 0 on link + img stops the logo being
   squashed when the header row tightens (Seth, 2026-08-17). */
.brand {
  flex-shrink: 0;
}

.brand img {
  display: block;
  height: 72px;
  width: auto;
  flex-shrink: 0;
}

/* Product descriptor beside the PD lockup (the app name "PDRA" is a working
   title and never shown to users). Pushed to the RIGHT edge of the header
   cluster (Seth, 2026-08-17): with the header Sign-in gone, the tag takes that
   side. margin-left:auto on existing markup - no new wrapper. */
/* PDRA has no header nav, but canon's fixed-width rule puts margin-left:auto
   on .site-nav-links - two auto margins in one flex row split the free space,
   stranding the tag mid-header at every width. Neutralise the nav's auto so
   the tag's is the only one and it anchors hard right. */
body.fixed-width .site-nav-links,
.site-header .site-nav-links {
  margin-left: 0;
}

/* Empty shell slots still occupy flex positions and each drags a --s-5 gap,
   pushing the tag ~48px off the right edge. Collapse them until they have
   content (nav links poured / signed-in auth chrome rendered). */
.site-nav-links:empty {
  display: none;
}

.header-tools:empty {
  display: none;
}

/* Signed-in account chrome lives in the page-header (Seth, 2026-08-17).
   Canon fixed-width centres page-header content (nav-pill assumption);
   account chrome reads better right-anchored - app-level override. */
body.fixed-width .page-header-inner {
  justify-content: flex-end;
}

.page-header-inner .pdra-auth {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  /* Span the header column so the Admin link's auto margin has room to push
     it to the left edge while the account actions stay right-anchored. */
  flex: 1 1 auto;
}

/* Admin link sits at the LEFT of the account bar (Seth, 2026-09-02); the
   rest of the chrome stays right-anchored. Layout-only override, the link
   itself is canon .btn.btn-ghost. */
.pdra-auth .pdra-auth-admin {
  margin-right: auto;
}

/* Server-rendered admin chrome groups its left links (Admin, and Usage for
   the back-door account) so the auto margin sits on the group. */
.pdra-auth .pdra-auth-left {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-right: auto;
}

.pdra-auth .pdra-auth-left .pdra-auth-admin {
  margin-right: 0;
}

/* Narrow viewports: the signed-in name is purely informational - hide it
   outright rather than manage long-name wrap pathology (Seth ruling
   2026-08-21, replacing the 2026-08-20 wrap machinery). Users know who
   they are; the two nav actions keep the bar. */
@media (max-width: 520px) {
  .pdra-auth .pdra-auth-user {
    display: none;
  }
}

.page-header-inner .pdra-auth:empty {
  display: none;
}

.pdra-brand-tag {
  margin-left: auto;
  color: var(--c-secondary);
  font-weight: 500;

  letter-spacing: 0.3px;
  white-space: nowrap;
}

/* Small screens: let the long descriptor wrap (right-aligned) instead of
   forcing the logo to squash. */
@media (max-width: 800px) {
  .pdra-brand-tag {
    white-space: normal;
    text-align: right;

    max-width: 224px;
  }
}

/* Very narrow screens (old-iPhone class): the tag was crushed off-screen by
   the fixed-size logo - wrap it to a full second row beneath the lockup.
   The chrome height var grows in step so the fixed header and the body's
   content offset reflow together (Seth 2026-08-20). AFTER the base rule so
   the margin-left/max-width overrides win at equal specificity. */
@media (max-width: 520px) {
  :root {
    --site-header-height: 126px; /* +8px air beneath the stacked tag (Seth) */
  }

  .site-header-inner {
    flex-wrap: wrap;
    row-gap: 0;
  }

  .pdra-brand-tag {
    margin-left: 0;
    flex-basis: 100%;
    max-width: none;
    text-align: left;
    line-height: 1.2;
  }
}

.pdra-view {
  width: 100%;
  display: flex;
  justify-content: center;
  margin-top: clamp(8px, 3vh, 40px); /* halved (Seth 2026-08-20 - was 16/6vh/80) */
  margin-bottom: var(--s-8); /* breathing room on every view - CTAs off the browser chrome (Seth) */
}

.pdra-view[hidden] {
  display: none;
}

.pdra-card {
  max-width: 544px;
  width: 100%;
  text-align: center;
}

.pdra-card-wide {
  max-width: 700px; /* Seth-specified 2026-08-19 (was 42rem -> 672px) */
  text-align: left;
}

/* ---- landing (hero + trust + three-step + graphic) ---------------------- */
.pdra-landing {
  max-width: 640px;
  width: 100%;
  text-align: center;
  /* bottom breathing room now app-wide on .pdra-view */
}

.pdra-hero-title {
  margin: 0 0 var(--s-4);
  font-family: var(--ff-display);

  color: var(--c-body);
}

.pdra-hero-sub {
  margin: 0 auto var(--s-5);
  max-width: 544px;

  color: var(--c-mid);
}

/* Graphic slot - asset arrives post-selection. Collapses cleanly when empty
   (the :empty selector removes it from flow entirely). */
.pdra-hero-graphic {
  margin: 0 auto var(--s-5);
  max-width: 544px;
}

.pdra-hero-graphic:empty {
  display: none;
}

.pdra-hero-graphic img {
  max-width: 100%;
  height: auto;
  border-radius: var(--r-md);
}

/* Three-step row. Uses the canonical spacing grid; wraps to a column on
   narrow viewports (see the responsive block). */
.pdra-steps {
  list-style: none;
  margin: 0 0 var(--s-5);
  padding: 0;
  display: flex;
  gap: var(--s-4);
  justify-content: center;
}

.pdra-step {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  max-width: 192px;
}

.pdra-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--s-6);
  height: var(--s-6);
  flex-shrink: 0; /* wrapping label text must never squash the bubble (Seth 2026-08-20) */
  border-radius: var(--r-pill);
  background: var(--c-primary);
  color: white;
  font-weight: 600;

  /* League Spartan's numerals ride high in their em box - geometric flex
     centring leaves them visibly above optical centre. Font-specific nudge. */

  padding-top: 2.1px;
}

.pdra-step-label {

  color: var(--c-body);
}

/* Trust line - quiet, small, not planning advice / no compliance certification. */
.pdra-trust {
  margin: 0 auto var(--s-5);
  max-width: 544px;

  color: var(--c-mid);
}

.pdra-landing-cta {
  margin-top: var(--s-2);
}

/* ---- generic lede (used on error/other simple views) ------------------- */
.pdra-eyebrow {
  margin: 0 0 var(--s-2);
  text-transform: uppercase;
  letter-spacing: 1px;

  color: var(--c-mid);
}

.pdra-lede {
  margin: 0 auto var(--s-3);
  max-width: 480px;
  color: var(--c-mid);
}
/* ---- buttons (layout composition only; canon skins them) ----------------
   These rules NEVER set background / border / colour - they only size and
   space. The canonical .btn / .btn-primary / .btn-outline (+ :hover, :focus)
   from components.css render the skin + states verbatim. */
.pdra-start,
.pdra-restart,
.pdra-fresh,
.pdra-retry,
.pdra-landing-cta {
  margin-top: var(--s-3);
}

/* Answer options - stacked list. Width comes EXPLICITLY from .btn-full on the
   buttons (Seth ruling 2026-08-19: the correct mechanism); align-items
   flex-start kills flex-column's implicit stretch so nothing is silently
   full-width without the class. */
.pdra-answers {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-2);
}

/* Subtle marker for the known blank-label authoring gap. */
.pdra-answer[data-authoring-gap="true"] {
  border-style: dashed;
}

.pdra-gap-marker {
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--c-mid);
  opacity: 0.8;
}

/* ---- wizard ------------------------------------------------------------- */
.pdra-progress {
  margin: 0 0 var(--s-3);

  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--c-mid);
}

/* Layout only - skin is canon .error-msg (canon reset item 3b, 2026-08-19). */
.pdra-inline-note {
  margin: 0 0 var(--s-3);
}

.pdra-question {
  margin-bottom: var(--s-5);
}

.pdra-question-text {
  margin: 0 0 var(--s-4);

  color: var(--c-body);
}

/* Chart bold emphasis inside question headings (Seth 2026-08-20): canon
   sets headings AND strong at weight 500, so <strong> was invisible in
   the h2 - lift it to 700 there. Trail/body text needs nothing (400 vs
   500 already reads). */
.pdra-question-text strong {
  font-weight: 700;
}

/* Media slot - collapses entirely when empty (the [hidden] attribute). */
.pdra-media {
  margin: 0 0 var(--s-4);
}

.pdra-media[hidden] {
  display: none;
}

.pdra-media-img {
  max-width: 100%;
  height: auto;
  border-radius: var(--r-md);
}

.pdra-media-caption {
  margin: var(--s-2) 0 0;

  color: var(--c-mid);
}

/* Help expander (styleguide details/accordion pattern). */
.pdra-help {
  margin: 0 0 var(--s-4);
}

.pdra-help-summary {
  cursor: pointer;
  color: var(--c-primary);
  font-weight: 600;
}

.pdra-help-body {
  margin: var(--s-2) 0 0;
  color: var(--c-mid);
}

/* ---- clause reference (admin-only, hidden by default) ------------------- */
.admin-only {
  display: none;
}

html[data-admin="1"] .admin-only {
  display: inline-block;
}

.pdra-clause {
  margin: 0 0 var(--s-2);
  padding: 1.5px var(--s-2);
  border-radius: var(--r-sm);
  background: var(--c-invert-2);
  color: var(--c-mid);
  font-family: var(--ff-mono);

  letter-spacing: 0.2px;
}

/* ---- trail (answers-so-far, Seth vision 2026-08-20) ---------------------
   Canon .disclose summary made a flex row so the divider line fills to the
   right (OptimAI .section-header/.section-line reference). The "fake table"
   is a column of square-edged white cells with shared 1px borders - divs
   only, no table markup. Layout rules here; skin stays canon/token. */
.pdra-trail {
  margin: var(--s-5) 0 var(--s-4);
}

.pdra-trail > summary.pdra-trail-summary {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--c-primary);
  text-transform: uppercase;
}

.pdra-trail > summary.pdra-trail-summary:hover {
  color: var(--c-secondary);
}

/* Arrow + divider follow the text (canon's triangle is an explicit
   --c-secondary border-left and never tracks the label colour). */
.pdra-trail > summary.pdra-trail-summary::before {
  border-left-color: var(--c-primary);
}

.pdra-trail > summary.pdra-trail-summary:hover::before {
  border-left-color: var(--c-secondary);
}

.pdra-trail > summary.pdra-trail-summary:hover .pdra-trail-line {
  background: var(--c-secondary);
}

.pdra-trail-line {
  flex: 1;
  height: 2px;
  background: var(--c-primary);
}

.pdra-trail-table {
  display: flex;
  flex-direction: column;
  margin-top: var(--s-3);
}

/* No fill (Seth 2026-08-20) - the table is line-work; cells show their
   container through (card white on the outcome page, page chalk in the
   wizard disclose). Also makes corner-overpaint impossible. */
.pdra-trail-cell {
  border: 1px solid var(--c-invert-1);
  padding: var(--s-3);
}

.pdra-trail-cell + .pdra-trail-cell {
  border-top: 0; /* adjacent cells share one 1px rule, table-style */
}

.pdra-trail-q {
  color: var(--c-body);
}

/* Answer line: label + value left, Change button (read) or select +
   cancel/commit icons (edit) pushed right. */
.pdra-trail-a {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-1);
  color: var(--c-mid);
}

.pdra-trail-a-value {
  color: var(--c-body);
  font-weight: 600;
}

.pdra-trail-change {
  margin-left: auto;
}

.pdra-trail-edit-actions {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

/* Cancel/commit indicators at canon's editable-table in-cell size (22px -
   the .table.editable bump; default .circle is 16px and reads tiny here). */
.pdra-trail-edit-actions .cell-action .tick.circle,
.pdra-trail-edit-actions .cell-action .cross.circle {
  width: 22px;
  height: 22px;
  font-size: 22px;
}

.pdra-trail-empty {
  margin: 0;
  color: var(--c-mid);
}

/* Outcome card (Seth 2026-08-20): answers table bleeds to the card edges
   (mirrors the header band's negative horizontal margins; card padding
   --s-4) with side borders dropped - top/bottom rules only, full width.
   Cell horizontal padding matches the card's own (--s-4) so question text
   aligns with the address line; the card's bottom padding goes and the
   last cell drops its border - the card's own edge closes the table. */
.pdra-outcome-card {
  padding-bottom: 0;
}

.pdra-outcome-card .pdra-trail-table {
  margin-left: calc(-1 * var(--s-4));
  margin-right: calc(-1 * var(--s-4));
}

.pdra-outcome-card .pdra-trail-cell {
  border-left: 0;
  border-right: 0;
  padding-left: var(--s-4);
  padding-right: var(--s-4);
}

.pdra-outcome-card .pdra-trail-cell:last-child {
  border-bottom: 0;
}

/* Verdict badge text sit fix - same League Spartan hack as the hub status
   flag's label span. White restated because canon base.css's [class$="-label"]
   catch-all recolours any *-label class (the exact pdra-flag-label trap). */
.card-header .badge .pdra-badge-label,
.pdra-outcome-head .badge .pdra-badge-label {
  transform: translateY(2px);
  color: white;
}

.pdra-back {
  margin-top: var(--s-2);
}

/* ---- resume link -------------------------------------------------------- */
/* Layout only - skin is canon .notice.neutral (canon reset item 5, 2026-08-19). */
.pdra-resume {
  margin-top: var(--s-4);
}

.pdra-resume-label {
  margin: 0 0 var(--s-2);

  font-weight: 600;
  color: var(--c-body);
}

.pdra-resume-row {
  display: flex;
  gap: var(--s-2);
}

/* Layout only - the skin is canon .input (composed in markup, 2026-08-19
   canon reset). */
.pdra-resume-input {
  flex: 1 1 auto;
  min-width: 0;
}

/* Copy button alignment beside the taller input (Seth-specified). */
.pdra-resume-row .btn {
  margin-top: 2px;
}

/* ---- flags notice ------------------------------------------------------- */
.pdra-flags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin: 0 0 var(--s-4);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-md);
  background: var(--c-invert-2);
}

.pdra-flags-title {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--c-mid);
}


/* ---- outcome ------------------------------------------------------------ */
.pdra-outcome-heading {
  margin: 0 0 var(--s-4);

  color: var(--c-body);
}

.pdra-outcome-body {
  margin: 0 0 var(--s-4);
  color: var(--c-mid);
}

/* Verdict stroke wrapper (Seth 2026-08-20): the original stand-off stroke
   kept, but wrapping ONLY the results content - never the callout above
   (the old [data-outcome] host variants flanked everything, and mapped
   PERMITTED IMPROVEMENT to navy). Colour = the shared verdict synonym
   composed on the wrapper; the callout stays brand green always - it
   carries copy, not result semantics. */
.pdra-outcome-result {
  border-left: 4px solid var(--state-color, var(--c-invert-2));
  padding-left: var(--s-4);
}

/* The wrapper's state synonym is for the STROKE only - its --state-color
   cascades into the card, where canon's card border AND card-header title
   both read it (the whole card tinted verdict-green). Pin both back to
   neutral; the verdict badge is untouched (its own synonym class re-sets
   the var locally on the badge element). */
.pdra-outcome-result .pdra-outcome-card {
  border-color: var(--c-invert-1);
}

.pdra-outcome-result .pdra-outcome-card .card-header .pdra-project-title {
  color: var(--c-primary); /* brand green, matching the hub (Seth ruling) */
}

.pdra-review {
  margin: var(--s-4) 0;
}

.pdra-review-summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--c-primary);
}

.pdra-review-list {
  margin-top: var(--s-3);
}

/* CTA block (destination pending - button rendered disabled). */
.pdra-cta {
  margin: var(--s-5) 0 var(--s-3);
  padding: var(--s-4);
  border-radius: var(--r-md);
  background: var(--c-invert-2);
  text-align: center;
}

.pdra-cta-lede {
  margin: 0 0 var(--s-3);
  color: var(--c-body);
  font-weight: 600;
}

/* Full-report link on the outcome view (canon .btn-primary in the markup). */
.pdra-report-link {
  margin: var(--s-4) 0;
}

/* ---- error -------------------------------------------------------------- */
.pdra-error-title {
  margin: 0 0 var(--s-3);

  color: var(--c-body);
}

.pdra-error-msg {
  margin: 0 0 var(--s-4);
  color: var(--c-mid);
}

/* ---- responsive --------------------------------------------------------- */
@media (max-width: 512px) {
  .pdra-resume-row {
    flex-direction: column;
  }
  .pdra-steps {
    flex-direction: column;
    align-items: center;
  }
  .pdra-step {
    flex-direction: row;
    max-width: none;
    width: 100%;
    text-align: left;
  }}

/* ---- auth: header slot (signed-in chrome only) --------------------------
   Per the 2026-08-17 amendment the header shows auth chrome ONLY when signed
   in (name / your-assessments / sign-out); signed-out renders nothing here.
   The provider chooser now lives inside the auth MODAL, not this slot. */
.pdra-auth {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.pdra-auth-user {
  font-weight: 600;
  color: var(--c-body);
}

/* ---- auth: modal (Get started -> sign-in, then name confirmation) -------
   Canonical .modal > .card markup (components.css doc block). The doc example
   sets the card max-width inline; we use this app class with a token-scaled
   value instead so no inline style is emitted. */
.pdra-modal-card {
  max-width: 400px;
  width: 100%;
  text-align: center;
}

.pdra-modal-lede {
  margin: 0 0 var(--s-4);
  color: var(--c-mid);

}

/* Provider chooser inside the modal. The GIS button renders into
   #pdra-google-btn at a fixed 320px width; the Microsoft button matches it. */
.pdra-auth-providers {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
}

.pdra-auth-google {
  min-height: 40px;
}

/* Canon .error-msg at app scale (Seth-specified 2026-08-19: canon's 12px too
   quiet here). */
.error-msg {
  font-size: 20px;
}

/* Canon .label at app scale (Seth-specified 2026-08-19). */
.label {
  font-size: 16px;
}

/* ---- Form-control accent: PRIMARY not SECONDARY (Seth ruling 2026-08-19) --
   Canon's form family uses --c-secondary for resting borders and checked-hover
   accents. PDRA runs the whole family on --c-primary instead. Mirrors canon's
   own selector organisation (components.css form/controls block) and covers
   components not yet used in-app (textarea, select, checkbox, radio, toggle,
   combo) so future adoption inherits the ruling. Focus states already use
   primary in canon - untouched. Checked-hover FILLS move with their borders
   so no state mixes tokens. */

/* Resting borders */
.input,
.textarea,
.select,
.combo-select-trigger {
  border-color: var(--c-primary);
}

/* App-scale control text (Seth-specified 2026-08-19; canon default 16px)
   + League Spartan baseline trim (Seth-specified: bottom 8px vs canon 10px). */
.input,
.textarea,
.select {
  font-size: 20px;
  padding-bottom: 8px;
}

/* Select hover: border + the arrow-zone divider strip */
.select:hover {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8' viewBox='0 0 14 8'%3E%3Cpath d='M0 0l7 8 7-8z' fill='white'/%3E%3C/svg%3E"),
    linear-gradient(to right, transparent calc(100% - 38px), var(--c-primary) calc(100% - 38px));
  border-color: var(--c-primary);
}

/* Select resting/error chevrons: canon hardcodes TD colours inside SVG data
   URIs (tokens cannot reach into a data URI), so the full two-layer
   background-image is re-declared with PD fills (Seth 2026-08-20): resting
   TD teal 2A8A81 -> PD primary 196131; error TD red DC2626 -> PD red C0392B.
   Divider-strip gradient layer preserved verbatim from canon. Hover (white
   chevron) needs no recolour. combo-select trigger left canon until adopted. */
.select {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8' viewBox='0 0 14 8'%3E%3Cpath d='M0 0l7 8 7-8z' fill='%23196131'/%3E%3C/svg%3E"),
    linear-gradient(to right, transparent calc(100% - 38px), var(--c-invert-1) calc(100% - 38px), var(--c-invert-1) calc(100% - 37px), transparent calc(100% - 37px));
}

.select.error {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8' viewBox='0 0 14 8'%3E%3Cpath d='M0 0l7 8 7-8z' fill='%23C0392B'/%3E%3C/svg%3E"),
    linear-gradient(to right, transparent calc(100% - 38px), var(--c-red) calc(100% - 38px), var(--c-red) calc(100% - 37px), transparent calc(100% - 37px));
}

/* Checkbox checked/indeterminate hover accent */
.choice:hover .checkbox:checked,
.checkbox:checked:hover,
.choice:hover .checkbox:indeterminate,
.checkbox:indeterminate:hover {
  background-color: var(--c-primary);
  border-color: var(--c-primary);
}

/* Radio checked hover accent */
.choice:hover .radio:checked,
.radio:checked:hover { border-color: var(--c-primary); }
.choice:hover .radio:checked::after,
.radio:checked:hover::after { background: var(--c-primary); }

/* Toggle checked hover track */
.toggle:has(input:checked):hover { background: var(--c-primary); }

/* Combo trigger hover border */
.combo-select:hover:not(:has(:disabled)) .combo-select-trigger {
  border-color: var(--c-primary);
}

/* Layout only - skin is canon .error-msg (composed in markup, canon reset
   item 1, 2026-08-19; margins per Seth review). */
.pdra-auth-error {
  margin-bottom: var(--s-4);
}

.pdra-auth-error[hidden] {
  display: none;
}

.pdra-modal-trust {
  margin: var(--s-4) 0 0;

  color: var(--c-mid);
}

/* Microsoft sign-in button - branded parity with the GIS-rendered Google
   button: white face, subtle border, four-square mark left of the label
   (per Microsoft's sign-in branding guidance). This is a vendor-branded
   control, so its palette is fixed by Microsoft's guidance, not app tokens. */
.pdra-auth-ms {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  /* Fixed shared width with the GIS button (renderButton width: 320) so the
     pair sit as visual equals - change BOTH together. */
  width: 320px;
  height: 40px;
  background: #ffffff;
  color: #3c4043;
  border: 1px solid #dadce0;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-weight: 500;
  cursor: pointer;
}
.pdra-auth-ms:hover {
  background: #f7f8f8;
}
.pdra-auth-ms-logo {
  flex: 0 0 auto;
}

/* Name-confirmation form (swapped into the SAME modal card on first sign-in). */
.pdra-name-form {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  text-align: left;
}

/* ---- "Your assessments" account view ------------------------------------ */
.pdra-account-heading {
  margin: 0 0 var(--s-4);
  color: var(--c-body);
}

.pdra-account-status {
  color: var(--c-mid);
}

.pdra-account-list {
  list-style: none;
  margin: 0 0 var(--s-4);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.pdra-account-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
}

.pdra-account-meta {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

.pdra-account-outcome {
  font-weight: 600;
  color: var(--c-body);
}

.pdra-account-date {
  color: var(--c-mid);
}

@media (max-width: 512px) {
  .pdra-account-item {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ---- project init (address form + prefill) [S-B] ------------------------ */
.pdra-init-heading {
  margin: 0 0 var(--s-3);
  color: var(--c-body);
}

.pdra-init-form {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  text-align: left;
  margin-top: var(--s-4);
}

.pdra-init-submit {
  margin-top: var(--s-2);
}

/* Dismissible prefill offer - quiet panel above the fields. */
/* Layout only - colour comes from canon .notice.warning (amber --state-fade
   bg + --state-color border). The old background override here re-skinned the
   canon notice grey - removed 2026-08-19 (Seth walkthrough catch). */
.pdra-prefill {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  text-align: left;
}

.pdra-prefill-label {
  font-weight: 600;
  color: var(--c-body);
}

.pdra-prefill-addr {
  color: var(--c-mid);
}

.pdra-prefill-actions {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
}

/* ---- Tier-2 address autocomplete dropdown [S-D] ------------------------- */
/* Positioned wrapper around the address-line input so the popup anchors to the
   field. The input is canon .input; this wrapper only positions the popup. */
.pdra-typeahead {
  position: relative;
  display: block;
}

.pdra-typeahead .input {
  width: 100%;
}

/* The suggestions listbox: an elevated panel directly under the input. Styled
   from canon tokens (radius/border/colour); scrolls when long. */
.pdra-ac-list {
  position: absolute;
  top: calc(100% + var(--s-1));
  left: 0;
  right: 0;
  z-index: 20;
  margin: 0;
  padding: var(--s-1);
  list-style: none;
  max-height: 240px;
  overflow-y: auto;
  background: white;
  border: 1px solid var(--c-invert-1);
  border-radius: var(--r-sm);
  box-shadow: 0 6px 20px color-mix(in srgb, var(--c-black) 14%, transparent);
}

.pdra-ac-option {
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  color: var(--c-body);

  cursor: pointer;
}

/* Active (keyboard or hover) option - aria-selected drives the highlight. */
.pdra-ac-option[aria-selected="true"] {
  background: color-mix(in srgb, var(--c-primary) 12%, transparent);
  color: var(--c-body);
}

/* ---- project hub [S-B] -------------------------------------------------- */
.pdra-hub-lede {
  text-align: left;
  max-width: none;
}

.pdra-projects {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  margin: var(--s-4) 0;
  text-align: left;
}

.pdra-project-title {
  margin: 0 0 var(--s-2);

  color: var(--c-body);
}

/* Header-band sit + slimmer band (Seth 2026-08-20). */
.card-header .pdra-project-title {
  margin-top: 2px;
}

.pdra-project .card-header {
  padding-top: 8px;
  padding-bottom: 8px;
}

/* Secondary address line beneath a named project's title (S-E). */
.pdra-project-addr {
  margin: calc(-1 * var(--s-1)) 0 var(--s-2);

  color: var(--c-mid);
}

/* Card body action row: verdict left (when present), buttons right. */
.pdra-project-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-top: var(--s-2);
}

/* Verdict text reads the composed state synonym (green/red/amber set
   --state-color; consumers must read it - canon synonyms paint nothing
   themselves). Fallback body ink if no synonym present. */
.pdra-project-verdict {
  color: var(--state-color, var(--c-body));
}

.pdra-project-row .pdra-project-actions {
  margin-left: auto; /* buttons stay right even with no verdict */
}

.pdra-project-actions {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
}

/* Header state flags (header SIBLINGS of the h3, not inside it): normal
   case (canon .flag is uppercase); state colour as the 1px outline. The
   League Spartan sit fix is a transform on the TEXT SPAN ONLY - no layout
   change, so the pill stays slim and the dot stays centred (the auth-ghost
   lesson adapted for a two-child pill) - all Seth-specified 2026-08-19. */
.pdra-project .card-header .flag {
  text-transform: none;
  border-color: var(--state-color, var(--c-invert-2));
}

.pdra-project .card-header .flag .pdra-flag-label {
  transform: translateY(2px);
  text-transform: none;
  color: var(--state-color, var(--c-body));
}

/* Hub head row: heading left, Start-another right (Seth 2026-08-20).
   Replaces the orphaned .pdra-hub-another rule. The heading's canon 16px
   margin-bottom moves onto the row - inside a centred flex row it inflates
   the h2's margin box and shoves the button below the baseline. */
.pdra-hub-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
}

.pdra-hub-head .pdra-account-heading {
  margin-bottom: 0;
}



/* ---- cost-notification screen [S-B] ------------------------------------- */
.pdra-cost-price {
  margin: 0 0 var(--s-3);
  font-family: var(--ff-display);

  color: var(--c-body);
}

/* Action row: pay + back side by side with standard gap (Seth 2026-08-20).
   Replaces the orphaned .pdra-cost-pay/.pdra-cost-back rules (markup had
   long since dropped those classes - buttons were butting together). */
.pdra-cost-actions {
  display: flex;
  gap: var(--s-3);
  justify-content: center;
  margin-top: var(--s-3);
}

/* Postcode assist hint (advisory - ok/warn states, canon tokens). */
.pdra-field-hint-ok {
  color: var(--c-primary);
}

.pdra-field-hint-warn {
  color: var(--c-amber);
}

/* ---- PD button treatment (Seth walkthrough, 2026-08-18) ------------------
   Brand-level button typography for this app: larger, ALL CAPS with letter
   spacing, League Spartan baseline correction (the face rides high in its em
   box, so bottom padding is trimmed relative to top for optical centring).
   Colours/fills/hovers still come verbatim from canonical components.css -
   this layer touches TYPE and SPACING only. */

/* Wizard answer buttons: prominent - roughly double type size, default
   canonical fill, rounded (Seth: "like the large size... default button
   style fill and rounded corners and probably twice the existing font size"). */

/* Copy-resume-link: standard button, doubled width for prominence. */

/* Page-header account chrome: Title Case (not caps), sized to match the
   username, ghost styling retained. */


/* ---- wizard topline: back-nav inline-left of the context eyebrow --------- */
.pdra-topline {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-3);
}

.pdra-topline .pdra-eyebrow {
  margin: 4px 0 0; /* top 4px: baseline-align with the back-nav icons (Seth) */
}

/* ---- hub project cards: trim excess bottom padding ----------------------- */
.card.pdra-project {
  padding-bottom: var(--s-4);
}

/* ---- walkthrough batch 2 (Seth, 2026-08-18) ------------------------------ */

/* Header account chrome: username matches canon .btn text (16px) so the
   chrome reads as one size (Seth ruling 2026-08-19, replacing yesterday's
   parity fix that outlived the buttons it matched). */
.pdra-auth-user {
  font-size: 16px;
  padding-top: 4px; /* Seth-specified - baseline align with the chrome ghosts */
}

/* Answer buttons: pulled back ~20% from mega ("bordering on tacky"). */

/* Copy button: half the previous width - "double the original", not five times. */

/* back-nav (Seth 2026-08-20): primary chevron, 2px border (canon 1px);
   hover = solid secondary fill with white chevron. */
.back-nav {
  border-width: 2px;
  border-color: var(--c-primary);
  color: var(--c-primary);
}

.back-nav:hover {
  background: var(--c-secondary);
  border-color: var(--c-secondary);
  color: white;
}

/* Prefill banner now rides the canonical amber .notice - keep only the
   layout internals of the old custom banner. */
.notice.pdra-prefill .pdra-prefill-actions {
  margin-top: var(--s-3);
  display: flex;
  gap: var(--s-3);
}

/* ---- walkthrough batch 3 (Seth, 2026-08-18) ------------------------------ */

/* Mega treatment shared by the landing CTA, init submit, and (via
   .pdra-answer) the wizard answers - "it's the whole point". */

/* Required-field marking + explainer. */
/* Consumer for the canon state synonyms on inline text: .red (etc.) sets
   --state-color only - something must read it (same pattern as canon's own
   ".notice strong"). Compose as class="red pdra-required-star". */
.pdra-required-star {
  color: var(--state-color, var(--c-red));
  font-size: 20px; /* Seth-specified */
}

.pdra-required-note {
  margin: var(--s-2) 0;

  color: var(--c-mid);
}

/* NOT SURE answers: solid amber (clarification route), white text; canon
   hover-to-secondary still applies for consistency. */

/* Buttons: +4px-equivalent top padding at base size (Seth eyeball round) -
   pushing the high-riding face further down. em-scaled as before. */

/* Page-header bar shaved 3px (eyeball test). */
body.has-page-header {
  --page-header-height: 45px;
}

/* Cost price: breathing room below (blank-line effect). */
.pdra-cost-price {
  margin-bottom: var(--s-5);
}

/* App-level link affordance: hover underline on ALL links (Seth ruling
   2026-08-19; canon hover is colour-shift only). Anchors composed as
   buttons are excluded (Seth 2026-08-20 - they are buttons, not links). */
a:not(.btn):hover {
  text-decoration: underline;
}

/* Value anchor line on the landing (verified fee anchor, Seth 2026-08-18). */
.pdra-value-line {
  margin: 0 auto var(--s-5);
  max-width: 544px;

  font-weight: 600;
  color: var(--c-primary);
}

/* ---- review navigation (slice S-F) --------------------------------------
   Back means REVIEW, change means rewind. The review view reuses the wizard
   topline + .back-nav canon component; the forward chevron is the same
   component mirrored. App-widget classes only, canon tokens only. */

/* Review topline: eyebrow takes the free space between the back and forward
   chevrons so the forward affordance sits hard-right. */
.pdra-topline-review .pdra-eyebrow {
  flex: 1 1 auto;
}

/* Forward chevron shares the optical baseline nudge with the back chevron. */
.pdra-topline .pdra-fwd-nav {
  position: relative;
  top: -2px;
}

/* Calm review context line - quiet, non-alarming. */
/* Inert answer display in review: every option is shown but disabled. Width
   comes from explicit .btn-full on the buttons (same mechanism as live
   answers - Seth ruling 2026-08-19). */

/* Change affordance sits below the inert options, set off by a hairline like
   the live trail block. */
.pdra-review-change {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-invert-2);
}

/* Review mode: light amber wash on the question region (Seth, 2026-08-18) -
   state colour, not button styling; PD amber-fade token. */
.pdra-question-review {
  background: var(--c-invert-2); /* lightest grey (Seth 2026-08-19; supersedes the S-F amber wash) */
  border-radius: var(--r-md);
  padding: var(--s-4);
}

/* .btn-amber - STYLEGUIDE-PENDING (rule-5 prototype; tracking: TD STYLEGUIDE
   BUGS.md 2026-08-18 "btn state-synonym coupling / btn-amber"). Canon's state
   synonyms are not yet consumed by .btn (0 of 70 consumer lines are buttons),
   so this project adds the missing amber variant in the override layer,
   mirroring canon's own .btn-danger shape. Hover falls through to canonical
   .btn:hover (secondary) exactly like every other variant. Back-port to
   td_styleguide (ideally as full state-var coupling) before prod promotion,
   then delete this block and consume canon. */
.btn-amber {
  background: var(--c-amber);
  color: white;
  border-color: var(--c-amber);
}

/* ---- S-G callback-capture callout --------------------------------------- */
/* Seth 2026-08-20: PD pale green callout. Canon .callout-feature tints from
   --c-secondary (PD navy here); the results-page callback callout wants the PD
   green brand accent instead. Re-declares canon's exact gradient shape with
   --c-primary (PD green) and moves the left border to match. Layout/skin only -
   no typography override (canon owns type; the consent line uses canon
   .help-text). */
.callout-feature {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--c-primary) 4%, transparent),
    color-mix(in srgb, var(--c-primary) 8%, transparent)
  );
  border-left-color: var(--c-primary);
  border-radius: var(--r-md); /* match the cards (canon default is --r-sm) */
}

/* Action area + inline mini form layout (Seth 2026-08-20). Spacing only. */
.pdra-callback-action {
  margin-top: var(--s-3);
}
.pdra-callback-form {
  margin-top: var(--s-2);
}
.pdra-callback-consent {
  margin-top: calc(-1 * var(--s-2));
  margin-bottom: var(--s-3);
}
.pdra-callback-optin {
  margin-bottom: var(--s-3);
}
.pdra-callback-form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-3);
}

/* ---- K4: multi-flow run surfaces (checklist / eyebrows / results) --------
   Layout + spacing ONLY - every visible skin is canon (.choice/.checkbox,
   .help-text, .btn composition, the shared state synonyms). Tokens/px per the
   contract. */

/* Works checklist (meta multiselect): stacked canon .choice rows. The chart's
   option copy carries a deliberate line break before its parenthetical
   examples - pre-line honours it without inventing markup. */
.pdra-checklist {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-3);
}

.pdra-checklist .choice {
  align-items: flex-start; /* two-line labels: box aligns to the first line */
}

.pdra-checklist-text {
  white-space: pre-line;
}

/* Walkthrough tweaks (Seth, 2026-08-28). Layout/size only - skin stays canon.
   Checkbox ~30% larger than the 16px canon base with the tick glyph scaled to
   match, and nudged 2px down so the box sits on the label's first-line
   baseline rather than riding high. */
.pdra-checklist .checkbox {
  width: 21px;
  height: 21px;
  margin-top: 2px;
  flex-shrink: 0;
}

.pdra-checklist .checkbox:checked,
.pdra-checklist .checkbox:indeterminate {
  background-size: 21px 21px;
}

/* Option typography: class name strong on the first line, the explainer on
   its own line in quiet grey (parens stripped in JS). */
.pdra-checklist-name {
  display: block;
  /* Pin to body ink: edit contexts (trail/review rows) cascade grey into the
     checklist - the identifier stays default-dark everywhere (Seth, 2026-08-28). */
  color: var(--c-body);
}

.pdra-checklist-sub {
  display: block;
  color: var(--c-mid);
}

/* "- " lines in chart question text render as a real list (designated-land
   enumerations). Lives inside the question heading; inherits its type scale. */
.pdra-question-list {
  margin: var(--s-2) 0 0;
  padding-left: var(--s-5);
  list-style: disc;
}

.pdra-checklist-helper {
  margin: 0;
}

.pdra-checklist-actions {
  margin-top: var(--s-2);
}

/* Group eyebrow above a run question (works-language context; "About the
   property" on the global meta questions). Same quiet chrome as the base
   eyebrow; tightened to sit against the question heading. */
.pdra-group-eyebrow {
  margin: 0 0 var(--s-2);
}

/* Group eyebrow separating a run trail's per-flow stretches (wizard disclose
   + results trodden trail). */
.pdra-trail-group {
  margin: var(--s-4) 0 var(--s-2);
}

/* Seeded-answer cue rides the answer line, quiet (canon .help-text skin). */
.pdra-trail-seeded {
  margin-left: var(--s-2);
}

/* Class-qualifier header on run results: one row per class verdict. Verdict
   text reuses .pdra-project-verdict (state synonym composed) - here it sits
   right of the works-language name. */
.pdra-run-verdicts {
  padding: var(--s-3) var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.pdra-run-verdict-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-3);
  flex-wrap: wrap;
}

.pdra-run-verdict-name {
  font-weight: 600;
}

/* Rules-version stamp line - quiet footnote BELOW the results card
   (moved outside the card, Seth 2026-08-28). */
.pdra-run-stamp {
  margin: var(--s-3) 0 var(--s-4);
  color: var(--c-mid);
  font-size: 13px;
}

/* Multiselect answer in the trail: stacked identifier list (Seth, 2026-08-28
   - explainers dropped, one option per line). Rides inside the answer strong. */
.pdra-trail-answer-list {
  margin: 0;
  padding-left: var(--s-4);
  list-style: disc;
}

/* ---- Run results shape (Seth design, 2026-08-28) ------------------------
   Bare summary at page top: title-as-page-header + inline badge, address,
   per-class verdict lines. Trail card below with grey/green group bands. */
.pdra-outcome-summary {
  margin: 0 0 var(--s-5);
}

.pdra-outcome-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}

.pdra-outcome-title {
  margin: 0;
  color: var(--c-primary);
}

.pdra-outcome-summary .pdra-project-addr {
  margin: var(--s-2) 0 0;
  /* Hairline divider between the address and the verdict list (Seth). */
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-invert-2);
}

.pdra-outcome-summary .pdra-run-verdicts {
  margin-top: var(--s-3);
}

/* Group bands sit FLUSH on the first row beneath them - kill the canon
   variant's bottom margin AND the trail table's own top margin when it
   directly follows a band (the actual gap source: .pdra-trail-table
   margin-top rides under the band). */
.pdra-outcome-card .card-header.headers-grey {
  margin-bottom: 0;
}

.pdra-outcome-card .card-header.headers-grey + .pdra-trail-table {
  margin-top: 0;
}

/* Mid-card divider band: clear air above the band (the canon variant's
   negative top margin is for card-top caps), square corners, same bleed. */
.pdra-outcome-card .card-header.headers-grey.pdra-trail-band {
  margin-top: var(--s-5);
  border-radius: 0;
}

/* ---- K5: answer-change flow ---------------------------------------------- */
/* "Ruled out" flag on a decisive trail answer row (canon .flag.red.dot
   composition). Same base.css [class$="-label"] guard as the hub flag: the
   catch-all recolours any *-label class, so the state colour is restated on
   the inner span explicitly. Sits beside the answer value, never pushes the
   Change control off the right edge. */
.pdra-trail-a .flag.pdra-ruled-out {
  text-transform: none;
  border-color: var(--state-color, var(--c-invert-2));
  flex-shrink: 0;
}

.pdra-trail-a .flag.pdra-ruled-out .pdra-flag-label {
  transform: translateY(2px);
  text-transform: none;
  color: var(--state-color, var(--c-body));
}

/* Confirm-replay screen: the quiet context line above the prefilled options
   (canon .help-text supplies the face; this is layout only). */
.pdra-confirm-note {
  margin: 0 0 var(--s-3);
}

/* The single primary action of a confirm screen, set off from the retained
   option stack with clear air (the options above it stay tappable). */
.pdra-answers-confirm .pdra-confirm-continue {
  margin-top: var(--s-4);
}

/* Change-confirm modal action row (canon buttons; layout only). */
.pdra-change-actions {
  display: flex;
  gap: var(--s-3);
  justify-content: center;
  margin-top: var(--s-4);
}

/* STYLEGUIDE-PENDING (rule-5 prototype, tracked in TD STYLEGUIDE BUGS.md
   2026-08-28): ink-filled button variant - canon has no dark fill. Born for
   the confirm-rewalk "Confirm and continue", which must read clearly distinct
   from the primary-filled retained answer above it (Seth ruling). Back-port
   to canon then delete this block and consume the canonical class. */
.btn-ink {
  background: var(--c-body);
  color: white;
  border-color: var(--c-body);
}

.btn-ink:hover,
.btn-ink:focus {
  background: var(--c-primary);
  border-color: var(--c-primary);
}

/* Notices ribbon admin gating: .pdra-flags' own display:flex (line ~681)
   outguns the generic .admin-only display:none at equal specificity - the
   same cascade class as the [hidden]-vs-.btn lesson. Compound selectors
   settle it (and the admin reveal restores the correct flex, not
   inline-block). */
.pdra-flags.admin-only {
  display: none;
}

html[data-admin="1"] .pdra-flags.admin-only {
  display: flex;
}

/* ---- admin surface layout hooks (Forge, 2026-09-02, pdra-admin-overhaul) --
   The server-rendered /admin pages share this sheet with the SPA. Layout-only
   pdra-admin-* hooks: the content block sits DIRECTLY in body after the
   page-header (canon skeleton) and clamps to the fixed-width 1200px column;
   the filter bar lays canon .field blocks in a row; click-through rows get a
   pointer. Every component inside is canon (.table, .flag, .badge, .field,
   .label, .input, .select, .checkbox, .btn) and is not re-skinned here. */
.pdra-admin {
  width: 100%;
  max-width: 1200px;
  margin: 16px auto var(--s-8);
}

.pdra-admin-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
}

.pdra-admin-filters .field {
  margin-bottom: 0;
  min-width: 180px;
}

/* Clear pill sits 6px above the input baseline (Seth, 2026-09-03). */
.pdra-admin-filters .pdra-admin-clear {
  margin-bottom: 6px;
}

.pdra-admin .table tr[data-href] {
  cursor: pointer;
}

.pdra-admin-badges {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--s-1);
}

.pdra-admin-nav {
  display: flex;
  gap: var(--s-3);
  margin-top: var(--s-4);
}

/* ---- admin detail = read-only mirror of the results page (Seth, 2026-09-02 pm)
   Capped column (Seth: ~800px) so long-worded questions wrap compactly;
   everything inside reuses the results-page classes above. Layout only. */
.pdra-admin-detail {
  max-width: 800px;
  margin: 0 auto;
}

.pdra-admin-customer {
  margin: var(--s-3) 0 0;
  color: var(--c-body);
  font-weight: 600; /* same weight as .pdra-run-verdict-name */
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}

.pdra-admin-created {
  margin: var(--s-1) 0 0;
  color: var(--c-mid);
  font-size: 13px;
}

/* Admin flags and badges take the SAME fixes as the hub and results page
   (Seth, 2026-09-02 pm: already solved in the main app, do not re-solve):
   League Spartan sit fix on the text span only, normal case, state colour
   on the flag outline and label, white badge text (canon base.css's
   [class$="-label"] catch-all would otherwise recolour both labels). Scoped
   to .pdra-admin, which wraps every admin page's content. */
.pdra-admin .flag {
  text-transform: none;
  border-color: var(--state-color, var(--c-invert-2));
}

.pdra-admin .flag .pdra-flag-label {
  transform: translateY(2px);
  text-transform: none;
  color: var(--state-color, var(--c-body));
}

.pdra-admin .badge .pdra-badge-label {
  transform: translateY(2px);
  color: white;
}

/* Compact list (Seth, 2026-09-03): Status and Customer cells stack their
   lines; each class sits on one line with its verdict badge beneath. */
.pdra-admin-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-1);
}

.pdra-admin-id {
  font-size: 12px;
  color: var(--c-mid);
}

.pdra-admin-addr {
  font-size: 13px;
  color: var(--c-mid);
}

.pdra-admin-class {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.pdra-admin-class-name {
  white-space: nowrap;
}

.pdra-admin-class + .pdra-admin-class {
  margin-top: var(--s-2);
}

/* Admin detail callback card (Seth, 2026-09-04): a clear gap between the card and
   the results table beneath it. Layout override on the app hook class only; the
   card itself is canon (.card > .card-header.headers-grey > .card-body.split). */
.pdra-admin-callback {
  margin-bottom: var(--s-6);
}

.pdra-admin-callback .card-body {
  padding-top: var(--s-2);
  padding-bottom: var(--s-2);
}

/* Callback card columns (Seth, 2026-09-04): divider on column A at full height in
   the card-border grey (canon .split-flip puts the border on the first child); the
   Contacted tick indents to the field values. */
.pdra-admin-callback .split {
  align-items: stretch;
}

.pdra-admin-callback .split > :first-child {
  border-right-color: var(--c-invert-1);
}

.pdra-admin-contacted {
  display: block;
  padding-left: var(--s-5);
}
